Skip to content

CENSUS-IMAGE 0A: one seeded-image derivation, a measured identity, and the census envelope grammar - #11731

Merged
gunbai-bot[bot] merged 32 commits into
mainfrom
session/sleek-ferret-265
Sep 20, 2026
Merged

gunbai-bot[bot] merged 32 commits into
mainfrom
session/sleek-ferret-265

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

CENSUS-IMAGE 0A: one seeded-image derivation, a measured identity, and the census envelope grammar

Stage 0A of the Mt. Collins census image (work item adhoc-6b13c807-a40; parent decisions from eager-owl-205 are summarized below).

What recovery found

  • Output recovered, source never committed. The earlier census's output is committed (artifacts/bmc/mtcollins1-host-capture.txt, attempt=3, Preserve mtcollins1 hardware-census and boot-path evidence #10965). It ran in the live environment (tmpfs workload, sr0 mounted), so no Curtin recut is needed. Its seed and program were never committed, and the medium's stock volume label shows the ISO wasn't built by any modeled route. The capture program here is therefore a reconstruction from that file's ENVELOPE/SECTION/ARGV/EXIT lines, and it is labelled as one.
  • The derivation already exists. A modeled seeded-image derivation was already in the tree: extdeps.provisioning.ubuntu_seeded_install_media{,_remaster}, the xorriso -boot_image any replay that keeps the arm64 El Torito/ESP boot intact (srv4 fleet subsumption + BMC virtual-media install path + modeling cleanup #7027), used by srv3. A standalone CensusImageBuildInput would have been a second authority (§3). Parent ruled (A): generalize it, and rewire srv3 in the same change (root cut, no two representations).

The change

  • extdeps.provisioning.ubuntu_seeded_install_media: UbuntuSeededInstallMediaBuildInput. The payload is a parameter (rendered user-data plus NoCloudSeedFiles); the volume id is a parameter; dates are pinned; the stem and builder revision are fields. Every field reaches seeded_install_media_build_key. Identity is measured: UbuntuSeededInstallMediaBuilt { build_key, output_digest, image_name }, where image_name = <stem>-<first 16 hex of the output sha256>.iso.
  • …_remaster: seeded_install_media_stage verifies the stock sha256 before building (the upstream digest). It then extracts, writes the seed, patches grub, runs xorriso.Iso.ReplayBuildPinnedDates (-volume_date uuid / all_file_dates, so identical inputs reproduce identical bytes), and reads the digest off the written file. The old sidecar, the input-hash identity and the rebuild-in-place-when-stale path are deleted.
  • gunbc.seeded_install_media_publish: publish_seeded_image / resolve_seeded_image.
    • Create-only publish. A hard link fails if the name exists. An existing name with the same digest counts as already published; with a different digest it refuses and replaces nothing.
    • Read-back, then record. The published file is read back, and only then is the derivation record written (build key → digest).
    • Resolution re-measures. Consumers resolve through the record and re-measure the file before trusting it.
    • Two write boundaries. BmcExportBoundary (admitted against the export's ownership requirement) and HostArtifactsDirectory.
  • gunbc.machine_intake_boot_image_fetch: the stock fetch's publish is now create-only too (BootImagePresentWithDifferentDigest). boot_image_published_path is the single composition of export dir + name.
  • gunbc.machine_intake_host_capture_envelope: one grammar, read in both directions (§4). The stage roster and framing are declared once; the program renderer and the verdict parsers read the same rows.
  • gunbc.machine_intake_mtcollins1_census_image:
    • Parameterized by stage roster. The census image is mtcollins1_seeded_image_input(stages, stem, volume_id) applied to the census roster.
    • Seed. Upstream early-commands runs /cdrom/gunbc-census/capture.sh with interactive-sections: ["*"]. If the power-off fails, the unit waits at the installer and no unattended storage step is reachable.
    • Boot configuration. autoinstall "ds=nocloud;s=/cdrom/gunbc-census/" console=ttyAMA0,115200, label GUNBC_MTC1_CENSUS_2404_3.
    • Publish target. mtcollins1_census_image_publish builds from the stock medium in /srv/bmc and publishes into the same export.
  • srv3 rewired onto the same derivation. Its NBD serve step and apply entry resolve the image, and an unresolved image refuses the serve step (ActuatorStepImageUnresolved). The install diagnostic compares measured sha256 to measured sha256. Two predicates that had no consumer and existed only over the deleted static path are removed.

Witnesses

  • test.claim.mtcollins1_census_image (hermetic, supplied captures):
    • a complete envelope parses on every verdict axis;
    • RED: a workload token that appears only in the ARGV line is not a result;
    • RED: without the seed, the boot reaches the installer and is never census-complete;
    • the envelope is matched against its own machine;
    • the roster follows the brief's order;
    • the program writes every section, then END, then sync, then the halt;
    • the seed runs early and leaves every section interactive;
    • every build input reaches the derivation key (program byte, cmdline, label, both dates, builder revision, an appended stage), and the positive control reproduces it;
    • the image name is the stem plus the measured digest.
  • test.claim.mtcollins1_census_image_local_wet (the inhabitance half, local-wet lane, triple-enrolled): the attempt=3 capture parses under the reconstructed grammar; the renderer's program executed under sh parses back, including a nonzero stage exit and shell quoting.
  • The affected srv3 / NBD / diagnostic / selection witnesses now take a supplied resolved image. There is a new RED that the serve step serves the resolved path and refuses each unresolved arm.

Declared frontiers (not in this PR)

🤖 Generated with Claude Code

…, and the census envelope grammar

Generalizes extdeps.provisioning.ubuntu_seeded_install_media{,_remaster} (parent ruling (A))
instead of minting a second image authority: the seed payload, stage roster, volume id and pinned
dates are build inputs; the image identity is the sha256 read off the written ISO; publication is
create-only (hard link, refuse on a taken name) with read-back and a derivation record consumers
resolve and re-measure. srv3 is rewired onto the same derivation in this change.

Adds gunbc.machine_intake_host_capture_envelope (stage roster + framing, rendered and parsed from
one set of rows; the program is a RECONSTRUCTION from artifacts/bmc/mtcollins1-host-capture.txt)
and gunbc.machine_intake_mtcollins1_census_image (live-session early-commands seed, every installer
section interactive, built and published inside srv2's /srv/bmc export).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 19, 2026 17:05
gunbc-ci-auto-heal and others added 4 commits September 19, 2026 17:25
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rrors, a misplaced image argument, the deleted static ISO path

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…built program's bash-emit dissolution trigger (review 68602)

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68602 in 0a3703a:

  • The local host_capture_sh_quote is deleted. Stage framing now quotes through extdeps.posix.shell_command_language posix_single_quote, the one authority for the POSIX §2.2.2 encoding. The local-wet round trip (echo 'it'\''s quoted') still exercises it through a real sh.
  • Added host_capture_program_shell_emit_dissolution_trigger on the carrier. It names the four string-built renderers and dissolves on bash-emit (General orchestration intent to Bash emit fold over grammar rows #5828 / ROADMAP 6-shell-slice0 / shell-to-intent Phase 2) rendering a stage roster through orchestration emit. This replaces, beside the new program, the install_media_remaster_bash_emit_dissolution_trigger row that was deleted along with the old remaster's shell.
    — sent from sleek-ferret-265

gunbai-bot Bot pushed a commit that referenced this pull request Sep 19, 2026
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lass, attempt=3 roster, srv3 runbook

- resolve_seeded_image: a record whose image was removed resolves SeededImageRecordedImageAbsent and
  publish rebuilds into the free name; an unreadable image is SeededImageUnobservable, never diverged.
  New local-wet claim drives the real resolver through absent / diverged / resolved.
- seeded_install_media_builder_revision: declared below-ceiling class with a capability-grain
  next-rung trigger (gunbc.recurring_failure_mode a_hand_bumped_builder_revision_keys_a_derivation).
- host_capture_census_stages carries attempt=3's sections with its argv; dmesg-full is the one
  declared omission (already on the console stream the envelope is written to).
- srv3 runbook names the derivation/resolve route instead of the deleted static path.

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68615 in 6dd390c:

  1. Absent vs unreadable image. Agreed; it was a behavioural defect. resolve_seeded_image now distinguishes three unresolved states with different remedies:

    • SeededImageRecordedImageAbsent: the record exists but its image was removed. publish_seeded_image rebuilds into the free name.
    • SeededImageRecordDiverged: the image holds other bytes. Publish refuses and replaces nothing.
    • SeededImageUnobservable: the image exists but can't be read. Publish refuses and accuses no bytes.

    New claim test.claim.mtcollins1_census_image_local_wet a_removed_image_is_absent_not_diverged_by_real_execution drives the real resolver against a temp dir through absent, then diverged, then resolved (the digest is read off the written file). It is triple-enrolled. The NBD serve step refuses the new arm too, and a RED is added for it.

  2. Builder revision. There is no evaluation-time content hash of a declaration closure today, so the revision cannot be derived yet. It is now a declared below-ceiling class: gunbc.recurring_failure_mode.a_hand_bumped_builder_revision_keys_a_derivation (invalid state, harm, ceiling = structurally impossible, capability-grain next-rung trigger plus its discriminating RED), cited on the carrier.

  3. Roster narrowing. host_capture_census_stages now carries attempt=3's sections with attempt=3's argv, including dmidecode 16/17, meminfo, lscpu, numa, boot-cmdline and edac-find. dmesg-full is the one omission, declared on the carrier with its reason (the kernel log is already on the ttyAMA0 stream the envelope is written to) and what re-adds it.

  4. Runbook. Hard constraint 2 and step 0b's expected output now name srv3_seeded_install_media_input / publish_seeded_image / srv3_seeded_install_media_resolve and the refusal arms, not the deleted symbol.
    — sent from sleek-ferret-265

…(review 68635)

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68635 in dd1385d. mtcollins1_census_image_publish and mtcollins1_census_image_resolve now carry a declared-frontier annotation on the carrier (DESIGN §3c's second arm), naming each consumer and the trigger:

  • publish: consumed by stage 0B/0C, a fleet-converge step run on srv2 (host=srv2, SM/WIF prelude, same job shape as mtcollins1_fetch_boot_image) that builds and publishes inside /srv/bmc and emits the name and digest as its receipt.
  • resolve: consumed by stage 0D, gunbc.machine_intake_mtcollins1_boot_run (approval loop D: converge materialization, loopback bind, mtcollins1_boot mode #11484), whose signed boot subject binds the resolved image_name and output_digest in place of the stock ones.

The frontier retires when both land and call these functions. They are not wired in this PR because stage 0B/0C is the job that runs on srv2 hardware, and stage 0D edits #11484, which eager-owl-205 owns.
— sent from sleek-ferret-265

gunbc-ci-auto-heal and others added 2 commits September 19, 2026 21:29
…ousBareNameRead once the census publish path reaches v2.std.text)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…re gets an executing reader

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68664 in 07bd82c:

  1. One tty. mtcollins1_census_console_tty ("ttyAMA0") and mtcollins1_census_console_baud are the rows; the device the program exec >s and the kernel's console= argument are both derived from them, so the two spellings cannot be edited apart. The witness asserts the derivation rather than the literals.
  2. Dangling fixture. Rather than delete srv3_remote_bmc_probe_observation, I restored its reading as an executing claim: test.claim.srv3_os_install_diagnostic a_remote_bmc_probe_alone_needs_the_serve_observation runs diagnose_srv3_install over that fixture with the new intent fixture and asserts InconclusiveNeedsServeObservation. The deleted production fn had no caller, so this reading never executed; now it does, and the fixture has a consumer.
    — sent from sleek-ferret-265

gunbc-ci-auto-heal and others added 2 commits September 19, 2026 23:27
…onstructors (floor AmbiguousBareNameRead)

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

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68712 in 56655cf. The census witness module now declares its imports explicitly (std.logic / std.types / std.string_type, extdeps.provisioning.ubuntu_seeded_install_media, gunbc.machine_intake_mtcollins1_boot_artifact, gunbc.machine_intake_host_capture_envelope, gunbc.machine_intake_mtcollins1_census_image, v2.std.live_tree), matching every sibling in dag/test/claim/machine_intake/.

On whether it was executing: several witness files elsewhere in the tree carry no import block and are resolved implicitly, which is why it was written that way, and the floor's own refusals on this branch have been AmbiguousBareNameRead (a bare read that reaches two declarers) rather than an unresolved name — so bare reads do resolve. But I cannot show you a green execution of these eight claims yet, and that is the honest state: no witnesses run has completed on this branch. Explicit imports remove the question either way, and they also pre-empt the ambiguity class that has already refused this branch twice in extdeps.tools.coreutils_stat. I will report the executed result when the run on this head finishes.
— sent from sleek-ferret-265

# Conflicts:
#	dag/gunbc/srv3/srv3_os_install_diagnostic.dag
briansrls pushed a commit that referenced this pull request Sep 20, 2026
…nd the action-use census reads every workflow through it

extdeps.languages.yaml is now a bounded-subset reader and writer whose contract is meaning, not
text: every document ingest_yaml_source ACCEPTS denotes, under the YAML 1.2.2 core schema, exactly
the YamlValue it returns, and every construct outside the declared subset is REFUSED with the line
it sits on -- never reinterpreted as a string, never dropped. The writer is the same contract turned
around: ingest_yaml_source(emit_yaml(v)) == v, or a refusal naming the path it could not write.

WHAT WAS WRONG (source audit on #11663, comment 5743133113; each verified against the
code before it was fixed). The reader had no refusal arm -- unrecognized text became a string -- so
`{uses: x}` was a string, a single-quoted scalar kept its quotes, `\n` and `\q` were neither decoded
nor refused, a quoted key kept its quotes, `key: # c` became the string "# c", a `|` literal lost the
line break it clips, and a flow sequence split on the literal ", " (so `[a,b]` was one element and
`["a, b", c]` split inside the quotes). The writer filtered a literal's empty lines out, wrote `|`
for text with no final break, and wrote the string "123" unquoted, which reads back as an int.

WHY THE WITNESSES DID NOT SEE IT: they compared serialize(parse(x)) with serialize(expected), and
the round trip was emit(parse(emit(v))) == emit(v). Both compare the WRITER's text, so a loss in the
writer masked the same loss in the reader -- the "blank lines are kept" claim could not fail for that
reason -- and a type change the writer re-spells identically passed. Rostered as
gunbc.recurring_failure_mode bounded_reader_reinterprets_what_it_does_not_model.

THE SUBSET is declared in the reader's module header, construct by construct, with its refusals.
Accepted: the core schema (null, bool, int in decimal/0o/0x, float with exponent and .inf/.nan,
otherwise string); both quote styles on one line, with every escape section 5.7 names; quoted keys;
one-line flow sequences and the empty flow mapping; `|`, `|-` and `|+` with auto-detected
indentation; block collections at any increasing indentation, compact `- key: value` items, compact
nested `- - x`, and a sequence at its key's own column; comments and empty lines between nodes.
Refused, each with its own located reason: folded scalars, indentation indicators, anchors, aliases,
tags, directives, document markers, explicit `?` keys, flow mappings, nested or multi-line flow
collections, multi-line plain and quoted scalars, a comment after a value, a duplicate key, a tab in
leading whitespace, a line ending in whitespace, and every character YAML's printable set excludes or
this reader cannot tell from whitespace.

THE WITNESSES NOW COMPARE DECODED STRUCTURE. test.claim.yaml_ingest_witness compares parse(text)
with hand-written values, one conformance claim per construct, each with a red control that must
name its line and reason; test.claim.yaml_emit_witness compares parse(emit(v)) with v over strings
and multi-line texts built to break plain-versus-quoted and chomping, plus the writer's refusals by
path. Four planted reader defects (clip drops its break, unknown escapes pass, duplicate keys admit,
plain text never resolves) and three planted writer defects (empty lines filtered, always `|`, digit
strings unquoted) each turned their own control red.

THE CENSUS READS EVERY EXECUTED FILE THROUGH THE MODELED READER, and the line projection is deleted
with its frontier row (gunbc.action_use_admission realized_workflow_action_uses, uses_line_reading,
uses_value_text, uses_site_of, realized_workflow_projection_frontier_rows). A use is taken from where
GitHub reads one -- jobs.<id>.uses and jobs.<id>.steps[<i>].uses -- so the site is where the key
sits, a quoted or escaped `uses` key is decoded and read, and a script line spelled like a `uses:`
key is script content. test.claim.action_use_admission_witness carries one claim per workflow file,
joined to the directory listing by identity in both directions, so a workflow added without a claim
refuses by name.

THE BUDGET IS A CONSTRAINT, AND IT IS MET WITHOUT A SECOND READER. The census claim over the largest
committed workflow (.github/workflows/fleet-converge.yml, 912 lines) measures 67,692 eval steps
against v2.workflow.required_floor's 72,300 per new witness, re-derived by claim_batch on that
claim. The reader was 138,483 steps on that file before this change and is ~61,000 after, reading it
correctly: a block is split into its entries by marking the line breaks at its own indentation with
a sentinel the document is already refused for, so deeper lines and literal bodies are never walked
line by line. Three cost-shape defects found on the way are fixed at their owning links: admission
admitted every occurrence of a use where the question is per (site, text) (realized_distinct_uses),
the manifest join scanned every reading per use (action_manifest_readings_by_producer), and
std.types commit_sha_text_holds ran a lambda per character of every 40-character head.

THE COMMITTED WORKFLOWS ARE REGENERATED, and the diff is only what the old writer got wrong: 46
`run: |` become `|-` (the scripts carry no final line break) and 11 become `|+` (they end in a blank
line the old writer dropped); MALLOC_ARENA_MAX and fetch-depth are quoted, because they are STRINGS
in the model and unquoted they read back as ints.

A DUPLICATED CONTRACT EPOCH IS NOW THE READER'S REFUSAL, not a count downstream: an ingested mapping
cannot hold a key twice, so gunbc.required_ci_epoch_observation RequiredCiEpochDuplicated is deleted
as the lower-rung handling the climb obsoletes (DESIGN section 4b), and its control stays, asserting
the reader's located refusal.

NOT IN THIS COMMIT: gunbc.os_install_emit autoinstall_user_data still calls the writer's old total
entry point, so this tree does not typecheck yet. Its refusal has to travel as a typed outcome to
the srv3 install-media build input (parent ruling), and #11731 is rewriting that chain
now; sleek-ferret-265 and I agreed #11731 lands first and this branch rebases onto it. The PR stays
draft until then.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbc-ci-auto-heal and others added 2 commits September 20, 2026 00:50
…o replay takes neutral map parameters

Main's floor_route_gap chunk_17 (fabric db wet) and mine collided; mine is renumbered chunk_18 and
both are in the chunks list. ReplayBuildPinnedDates takes map_one/map_two source and iso-path again;
/boot/grub/grub.cfg is authored in the provisioning module that owns the medium's layout.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…mise as a bet

xorriso runs left to right, so both -volume_date commands now follow the -map commands; issued
before them, the freshly mapped seed and grub.cfg would have carried the build instant. The
SeededInstallMediaPinnedDates annotation no longer states byte-identical rebuild as settled: it
states what is established, what is not, what would settle it (the srv2 build-twice control), and
why nothing silently depends on it -- a non-reproducible rebuild publishes a different name rather
than a wrong image.

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

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 68762 in 7f9e9da. Both halves were right.

  1. Command order. -volume_date all_file_dates applied to the files then in the image, and it was issued before the two -map commands, so the freshly mapped seed directory and grub.cfg would have carried the build instant — the pinning would not have covered the files the derivation is about. Both -volume_date commands now follow the maps, and the operation's exit annotation says the ordering is load-bearing and why.
  2. The premise was asserted, not executed. SeededInstallMediaPinnedDates now types it as a bet per §4d: what IS established (without pinning, a rebuild measures a different digest), what is NOT (that pinning these two dates is sufficient; xorriso may carry other build-varying state, and the ordering above is read off the tool's documented execution rather than measured), and what would settle it (the srv2 control: build twice from one input and compare measured digests, then change one seed byte and compare again).

Worth adding explicitly, since it bears on how much weight the bet carries: nothing silently depends on it. If a rebuild is not byte-identical it measures a different digest, so it publishes under a different name; create-only publication replaces nothing and the record names whichever bytes were actually built. The cost of the bet being wrong is a second published image, not a wrong one. That is now in the annotation too.

Executed evidence on this branch, since CI no longer runs the floor (main's #11742 replaced the required witnesses check with cargo build): I built the interpreter locally and ran both census witness files against the merged tree. All 13 claims PASS — 10 hermetic (roster order, halt ordering, the ARGV false-green red, every-input-reaches-the-key with its positive control, digest-derived name) and 3 wet (attempt=3's committed capture parses under the reconstructed grammar; the rendered program executed under sh -c and parsed back including a nonzero-exit stage and an embedded quote; the resolver's absent / diverged / resolved arms against a real directory).
— sent from sleek-ferret-265

gunbc-ci-auto-heal added 2 commits September 20, 2026 01:27
# Conflicts:
#	dag/extdeps/tools/coreutils_stat.dag
# Conflicts:
#	src/v2/workflow/floor_route_gap.dag
@gunbai-bot

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

CI note: this PR's heal-generated-artifacts red is inherited from main, not from this change. main's tip #11761 enforces the §4c annotation-attachment rule, and src/v2/workflow/floor_naming_hygiene.dag carries a trailing comment block (authored in #11573) that names no subject, so resolve refuses twelve lines of it. The file here is byte-identical to main's.

Repair is cut as its own one-file PR against a clean main base: #11780. Once it lands I will merge main again here and CI should clear. clippy and compiler are already green on this head.
— sent from sleek-ferret-265

gunbc-ci-auto-heal and others added 2 commits September 20, 2026 03:11
Ledger-Repair-Judged: docs/design-rung-drops.md
Ledger-Rows-Repaired: docs/design-rung-drops.md namespace_wave_admission_wall_removed
Heal-Candidate-Run: 35485963825
Review 69300.

HistoricalStageNewlyIntroduced could never be accepted. A newly
introduced stage has no section in the historical capture, so the Absent
arm answered false before that disposition was reached, while
roster_matches_bindings counted the stage as carried and passed: the
first stage anyone added would have gone green on the dry claim and
permanently red on the wet one, and the wet failure would have read as a
capture problem rather than a checker problem. The disposition is now
decided before the historical section is demanded, and it still has to
earn itself -- if the capture DOES carry the section, the row is wrong
about history and it fails.

census_historical_capture and HistoricalCaptureIdentity had no reader,
and the wet claims bound the capture by path literal, so the row's
stated job -- constraining the producer to that committed digest and
byte count -- was performed by nothing. Rather than delete it, the job
is now done: both existing claims read the path from the row, and a new
claim checks the recorded sha256 and byte count against the bytes on
disk. The bindings are statements about ONE artifact and the file sits
in a worktree where anything may rewrite it, so this is also the brief's
digest-disagreement refusal, which had no executing claim until now.

The new claim is enrolled on both the wet schedule and the floor
route-gap chunk; an unenrolled claim is the defect review 69157 already
caught here once.

Evidence: mtcollins1_census_image_local_wet_test 7 PASS / 0 FAIL, and
the compared values are real -- measured sha256 a9b880c3..fd2a and
270880 bytes both match the committed rows.

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

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Both findings fixed at 8cc7dd0 (review 69300). Verified both against the code first; both were real.

HistoricalStageNewlyIntroduced could never be accepted — this was the serious one. Your trace is exact: a newly-introduced stage has no section in the historical capture, so host_capture_bound_section_argv yields Absent and the outer match returned false before that disposition was ever reached, while roster_matches_bindings counted the stage as carried and passed. The first stage anyone added would have gone green on census_roster_matches_bindings and permanently red on the_historical_binding_holds_against_the_committed_capture_by_real_execution — and the wet failure would have read as a capture problem rather than a checker problem, which is the expensive part.

The disposition is now decided before the historical section is demanded. It still has to earn itself: if the capture does carry the section, the row is wrong about history and it fails. So the arm is reachable and discriminating in both directions rather than being a permanent false.

census_historical_capture / HistoricalCaptureIdentity had no reader. Correct, and the sharper half of your finding is the consequence you name — the wet claims bound the capture by path literal, so the row’s stated job, constraining the producer to that committed digest and byte count, was performed by nothing.

I did not delete this one. Unlike historical_binding_names (deleted last round), the job here is real and the brief requires it: the bindings are statements about one artifact, read against a different file they are statements about nothing, and the file sits in a worktree where anything may rewrite it. So the row is now load-bearing — both existing claims read the path from it, and a new claim checks the recorded sha256 and byte count against the bytes on disk. That is also the brief’s digest disagreement → refuse RED, which had no executing claim until now.

The new claim is enrolled on both the wet schedule and the floor route-gap chunk — an unenrolled claim is the defect review 69157 caught here once already.

Evidence: mtcollins1_census_image_local_wet_test — 7 PASS / 0 FAIL. I also checked the new claim is not vacuously green: measured sha256 = a9b880c3…fd2a and 270880 bytes, both matching the committed rows, so it is comparing real values.

— sent from sleek-ferret-265

Side-chat wall (review 5261076419). host_capture_marker_matches compared
host_capture_run_identity_value(a.run) against
host_capture_run_identity_value(run) -- the projected TEXT only -- so
HistoricalAttemptOrdinal { ordinal: "3" } and KernelBootId { boot_id:
"3" } were the same run, and an envelope begun by the historical program
could be closed by a kernel boot. That is the confusion the two forms
were introduced to end, reintroduced one layer down in the comparison.
An attempt ordinal and a boot id are drawn from different spaces, so a
shared spelling between them means nothing.

host_capture_run_identity_same matches over both identities: same arm
with equal payload matches, different arms never match regardless of
text.

The two controls the suite lacked, both enrolled:
  the_same_text_under_two_identity_forms_is_not_one_run -- attempt=3
    begin with boot-id=3 end must refuse, and the reverse order too.
  the_same_text_under_one_identity_form_is_one_run -- the positive
    control, so the refusal is the FORM discriminating and not the text
    failing to compare.

The RED is verified discriminating rather than assumed: with the
comparison temporarily reverted to text-only the file measured 21 PASS /
1 FAIL, failing exactly the cross-form claim while the positive control
still passed. Restored, it measures 22 PASS / 0 FAIL.

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

@briansrls briansrls 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.

SOURCE SIGN-OFF — exact head 9ab8c6f.

This supersedes my REQUEST_CHANGES review 5261076419. The remaining identity wall is closed:

  • host_capture_run_identity_same is constructor-aware and total: HistoricalAttemptOrdinal compares only with HistoricalAttemptOrdinal, KernelBootId only with KernelBootId, and cross-constructor pairs are false regardless of equal payload text.
  • host_capture_marker_matches consumes that equality rather than projecting both identities to String.
  • the_same_text_under_two_identity_forms_is_not_one_run covers both directions (attempt=3 begin / boot-id=3 end, and the reverse).
  • the_same_text_under_one_identity_form_is_one_run is the positive control for both identity forms.
  • The recorded mutation is discriminating: restoring text-only comparison yields 21/22 with exactly the cross-form claim red while the positive control remains green; the repaired source yields 22/22.

The commit changes only the envelope comparison and the hermetic witness. The previously accepted bounded-envelope, workload pass-status/full-coverage, measure-derived footprint, one-observation-per-case, and 19-stage historical-binding walls remain intact. The 7/7 local-wet receipt is on the parent source; this exact delta does not touch the wet file, and its same-form behavior is directly covered by the new exact-head positive control.

All four exact-head checks are green. No srv2 publication is required here; 0B/0C/0D remain declared frontiers.

APPROVE for enqueue on this exact SHA.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit 4f04146 Sep 20, 2026
4 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/sleek-ferret-265 branch September 20, 2026 18:52
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
…branch was scoped

The invariant is not "these four files". It is that
`git grep -nE "^[[:space:]]+//" -- '*.dag'` returns ZERO files, AT THE HEAD BEING
MERGED INTO. Main moved: #11731 landed two more files carrying indented
annotations, so the four-file repair no longer cleared the wall.

  dag/gunbc/machine_intake/host_capture_historical_binding.dag              7  NEW
  dag/gunbc/target_binding.dag                                              5
  dag/gunbc/namespace/namespace_reference_derived_residency_qualification.dag 4
  dag/gunbc/floor_memory_demand.dag                                         4
  dag/test/claim/machine_intake/mtcollins1_census_image_local_wet_test.dag  3  NEW
  dag/gunbc/cloudflare/r2_permission_group_observe.dag                      1

Six files, twenty-four lines; the census returns zero at this head.

Both new blocks are body-position rather than merely indented — one inside a
`match` arm, one inside a `test fn` body — so neither could be fixed by changing a
column. Each joins the leading annotation of the declaration it sits in, restated
so it is true of that declaration rather than of the arm it sat in:

  - host_capture_historical_binding.dag — the NewlyIntroduced-is-decided-first
    rationale becomes a statement about the fold's ordering.
  - mtcollins1_census_image_local_wet_test.dag — the substring-absence rationale
    becomes a statement about how the claim below asserts.

This is the third time today the census has been the thing that moved: the parse
log missed one file, a correct census dropped a line that produced no parse FAIL,
and now a correct census went stale because main moved under it. The population is
whatever the census says at the head you are merging into.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
Three §4c body annotations hoisted to module-item grain (host_capture_historical_binding, runner_microvm_boot_probe, mtcollins1_census_image_local_wet_test), and floor_route_gap chunk_20's seven 'tail:' fields whose value sat on the next line -- a parse refusal that orphaned every annotation in the file -- joined onto one line like every other chunk.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
…t_capture_historical_binding and runner_microvm_boot_probe to module grain (they refuse to parse and red every floor run)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
…left in chunk_20 (expected expression, found Newline; reds every floor run)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
…now moved three times

Census on current main is seven files, twenty-seven lines. The new one is
`dag/gunbc/runner/runner_microvm_boot_probe.dag` (3 lines); the other six are
unchanged.

Four files, then six after #11731, now seven. Each scoping was correct for the head
it was taken against and stale by the time the PR was ready. That is a property of
the rate `.dag` files are landing, not of the repair — and it is the strongest
argument for landing the parse repairs quickly rather than perfecting them.

The new block is body-position, inside a `match` arm within
`runner_microvm_boot_probe_wet`, so it could not be fixed by changing a column. It
joins the leading annotation of that function and is restated to be true of the
fold rather than of the arm it sat in: the executor login comes from the host's
roster row, so the host binding is resolved before any login is named, and a probe
on a host with no roster row reports BootNotAttempted rather than an image or
console verdict.

`git grep -nE "^[[:space:]]+//" -- '*.dag'` returns ZERO files at this head.

No proofs re-taken. The A/B and the CI evidence already in this PR establish the
mechanism, and three more relocated lines do not change what the repair does.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 21, 2026
…11731 (no ISO on the runner) and the schedule now says so

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 21, 2026
…-image rendered-program row from the schedule (red on main since #11731) with its reason and return trigger

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 22, 2026
… refusal against #11731's seeded-image design

The srv3 chain and the Mt. Collins census image are both built from one rendered
user-data body, so both derivations carry the renderer's outcome and ride the
refusal arms gunbc.seeded_install_media_publish already has; the readback chain
refuses before its first leg when there is no build key to find a record by.
Direct readers of the build input that only need the stem or the label read the
rows the input is built from; witnesses that need an input's shape supply the body.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant