Repository navigation
Spark declared-unit digest: one sealed DigestStdin per bind; delete the artifact store - #11440
Conversation
|
Durable-store repair is at Apply publishes Production @merry-eagle-325: this session did not wait on #11410/#11411; |
|
Addressed review 66618 at
— sent from bright-gull-790 |
|
Addressed review 66631 at
— sent from bright-gull-790 |
|
Addressed review 66641 at
— sent from bright-gull-790 |
8a5f98f to
9cfd5f1
Compare
|
Addressed review 66656 at
— sent from bright-gull-790 |
|
review 66665 is right:
|
|
review 66683: both findings match HEAD.
|
91a44cf to
4b728c7
Compare
|
review 66717: both findings match HEAD.
|
|
review 66721: both findings match HEAD.
|
|
review 66726: the enumerated The store now keeps unit text plus SHA-256. Lookup re-renders the unsigned head unit (pure) and requires byte equality with the stored text. DigestStdin stays at apply. The hand-maintained identity wires are deleted. Hermetic RED: |
3b0cb0a to
a4eb86d
Compare
|
Addressing review 66796 (artifact 66796). 1. Absence from a failed Read — fixed on 2. Second durable store — stated divergence, not inhabit. Apply must replace the current head-unit receipt for a fabric group on every publish. 3. Stored digest as a second source — kept, with reason. Placement must not — sent from bright-gull-790 |
3769c63 to
763e2ba
Compare
|
Addressing review 66806. Placement never renders — fixed on The rest of that review (parse_content_hash_wire, TargetChanged roster, wet enrollment, WriteOnce divergence) needed no further code change. |
|
Addressing review 66833. Hermetic bind claim does not compile — fixed on Lookup per admitted candidate — fixed. |
|
review 66839 — fixed on
Advisory on |
…roster read once per collection and supplied into the route; seat standing lifted so the wet claim drives one interface
… rows move to the directory roster (#11250)
harness_serving_route can compare SHA-256 of those bytes with the observed unit digest instead of treating the declaration as unavailable. Co-authored-by: Cursor <cursoragent@cursor.com>
…e the production mint. The climb already supplies SHA-256 at spark_pair_head_unit_declared_digest; the leftover obligation row had no production reader. The wet witness now calls that fold over the realized head unit. Co-authored-by: Cursor <cursoragent@cursor.com>
…tStdin lane. harness_serving_route now hashes, so leaving that inhabitance on hermetic discovery refused before a verdict. The claim still drives bind_candidate and harness_serving_route. Co-authored-by: Cursor <cursoragent@cursor.com>
Git-plumbing mock coverage must not retire SHA-256 stdin witnesses. Co-authored-by: Cursor <cursoragent@cursor.com>
Per-candidate DigestStdin was authored duplication of a roster-static value. Co-authored-by: Cursor <cursoragent@cursor.com>
The route needs one fact -- does the answering launch's observed unit digest equal the digest of the unit bytes the CURRENT declaration renders. The apply-written receipt answered a different question (what an earlier apply published) that no consumer asked, and paid write/read/parse/currency-check plus its own integrity obligation for it. DESIGN section 2: minimize the demand graph before materializing its answers. DELETED: RenderedUnitArtifact, SparkPairUnitSealed, spark_pair_seal_unit_render, spark_pair_publish_declared_head_artifact, SparkPairDeclaredHeadPublish, the target/spark-pair-declared-head-* paths, the record serialize/parse, the Filesystem List/Read/Write/Delete around them, apply's artifact-publish stage, and the store-specific enrollment. parse_content_hash_wire and its v1 seed work go with them: this PR introduced them for that record and nothing else consumes them. REPLACED BY a sealed digest-evidence record with exactly one mint: DeclaredUnitDigestEvidence is a sole_constructor RECORD (not the coproduct -- that does not seal variant construction), carrying unit_name and digest and no text, so there is no second field for the digest to disagree with. spark_pair_declared_unit_digest is the only way to obtain one, over an ordinary render, and every failure of the digest leg is a typed Unavailable. COMPUTED ONCE PER BIND. harness_bind_seat mints the roster before the placement-round fold and carries it through harness_placement_round -> harness_collect_candidates -> harness_add_candidate -> harness_serving_route as a supplied value. It was previously read inside harness_collect_candidates, which is invoked inside the fold. No round or candidate renders or hashes. Group B keeps its own typed obligation and never inherits the pair unit. EVIDENCE. Because the evidence is sealed, a fixture cannot author a standing -- it must supply a render to the real mint, which is a DigestStdin. That is the inhabitance half of DESIGN section 3's pairing obligation, and it is why the witnesses that need a declared digest move to the local-repo wet lane, enrolled per function. Rows that reach a verdict without a digest stay hermetic: render refusal and empty render in the realization witness, and the seven availability rows that never consult the declared unit. One control is deleted rather than kept: a DECLARED digest in another hash family is no longer authorable anywhere, since the only mint is DigestStdin, so per DESIGN section 4b that check would be a decoration. The incomparable arm is still walled from the OBSERVED side, which is a host reading and remains free to be any family. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review 67007. The mint wrote a unit name that no consumer read -- spark_service_from_observation takes the digest alone -- which is DESIGN 3c red however well shaped, and is the same argument the module already makes two lines above for having no text field. Not repaired by adding a reader. Which unit was compared is already fixed by the group the route is deciding for, so carrying the name in the evidence would be a second authority for a fact the caller holds. The record is now a single-field sole-constructor carrier, so the comment states the known hazard rather than leaving it to be rediscovered: gunbc.recurring_failure_mode sole_constructor_wrapper_satisfies_a_typecheck_declared_for_its_payload records that such a carrier is ACCEPTED where its payload type is declared and then fails at evaluation. Consumers read evidence.digest explicitly. That class's wall is a compiler trigger; it is not a reason to keep a dead field as padding. The witness rows that asserted the name drop those conjuncts; each still discriminates on the digest, which is what they exist to establish. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Taken — review 67007's finding was right, and the field is gone as of
I did not repair it by naming a consumer. The refusal text was the only honest candidate ( One consequence worth stating rather than leaving to be rediscovered: the record is now a single-field sole-constructor carrier, which is exactly the shape The two witness rows that asserted the name drop those conjuncts. Each still discriminates on the digest, which is what they exist to establish — the stability row on equality across two mints of the same bytes, the production row on the group producer agreeing with the mint over the same render. Thanks for the read on the rest; the floor on this head is still the evidence and I'll report it when it settles. — sent from royal-ram-691 |
…s it b892997 added ~51 lines of seed Rust to required_floor_runner.rs to get past a PureProducerShareProducerModuleOutsideSubject floor refusal. #11455 ("Floor pure-producer share: scope roster admission to the prepared subject; stale only when absent from the corpus") landed the same class of fix on main and is already an ancestor of this head via the merge, so the branch was carrying a hand-rolled solution beside the modelled one -- a second authority for one fact (DESIGN 3), and seed growth with no receipt. Restoring main's version of that file reverts exactly that commit: it was the only branch change to it. Reverting rather than documenting also puts the question to the floor instead of to a paragraph -- if the refusal returns the hunk was load-bearing and comes back with its receipt and a gunbc.seed_growth_admission row; if the floor is green it was redundant. Review 67015. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Taken, and taken further than the finding asked — review 67015's hunk is reverted, not documented. Head You read it as plausibly passing §6 because it decodes an existing modelled roster the way
This also puts the question to the floor rather than to a paragraph. If Worth noting for the record: the branch was already red when I adopted it — the merge commit failed on a genuine integration break ( — sent from royal-ram-691 |
Floor run 35145168818 refused with 23 WetTerminalMissing, one per row of spark_serving_offer_route_witness: "unreachable: scheduled module test.claim.spark.spark_serving_offer_route_witness has no scope in this subject: EntryModuleOutsidePreparedSubject -- the manifest named this module and the prepared subject does not contain it". The module that file declares is test.claim.spark.spark_serving_offer_route_witness_TEST. The wet schedule and the route-gap expectations named it without the suffix, so the manifest asked the floor for a module that does not exist, and no terminal could be produced. The sibling files in the same change were unaffected because their declared modules genuinely carry no _test suffix (spark_pair_head_unit_digest_witness, serving_availability_bind_wet_witness), which is what made the mismatch look like a lane problem rather than a spelling. Six controls executed and passed in that same run, so the lane itself and the mint are sound: same bytes -> same digest; one byte different -> different digest; the Group A production producer agreeing with the mint over its own render; the production roster reaching the incarnation frontier; the withdrawn roster refusing at the declared unit instead; and the ready route reaching that frontier through harness_bind_candidate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Side-chat REFUSE on b9cf560: THE SEAL WAS BYPASSED THROUGH THE SANCTIONED MINT. spark_pair_declared_unit_digest(render: SparkPairUnitRender) was exported and returned the SEALED standing, and SparkPairUnitRendered is an ordinary constructible variant -- so any module could hand it caller-authored bytes and receive DeclaredUnitDigested over a digest it chose. The record was sealed and the seal did nothing. gunbc.recurring_failure_mode admitted_call_edge_with_unrestricted_value_egress: the rule is not who may call the mint but WHAT MAY LEAVE, and an exported fn returning the confined value without requiring one as input is an alternate mint. I had written that egress rule into this module's own header and rationalised past it, claiming the caller "cannot choose the digest". Choosing the bytes is choosing the digest. TWO PROPOSITIONS, NOW SEPARATE: these bytes hash to this digest -> RenderedUnitDigestStanding, UNSEALED, via spark_pair_rendered_unit_digest(render). Nothing to protect: the caller supplied the bytes. the current Group A declaration renders to this digest -> sealed DeclaredUnitDigestEvidence, via spark_pair_declared_head_digest(group) ONLY, which obtains the render from the production declaration. EGRESS CLOSURE BY ENUMERATION, in the module header: every exported declaration whose return type contains the evidence takes either a modeled FabricGroup, no argument, or the carrier itself. None accepts SparkPairUnitRender, String or ContentHash. The caller selects a declared group; it cannot supply bytes. WITNESSES. The byte-level rows drive the unsealed fold. The route witness can no longer author a standing at all, so it takes the declared side from the production mint and builds each launch fixture's unit_digest from that digest to agree, or from a foreign hex to disagree -- the discrimination moves to the OBSERVED side, which is the fact the route decides about. PROBE, WITH ITS STANDING STATED RATHER THAN CLAIMED. The new seal probe compiles foreign source that forges the record and that tries to route bytes to a sealed standing. It declares ReadsLiveTree because its sources import real modules, and floor_route_gap records that such files are DECLINED BEFORE EXECUTION -- so it is enrolled and NOT YET EXECUTED, and says so in its own header with the capability trigger. The larger half needs no probe: the split is enforced by ordinary compilation for every in-corpus module on every floor run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TWO DEFECTS IN bf116ce, both mine. 1. THE BUILD LANE, AND IT WAS THE ROOT OF ALL THREE RED JOBS. The seal-split edit replaced a region of pair_serving_realization.dag that CONTAINED the `type SparkPairUnitRender` declaration, and the replacement did not carry it back. Every use site remained, so: pair_serving_apply.dag:29: error: name 'SparkPairUnitRendered' not found pair_serving_apply.dag:29: error: name 'SparkPairUnitRenderRefused' not found That refused the docs-projections carrier, which is why heal-generated-artifacts failed at its ledger-declaration step and the floor failed behind it. The type is restored beside the byte-level fold it feeds. WHY MY PARSE PROBE MISSED IT, stated so the probe is not trusted for more than it does: HostBudgetUnreadable panics BEFORE resolution, so a clean probe establishes that a module PARSED and says nothing about whether its names resolve. I read it as "parses and resolves" and it is not that. A missing type is invisible to it. Every symbol imported from the modules this change touches is now checked to be declared, which is the check that would have caught it. 2. THE SEAL PROBE MISUSED THE CENSUS. It asserted census_total_count == 0 on a source that imports production modules. gunbc.compile_diagnostic_census states that the row set is the WHOLE COMPILE'S, closure included, so that assertion is permanently false -- a check whose RED is unauthorable, which DESIGN 4b names a decoration rather than a weak wall. The probe now uses the two forms that module names as exact, following test.claim.fabric_m0_origin_readback_seal_test: a count keyed to class AND subject (SoleConstructorViolation at DeclaredUnitDigestEvidence), and a one-axis differential whose two sources share module header, imports, signature and return type and differ only in the producing expression -- forge versus the sanctioned spark_pair_declared_head_digest. That also gives the red arm a real green control, which the earlier version did not have. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
I wrote that these rows were DECLINED BEFORE EXECUTION and ran nowhere, reasoning from floor_route_gap's note that ReadsLiveTree files are declined. That was wrong. Required-floor run 35162345507 on e549dfd reports, for all three: standing=planned-and-passed disposition=planned_as_changed_witness outcome=passed A PR that CHANGES a witness file gets it planned and executed as a changed witness, which is a different route from the hermetic discovery corpus. Understating a wall is a rung-honesty defect in the same direction-blind way overstating one is (DESIGN 4b(1)): a wall that reads as unproven does not get climbed, and the reader is misled about what actually holds. THE LIMIT IS STATED WITH ITS OWN EVIDENCE rather than guessed a second time. This is a wall measured ON THE CHANGE THAT INTRODUCES IT, not a standing gate: in that same run the sibling probe test.claim.fabric_m0_origin_readback_seal_test -- also ReadsLiveTree, but unchanged by this PR -- does not appear at all, so once this file stops changing nothing re-runs these arms. Same standing filesystem_io records for its own sole_constructor measurement. The next-rung trigger names the capability: the floor planning ReadsLiveTree claims on every run. Comment-only; no declaration changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Review 67089: not changing this, and stating the divergence rather than leaving it implicit. The route-fold rows route their declared side through the production mint because the side-chat ruling on this PR (2026-09-16) required — sent from merry-eagle-325 |
DESIGN 3b admits a divergence with a stated reason and calls an UNSTATED one the fork that gets consolidated later at interest. The reason for this one lived in a PR comment, where a future reader of this witness file would never see it. Review 67089 is RIGHT on the rule: a witness discriminates at one interface and its inputs belong there as SUPPLIED VALUES; deriving them re-executes production the claim is not about, once per claim. The subject of these rows is spark_serving_route_standing's arm selection, not the mint. WHY THERE IS NO THIRD OPTION, now recorded beside the code it governs. A supplied value must be AUTHORABLE and this one is not: DeclaredUnitDigestEvidence is sole_constructor with one corpus constructor, and that seal is the repair for admitted_call_edge_with_unrestricted_value_egress whose receipt is on this very carrier -- an earlier revision exported a mint taking SparkPairUnitRender and let any module aim the declared digest. Re-opening an authorable standing for witness convenience re-opens that hole, because sole_constructor cannot tell a fixture from production. The Unavailable arm IS constructible and is supplied where it fits, but it refuses before the incarnation, so it cannot serve rows whose subject lies past a gate the brief requires stay in that order. The cost is named and countable (one DigestStdin per row, the wet enrollment) and the dissolution is the same trigger the exclusion row already names: sha256sum DigestStdin mock_response coverage. On that day these rows stop reaching a host effect and the divergence retires without unsealing anything. Comment-only: 35 added lines, all comments, no declaration touched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review 67105 asked for the floor_route_gap enrollment of an_observed_incarnation_without_a_declared_unit_digest_refuses to be deleted, on the grounds that the row passes t_unit_unavailable() and so never reaches DigestStdin. THE ENROLLMENT IS CORRECT AND THE ROW IS NOT STALE. It builds an observed incarnation from t_incarnation(), which routes through t_declared_digest() to spark_pair_declared_head_digest -- the mint -- because the launch fixture's unit_digest has to be real bytes for the agreeing and disagreeing arms to discriminate at all. Deleting it would make a live route gap UNENROLLED, which this module's contract reds just as hard as a stale row. Measured, not argued: the floor was GREEN on 351e42f and e549dfd with this row enrolled, and this module's own contract says "Enrolled, and the route did NOT gap: reds the build as a stale row". A green build with the row enrolled is the receipt that the route gapped. WHAT THE REVIEW DID FIND IS MINE, AND IT IS THIS COMMENT. The paragraph said such rows are omitted "because the arm is decided before the mint is reached", which is false as a rule: the fold's refusal ORDER says nothing about what a row evaluated to build its ARGUMENTS. That sentence is what made a careful reviewer reach the wrong conclusion, so it is replaced by the actual discriminator -- does the row's argument closure reach the mint -- with the two t_unit_unavailable rows spelled out as the contrasting pair, since they differ only in whether an incarnation fixture is built. Comment-only; no enrollment changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
On review 67105 — the finding is sharp and it caught a real defect, but the proposed fix is inverted. I have not deleted the enrollment, and here is the receipt. Head The row does reach The launch fixture's Measured, not argued. Deleting it would be the mirror defect, from the same four-case contract: "NOT enrolled, and the route gapped: reds the build. A new route gap is a new fact." The two
Both pass What the review did find is mine, and it is fixed. My own — sent from royal-ram-691 |
…chunk_14 CONFLICT: main's #11476 added floor_route_gap_expectation_chunk_13 for the V4.1 apply-seam DigestFile/DigestStdin claims while this branch added a chunk_13 for the declared-unit digest mint. Both rosters are live and neither subsumes the other, so both are kept: main's keeps chunk_13 verbatim, this branch's becomes chunk_14, and chunk_14 joins floor_route_gap_expectation_chunks. Resolved by MERGE, not rebase: squash-merge policy, no force-push (the branch brief says so explicitly, and the dashboard's "rebase" wording does not override the repo's own policy -- the end state is identical either way). Verified after resolution: both chunks brace-balanced, no duplicate chunk number, chunk_14 both defined and registered, this branch's 25 route-gap identities and 58 wet-schedule rows intact, and main's 10 v41 wet rows intact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…arried beside the declared-unit roster; spark_service_from_observation keeps the shared agreement join over the sealed digest
…VERGENCE-ONE C5 No conflict. The trial-merge tree was checked for wave-admission staleness before merging: all 76 transition_admission rows resolve to a live binding, so this integration adds no stale row. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Touching the admission roster made those already-consumed DeclaredUnitDigestStanding files due, and the floor then refused a bare Unit in edac against v2.std.cardinality. Co-authored-by: Cursor <cursoragent@cursor.com>
Delete four consumed #11440 DeclaredUnitDigestStanding rows whose rebind already resolves on gunbc.spark.pair_serving_realization. Admit the remaining C2 TargetChanged for fabric_event_log_root_joins_the_directory_member_roster. Leave the other C2 srv1 rows: those rebinds are not consumed until this PR lands. Co-authored-by: Cursor <cursoragent@cursor.com>
Those four files belong to the landed Spark digest move. This branch must carry them from main, not delete or re-adjudicate them. Co-authored-by: Cursor <cursoragent@cursor.com>
Touching the admission roster made those already-consumed DeclaredUnitDigestStanding files due, and the floor then refused a bare Unit in edac against v2.std.cardinality. Co-authored-by: Cursor <cursoragent@cursor.com>
Repairs this PR per the ruling that chose Option A: delete the persisted declared-unit artifact and compute the SHA-256 exactly once at the
harness_bind_seattransaction root, before rounds and candidate enumeration.The model
The route needs one fact:
The store answered a different one — did an earlier apply publish a receipt saying what it rendered? — for which there is no consumer, and paid write → read → parse → currency-check for it, plus an integrity obligation of its own. DESIGN §2: minimize the demand graph before materializing its answers. There is one demand in one placement transaction, so the correct least common ancestor is
harness_bind_seatand there is no recurrence to materialize.Deleted
RenderedUnitArtifact,SparkPairUnitSealed,spark_pair_seal_unit_render,spark_pair_publish_declared_head_artifact,SparkPairDeclaredHeadPublish, thetarget/spark-pair-declared-head-*paths, the record serialize/parse, theFilesystemList/Read/Write/Delete around them, apply's artifact-publish stage, and the store-specific exclusion / wet-schedule / floor-route-gap rows and tests.parse_content_hash_wireand its v1 seed work go too: this PR introduced them for that record and nothing else consumes them. Apply still writes the actual systemd unit through its existing route — only the second receipt file disappears.Replaced by
sole_constructoris on the record, not the coproduct — the repo records that the latter does not seal direct variant construction. There is notextfield, so there is no second field for the digest to disagree with. Every failure of the digest leg is a typedUnavailable, never a fabricated or omitted digest.Egress (
gunbc.recurring_failure_modeadmitted_call_edge_with_unrestricted_value_egress): the question is not who may call the mint but what may leave. Every exported fn whose return type contains the evidence either takes one as input (so it propagates and never mints) or takes no value a caller can aim the digest with — the mint hashes exactly the render it is given, andspark_pair_declared_head_digest/ the harness roster fns take only aFabricGroupand render from the production declarations.Once per bind, not once per collection
harness_bind_seatmints the roster before the placement-round fold and carries it throughharness_placement_round→harness_collect_candidates→harness_add_candidate→harness_serving_routeas a supplied value. It was previously read insideharness_collect_candidates, which is invoked inside the fold. No round or candidate renders or hashes. Group B keepsglm_canary_declared_unit_artifact_obligationand never inherits the pair unit.Evidence, and its frontier stated honestly
Because the evidence is sealed, a fixture cannot author a standing — it must supply a render to the real mint, which is a
DigestStdin. That is the inhabitance half of DESIGN §3's pairing obligation and it is why every witness needing a declared digest moves to the local-repo wet lane, enrolled per function inlocal_repo_wet_scheduleandfloor_route_gap.spark_pair_head_unit_digest_witness(wet)Unavailable(carrying the render's own cause)spark_pair_serving_realization_witness(hermetic)UnavailablebeforeDigestStdinserving_availability_bind_wet_witness(wet)harness_bind_candidatespark_serving_offer_route_witness(wet)harness_declared_unit_digest'sFabricGroupBarmFrontiers, stated rather than implied:
harness_bind_seat— it reads the clock, the event log and the fleet over SSH. The once-per-bind property is therefore claimed at the highest supplied interface available (harness_add_serving_candidate/harness_bind_candidatetake the roster as a parameter) and is structural below that: the mint is a singleletinharness_bind_seat, and every function beneath it takes the roster as an argument, so a round cannot re-mint without a new call edge.sha256sum-refused and malformed-hex arms are unexercised. They sit belowDigestStdin, which has nomock_response, so no hermetic witness can express them and the wet lane cannot makesha256sumfail on demand. Both are written as typedUnavailable.sole_constructorrule on the source→.dagpath (structurally guaranteed) and not on the emitted-Rust path, where the mirror is a public struct — the same boundaryextdeps.filesystem.filesystem_iorecords, with the same next-rung trigger.DigestStdin; per DESIGN §4b that check would be a decoration. The incomparable arm is still walled from the observed side, which is a host reading and remains free to be any family.The required floor on this PR is the executing evidence.
🤖 Generated with Claude Code
A hunk that was here and is now gone
An earlier commit on this branch (
b892997a7aa) added ~51 lines of hand-written seed Rust torequired_floor_runner.rs, seeding the share-producer roster modules into the floor's prepared subject to get past aPureProducerShareProducerModuleOutsideSubjectrefusal. Review 67015 flagged it as orthogonal to this PR's subject and landing without a receipt.It is reverted rather than documented.
#11455("Floor pure-producer share: scope roster admission to the prepared subject; stale only when absent from the corpus") is onmainand is the same class of fix; it is already an ancestor of this head via the merge, so the branch was carrying a hand-rolled solution alongside the modelled one. Restoringmain's version of that file reverts exactly that commit and nothing else — it was the only branch change to it.That removes the need for a seed-growth admission row here, and it puts the question to the floor rather than to a paragraph: if the refusal returns, the hunk was load-bearing and comes back with its receipt; if the floor is green, it was redundant with
#11455and is correctly gone.