Skip to content

spec(anchor)!: a Level 2 anchor verdict requires the registry entry - #533

Merged
imran-siddique merged 7 commits into
mainfrom
fix/464-anc-entry-binding
Oct 22, 2026
Merged

imran-siddique merged 7 commits into
mainfrom
fix/464-anc-entry-binding

Conversation

@imran-siddique

Copy link
Copy Markdown
Member

Refs #464. Breaking, proposed: this changes what Level 2 requires, so it waits out the 30-day comment period under GOVERNANCE.md.

Ruling of 2026-10-15: TR-ANC-002 judged the proof against a merkle_root and leaf_count the receipt brought with it, so a pass tied the record to no entry. Registry Anchor Format §6 now requires the entry itself. The receipt's root and count must equal the entry's, and with no entry Level 2 is not earned. The suite takes it with --entry.

Nothing identifies an entry from the transparency URI yet. The pass message says that link was not checked, and #448 finding 21 tracks it. That supersedes the 09-23 line on trace-tests#92 until the link exists.

The worlds from trace-tests#92, in tests/test_tr_anc_entry_binding.py:

World TR-ANC-002
matching sealed entry pass
wrong caller root fail
only entry root changed fail
only entry count changed fail
entry absent fail

Removing each new comparison breaks at least one test. Conformance suite on Windows: 798 passed, plus one test_manifest_ref_draft_vectors failure that main shows too.

Overlap: #519 edits the same three docs pages.

🤖 Generated with Claude Code

TR-ANC-002 judged the inclusion proof against a merkle_root and leaf_count
that came from the receipt, so a pass tied the record to no registry entry.
Registry Anchor Format section 6 now says a Level 2 verdict rests on the
entry itself (the third input of section 5.1): the receipt's root and count
must equal the entry's or the anchor is refused, and with no entry Level 2
is not earned.

The suite takes the entry with --entry (run() and tr_anc.check() take
entry=). A missing entry fails TR-ANC-002 the same way a missing receipt
does. Nothing yet identifies an entry from the transparency URI, so the
pass message names the entry and says that link was not checked; it stays
open as finding 21 of #448.

Breaking, proposed: this redefines what Level 2 requires, so it needs the
30-day comment period and Project Lead sign-off under GOVERNANCE.md.

Refs #464

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Imran Siddique <45405841+imran-siddique@users.noreply.github.com>

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent technical review of 95e160a. Current-head CI and Conformance CI succeeded. Fresh hash-locked Python 3.12.14 dependencies: reference suite 4,033 passed / 48 skipped; conformance 799 passed / 5 xpassed. The new entry-binding module passes all 18 cases.

I separately built RFC 6962 trees by recursive largest-power-of-two splitting, rather than the test helper's level-by-level promotion, and checked every leaf position for sizes 1 through 33 (561 proofs), using records with non-ASCII content and an included signature field. Each valid proof passes; changing only the entry root, changing only its count, omitting the entry, or changing the claim signature each refuses (2,244 refusal twins). Disabling the new root comparison causes 1 failure / 17 passes; disabling the count comparison 2 failures / 16 passes; synthesizing a missing entry from receipt fields instead of refusing causes 4 failures / 14 passes. Symbols and valid controls were retained; temporary mutations restored.

The bounded guarantee is consistent with the new PASS diagnostic: receipt root/count match the supplied entry, and inclusion replays to that root. It does not establish that this is the entry named by transparency or authenticate the entry's origin. Controls with changed producer/batch_id but identical root/count still pass, as expected under the stated limitation. This does not close #448 finding 21.

One nonblocking shape-validation observation: parse_entry accepts ts='not-a-timestamp' as long as it is nonempty, while section 4 describes ISO-8601 UTC with a Z suffix. Either validate that field in a follow-up or make the parser's narrower shape-validation ceiling explicit; a passing inclusion result should not be read as timestamp validation.

No blocking defect found in the implemented root/count/entry-presence guarantees. This is technical evidence, not approval to bypass the breaking-change comment period, Project Lead decision, or remaining URI-binding work.

@solloek369-arch

Copy link
Copy Markdown
Contributor

