lib+vectors: uplift typed_ref.py citations to -01 §7/§7.1, fold Joel's ARP typed-ref vectors - #18
lib+vectors: uplift typed_ref.py citations to -01 §7/§7.1, fold Joel's ARP typed-ref vectors#18StevenMih wants to merge 3 commits into
Conversation
…l vector typed_ref.py's digest_alg consistency check (-01 §7.1) was already implemented in 7c9f642 (2026-07-31, cpb-pr2-anton-round2), but the module still declared its target as -00 and every typed-ref citation pointed at §6/§6.1 (Statement-to-Receipt Binding / Leaf Construction) instead of §7/§7.1 (Typed Digest References / Cross-Profile Comparability) -- the section that actually defines this behavior in both -00 and -01, which share identical top-level numbering. Adds typed-ref-fail-05, promoting the existing digest_alg-mismatch coverage into a proper vector JSON (SHA-512, MD5, an unregistered name, and the empty string, each carrying an otherwise-correct digest) and registers its failure_reason in the vector-coverage dispatch gate. [cpb-typed-ref-01-uplift-and-joel-vectors] Signed-off-by: stevenmih <stevenmih88-3@gmail.com>
…yout Byte-for-byte fold of vectors 01 (PASS control) and 02 (MUST-FAIL, digest_alg inconsistent with registered context) from arp-typed-ref-cpb01-v0.1.json (SHA-256 88153dd1...673d, verified against Joel's pin). 03 is excluded per PM ruling (withdrawn by its own criterion), 04 is not-applicable to this library (no leaf construction), 05 is ARP-side. test_typed_ref_pass now tolerates typed-ref-cpb01-01's schema (registry entry at the vector's top level, expected digest under `expected` rather than `verification`) without touching the vector's own field layout. test_vector_coverage.py registers a real handler for digest_alg_inconsistent_with_registered_context so the coverage gate exercises typed-ref-cpb01-02 against the actual library; confirmed it flips to failure when the digest_alg check is mutated out. [cpb-typed-ref-01-uplift-and-joel-vectors] Signed-off-by: stevenmih <stevenmih88-3@gmail.com>
The standalone vector checker (no dependency on the cpb library) had no category matching typed-ref-fail-05's or the newly-folded typed-ref-cpb01-02's shape -- both are must_fail vectors whose carried digest is otherwise correct and whose digest_alg is mislabeled, which is a distinct invariant from every existing category. Without this, both vectors hit the ran_any_check=False hard failure, and the vectors CI check was red starting from the uplift commit. Resolves the registry entry from either shape (nested under cited_artifact, or a sibling of it at the vector's top level) and reads examples from either typed_references_with_mislabeled_digest_alg (a list) or typed_reference (a single object). Registers a mutant generator per the file's own mutation-probe self-test requirement; confirmed locally that a condition-removed mutant (digest_alg set to the correct algorithm) flips the check to failure. [cpb-typed-ref-01-uplift-and-joel-vectors] Signed-off-by: stevenmih <stevenmih88-3@gmail.com>
98753c9 to
b84c41d
Compare
tyche-dev
left a comment
There was a problem hiding this comment.
Reviewed at exact head b84c41da9692385c15e7c32df5c6ce4238a9dce7. Requesting changes on three points, none of which touches the substance of the uplift.
What passes. Re-run at this head: pytest lib/tests/ → 35 passed; check_vectors.py vectors/ → 29 pass/exercised, 1 informative, 5 no-check, 0 FAILED; neutrality self-test OK. The new Category I check is executable rather than decorative — the ARP fail vector is accepted by the pre-uplift checker at 9eebdcf and rejected at this head with DigestAlgorithmMismatchError, the PASS control is accepted, and zeroing its digest is correctly rejected with ContextMismatchError. The disposition recorded in the description is internally coherent: 01/02 folded, 03 withdrawn by its own stated criterion, 04 not applicable because this library builds no log leaf, 05 ARP-side.
1. The citation this PR exists to uplift is still wrong. lib/cpb/typed_ref.py:130 reads:
"""An entry in the Artifact Type Registry (§11.2 / REGISTRY.md).
In the draft in this tree, §11.2 is Low-Entropy Fields, under Security Considerations; the Artifact Type Registry is §13.2, under IANA Considerations. A PR whose stated purpose is a revision/citation uplift should not leave a false section pointer in the file it uplifts.
2. The folded source bytes cannot be independently re-established. The description pins the external file arp-typed-ref-cpb01-v0.1.json at SHA-256 88153dd1c4b62cfd313cd890ae84fc65de1f67bcd6db7556fce00b7893ce673d. That file is not in the repository, not attached to this PR, and not on the email thread I have. The two resulting vector files can be tested on their own, but "byte-for-byte fold" is exactly the claim that cannot be checked without the source. Either attach it or give an immutable retrievable coordinate (a commit pin in Joel's repo would do), so the SHA and the 01/02 extraction can be recomputed rather than taken on trust.
3. This PR and #10 cannot both merge as conformant. #10 mandates exact-byte ASCII comparison for digest_alg. At this head the library compares case-insensitively — lib/cpb/typed_ref.py:315, ref.digest_alg.upper() != expected_alg.upper(), with the same pattern at .github/check_vectors.py:648. Executed against a registered SHA-256 context:
'SHA-256' -> ACCEPTED
'sha-256' -> ACCEPTED
'ShA-256' -> ACCEPTED
'SHA512' -> rejected (DigestAlgorithmMismatchError)
The vector prose here also treats algorithm names case-insensitively. The test suite does not catch the divergence because it carries no case-difference vector. Decide the rule once — exact-byte or case-insensitive — and enforce it with two-sided vectors so whichever line lands second cannot silently contradict the first. This is the same reconciliation #10 is waiting on, so settling it unblocks both.
Release condition. Re-review after (a) §11.2 → §13.2, (b) the source file or an immutable coordinate for it, and (c) the digest_alg rule reconciled with #10 and covered by executable two-sided vectors. Any repaired head needs a fresh exact-head review; no consent transfers from b84c41da.
tyche-dev
left a comment
There was a problem hiding this comment.
Reviewed at exact head b84c41da9692385c15e7c32df5c6ce4238a9dce7, against main as of today's #8 and #19 merges.
No rebase needed. git merge-tree against current main shows zero conflicts, and the section numbers this PR uplifts to are still correct post-#19: as-transmitted landed as §3.3, so Typed Digest References remains §7 and Cross-Profile Comparability §7.1. All checks green at this head.
Two content items to settle before merge, both created by what landed on main after this branch was cut:
-
ArtifactTypeRegistryEntry.__post_init__now misstates the registry. It rejects any algorithm butjcs-nwith "only 'jcs-n' is defined in this revision of the spec" — since #8,as-transmittedis a Registered entry in the Canonicalization Algorithm Registry. Nothing breaks today (the only registered artifact type,agent-action-capsule, usesjcs-n), but the error text now asserts something false about the registry, in a library whose stated discipline is that messages quote the spec accurately. The class docstring also still cites "§11.2 / §11.1" — the -00 numbering this PR exists to retire; IANA is §13 in -01. Two small edits. -
The
purposefield (#19) is silently dropped. The dict path inverify_typed_refextracts exactlytype/digest_alg/digest, so a reference carryingpurposeverifies with the field ignored. For today's single-context registry that is spec-permissible behavior (§13.2:purposeMAY be omitted when exactly one context is registered), but a spec-defined field silently discarded is the same read-in-isolation smell this repo's REGISTRY.md rules exist to prevent. Either (a) accept and validate it minimally — on a single-context type, ifpurposeis present it must match that context's registered label, else raise — or (b) state explicitly in the PR description and a code comment thatpurpose/multi-context handling is scoped out to the fast-follow #19 already flagged (which also owes the ambiguous-purpose MUST-FAIL vector). Both are acceptable; silence is not.
Fix (1) and pick a lane on (2), return the exact head, and I'll do the bounded final review and merge.
Summary
lib/cpb/typed_ref.py's citations from -00 §6/§6.1 to -01 §7/§7.1 (Typed Digest References / Cross-Profile Comparability) — thedigest_algconsistency check itself was already implemented in7c9f642; this fixes the module's stated target and docstrings, and addstyped-ref-fail-05(SHA-512/MD5/unregistered/emptydigest_alg, each carrying an otherwise-correct digest).arp-typed-ref-cpb01-v0.1.json(pinned SHA-25688153dd1c4b62cfd313cd890ae84fc65de1f67bcd6db7556fce00b7893ce673d, verified) byte-for-byte intovectors/typed-refs/pass/02-arp-conformance-baseline.jsonandvectors/typed-refs/fail/06-arp-digest-alg-inconsistent-with-registered-context.json.rawrepresentation typing) excluded per PM ruling — withdrawn by Joel's own criterion (§7'sdigesttyping is resolved at the payload-class level, not the registry entry).observed_verified: "not-applicable", 8/8 preconditions hold).draft-hillier-scitt-arp), not a CPB finding.test_typed_ref_passnow tolerates typed-ref-cpb01-01's own field layout (registry entry at the vector's top level, expected digest underexpected) without rewriting the folded vector's fields.test_vector_coverage.pyregisters a real handler fordigest_alg_inconsistent_with_registered_contextso the must-fail coverage gate exercises typed-ref-cpb01-02 against the actual library.Test plan
arp-typed-ref-cpb01-v0.1.jsonverified against Joel's pin.pytest lib/tests/— 35 passed.9eebdcf, before7c9f642) and refused (DigestAlgorithmMismatchError) on this branch.digest_algcomparison intyped_ref.pyflipstest_every_must_fail_vector_is_exercised[typed-ref-cpb01-02]andtest_typed_ref_pass(independently, via a corrupted-expected-digest mutant) to failure; restored and re-verified green.[cpb-typed-ref-01-uplift-and-joel-vectors]