fix(directory): open-world listing shape — tolerate unknown top-level fields (SIG-5 / §11.1.2)#16
fix(directory): open-world listing shape — tolerate unknown top-level fields (SIG-5 / §11.1.2)#16cX3po wants to merge 2 commits into
Conversation
… fields (SIG-5 / §11.1.2) listingVerification rejected any listing whose top-level keys weren't in a frozen 13-key allowlist. That contradicts the §11.1.2 additivity contract and the older-reads-newer guarantee (CORE.md): the first spec minor that adds a top-level listing field would make every such listing rejected by every directory running the closed allowlist. SIG-5 (preserve-unknown) is the mechanism — a verifier MAY ignore the meaning of unknown fields but MUST preserve their bytes. Fix is validator-only. verifyListing() already hashes the whole scope (contentHash over raw-minus-signature), so unknown fields stay signature-bound and a field injected after signing still fails the hash — signature binding is unchanged. The validator reads only the recognised fields, so unknown fields are neither indexed nor interpreted. Vector pair added: (1) an unknown additive top-level field present at signing is accepted as the dacs-v0.1 profile; (2) an unknown field injected AFTER signing is rejected on the whole-scope hash. Full suite 35/35, typecheck clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Credit for surfacing this belongs to the independent directory review that flagged the closed top-level allowlist — we verified it against the RI + spec and took the fix so it doesn't sit as a duplicate open issue. How we checked it before filing:
One thing worth a second pair of eyes: |
mj-deving
left a comment
There was a problem hiding this comment.
Reviewed this against origin/main, including the identityVerification.ts question from the PR comment.
Validation I ran locally on head 2d3c92b21f46e79dc7e7175c45da2cbdb5b265a5:
bun run test-> 35/35 passbun run typecheck-> passautoreview --mode branch --base origin/main-> clean, no accepted/actionable findings
My read on the second-pair-of-eyes question: identityVerification.ts is not the same closed-world acceptance bug. The INSTITUTIONAL set is only a tier-elevation gate after a claim has already passed verifiedBy / recipe / authority checks; an unknown scheme does not make the listing invalid, it just cannot silently elevate to institutional unless the Directory policy knows that scheme is institution-grade.
So the PR's open-world listing change looks bounded: unknown listing fields remain whole-scope signature-bound, and the injected-after-signing negative covers the important safety edge.
No findings from me.
Problem
dacs-directorylistingVerification.tsrejected any listing whose top-level keys were not in a frozen 13-key allowlist (closed-world):This contradicts the §11.1.2 additivity contract and the older-reads-newer guarantee (CORE.md): a later minor may add a top-level listing field, and an older reader must still consume the newer-minor artifact. SIG-5 (preserve-unknown) is the mechanism — a verifier MAY ignore the meaning of unknown fields but MUST NOT strip them.
It is latent on v0.2 (today's additions are nested), but the first spec minor that adds a top-level listing field would make every such listing rejected by every directory still running the allowlist.
Fix (validator-only)
Remove the closed-world reject clause (and the now-unused allowlist). Signature integrity is unchanged:
verifyListing()already hashes the whole scope viacontentHash(scope)(raw minussignature), so unknown fields stay signature-bound and a field injected after signing still fails the hash. The validator reads only the recognised fields, so unknown fields are neither indexed nor interpreted.Tests
A vector pair in
verification.test.ts:dacs-v0.1profile;Receipts: full suite 35/35,
tsc --noEmitclean, and the acceptance vector provably fails without the fix (closed allowlist →null).Independently surfaced during an external review of the directory; verified against the spec and the RI before filing.