Non-blocking, for the comment period on 95e160a. This sits outside the bounded review above — @dinakarjs scoped that to the receipt-to-entry binding and the inclusion replay, and found no blocking defect there. The question below is about which object the inclusion covers for one format. It predates this PR; I'm raising it here because #533 is where what a Level 2 anchor verdict establishes is being redefined.

Failing behaviour. For cmcp-runtime, TR-SIG and TR-ANC-002 judge different objects, and the reference registry anchors the one the suite does not.

Smallest case. Registry-side: a RuntimeClaim anchored with the registry's own _leaf_hash/_build_tree, the same bytes handed to both verifiers — registry verify_inclusion PASS, suite TR-ANC-002 FAIL. Suite-side: the same inner trace, proof and entry, with gateway.session_id and gateway.catalog.hash changed and the envelope re-signed — TR-ANC-002 still PASS.

Expected. Registry Anchor Format §1: "The unit of anchoring is the complete signed claim object, signature included … if either the claim body or its signature changes, the anchor no longer matches."

Consequence. For this format a Level 2 pass fixes the bytes of the inner trace, not the identity of the signer's envelope or the scope of the gateway facts bound to it. Two differently signed envelopes satisfy the same anchor.


extract_trace returns record["trace"] for cmcp-runtime (conformance/src/trace_tests/loader.py), and _run_core passes the full RuntimeClaim to TR-SIG but only the inner trace to TR-ANC. TRACE v0.2 §3.2.2 lists cMCP's RuntimeClaim as an enveloping-signature profile, so the signature belongs on the envelope; that signature covers the inner trace, but the suite's anchor leaf excludes the outer gateway object and the signature itself.

The registry anchors the other object. claim_leaf_subject (trace-registry src/trace_verify/_verify.py) classifies a submission as envelope only when its keys are exactly producer, trace and signature; a RuntimeClaim is classified record, and its leaf is taken over the whole claim.

Reproduced locally with synthetic Ed25519-signed RuntimeClaims; registry at 0fb5f48, suite at 95e160a.

Registry route — leaf and tree from the registry's own _leaf_hash/_build_tree (batch of three), the same bytes given to both verifiers:

verifier result
registry trace_verify.verify_inclusion PASS
suite run(…, "cmcp-runtime", 2), TR-SIG / TR-ANC-002 PASS / FAIL: inclusion proof does not reproduce the committed merkle_root

Suite route — this PR's _receipt/_entry helpers:

world TR-SIG TR-ANC-002
proof over the complete signed RuntimeClaim PASS FAIL
proof over the inner trace PASS PASS
same inner trace, proof and entry; gateway.session_id and gateway.catalog.hash changed, envelope re-signed PASS PASS

In the two passing worlds, differently signed envelopes use the same inner trace, proof and supplied entry, so the checks do not establish inclusion of either complete signed RuntimeClaim.

Question. Is the intended Level 2 anchor subject for cmcp-runtime the complete signed RuntimeClaim, as the registry anchors it, or only its nested TRACE claim? If the complete claim, the registry route above is the positive control and the second and third suite worlds, with proof and entry held fixed, are refusal controls. If the nested claim, the registry and the verdict wording would both need to say so. (The signature pre-image for this profile is a separate question, open as #448 item 6.)

This route is not reachable from cMCP's producer today: GatewayTrace at cMCP e116c24 is extra="forbid" and has no transparency field, so a cMCP-issued claim cannot carry the claim Level 2 requires. I'm raising the subject question now so it is settled before that route opens.

This concerns which bytes the inclusion proof covers, not a signature bypass: changing gateway fields needs a re-signature with the key in trace.cnf.jwk. Module results for TR-SIG and TR-ANC-002 only, on synthetic RuntimeClaims that are not schema-complete and carry no freshness challenge; the four-field receipt is used throughout so the receipt-shape question does not interfere; the registry leaf and tree come from its own functions, not its full ingest pipeline. Not an aggregate Level 2 result.

Copy link
Copy Markdown
Contributor

Independent follow-up to Loek's anchor-subject report at 95e160a. I reproduced the distinction locally on Python 3.12.14 with fresh synthetic Ed25519 keys, a single-leaf proof computed from canonical_claim_bytes, and the existing loader/signature/anchor modules:

Anchored object / submitted claim TR-SIG TR-ANC-002
complete signed RuntimeClaim PASS FAIL
nested trace PASS PASS
changed gateway.session_id and gateway.catalog.hash, envelope re-signed, same nested-trace receipt/entry PASS PASS

Direct verify_inclusion over the complete original signed object passes; changing and re-signing the envelope with that original whole-object proof fails. This independently confirms the runner boundary: extract_trace removes the envelope before TR-ANC, while TR-SIG receives the complete record. These are module-level synthetic checks, not schema-complete or aggregate Level 2 acceptance, and I did not rerun the registry ingest pipeline.

My recommendation is to retain registry-anchor-v1 §1's complete signed claim subject and pass an explicit anchor subject alongside the normalized trace into TR-ANC. Keep the URI/receipt shape checks on the trace and include a full-envelope positive twin plus re-signed-gateway and signature-change refusal twins. A nested-only interpretation would require explicit normative wording and registry alignment. @imran-siddique @lywinged please record the intended subject before implementation; my earlier receipt-to-entry review does not resolve or approve this broader semantic choice. Preserve the 30-day comment period and keep #448 item 6 and URI-to-entry binding item 21 distinct. No normative/runtime change or merge requested here.

…ate the entry ts

For cmcp-runtime the runner handed TR-ANC the nested trace while Anchor
Format section 1 and the reference registry anchor the whole envelope, so a
registry-valid anchor failed and a re-signed envelope with changed gateway
fields still passed. TR-ANC now takes the complete record as its subject.
parse_entry also rejects a ts that is not ISO-8601 UTC ending in Z.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Imran Siddique <45405841+imran-siddique@users.noreply.github.com>
@imran-siddique

Copy link
Copy Markdown
Member Author

@solloek369-arch @dinakarjs thanks, reproduced here too. Recording the subject: it is the complete signed claim, as Anchor Format §1 already says, and the next commit makes the suite follow it. For cmcp-runtime the runner now passes the whole envelope to TR-ANC as subject, while URI and receipt shape checks stay on the trace. Twins: full-envelope anchor passes, nested-trace-only anchor fails, re-signed envelope with changed gateway fields fails, changed signature fails. It also rejects an entry ts that is not ISO-8601 UTC with Z. Item 6 and finding 21 stay separate.

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up technical review at exact head fe5d01e closes the two findings from the previous discussion: the runner passes the complete signed record as the anchor subject, and parse_entry validates the UTC-Z timestamp shape/calendar date.

Independent Python 3.12, absolute PYTHONPATH to this checkout: full conformance suite 812 passed, 5 xpassed (XPASS is reported separately, not counted as additional passing requirements). Current-head hosted technical checks succeed. Separate synthetic-key probe used independently constructed sorted-key JSON preimages and a SHA-256 single-leaf proof: original whole-envelope anchor TR-SIG/TR-ANC pass/pass; nested-trace-only proof pass/fail; changed gateway session with a valid re-signature against the original full-envelope proof pass/fail; changed signature fail/fail. These are module-level controls, not aggregate Level 2 acceptance or registry ingest validation.

Regression sensitivity on temporary edits: removing subject=record from the runner fails the whole-envelope positive and nested-only refusal tests (2 failures). Removing timestamp validation fails all 7 malformed-date cases while both valid UTC timestamp cases pass. Sources restored, clean worktree; diff whitespace check passes.

No remaining blocking implementation finding in this bounded follow-up. The 30-day breaking-change comment period and Project Lead sign-off still apply; this is not authorization to bypass them. URI-to-entry binding (#448 finding 21), entry-origin authentication, and the separate signature-preimage item 6 remain outside this correction.

Registry Anchor Format section 5 defines the inclusion proof as
leaf_index and audit_path, and the section 5.1 algorithm takes
merkle_root and leaf_count from the registry entry. TR-ANC-002 still
required both on the receipt, so a proof-only receipt with a matching
entry was refused as malformed.

TR-ANC-002 now replays the proof against the entry's root and count.
A receipt that carries its own copies must still carry the entry's
(section 6). parse_receipt keeps its contract for callers that replay
a self-contained receipt without an entry.

Signed-off-by: Sankalp Gilda <23521054+astrogilda@users.noreply.github.com>
A receipt may leave leaf_count out and take the entry's, but one that
carries the field must carry an integer. An explicit null was read as
absent and skipped the comparison with the entry.

Signed-off-by: Sankalp Gilda <23521054+astrogilda@users.noreply.github.com>

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review at 6a9d803: the entry-authoritative root/count correction behaves as intended, but the receipt fuzz oracle needs updating before the technical checks are green.

Blocking harness defect: conformance/.clusterfuzzlite/fuzz_receipt.py:124 calls parse_receipt(receipt) after TR-ANC-002 passes. A legitimate proof-only receipt can now pass using the supplied entry, whereas parse_receipt intentionally still requires self-contained root/count fields. Deleting leaf_count or merkle_root from the genuine receipt therefore raises InclusionError in this post-PASS assertion. Hosted ClusterFuzzLite run 38987830178 / job 117263304673 reports precisely the missing-leaf_count exception. This is a stale harness assumption, not evidence of an inclusion-verification bypass.

Please retain the earlier standalone parse_receipt exception-safety probe, but make the post-PASS oracle use parse_proof(receipt) for index/path and parse_entry(_ENTRY) for the authoritative root/count; independently replay verify_inclusion(claim, index, path, entry_count, entry_root), retaining the expected-claim and genuine-root assertions. Do not merely suppress the exception or skip proof-only inputs. Add deterministic harness coverage for omitted leaf_count, omitted merkle_root, and both omitted, then rerun ClusterFuzzLite.

Validation on this exact checkout, Python 3.12: 49 targeted anchor tests passed; full conformance suite 818 passed, 5 xpassed (reported separately). A deterministic probe loaded the actual fuzz fixture with only Atheris instrumentation stubbed: all three omission variants pass TR-ANC-002, raise in the old self-contained parser, and pass an entry-based independent replay. Wrong-claim, wrong-entry-root and wrong-entry-count controls remain refused. This was not a fresh Atheris campaign or a replay of the minimized byte input.

The 30-day breaking-change comment period and Project Lead sign-off remain required. URI-to-entry binding (#448 finding 21) and entry-origin authentication remain unverified; this review does not establish aggregate Level 2 acceptance.

Copy link
Copy Markdown
Contributor

Concrete companion for the fuzz-oracle review finding: #559, targeting this PR's branch at 6a9d803. Head bc3b465 changes only the harness and adds five deterministic callback tests. Full local conformance: 823 passed, 5 xpassed; Ruff passes. Restoring the old post-PASS oracle in memory makes all three optional-field omission regressions and the independent-replay refusal test fail, while the self-contained control passes. The standalone parser exception-safety probe is retained. Please incorporate/review the companion and rerun hosted ClusterFuzzLite; a fresh fuzz campaign is still required before the red check is resolved. Governance comment period and Project Lead sign-off remain unchanged.

Cover proof-only receipt variants and ensure the fuzz oracle independently
replays a reported PASS against the registry entry root and leaf count.

Signed-off-by: Srinivasa Dinakar Jainti <dinakarjs@gmail.com>
Signed-off-by: Srinivasa Dinakar Jainti <dinakarjs@gmail.com>

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact head 613a6fd. The two-file follow-up addresses my stale fuzz-oracle finding: the callback parses proof index/path separately, takes root/count from the supplied entry, and independently replays inclusion. The standalone self-contained parse_receipt exception-safety probe remains. The target is executable (100755).

Independent Linux/Python 3.12 validation with the repository's hash-pinned reference/conformance test dependencies: full conformance suite 823 passed, 5 xpassed (reported separately). Ruff on the two follow-up Python files and diff whitespace checks pass. Restoring the old post-PASS oracle in memory causes four deterministic callback failures while the self-contained positive control passes. No source mutation was retained. The exact-head hosted ClusterFuzzLite PR run 39080185620 succeeds; I did not run a new Atheris campaign locally.

No remaining technical blocker from my earlier fuzz-harness review. This approval is bounded to that correction; the 30-day breaking-change comment period and Project Lead sign-off remain required. URI-to-entry identity and entry-origin authentication remain outside this correction; no aggregate Level 2 or production acceptance is established.

Keeps both Unreleased entries in CHANGELOG.md (this change and #565).

Signed-off-by: Imran Siddique <45405841+imran-siddique@users.noreply.github.com>

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@imran-siddique

imran-siddique commented Oct 19, 2026 •

Copy link
Copy Markdown
Member Author

Merged main to clear a CHANGELOG conflict with #565 (both entries kept); nothing else changed. This is a conformance level redefinition, so under GOVERNANCE.md it merges no earlier than Friday 14 November, 30 days after the comment on #464 that opened the period. @dinakarjs the push dismissed your approval; a re-approval any time before then is all it needs.

@dinakarjs dinakarjs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renewing my bounded technical approval at 0555c4c after the merge dismissed the earlier review. The fuzz callback, deterministic callback tests, entry/proof parsing and TR-ANC consumer are byte-unchanged from approved 613a6fd; the changelog retains both this proposal and #565's entry.

Independent focused run on exact checkout, Python 3.12.14: 67 tests passed across test_fuzz_receipt, test_tr_anc_entry_binding, test_tr_anc_inclusion and test_tr_anc_subject. Existing environment reused; no fresh lock rebuild or local Atheris campaign. Current-head hosted CI, Conformance CI and ClusterFuzzLite all succeed. Prior full-suite and behavioral-reversal evidence remains in my earlier review; I did not repeat it here.

This approval covers the corrected harness/entry-binding implementation and discloses my earlier companion-test contribution. The minimum comment period and Project Lead sign-off remain required; the latest maintainer comment now gives 14 November as the earliest merge date, superseding the email's earlier 2 November date. URI-to-entry identity and entry-origin authentication remain outside this correction. References: registry-anchor-v1 sections 5.1/6 and GOVERNANCE.md in this exact checkout. Reviewed with Codex assistance.

@imran-siddique

Copy link
Copy Markdown
Member Author

@rajnisht7 handing this one to you. It is a conformance level redefinition, so under GOVERNANCE.md it cannot merge before Friday 14 November, 30 days after the notice. If it is still green and @dinakarjs's approval of 0555c4c still covers the head then, please merge it.

@rajnisht7

Copy link
Copy Markdown
Member

@rajnisht7 handing this one to you. It is a conformance level redefinition, so under GOVERNANCE.md it cannot merge before Friday 14 November, 30 days after the notice. If it is still green and @dinakarjs's approval of 0555c4c still covers the head then, please merge it.

Sure, thank you. will hold this PR until 14 November as per GOVERNANCE.md (30-day comment period for a conformance-level redefinition), and only merge then if CI is still green and @dinakarjs's approval still covers the head

@lywinged lywinged left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REVIEW on #533, head 0555c4c: Approve

Measured on 0555c4c against its merge base 53e347c, with the hash-pinned requirements. The conformance suite is 919 passed, 2 skipped, 5 xpassed on 3.11, 3.12 and 3.13, and the three steps of conformance-ci.yml pass on 3.13; 919 is the merged head, where the 823 reported at 613a6fd was the count before the merge brought main's tests in. The reference suite is 4522 passed, 48 skipped on 3.11 and 3.12. No objection from this maintainer; what follows is what the approval rests on.

  1. What is unchanged since the last approval. Against 613a6fd, tr_anc.py, inclusion.py, fuzz_receipt.py, fuzz_record.py, test_fuzz_receipt.py, test_tr_anc_entry_binding.py, test_tr_anc_subject.py, test_tr_anc_inclusion.py, unit/test_tr_anc.py, test_modules_never_raise.py and unit/test_untrusted_input_hardening.py are byte-identical. runner.py and cli.py differ by the expected_policy_hash plumbing the merge brought in from main, and test_anchor_vectors.py by an encoding="utf-8" from the same source.

  2. What holds the change in place, on this head. With no entry, falling back to the receipt's own root and count, which is the verdict before this change, fails test_the_four_worlds_and_the_absent_entry[entry-absent], test_each_refusal_names_its_reason, test_the_runner_passes_the_entry_through and test_the_cli_reads_entry. Dropping the count comparison fails the changed-count world and the message test and nothing else: with the entry's count moved from 5 to 6, the proof for leaf 3 still replays, so the comparison is the only thing that catches it. Dropping the root comparison fails the wrong-root world and the message test. Reverting the runner's subject to the nested trace fails test_complete_envelope_anchor_passes and test_nested_trace_only_anchor_fails. Dropping the calendar check on ts fails the two impossible dates. Accepting a boolean leaf_count on the entry fails bool-count. Replaying against the receipt's own copies once they have been checked equal to the entry's fails nothing, and cannot. Twenty thousand seeded random receipt and entry pairs through tr_anc.check raised nothing.

  3. The spec and the surfaces. The four MUST and one MUST NOT added to Anchor Format §6 (rest on the entry; check each copy the receipt carries equals it; refuse if either differs; do not report Level 2 without it; state the unchecked link) are each implemented in tr_anc.py, and the entry is the third input of §5.1 as the text says. conformance/docs/levels.md, error-codes.md, modules.md, modules/tr-anc.md and LIMITATIONS.md say what the code does, the CHANGELOG entry names what breaks and what an implementer does, and the anchoring tutorial already tells a holder to keep the entry with the record and the proof. The link from transparency to the entry, finding 21 of #448, is named as unchecked in the spec, the docs, the pass message and both CHANGELOGs; the entry's origin in LIMITATIONS.md and in the earlier reviews. The document has never carried a CHANGED marker, so I do not ask for one here.

  4. One correction. 30 days from the opening on Thursday 15 October is Saturday 14 November, not Friday.

  5. One gap, for a follow-up. trace-tests verify reads the entry from a file the way it reads the receipt, and the hardening test treats --entry as it treats --receipt, but no fuzz target does: fuzz_receipt.py fixes the entry to the genuine one and fuzz_record.py to a constant, so parse_entry sees fuzzed bytes nowhere. This is a different gap from the oracle #559 fixed. The deterministic cases reach a missing ts and batch_id, an empty producer, a boolean and a zero leaf_count, a malformed merkle_root, seven ts shapes and a non-object entry; they do not reach a missing merkle_root, leaf_count or producer, or a non-string ts, producer or batch_id, which the parser refuses and nothing exercises. Giving half of fuzz_receipt.py's inputs to the entry would close it. A nit beside it: under conformance/pyproject.toml's own strict mypy, which no workflow runs, cli.py gains two type-arg errors of the kind its line 86 already had.

  6. The process, since the author is the Project Lead and the sign-off is his own. dinakarjs is neither Maintainer nor Reviewer in MAINTAINERS.md, his approvals are by his own words bounded to the fuzz-oracle correction, and two of the branch's seven commits are his through #559, so this is the first maintainer review of the substantive change and one of the two inputs GOVERNANCE asks for under "no unresolved objections from Maintainers". The page says at least one approving review is required to merge, and the merge on 19 October dismissed the one that was there, so whoever merges on 14 November needs an approval of that head.

Approving on 0555c4c for the conformance requirements. The comment period and the Project Lead's sign-off are theirs.

Copy link
Copy Markdown
Contributor

Prepared the requested entry-parser fuzz follow-up as draft #599, stacked on this PR's exact 0555c4c head. It changes only the fuzz callback and deterministic harness tests. Half the input paths now vary the entry; raw JSON and structured mutations reach parse_entry and the real TR-ANC checker. Missing/type-invalid field controls, a valid twin, five mutation branches and false-pass replay controls are included.

83 focused tests pass on Python 3.12.14; Ruff passes. Disabled-entry-lane, fixed-entry and direct-parser-removal trials are documented in the PR, including the initially masked direct-parser trial and the control added to expose it. No real Atheris campaign or full platform matrix is claimed. Please keep #533's governance hold and this branch's acceptance separate; the follow-up should be rebased/retargeted only after the parent is accepted.

@imran-siddique
imran-siddique merged commit 295c36d into main Oct 22, 2026
27 checks passed
@imran-siddique
imran-siddique deleted the fix/464-anc-entry-binding branch October 22, 2026 02:47
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.

6 participants