Skip to content

docs(conformance): record where requirements are gated, and where they deliberately are not - #312

Merged
dmealing merged 1 commit into
mainfrom
docs/conformance-requirements-boundary
Aug 19, 2026
Merged

docs(conformance): record where requirements are gated, and where they deliberately are not#312
dmealing merged 1 commit into
mainfrom
docs/conformance-requirements-boundary

Conversation

@dmealing

Copy link
Copy Markdown
Member

What

Adds a "Split coverage" subsection to docs/CONFORMANCE.md, plus the missing requirement-* row in the fixture-to-doc mapping.

Why

The corpus matrix is corpus-shaped: one row per corpus. A feature whose coverage splits — across several corpora, or between its vocabulary and its behaviour — never gets a row, so its boundary is discoverable only from the feature doc. Requirements are exactly that shape, and today docs/CONFORMANCE.md does not mention them at all.

The boundary being recorded:

  • Vocabulary — gated in all five ports. The types, attributes and closed enums travel in registry-conformance's byte-matched manifest, and accept/reject behaviour is pinned by requirement-* fixtures in fixtures/conformance/.
  • Checks — TypeScript only, by decision. The meta verify diagnostics ship in the TS CLI; the other ports load and validate and stop there. Same call as ADR-0015 — one implementation of a build-time gate rather than five. verify-conformance therefore holds no requirement cases.

That last fact is the reason this is worth writing down: an empty verify-conformance looks identical whether it is a deliberate scope decision or an oversight. It was previously stated only at docs/features/requirements.md:6-7, which is not where a reader goes to ask what is gated where.

How it is written

As mechanisms, not attribute names. The requirement vocabulary has a breaking change scheduled (FR-038) that moves what the manifest contains without moving the boundary between the two halves — so enumerating today's attributes would go stale at that slot while the boundary claim stays true.

Provenance

Found while answering a question about cross-language requirements coverage after #311. Raised with the session that owns FR-038, which declined a cross-port verify corpus with reasons (documented scope, the ADR-0015 precedent, and a rule with a scheduled expiry) and handed this documentation gap back as non-colliding. No overlap with that worktree.

Verification

Docs-only, no code paths touched. Every link and fixture prefix asserted in the diff was checked to exist: docs/features/requirements.md, spec/decisions/ADR-0015-single-shared-migrate-engine.md, fixtures/conformance/requirement-disposition-and-planned, fixtures/conformance/requirement-levels-and-nesting, fixtures/conformance/error-unknown-attr-requirement.

🤖 Generated with Claude Code

…y deliberately are not

The corpus matrix is corpus-shaped, so a feature split between its vocabulary and
its behaviour gets no row and its boundary is discoverable only from the feature
doc. Requirements are exactly that: the vocabulary is byte-gated in all five ports
via the registry-conformance manifest plus requirement-* metamodel fixtures, while
the meta verify checks over them are TypeScript-only by decision, on the same
ADR-0015 reasoning that made schema migration TS-owned. verify-conformance holds no
requirement cases, and a reader had no way to tell that apart from an oversight.

Stated as mechanisms rather than as a list of attribute names, because the
requirement vocabulary has a breaking change scheduled (FR-038) that moves what the
manifest contains without moving the boundary itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dmealing
dmealing merged commit 5d48bcb into main Aug 19, 2026
1 check passed
@dmealing
dmealing deleted the docs/conformance-requirements-boundary branch August 19, 2026 04:11
dmealing added a commit that referenced this pull request Aug 19, 2026
Additive to #312's "Split coverage" section, which arrived while I was writing the
same thing. Its framing is better than mine — a general heading that extends to any
feature split across corpora — so this keeps it and adds only the two parts mine
carried that it does not.

FIRST, THE TEST. A deliberate split and a real parity gap look identical in the
matrix: one port covered, four blank. What separates them is what the uncovered
ports CLAIM. Requirements claim nothing — they load the vocabulary and stop, which
is what the feature doc says. `{{#hasField}}` in 0.23.1 was the opposite: the JVM
emitted `has<Field>()` onto payload records AND verify accepted the section, while
no render engine implemented the other half. Two ports shipped halves of one
promise and no fixture could see it. A split is deliberate when no port makes a
claim the corpus would have to check; it is a gap when one already did.

SECOND, THE HAZARD the scheduled removal walks into. Contract prose lives inside
attr DESCRIPTIONS in `expected-registry.json` — byte-matched by five ports, gated
nowhere else. `@verifiedBy` holds "verify checks each name EXISTS and is not
skipped; it never runs them"; `@trackedBy` holds "NOT resolved by verify, which
does not reach the network". Deleting an attribute deletes its description and the
guarantee's only gate with it. Same class as the ADR-0047 renumbering trap, where
that identifier could not be renumbered precisely because it was baked into those
same byte-gated descriptions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhpswkF1NvwxhFWMmdAT15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant