Skip to content

Spark pair head-unit declared digest from rendered bytes - #11418

Closed
gunbai-bot[bot] wants to merge 16 commits into
mainfrom
session/smart-carp-164
Closed

gunbai-bot[bot] wants to merge 16 commits into
mainfrom
session/smart-carp-164

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Hash the exact systemd unit text from gunbc.spark.pair_serving_realization spark_pair_head_unit_file with SHA-256 (sha256sum stdin) at that render boundary, as DeclaredUnitDigested or a refusal that carries the render/hash cause.
  • harness_serving_route now passes spark_pair_head_unit_declared_digest into spark_serving_route_standing instead of DeclaredUnitDigestUnavailable.
  • Wet witnesses: same bytes hash stably; one extra byte differs; a different observed unit_digest is LaunchedFromDifferentUnit, not declared. Hermetic control: a render refusal is not a digest.

Test plan

  • gunbc run --claim-run a_render_refusal_is_not_a_declared_digest → PASS
  • hashing_the_same_rendered_bytes_is_stable → PASS
  • unit_text_differing_by_one_byte_gives_a_different_digest → PASS
  • a_declared_observed_mismatch_does_not_bind_as_declared → PASS
  • CI required lanes on this PR

Made with Cursor

Brian Searls and others added 3 commits September 14, 2026 23:14
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>
@gunbai-bot

gunbai-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 66429.

  1. Deleted spark_pair_head_unit_digest_unavailable_obligation. Production no longer constructs it; spark_serving_offer_route_witness_test now mints a local fixture DeclaredUnitDigestUnavailable so the standing arm stays reachable.

  2. The hermetic the_production_route_refuses_because_no_incarnation_is_observed driver of harness_serving_route cannot stay on the required floor: that function now reaches DigestStdin, which is NoMockResponse hermetically. Importing harness_seat into the digest wet witness typechecked past a 32GiB cgroup and page-thrashed (measured on this PR). What production actually mints is spark_pair_head_unit_declared_digest; harness_serving_route is the one-line pass-through of that standing. The wet witness now executes that fold (spark_pair_head_unit_declared_digest_hashes_the_realized_head_unit, PASS). The incarnation-unobserved refusal stays enrolled hermetically as an_agreeing_unit_digest_without_an_observation_refuses.

— sent from smart-carp-164

…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>
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 66442.

a_ready_route_reaches_the_existing_incarnation_frontier_in_the_product_path was the leftover hermetic driver of harness_bind_candidate → harness_serving_route. It is moved to test.claim.serving.serving_availability_bind_wet_witness (excluded from hermetic discovery, on local_repo_wet_schedule, floor-gap DigestStdin) and now also calls harness_serving_route directly. The rest of serving_availability_witness_test stays hermetic and no longer reaches DigestStdin.

Incarnation is still checked first, so today's route verdict remains ServiceIncarnationUnobserved whether the declared digest is supplied or not; the mint itself is what this PR adds, and the wet bind/route inhabitance is the last real-path execution of that wire.

— sent from smart-carp-164

Git-plumbing mock coverage must not retire SHA-256 stdin witnesses.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

review 66455 is correct: the two DigestStdin wet files were excluded under excl_local_repo_wet_reason / excl_local_repo_wet_dissolve, which name throwaway-repo git plumbing. That trigger could retire while Sha256.DigestStdin stayed uncovered.

48ea444b2e adds excl_local_repo_wet_digest_stdin_reason / excl_local_repo_wet_digest_stdin_dissolve (same sibling pattern as tempdir-write / bash / host-probe) and points both exclusion rows at them. Dissolve is mock_response coverage for DigestStdin, then re-enroll as hermetic discovery.

Per-candidate DigestStdin was authored duplication of a roster-static value.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

review 66465: agreed. harness_serving_route reminted spark_pair_head_unit_declared_digest on every candidate, which re-rendered the pair roster and spawned DigestStdin for a value that cannot change within a turn.

Production now calls spark_pair_declared_unit_digests() once in harness_collect_candidates and carries the group's standing into harness_bind_candidate / harness_serving_route. Lookup is spark_pair_head_unit_declared_digest_among (no subprocess). The wet product-path witness mints once and supplies the same standing to both calls.

@gunbai-bot gunbai-bot Bot mentioned this pull request Sep 15, 2026
6 tasks
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Review 66532 (both findings) addressed at 3870b16, plus the merge conflict with main.

Finding 1 — the wet bind claim was mistargeted. Agreed: harness_bind_candidate / harness_serving_route take a standing and never reach DigestStdin. The hermetic product-path claim is restored in serving_availability_witness_test with a supplied DeclaredUnitDigested (a_ready_route_reaches_the_existing_incarnation_frontier_in_the_product_path).

Finding 2 — no claim executed the collect → among → bind wire, and withdrawing the mint left every control green. That was true, and it was true for a structural reason: spark_serving_route_standing consulted the incarnation first, and production's incarnation is always EndpointIncarnationUnobserved, so the declared digest could not change any verdict on the harness wire. So the fix has two parts:

  • gunbc.spark.serving_offer spark_serving_route_standing now refuses DeclaredUnitDigestUnavailable before it matches the incarnation (the digest is decidable with no observation, and an unavailable one makes the route unidentifiable whatever is observed). spark_service_from_observation takes the ContentHash itself. New row the_declared_unit_is_refused_before_the_incarnation; the shared fixture t_standing now carries a digest so the region/incarnation rows still reach their arms.
  • harness_add_serving_candidate is now the one interface with every observation supplied (seats_held: ServingSeatStanding is lifted to its caller harness_candidate_from_standing; the only thing it reaches for itself is the roster lookup). serving_availability_bind_wet_witness drives it with the production roster spark_pair_declared_unit_digests() (real sha256sum, so it stays on the wet lane) and asserts the verdict is the incarnation refusal; its red control drives the same fold with this group's row withdrawn from that roster and asserts the verdict is the declared-unit refusal (spark_pair_no_realization_names_group_obligation, hoisted to a data row). Dropping the carry between the mint and the fold now changes the verdict, not a note. Wet schedule and floor-route-gap rows updated for the two functions.

What no claim still executes is harness_collect_candidates → harness_add_candidate themselves, because those read live endpoints; the wire is claimed from the first observation-free interface below them, and the annotation on harness_add_serving_candidate says so.

Roster. The three spark_service_from_observation admission rows are dropped (those spellings no longer occur there); six remain. Merging main brought in #11373's 32 delete after landing rows, which have landed, so they are consumed and deleted on this touch.

I could not execute the closure remotely (16 GiB cgroup page-thrashes on the runner, as the child found); the required floor is the executor for this head.

Brian Searls and others added 3 commits September 15, 2026 08:11
…ness drives production's roster-and-lookup route (review 66573)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…est claim paying a wet render; it is already held hermetically by the offer-route witness (review 66578)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Review 66578: agreed and fixed at 3ca6e3a. a_declared_observed_mismatch_does_not_bind_as_declared inspected only launch_unit_provenance's arm against a fixture digest, so the wet render it paid for was not the claim's subject — and that arm is already held hermetically with a supplied digest by spark_serving_offer_route_witness_test an_incarnation_from_a_different_unit_refuses (through the standing) — so the row is deleted rather than duplicated hermetically, with its local_repo_wet_schedule row and floor_route_gap expectation. The digest witness keeps its three rows that do inspect the real digest (stability, one-byte difference, production roster-and-lookup route).

— sent from merry-eagle-325

@briansrls
briansrls added this pull request to the merge queue Sep 15, 2026
@gunbai-bot
gunbai-bot Bot removed this pull request from the merge queue due to a manual request Sep 15, 2026
…ster.

The SHA-256 of the exact unit bytes stays DigestStdin at the render seal; apply reads artifact.text and serving admission reads artifact.digest from the same SparkPairRealization. Harness collection no longer mints spark_pair_declared_unit_digests; Group B uses the canary arm's own unrendered-unit obligation.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Review 66612 is on the stale head d409d20225. This change continues on #11440 (session/bright-gull-790). 66532/66573/66578 are already addressed there. Closing this PR so one change has one PR.

— sent from bright-gull-790

@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #11440 (session/bright-gull-790). Keep #11440 as the PR of record. Review history 66532/66573/66578 lives there; 66612 was on this stale head.

— sent from bright-gull-790

@gunbai-bot gunbai-bot Bot closed this Sep 15, 2026
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.

0 participants