Skip to content

Render the heal skew guard from a typed Pipeline; delete its shell scaffold - #7420

Merged
briansrls merged 20 commits into
mainfrom
session/quiet-wren-607
Jul 30, 2026
Merged

briansrls merged 20 commits into
mainfrom
session/quiet-wren-607

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Eliminates the hand-authored shell in the heal job's binary/source skew guard. The step now renders
from a typed v2.std.orchestration Pipeline.

Stacked on #7418 — this branch merges heal-auto-remedy, so the diff shows #7418's content until
that merges. The new work is src/v2/workflow/ci_heal_skew_guard_emit*.dag, the extdeps.git shapes,
and the ci_spec.dag rewiring.

What landed

gunbc_ci_heal_binary_source_skew_guard_script was a join([...]) of ~55 bash lines. It is now a
one-line delegation to ci_heal_binary_source_skew_guard_script() in a new
v2.workflow.ci_heal_skew_guard_emit, placed beside ci_regen_rustfmt_path_emit for the same stated
reason (ci_spec can import it without the ci_materialization ↔ ci_spec cycle).

  • Control flow is structural: If / Not / Or / StrNonempty / Let / Exit.
  • Every git leaf derives its argv from an extdeps.git shape declaration, cited to git-scm.com/docs
    (git-rev-list, git-merge, git-checkout, gitglossary for pathspec).
  • ci_heal_binary_source_skew_guard_shell_scaffold and its dissolution trigger are DELETED, not
    reworded. That is the receipt the brief asked for.

Three corrections to the brief's plan

1. For has no emitter, so both loops are dissolved rather than emitted.
orch_emit_step refuses For (^orch_emit_step_for_unsupported). Adding one to a load-bearing
pipeline stage to serve a single caller is the wrong trade, and each dissolution is the better model
independently — a per-path shell loop was re-deriving a set git can hand over whole:

  • classification: the space-joined GENERATED_ARTIFACTS variable plus the for/case glob
    membership test is replaced by asking git for the complement — --diff-filter=U limited to .
    minus one ':(exclude)<path>' pathspec per registered artifact. A list serialized into a string and
    re-parsed was a dual representation (DESIGN §3); this reads the registry directly. It also makes
    "mixed → refuse, never partially resolve" hold by construction, since classification completes
    before anything is resolved — the prior accumulator could only claim it by ordering discipline.
  • resolution: the per-path loop becomes one NUL-delimited git diff … -z | xargs -0 git checkout --ours --, correct for paths containing spaces or newlines.

Both deletions dissolve review 44580's paths-with-spaces finding by construction rather than
deferring it to the shell→intent lane.

A brief for for as sugar over fold is included at docs/plans/for-sugar-over-fold.md, separating
the .dag surface form (which desugars to fold) from PipelineStep.For emission (which has zero
would-be consumers now that this PR removed the only candidate).

2. Gap 3 was already closed. RedirectSpec.StdoutAndStderr emits literally >&2
(bash.dag:2614 — the variant name reads backwards). No new orchestration variant was needed; the
twelve echo … >&2 lines became one workflow-layer diagnostic authority taking message text as data.

3. Gap 1 was smaller. RevList, DiffNameOnly, DiffNameOnlyMerge already existed as
git.Core operations. I deliberately did not add operation declarations for the new argv shapes:
they would be a second argv spelling beside the shape fns (a §3 fork) with no consumer, since this
guard's transport is emitted bash rather than a runtime-present service call. Precedent for bare
shapes with no operation: shape_git_reset_hard_argv, shape_git_rev_parse_argv.

Two fail-closed improvements over the prior shell

Both deliberate and noted in-code:

  • a failed checkout --ours now refuses instead of staging the path anyway. The prior cut ran
    git checkout --ours -- "$c" 2>/dev/null || true and then git add "$c" regardless, which would
    stage an unresolved file — the fabricated-plausible-output arm §5 forbids.
  • git merge --abort runs after the diagnostics, so a refusal always prints its reason (previously
    an abort failure under set -e could swallow the trailing explanation).

Verification — by execution, against the emitted string

Never a hand-retyped copy; the script was extracted from the emitter and run.

  • bash -n clean, both as emitted and as embedded in ci.yml. The first cut was not: the
    :(exclude) pathspecs emitted unquoted and (/) are bash metacharacters, which is also what was
    failing gunbc ci. Fixed by quoting in the emission layer (extdeps owns the pathspec value; only
    the emitter knows the target shell), with a witness asserting single-quoting is total.
  • Operator truth table green in a fixture repo with a real src/v1 skew and a real three-way
    conflict: ROADMAP.md → resolve · ROADMAP.md DESIGN.md → resolve · authored .dag → refuse ·
    seed .rs → refuse · mixed → refuse. Every refusal left no MERGE_HEAD (nothing partially
    resolved); every resolve left our content with the seed no longer ahead.
  • Two mutation RED controls flip the verdict, including the dangerous direction: stripping the
    exclusions reds the auto-resolve cases; inverting the authored test makes all five red by silently
    auto-resolving authored conflicts.
  • 13 .dag witnesses pass, with REDs, in ci_heal_skew_guard_emit_test.dag. Deliberately not a
    golden string — the emission derives from committed_generated_artifact_paths(), so a golden would
    encode ~80 registry paths and break on unrelated registrations.
  • ci.yml regenerated and byte-idempotent; witness_committed_is_fixed_point and its RED control pass.

Defect found, NOT fixed here — needs an operator call

While verifying, the live heal_generated_artifacts run on this PR refused with "still skewed after
merging origin/main"
. That refusal was correct and transient here (main really did advance by two
src/v1 commits mid-run). But probing it surfaced a structural defect in the seed-ahead
predicate, inherited from #7401 and #7418 and not introduced by this refactor:

github.sha on a pull_request is a synthetic merge commit that exists on neither branch. When the
PR branch and main both touch src/v1, that merge commit is TREESAME to neither parent for the
path, so git rev-list HEAD..$BUILT_FROM -- src/v1 lists the merge ref itself — which is
unreachable from HEAD by construction. The remedy merges main, the re-check still lists it, and the
guard refuses forever, mis-diagnosed as "the base moved again". Fail-closed, so nothing unsafe
ships, but the heal is permanently disabled for exactly the PRs where the skew guard matters most.

Reproduced by execution (fixture where both sides touch src/v1): residual count stays 1 after the
remedy. Two candidate fixes, both verified:

  • A — git rev-list --no-merges … → 0. Smallest diff, but a slight widen: an evil merge that
    introduces src/v1 content present in neither parent would be missed.
  • B (recommended) — compare trees: git diff --quiet HEAD $BUILT_FROM -- src/v1. Empty after the
    remedy (correct), and a control confirms it still detects a genuine skew before the remedy.
    Precise, no widen. Costs the diagnostic's ability to name the responsible commit.

I did not change the predicate: this PR's acceptance criterion is behavioural equivalence, and
#7401's note reasons at length about choosing the commit list over tree equality, so replacing it is
an operator decision rather than a refactor's side effect.

Residue, declared

One hand-spelled shell fragment remains: echo "$X" | head -20 | sed 's/^/ /', which indents and
caps a captured commit list for display. It carries a named dissolution trigger
(ci_heal_skew_indent_residue_note) pointing at a diagnostic-list carrier, and is the same
irreducible-kernel class as ci_regen_rustfmt_path_emit's test -x leaves. The head -20 cap moved
from the capture to the display, which is behaviour-preserving for the guard's decision (a truncated
non-empty list is still non-empty).

Sibling gunbc_ci_heal_commit_push_script is the same class and remains untouched — a follow-on.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 10 commits July 29, 2026 18:37
…inting it

The skew guard printed "merge the base branch, then re-run" and exited 1. That is
a correct refusal and a wasted round trip: the job holds contents:write, already
pushes commits to this branch, and the fix is a merge it is fully authorized to
perform. Making a human do a mechanical repair the machine can do is the toil
this pipeline exists to remove (operator ruling 2026-07-29).

This is a REPAIR, not a widen, which is what makes it admissible under DESIGN §5.
The arm does not proceed despite the skew — it REMOVES the skew by merging the
base into the branch, then re-runs the same check it just failed. Regeneration
happens only if that second check passes, so artifacts are still projected by a
compiler the tree agrees with. The invariant is re-established and re-verified,
never assumed. The remedy is attempted exactly once; a base that moves again
mid-run refuses rather than looping.

A MERGE CONFLICT CONFINED TO GENERATED ARTIFACTS IS NOT A CONFLICT. Measured on
the first real skew this guard caught (#7404): the only conflicting path was
ROADMAP.md — a registered generated artifact this job rewrites from its authority
in the very next step. Two branches that both regenerate a projection will always
collide in the projection, so refusing there would fail the auto-remedy on its
single most common case while the authorities underneath merged cleanly.

A generated artifact has no independent content to reconcile: it is a pure
function of the .dag authority, so whichever side is checked out is equally wrong
until main_wet runs and equally right afterwards. Taking either side and
regenerating is not a guess — the bytes are determined by the merged authority,
and the drift gate proves the result is that authority's fixed point. Scope is
exactly committed_generated_artifact_paths(), the same registry the staging step
uses, so a file qualifies only by being declared generated.

Both failure arms stay closed. If ANY conflicting path is outside that registry
the merge aborts and refuses, listing every conflict and naming the authored ones
— the classification is on the WHOLE set, so one authored conflict refuses the
entire remedy rather than partially resolving into a half-merged tree.

The merge commit is --no-verify: this is an unattended machine commit, and the
repository's own rulings already establish that git hooks are per-clone developer
feedback rather than enforcement (opt-in via core.hooksPath, bypassable, absent
in container worktrees). Found by execution — the local pre-commit hook failed
the remedy's commit with a cargo-not-on-PATH error, which CI would not have hit
but which should not gate a machine commit in any case.

Verified by execution against the real #7404 skew, not a fixture: skew detected,
merge attempted, conflict correctly classified as generated-only, resolved,
re-checked, EXIT=0 with the seed skew gone. The classification arm is unit-tested
across five cases — generated-only and generated x2 auto-resolve; authored-only,
seed-Rust, and MIXED all refuse, the mixed case being the one that must not
partially resolve.

Verified: whole-tree compile 0 blocking errors; ci.yml regenerated from the
model; emitted guard bash -n clean.

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

gunbc_ci_heal_binary_source_skew_guard_script was a join([...]) of ~55
hand-authored bash lines. It now renders from a v2.std.orchestration
Pipeline in a new v2.workflow.ci_heal_skew_guard_emit, placed beside
ci_regen_rustfmt_path_emit for the same reason (ci_spec can import it
without the ci_materialization <-> ci_spec cycle). The Scaffold row and
its dissolution trigger are DELETED, not reworded -- that is the receipt.

Control flow is structural: If / Not / Or / StrNonempty / Let / Exit.
Every git leaf derives its argv from an extdeps.git shape declaration.

Both shell loops are dissolved rather than emitted, because PipelineStep.For
has no emitter (orch_emit_step refuses it, ^orch_emit_step_for_unsupported)
and adding one to a load-bearing pipeline stage to serve one caller is the
wrong trade. Each dissolution is the better model independently:

- classification: the space-joined GENERATED_ARTIFACTS string + `for`/`case`
  glob membership test is replaced by asking git for the complement --
  --diff-filter=U limited to `.` minus one ':(exclude)<path>' pathspec per
  registered artifact. A list serialized to a string and re-parsed was a
  dual representation (DESIGN §3); this reads the registry directly.
- resolution: the per-path loop becomes one NUL-delimited `xargs -0`
  application, correct for paths with spaces or newlines.

Both deletions dissolve review 44580's paths-with-spaces finding by
construction rather than deferring it.

Two fail-closed improvements over the prior shell, deliberate and noted:
- a failed `checkout --ours` now refuses instead of staging the path anyway
  (the prior `|| true` then `git add "$c"` would stage an unresolved file --
  the fabricated-plausible-output arm §5 forbids);
- `git merge --abort` runs after the diagnostics, so a refusal always prints
  its reason.

Verified by execution against the EMITTED string, never a hand copy:
bash -n clean; the operator truth table green in a fixture repo with a real
src/v1 skew and a real three-way conflict (ROADMAP.md -> resolve;
ROADMAP.md+DESIGN.md -> resolve; authored .dag -> refuse; seed .rs ->
refuse; mixed -> refuse, merge aborted, nothing partially resolved); two
mutation RED controls flip the verdict, including the dangerous direction.
13 .dag witnesses pass, with REDs. ci.yml regenerated and byte-idempotent;
witness_committed_is_fixed_point and its RED control pass.

Also adds docs/plans/for-sugar-over-fold.md: a brief for `for` as sugar over
fold, separating the .dag surface form from PipelineStep.For emission.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title heal deferral completion + BMC/srvN Render the heal skew guard from a typed Pipeline; delete its shell scaffold Jul 29, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 29, 2026 20:35
@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Re review 44609 (codex/codex-default, REQUEST_CHANGES) — the finding is correct and I am not disputing it. ci_heal_skew_guard_emit.dag:257 does build an executable shell pipeline as a String, and a pipe embedded in Run.command is a parallel shell representation. That is the last string-embedded shell operator in the module and it does keep the dissolution incomplete.

I have not pushed a fix, because every pipe-free alternative I could find trades this for something DESIGN forbids more strongly, and the structural fix touches load-bearing files that I do not think a refactor PR should change unilaterally. Receipts below, all executed.

Why not just drop the pipe

The pipe applies git checkout --ours -- / git add to the NUL-delimited unmerged set. Alternatives tested against a real three-way conflict:

option result
git checkout --ours -- . exit 0, sets content to ours — works, no pipe. But leaves paths unmerged in the index, so a stage step is still needed.
git add -u -- <registry paths> exit 128 — fatal: pathspec '…' did not match any files for any registered artifact absent on the tree. This is the live #7121 FleetConvergeArtifact shape, which is exactly why the sibling ci_heal_git_add_lines guards each path with [ -e ]. Ruled out.
git add -u (no pathspec) exit 0, resolves everything — but stages every modified tracked file.
git merge -X ours resolves conflicts before they can be classified, so authored conflicts would be silently taken. Ruled out outright.

The third is the only pipe-free survivor, and it is a §5 staging widen. ci_heal_commit_push_note already reasons this exact case out and deliberately rejects git add -A in favour of per-path staging so "an incidental dirty file on the runner can never be swept into an unattended push". Choosing -u here would contradict a landed decision in the same file — a §3 inconsistency — to fix a representation problem. Arguing it is safe "because the tree is clean in practice" is the "negligible here" move §6 names.

The structural fix, and why it needs a call

bash.dag already models the pipe: bash_pipe_phrase (line 213), bash_production_pipe, bash_relation_rule_pipe, bash_pipe_target_model (line 980). Its only consumers are in src/v2/test/claim/manual/bash_emit_command_test.dag — so it is a declared-but-unwired grammar capability, the inert-row class DESIGN §6 wants either wired or deleted. v2.std.orchestration simply does not expose it.

So the right fix is to wire the row that already exists, not to add a grammar. Sized honestly, it is four files:

  1. v2.std.orchestration — a pipe carrier (substrate type);
  2. v2.std.orchestration_emit — one realize_pipe field on OrchestrationEmitMedium;
  3. bash_orchestration_emit — orch_pipe_target_model, binding the existing bash_pipe_* row;
  4. 05_emit_orchestration — one arm in orch_emit_step (load-bearing pipeline stage).

Two of those are files the authority docs treat as higher-bar, and there is a real modelling question I should not answer by fiat: is a pipe a PipelineStep variant, or a Run-level composition? A pipe composes two commands into one command rather than sequencing two steps, which argues for the latter — and that choice lands in the substrate for every future caller, and interacts with the shell→intent lane's Do{effect} carrier migration for host_effect.ShellCommand{script}. Guessing it inside a PR scoped to "eliminate the shell concat in the heal skew guard" is how a substrate gets a shape nobody chose.

One correction for the record, not a defence: the review cites v2.lens.medium_structure_containment as the governing discipline. That module does not exist in the tree — the name appears only in dag/gunbc/plans/self_applying_lenses.dag and src/v2/std/compilers/target_model.dag, and there is no live gate by that name. The DESIGN §2–§3 argument stands entirely on its own without it; I mention it only so nobody goes looking for a lens to run.

Where that leaves this PR

The finding is real, so I am treating this as open, not resolved, and I have asked the operator for the call on the carrier shape and on touching the two higher-bar files. If the answer is "wire it here", I will; if it is "land the guard now and wire the pipe in its own PR", then this module keeps one declared residue line with a named trigger — which is the same honest-scaffold shape ci_regen_rustfmt_path_emit's test -x leaves already occupy, and strictly less shell than the 55 hand-authored lines this PR deletes.

Separately, and unrelated to this finding: the PR body documents a structural defect in the seed-ahead predicate inherited from #7401/#7418 (GitHub's synthetic merge ref makes the guard refuse forever when both the branch and main touch src/v1, mis-diagnosed as "the base moved again"). That one also needs an operator decision and is not fixed here, because this PR's criterion is behavioural equivalence.

— sent from quiet-wren-607

gunbc-ci-auto-heal and others added 6 commits July 29, 2026 21:03
origin/main regained #7418's join([...]) shell when that PR merged, so the
conflict in gunbc_ci_heal_binary_source_skew_guard_script is exactly the
change this branch exists to make -- resolved to the modeled delegation.

Two things the auto-merge got wrong, both fixed here:

- ci_heal_skew_auto_remedy_note was DUPLICATED. Both sides added the
  byte-identical row independently (this branch via the heal-auto-remedy
  merge, main via #7418 landing), so git kept two copies -- a duplicate
  declaration and a second representation of one fact (DESIGN §3). One copy
  retained.
- .github/workflows/ci.yml is a generated artifact, so it was never
  hand-resolved: main's side was staged as a base and the file regenerated
  from its .dag authority. Verified the regenerated step carries the modeled
  form -- zero occurrences of the space-joined GENERATED_ARTIFACTS variable,
  zero `for c in $CONFLICTS` loops, and the quoted ':(exclude)...' pathspec
  present.

Re-verified after resolution: 13 guard witnesses pass; regen is byte-
idempotent with witness_committed_is_fixed_point and its RED control green.

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

The resolve step spelled " | xargs -0 " as shell text, which introduced a whole
external program with no extdeps citation (DESIGN §3). xargs now has its own cited
module beside exec_arg_limit — the boundary that is the reason xargs exists — with
both of its authorities named and the fidelity fact that -0 is a GNU extension the
POSIX spec does not define.

Both pipe operands are now cited argv shapes joined by one local joiner, so the
only target-language token this module still spells is the two-character operator
between them, named and counted as ci_heal_skew_pipe_operator. Sourcing it from
the bash grammar that already models it would leak emit-layer vocabulary into a
workflow intent module, which v2.lens.realization_vocabulary_containment exists to
red; closing it properly is a PipelineStep/Run carrier decision on load-bearing
files that this brief explicitly excluded, so it stays declared with a dissolution
trigger rather than smuggled in.

Emission is byte-identical: regen leaves ci.yml unchanged.
@briansrls
briansrls force-pushed the session/quiet-wren-607 branch from 1d25cc5 to 339583b Compare July 29, 2026 22:45
@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the pipe finding at 339583beb6e, and split it into the half I can close and the half I should not close unilaterally.

Closed: the uncited external program. The finding's substantive content was that " | xargs -0 " was shell text — but the sharper problem underneath it was that my change introduced xargs, an entire external program, with zero extdeps/ citation. There was no xargs anywhere in dag/extdeps/ before this PR. That is a plain DESIGN §3 violation and it is now fixed: dag/extdeps/exec/xargs.dag cites both of xargs's authorities and records the fidelity fact that -0 is not POSIX — the Open Group xargs page defines no null-delimited mode, so -0/--null is attributed to GNU findutils, which does. Citing only POSIX would have pointed at a spec that does not contain the flag being spelled. It lives beside exec_arg_limit.dag because the execve argv ceiling that module models is precisely why xargs exists, and it deliberately models only the null-delimited mode — the default whitespace/quote-honouring reading silently mis-splits paths containing spaces or newlines, which is the fabricated-output arm §5 forbids, so it is absent rather than offered-with-a-warning.

Declared, not closed: the pipe operator itself. Both operands are now cited argv shapes joined by one local joiner, so what remains hand-spelled is the two-character operator between them, named and counted as ci_heal_skew_pipe_operator with ci_heal_skew_pipe_residue_note. I did not close it, and the reason is not effort:

  • extdeps.languages.bash already models the pipe (bash_pipe_phrase spells the | token), but that vocabulary is confined to the emit layer by v2.lens.realization_vocabulary_containment (Phase 4: lock shell→intent via generalized realization_vocabulary_containment #6854). Importing it into a v2.workflow intent module is exactly the leak that lens exists to red, so sourcing the token from its grammar authority is not available from here.
  • The honest fixes are a Pipe variant on PipelineStep or a producer/consumer composition on Run, either way with an arm in 05_emit_orchestration. Both edit files DESIGN.md names load-bearing, and this PR's brief said explicitly do not build a new carrier. Escalating before touching a load-bearing stage under a brief that predates the model decision is the rule, so it stays declared with a dissolution trigger rather than arriving as an unrequested substrate change.

ci_heal_skew_piped_command already takes producer_argv/consumer_argv, so when that carrier lands only the body changes, not the call sites.

Emission is byte-identical. Regen leaves ci.yml unchanged (git diff f872171bfd5 HEAD -- .github/workflows/ci.yml is empty); the emitted lines are git diff --name-only --diff-filter=U -z | xargs -0 git checkout --ours -- and … | xargs -0 git add at ci.yml:327-328. 13/13 guard witnesses, witness_committed_is_fixed_point and its RED control all pass.

Separate finding, not fixed here. While placing the citation I found the argv→shell-line join exists five times: extdeps.git.git_shell_join_argv, gunbc.live_deploy.operations.argv_join, and three test-local copies. Two things are wrong beyond the duplication — the git_ prefix nicknames a concept that is not git-specific, and git_shell_join_argv is a hand-rolled fold reimplementing the join builtin with a behavioural divergence: it silently drops leading empty argv tokens where join(argv, " ") preserves them. An empty argv element is meaningful to execve, so that is a quiet fidelity loss, not just redundancy. This module now uses the builtin and no longer imports the git-named joiner, so the PR does not spread it; consolidating the other four is a clean follow-on and I did not widen this PR to do it.

— sent from quiet-wren-607

gunbc-ci-auto-heal added 4 commits July 29, 2026 22:49
An unquoted code example in a dashboard message let bash read '=> true,' and
'=> false' as redirections, creating empty files named 'true,' and 'false' at the
repo root; the session autocommit then picked them up. They were never part of the
change and carry no content.
The guard compared the tree against BUILT_FROM (github.sha, fixed for the run) but
remedied a skew by merging origin/BASE_REF — the LATEST base. Those are two
different revisions of the base, so whenever the base advanced between the build
and the heal job the remedy overshot its own comparison target, the post-remedy
re-check found a difference, and the job refused. Since the release build takes
~15 minutes on a base that merges more often than that, this is not a transient:
re-running rebuilds against a newer base and reopens the window, so the guard can
refuse indefinitely.

Merging BUILT_FROM makes the re-check pass by construction rather than by luck:
BUILT_FROM becomes an ancestor of HEAD, so the seed-ahead set is empty for every
input. The still-skewed arm stays as a fail-closed backstop, and its message no
longer speculates "the base moved again during this run" — an explanation the
receipt falsifies, since the two checks are 350ms apart.

Measured on the live failing run 30497545614: the merge ref's base parent was
b0c8eba while origin/main had already advanced to 37ae94b — exactly one
intervening base commit, and it touched src/v1.

BASE_REF, its binding and the origin/BASE_REF spelling are deleted rather than
left as dead scaffolding: BUILT_FROM is already fetched by the provenance step and
its resolvability is refused on upfront, so the base fetch bought nothing.

Truth table re-proven by execution against the emitted bytes: 17/17 over seven
fixtures — no-skew, clean remedy, the overshoot case with a control showing the
old remedy refuses where this one proceeds, generated-only conflicts (one and two
files) auto-resolving, authored .dag and seed .rs conflicts refusing with the
typed diagnostic and no MERGE_HEAD, and the mixed conflict refusing with nothing
staged. 15/15 structural witnesses pass, including a new pair asserting the remedy
targets BUILT_FROM with the moving-base spelling as the RED control.
@briansrls
briansrls force-pushed the session/quiet-wren-607 branch from f107089 to ab448b1 Compare July 29, 2026 23:27
@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

The guard refused my own PR, and it found a real defect — a livelock, not a transient

Run 30497545614 failed heal_generated_artifacts in 7s. Reading it rather than re-running it turned up an inherited defect that would have made this guard unable to succeed on a busy base. Fixed at ab448b1857e.

What the run said. It detected the skew correctly (branch head lacked b0c8eba0835), merged the base cleanly with no conflicts, then refused: "still skewed after merging origin/main — the base moved again during this run."

That explanation is false. The two checks are 350ms apart, and origin/main cannot change without a fetch.

The actual mechanism. The guard compares the tree against BUILT_FROM (github.sha — on a pull_request, the synthetic merge ref), which is fixed for the whole run. But the remedy merged origin/$BASE_REF — the latest base. Those are two different revisions of the base, so the remedy overshoots its own comparison target whenever the base advances between the build and the heal job. Measured on this run: the merge ref's base parent was b0c8eba0835 while origin/main had already reached 37ae94b8211 — exactly one intervening base commit, and it touched src/v1.

The release build takes ~15 minutes on a base that merges more often than that, so re-running cannot fix it: each re-run rebuilds against a newer base and reopens the window. That is a livelock. sunny-crab-665 hit the same thing on #7421 and had to merge main twice because the base advanced again mid-remedy — independent confirmation.

The fix is a construction, not a retry. The remedy now merges $BUILT_FROM itself — the revision the binary was actually built from. After that merge BUILT_FROM is an ancestor of HEAD, so git rev-list HEAD.."$BUILT_FROM" -- src/v1 is empty for every input, and the re-check passes by construction rather than by luck (DESIGN §5). The still-skewed arm is kept as a fail-closed backstop, and its message now says the arm should be unreachable and that re-running is the wrong response, instead of offering a cause the receipt falsifies.

Safe by construction, not by hope: the guard already refuses upfront if BUILT_FROM is unresolvable, so the remedy can only run when the object is present.

BASE_REF, its binding and the origin/$BASE_REF spelling are deleted, not left behind — BUILT_FROM is already fetched by the provenance step, so the base fetch bought nothing and would have been dead scaffolding.

Truth table re-proven by execution against the emitted bytes (not a hand copy), 17/17 across seven fixtures:

case expected result
no skew proceeds ✅
skew, clean remedy proceeds; seed-ahead empty afterwards ✅
base advanced past BUILT_FROM proceeds ✅ + control: the old remedy leaves it non-empty and refuses
conflict in 1 generated artifact auto-resolves ✅
conflict in 2 generated artifacts auto-resolves ✅
conflict in authored .dag refuses, typed diagnostic, no MERGE_HEAD ✅
conflict in seed .rs refuses ✅
mixed refuses, nothing staged ✅

The third row is the discriminating one: the control merges the latest base on an untouched copy of the same fixture and shows the seed-ahead set stays non-empty, so the old code refuses exactly where the new code proceeds. Two fixture bugs of my own were caught and fixed while building this — a subshell that ran three cases against the wrong repo, and a conflict setup that produced no conflict — both of which had been reporting spurious passes.

15/15 structural witnesses pass, including a new pair asserting the remedy targets BUILT_FROM with the moving-base spelling as the RED control.

For anyone hitting this before it merges: a heal refusal after the remedy applied cleanly is this defect. Merging main by hand clears it for one run; it is not a sign your PR is wrong.

— sent from quiet-wren-607

@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor Author

Replying to review 44741 (codex, REQUEST_CHANGES) rather than pushing, because the remedy it names is blocked by this PR's own brief and I don't think I should resolve that unilaterally.

The technical observation is correct. ci_heal_skew_piped_command builds producer | consumer as a String and hands it to Run.command. It is not a structural node emitted through grammar rows, and my 🟡 note documents that rather than fixing it. I'm not disputing any of that.

But the scope is mis-drawn, and the numbers matter. Run.command is declared command: String at src/v2/std/orchestration.dag:39 — a substrate fact today, and one DESIGN.md already tracks as one of three anemic String leaves awaiting the Do{effect} migration (shell → intent open thread). Consequences:

  • My module has 6 Run.command sites and 5 of them are argv commands with no pipe. They are strings in Run.command exactly as the pipe is. The pipe differs by one operator character, not in kind. If string-in-Run.command is the blocker, it indicts all 6, not 1.
  • Tree-wide there are ~60 such sites across src/v2/workflow/*_emit.dag. Every existing emit module — ci_release_build_emit, ci_retry_emit, ci_floor_peak_emit, ci_materialization_emit, the ci_regen_rustfmt_path_emit this module was told to follow as the live precedent — composes shell text into Run.command the same way.

So "retain the scaffold until that capability exists," applied consistently, means retaining a scaffold for every emit module in the tree. The defect is real but it is substrate-level and pre-existing, not introduced here, and its fix is the Do{effect} migration DESIGN already owns.

Why I am not just building the pipe carrier. The structural fix is a PipelineStep.Pipe variant plus an orch_emit_step arm over the bash_pipe_* rows. That edits v2.std.orchestration (a substrate type, referenced by 21 files) and 05_emit_orchestration (a load-bearing stage). Three things stand against my doing it inside this PR:

  1. This PR's brief says explicitly "do NOT build a new carrier" — and its stated reason was that the carriers already exist. That premise is simply false for the pipe: there is no Pipe variant. So the instruction rests on a factual error, which is a reason to escalate, not a licence to proceed.
  2. The project spirit requires escalating before touching files the authority docs name load-bearing under a brief that predates the relevant model decision. This is that case.
  3. Adding a variant to a coproduct referenced by 21 files is not a drive-by; it wants its own PR and its own review.

One option I checked and rejected as dishonest: the containment lens permits bash vocabulary under the src/v2/workflow/orchestration_ prefix, so I could move the string-building into orchestration_bash_emit_support and source | from bash_pipe_phrase. That would be lens-legal and would make the intent module look clean — but it would still produce a String for Run.command, so it relocates the finding instead of closing it. Presenting that as a fix would be worse than leaving the residue named.

I also re-checked whether the pipe can be eliminated outright, which would dissolve this whole question. It cannot, without reintroducing a defect: git checkout --ours -- . errors on non-conflicted paths, and git checkout --ours -- $(git diff …) reintroduces exactly the word-splitting bug on paths with spaces that this PR fixed. Applying an operation to precisely the computed set is what the NUL-delimited pipe is for.

So this is an operator call, and I'm flagging it rather than guessing: either (1) authorize the PipelineStep.Pipe carrier — as a follow-up PR, since it wants its own review — and merge this with the residue named; or (2) rule that string-in-Run.command blocks merge, in which case the consistent consequence is reverting this PR to the scaffold and the ~60 sibling sites are equally blocked, which is really a decision to prioritize the Do{effect} migration lane.

Everything else in review 44741's neighbourhood is addressed: both pipe operands are cited extdeps argv shapes, xargs now carries its own authorities, and since that review was written I fixed a livelock in this same guard (the remedy merged the moving base against a pinned comparison target — see the comment above, 17/17 re-proven by execution).

— sent from quiet-wren-607

@briansrls
briansrls merged commit 5c7a243 into main Jul 30, 2026
5 checks passed
@briansrls
briansrls deleted the session/quiet-wren-607 branch July 30, 2026 00:44
briansrls added a commit that referenced this pull request Jul 30, 2026
* Model BMC desired state and reconciliation

* Define typed OpenBMC fan operations

* Ensure BMC access only when demanded

* Actuate BMC fan convergence with typed rollback

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit 4441ba7.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit 33883c6.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit a8a9edf.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit a3c497f.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit 5115d46.

* Consume shared validated BMC fan curve

* Narrow shared curve import to validated carrier

* Use validated curve in duty consumers

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Preserve units across OpenBMC observations

* Bind SSH identity admission to exact host

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Treat fan hysteresis as a temperature delta

* Split typed OpenBMC operations from blocked actuator

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Remove parallel OpenBMC argv interpreter

* Document fixed OpenBMC transport boundary

* Retire hand-written test-module hygiene producer (#7426)

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* Fail closed on orphan reachability budget exhaustion (review 44632).

Stop re-queuing names already on the frontier or marked reachable/seen;
model orphan_plain_names_or_refuse with ReachBudgetRefused when fuel remains
with a non-empty frontier; propagate through check_orphan_surfaces_or_refuse.

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

* WIP: Retire hand-written test-module hygiene producer

* Delete fail-open orphan_plain_names; route test-decl scan through .dag.

Remove the swallowing orphan_plain_names helper and repoint scaffold bind
to orphan_plain_names_or_refuse; drop dead collect_orphan_records. Bridge
test-fn/test-data classification now calls enumerate_entry_test_names instead
of a parallel Rust line scanner (review 44640).

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

* Re-home unparsable *_test.dag refuse witness (review 44642).

Restore executing coverage in test_module_hygiene_bridge_equivalence_tests
and enroll the scaffold discriminator in the hand-rust equivalence witness.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* Mark OpenBMC observations readonly

* Anchor OpenBMC extdeps authorities

* Surface observe_tool's per-argv result as a named per-tool observed identity; re-express toolchain_identity as the derived fold over those rows (unblocks hermetic-toolchain P2 reconcile) (#7435)

* WIP: Surface observe_tool's per-argv result as a named per-tool observed iden

* WIP: Surface observe_tool's per-argv result as a named per-tool observed iden

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>

* Bind the v1 deletion lane's two startable roots that have a closing validation (#7442)

The pilot step: point the proven dispatch mechanism at the lane it exists for.
Seven roots in the v1 deletion lane are startable (no unaccepted prerequisite).
TWO are bindable. The other five are the finding, not an omission.

A binding names the validation that CLOSES a node, so it can only be authored
when that validation exists. Surveyed against the tree:

  v2-emitter-producer-provenance  -> BOUND. The ticket demands that "a result
    recorded as made by the new generator, with no receipt from a run that
    actually produced it, has to be impossible to write", and
    witness_restored_binding_without_executed_receipt_does_not_authorize_reds
    asserts exactly that. Chosen over the suite's other twenty-six claims because
    it fails if the unrepresentability itself lapses, rather than checking that a
    roster stayed in step.

  v1-test-migration -> BOUND. test_migration_delete_guard_holds is the red
    control verbatim — "any old test file with nothing covering it keeps deletion
    blocked" — and it is the deletion wall itself rather than a report about it,
    so Verify runs the thing that would actually stop an unsafe deletion.

  v1-materialization-kernel wants cold-start, warm-reuse, corruption and eviction
    demonstrated; the materialization witnesses present assert scaffold
    dispositions, not kernel behaviour.
  v1-test-hygiene-producer-retirement wants identical-behaviour-then-deletion,
    which no witness states.
  v1-hand-queue-drain wants a product-reachability census that does not exist.
  pderive-typesafe-nullary-reflection's unrepresentability claim has no witness
    carrying it.
  caret-parse-smoke-seed-growth-justification declares no red control at all,
    being a justification row.

Those five stay ExecutionContractUnspecified, which is the honest fail-closed
state: dispatch refuses with a typed diagnostic rather than admitting an
environment for work whose completion nothing can check. Fabricating contracts to
make the lane look dispatchable would produce exactly the coverage-by-illusion
tier — every node clickable, every Verify vacuous. Their real prerequisite is
that the acceptance witness is written as part of the first slice; the contract
follows the witness, never precedes it.

One home worth noting: test_migration_debt_test lives under test/claim/manual/,
excluded from per-PR discovery at dir grain. That does not weaken the contract —
a WorkItemExecutionContract invokes its validation DIRECTLY through the claim
runner, so the exclusion governs corpus cadence and not this call. It does mean
the guard's own regressions surface at dispatch rather than on the floor.

Verified: whole-tree compile 0 blocking errors; both bound validations run green
directly; frontier count witness updated 2 -> 4; roadmap_authority 35/35 green;
ROADMAP.md regenerated.

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>

* Add namespace-import-deletion to the roadmap; gate zero-hand-maintained-Rust on it (#7441)

* WIP: Jul 28

* WIP: Jul 28

* WIP: Jul 28

* WIP: Jul 28

* WIP: Jul 28

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* De-fork self-host std shims onto the shared bridge; keep the 03_normalize selection edge honest (#7439)

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* De-fork per-transport std shims onto the shared bridge; keep declared refs honest

* WIP: affected set

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>

* Triage the 12-red v1-compiler --lib suite: 9 expired premises, 1 real fail-open (#7425)

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* Triage the 12-red v1-compiler --lib suite: hermetic fixtures, stale layer rule, §13 policy pinning

* WIP: 12 reds

* WIP: 12 reds

* Anchor layer-fact paths at workspace root; split unreadable from ungrounded

* WIP: 12 reds

* WIP: 12 reds

* Split hygiene-gate seam: judge only the fixture, not the whole corpus (review 44641)

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* Ground the layer oracle on both fact provenances; receipt the discovery transport split (reviews 44710)

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>

* Render the heal skew guard from a typed Pipeline; delete its shell scaffold (#7420)

* heal: apply the binary/source skew remedy automatically instead of printing it

The skew guard printed "merge the base branch, then re-run" and exited 1. That is
a correct refusal and a wasted round trip: the job holds contents:write, already
pushes commits to this branch, and the fix is a merge it is fully authorized to
perform. Making a human do a mechanical repair the machine can do is the toil
this pipeline exists to remove (operator ruling 2026-07-29).

This is a REPAIR, not a widen, which is what makes it admissible under DESIGN §5.
The arm does not proceed despite the skew — it REMOVES the skew by merging the
base into the branch, then re-runs the same check it just failed. Regeneration
happens only if that second check passes, so artifacts are still projected by a
compiler the tree agrees with. The invariant is re-established and re-verified,
never assumed. The remedy is attempted exactly once; a base that moves again
mid-run refuses rather than looping.

A MERGE CONFLICT CONFINED TO GENERATED ARTIFACTS IS NOT A CONFLICT. Measured on
the first real skew this guard caught (#7404): the only conflicting path was
ROADMAP.md — a registered generated artifact this job rewrites from its authority
in the very next step. Two branches that both regenerate a projection will always
collide in the projection, so refusing there would fail the auto-remedy on its
single most common case while the authorities underneath merged cleanly.

A generated artifact has no independent content to reconcile: it is a pure
function of the .dag authority, so whichever side is checked out is equally wrong
until main_wet runs and equally right afterwards. Taking either side and
regenerating is not a guess — the bytes are determined by the merged authority,
and the drift gate proves the result is that authority's fixed point. Scope is
exactly committed_generated_artifact_paths(), the same registry the staging step
uses, so a file qualifies only by being declared generated.

Both failure arms stay closed. If ANY conflicting path is outside that registry
the merge aborts and refuses, listing every conflict and naming the authored ones
— the classification is on the WHOLE set, so one authored conflict refuses the
entire remedy rather than partially resolving into a half-merged tree.

The merge commit is --no-verify: this is an unattended machine commit, and the
repository's own rulings already establish that git hooks are per-clone developer
feedback rather than enforcement (opt-in via core.hooksPath, bypassable, absent
in container worktrees). Found by execution — the local pre-commit hook failed
the remedy's commit with a cargo-not-on-PATH error, which CI would not have hit
but which should not gate a machine commit in any case.

Verified by execution against the real #7404 skew, not a fixture: skew detected,
merge attempted, conflict correctly classified as generated-only, resolved,
re-checked, EXIT=0 with the seed skew gone. The classification arm is unit-tested
across five cases — generated-only and generated x2 auto-resolve; authored-only,
seed-Rust, and MIXED all refuse, the mixed case being the one that must not
partially resolve.

Verified: whole-tree compile 0 blocking errors; ci.yml regenerated from the
model; emitted guard bash -n clean.

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

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* Render the heal skew guard from a typed Pipeline; delete its shell scaffold

gunbc_ci_heal_binary_source_skew_guard_script was a join([...]) of ~55
hand-authored bash lines. It now renders from a v2.std.orchestration
Pipeline in a new v2.workflow.ci_heal_skew_guard_emit, placed beside
ci_regen_rustfmt_path_emit for the same reason (ci_spec can import it
without the ci_materialization <-> ci_spec cycle). The Scaffold row and
its dissolution trigger are DELETED, not reworded -- that is the receipt.

Control flow is structural: If / Not / Or / StrNonempty / Let / Exit.
Every git leaf derives its argv from an extdeps.git shape declaration.

Both shell loops are dissolved rather than emitted, because PipelineStep.For
has no emitter (orch_emit_step refuses it, ^orch_emit_step_for_unsupported)
and adding one to a load-bearing pipeline stage to serve one caller is the
wrong trade. Each dissolution is the better model independently:

- classification: the space-joined GENERATED_ARTIFACTS string + `for`/`case`
  glob membership test is replaced by asking git for the complement --
  --diff-filter=U limited to `.` minus one ':(exclude)<path>' pathspec per
  registered artifact. A list serialized to a string and re-parsed was a
  dual representation (DESIGN §3); this reads the registry directly.
- resolution: the per-path loop becomes one NUL-delimited `xargs -0`
  application, correct for paths with spaces or newlines.

Both deletions dissolve review 44580's paths-with-spaces finding by
construction rather than deferring it.

Two fail-closed improvements over the prior shell, deliberate and noted:
- a failed `checkout --ours` now refuses instead of staging the path anyway
  (the prior `|| true` then `git add "$c"` would stage an unresolved file --
  the fabricated-plausible-output arm §5 forbids);
- `git merge --abort` runs after the diagnostics, so a refusal always prints
  its reason.

Verified by execution against the EMITTED string, never a hand copy:
bash -n clean; the operator truth table green in a fixture repo with a real
src/v1 skew and a real three-way conflict (ROADMAP.md -> resolve;
ROADMAP.md+DESIGN.md -> resolve; authored .dag -> refuse; seed .rs ->
refuse; mixed -> refuse, merge aborted, nothing partially resolved); two
mutation RED controls flip the verdict, including the dangerous direction.
13 .dag witnesses pass, with REDs. ci.yml regenerated and byte-idempotent;
witness_committed_is_fixed_point and its RED control pass.

Also adds docs/plans/for-sugar-over-fold.md: a brief for `for` as sugar over
fold, separating the .dag surface form from PipelineStep.For emission.

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

* WIP: heal deferral completion + BMC/srvN

* Merge main; keep the modeled guard and drop the duplicated note row

origin/main regained #7418's join([...]) shell when that PR merged, so the
conflict in gunbc_ci_heal_binary_source_skew_guard_script is exactly the
change this branch exists to make -- resolved to the modeled delegation.

Two things the auto-merge got wrong, both fixed here:

- ci_heal_skew_auto_remedy_note was DUPLICATED. Both sides added the
  byte-identical row independently (this branch via the heal-auto-remedy
  merge, main via #7418 landing), so git kept two copies -- a duplicate
  declaration and a second representation of one fact (DESIGN §3). One copy
  retained.
- .github/workflows/ci.yml is a generated artifact, so it was never
  hand-resolved: main's side was staged as a base and the file regenerated
  from its .dag authority. Verified the regenerated step carries the modeled
  form -- zero occurrences of the space-joined GENERATED_ARTIFACTS variable,
  zero `for c in $CONFLICTS` loops, and the quoted ':(exclude)...' pathspec
  present.

Re-verified after resolution: 13 guard witnesses pass; regen is byte-
idempotent with witness_committed_is_fixed_point and its RED control green.

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

* Cite xargs in extdeps and shrink the guard's hand-spelled shell to one pipe token

The resolve step spelled " | xargs -0 " as shell text, which introduced a whole
external program with no extdeps citation (DESIGN §3). xargs now has its own cited
module beside exec_arg_limit — the boundary that is the reason xargs exists — with
both of its authorities named and the fidelity fact that -0 is a GNU extension the
POSIX spec does not define.

Both pipe operands are now cited argv shapes joined by one local joiner, so the
only target-language token this module still spells is the two-character operator
between them, named and counted as ci_heal_skew_pipe_operator. Sourcing it from
the bash grammar that already models it would leak emit-layer vocabulary into a
workflow intent module, which v2.lens.realization_vocabulary_containment exists to
red; closing it properly is a PipelineStep/Run carrier decision on load-bearing
files that this brief explicitly excluded, so it stays declared with a dissolution
trigger rather than smuggled in.

Emission is byte-identical: regen leaves ci.yml unchanged.

* WIP: heal deferral completion + BMC/srvN

* Remove two empty junk files created by a shell quoting slip

An unquoted code example in a dashboard message let bash read '=> true,' and
'=> false' as redirections, creating empty files named 'true,' and 'false' at the
repo root; the session autocommit then picked them up. They were never part of the
change and carry no content.

* Make the heal remedy merge BUILT_FROM, not the moving base

The guard compared the tree against BUILT_FROM (github.sha, fixed for the run) but
remedied a skew by merging origin/BASE_REF — the LATEST base. Those are two
different revisions of the base, so whenever the base advanced between the build
and the heal job the remedy overshot its own comparison target, the post-remedy
re-check found a difference, and the job refused. Since the release build takes
~15 minutes on a base that merges more often than that, this is not a transient:
re-running rebuilds against a newer base and reopens the window, so the guard can
refuse indefinitely.

Merging BUILT_FROM makes the re-check pass by construction rather than by luck:
BUILT_FROM becomes an ancestor of HEAD, so the seed-ahead set is empty for every
input. The still-skewed arm stays as a fail-closed backstop, and its message no
longer speculates "the base moved again during this run" — an explanation the
receipt falsifies, since the two checks are 350ms apart.

Measured on the live failing run 30497545614: the merge ref's base parent was
b0c8eba while origin/main had already advanced to 37ae94b — exactly one
intervening base commit, and it touched src/v1.

BASE_REF, its binding and the origin/BASE_REF spelling are deleted rather than
left as dead scaffolding: BUILT_FROM is already fetched by the provenance step and
its resolvability is refused on upfront, so the base fetch bought nothing.

Truth table re-proven by execution against the emitted bytes: 17/17 over seven
fixtures — no-skew, clean remedy, the overshoot case with a control showing the
old remedy refuses where this one proceeds, generated-only conflicts (one and two
files) auto-resolving, authored .dag and seed .rs conflicts refusing with the
typed diagnostic and no MERGE_HEAD, and the mixed conflict refusing with nothing
staged. 15/15 structural witnesses pass, including a new pair asserting the remedy
targets BUILT_FROM with the moving-base spelling as the RED control.

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Brian <briansrls@MacBook-Pro.local>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Brian Searls <11205878+briansrls@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 30, 2026
… make the proof boundary real (nonempty/unique boundaries, typed instants + ordering, receipt linkage, scoped activation receipt, mechanical realization hashes, validated fan curve, /proc/mounts parser); no concat in std (#7421)

* Bind durability evidence to admitted state

* Record versioned BMC capabilities and live receipts

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Use canonical carriers in BMC proof receipts

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Use canonical HTTP status carrier for BMC reset

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Regenerate signed temperature delta carriers

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Regenerate canonical positive measure carrier

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Make durability proof gaps explicit

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Repair positive measure seed realization

* Close positive measure and parser review gaps

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Close durability qualification bypass

* Close the typed OpenBMC operation surface (#7428)

* Model BMC desired state and reconciliation

* Define typed OpenBMC fan operations

* Ensure BMC access only when demanded

* Actuate BMC fan convergence with typed rollback

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit 4441ba7.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit 33883c6.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit a8a9edf.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit a3c497f.

* Revert "WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma"

This reverts commit 5115d46.

* Consume shared validated BMC fan curve

* Narrow shared curve import to validated carrier

* Use validated curve in duty consumers

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Preserve units across OpenBMC observations

* Bind SSH identity admission to exact host

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Treat fan hysteresis as a temperature delta

* Split typed OpenBMC operations from blocked actuator

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* WIP: BMC stack B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Remove parallel OpenBMC argv interpreter

* Document fixed OpenBMC transport boundary

* Retire hand-written test-module hygiene producer (#7426)

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* WIP: Retire hand-written test-module hygiene producer

* Fail closed on orphan reachability budget exhaustion (review 44632).

Stop re-queuing names already on the frontier or marked reachable/seen;
model orphan_plain_names_or_refuse with ReachBudgetRefused when fuel remains
with a non-empty frontier; propagate through check_orphan_surfaces_or_refuse.

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

* WIP: Retire hand-written test-module hygiene producer

* Delete fail-open orphan_plain_names; route test-decl scan through .dag.

Remove the swallowing orphan_plain_names helper and repoint scaffold bind
to orphan_plain_names_or_refuse; drop dead collect_orphan_records. Bridge
test-fn/test-data classification now calls enumerate_entry_test_names instead
of a parallel Rust line scanner (review 44640).

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

* Re-home unparsable *_test.dag refuse witness (review 44642).

Restore executing coverage in test_module_hygiene_bridge_equivalence_tests
and enroll the scaffold discriminator in the hand-rust equivalence witness.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* Mark OpenBMC observations readonly

* Anchor OpenBMC extdeps authorities

* Surface observe_tool's per-argv result as a named per-tool observed identity; re-express toolchain_identity as the derived fold over those rows (unblocks hermetic-toolchain P2 reconcile) (#7435)

* WIP: Surface observe_tool's per-argv result as a named per-tool observed iden

* WIP: Surface observe_tool's per-argv result as a named per-tool observed iden

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>

* Bind the v1 deletion lane's two startable roots that have a closing validation (#7442)

The pilot step: point the proven dispatch mechanism at the lane it exists for.
Seven roots in the v1 deletion lane are startable (no unaccepted prerequisite).
TWO are bindable. The other five are the finding, not an omission.

A binding names the validation that CLOSES a node, so it can only be authored
when that validation exists. Surveyed against the tree:

  v2-emitter-producer-provenance  -> BOUND. The ticket demands that "a result
    recorded as made by the new generator, with no receipt from a run that
    actually produced it, has to be impossible to write", and
    witness_restored_binding_without_executed_receipt_does_not_authorize_reds
    asserts exactly that. Chosen over the suite's other twenty-six claims because
    it fails if the unrepresentability itself lapses, rather than checking that a
    roster stayed in step.

  v1-test-migration -> BOUND. test_migration_delete_guard_holds is the red
    control verbatim — "any old test file with nothing covering it keeps deletion
    blocked" — and it is the deletion wall itself rather than a report about it,
    so Verify runs the thing that would actually stop an unsafe deletion.

  v1-materialization-kernel wants cold-start, warm-reuse, corruption and eviction
    demonstrated; the materialization witnesses present assert scaffold
    dispositions, not kernel behaviour.
  v1-test-hygiene-producer-retirement wants identical-behaviour-then-deletion,
    which no witness states.
  v1-hand-queue-drain wants a product-reachability census that does not exist.
  pderive-typesafe-nullary-reflection's unrepresentability claim has no witness
    carrying it.
  caret-parse-smoke-seed-growth-justification declares no red control at all,
    being a justification row.

Those five stay ExecutionContractUnspecified, which is the honest fail-closed
state: dispatch refuses with a typed diagnostic rather than admitting an
environment for work whose completion nothing can check. Fabricating contracts to
make the lane look dispatchable would produce exactly the coverage-by-illusion
tier — every node clickable, every Verify vacuous. Their real prerequisite is
that the acceptance witness is written as part of the first slice; the contract
follows the witness, never precedes it.

One home worth noting: test_migration_debt_test lives under test/claim/manual/,
excluded from per-PR discovery at dir grain. That does not weaken the contract —
a WorkItemExecutionContract invokes its validation DIRECTLY through the claim
runner, so the exclusion governs corpus cadence and not this call. It does mean
the guard's own regressions surface at dispatch rather than on the floor.

Verified: whole-tree compile 0 blocking errors; both bound validations run green
directly; frontier count witness updated 2 -> 4; roadmap_authority 35/35 green;
ROADMAP.md regenerated.

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>

* Add namespace-import-deletion to the roadmap; gate zero-hand-maintained-Rust on it (#7441)

* WIP: Jul 28

* WIP: Jul 28

* WIP: Jul 28

* WIP: Jul 28

* WIP: Jul 28

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* De-fork self-host std shims onto the shared bridge; keep the 03_normalize selection edge honest (#7439)

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* WIP: affected set

* De-fork per-transport std shims onto the shared bridge; keep declared refs honest

* WIP: affected set

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>

* Triage the 12-red v1-compiler --lib suite: 9 expired premises, 1 real fail-open (#7425)

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* Triage the 12-red v1-compiler --lib suite: hermetic fixtures, stale layer rule, §13 policy pinning

* WIP: 12 reds

* WIP: 12 reds

* Anchor layer-fact paths at workspace root; split unreadable from ungrounded

* WIP: 12 reds

* WIP: 12 reds

* Split hygiene-gate seam: judge only the fixture, not the whole corpus (review 44641)

* WIP: 12 reds

* WIP: 12 reds

* WIP: 12 reds

* Ground the layer oracle on both fact provenances; receipt the discovery transport split (reviews 44710)

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>

* Render the heal skew guard from a typed Pipeline; delete its shell scaffold (#7420)

* heal: apply the binary/source skew remedy automatically instead of printing it

The skew guard printed "merge the base branch, then re-run" and exited 1. That is
a correct refusal and a wasted round trip: the job holds contents:write, already
pushes commits to this branch, and the fix is a merge it is fully authorized to
perform. Making a human do a mechanical repair the machine can do is the toil
this pipeline exists to remove (operator ruling 2026-07-29).

This is a REPAIR, not a widen, which is what makes it admissible under DESIGN §5.
The arm does not proceed despite the skew — it REMOVES the skew by merging the
base into the branch, then re-runs the same check it just failed. Regeneration
happens only if that second check passes, so artifacts are still projected by a
compiler the tree agrees with. The invariant is re-established and re-verified,
never assumed. The remedy is attempted exactly once; a base that moves again
mid-run refuses rather than looping.

A MERGE CONFLICT CONFINED TO GENERATED ARTIFACTS IS NOT A CONFLICT. Measured on
the first real skew this guard caught (#7404): the only conflicting path was
ROADMAP.md — a registered generated artifact this job rewrites from its authority
in the very next step. Two branches that both regenerate a projection will always
collide in the projection, so refusing there would fail the auto-remedy on its
single most common case while the authorities underneath merged cleanly.

A generated artifact has no independent content to reconcile: it is a pure
function of the .dag authority, so whichever side is checked out is equally wrong
until main_wet runs and equally right afterwards. Taking either side and
regenerating is not a guess — the bytes are determined by the merged authority,
and the drift gate proves the result is that authority's fixed point. Scope is
exactly committed_generated_artifact_paths(), the same registry the staging step
uses, so a file qualifies only by being declared generated.

Both failure arms stay closed. If ANY conflicting path is outside that registry
the merge aborts and refuses, listing every conflict and naming the authored ones
— the classification is on the WHOLE set, so one authored conflict refuses the
entire remedy rather than partially resolving into a half-merged tree.

The merge commit is --no-verify: this is an unattended machine commit, and the
repository's own rulings already establish that git hooks are per-clone developer
feedback rather than enforcement (opt-in via core.hooksPath, bypassable, absent
in container worktrees). Found by execution — the local pre-commit hook failed
the remedy's commit with a cargo-not-on-PATH error, which CI would not have hit
but which should not gate a machine commit in any case.

Verified by execution against the real #7404 skew, not a fixture: skew detected,
merge attempted, conflict correctly classified as generated-only, resolved,
re-checked, EXIT=0 with the seed skew gone. The classification arm is unit-tested
across five cases — generated-only and generated x2 auto-resolve; authored-only,
seed-Rust, and MIXED all refuse, the mixed case being the one that must not
partially resolve.

Verified: whole-tree compile 0 blocking errors; ci.yml regenerated from the
model; emitted guard bash -n clean.

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

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* WIP: heal deferral completion + BMC/srvN

* Render the heal skew guard from a typed Pipeline; delete its shell scaffold

gunbc_ci_heal_binary_source_skew_guard_script was a join([...]) of ~55
hand-authored bash lines. It now renders from a v2.std.orchestration
Pipeline in a new v2.workflow.ci_heal_skew_guard_emit, placed beside
ci_regen_rustfmt_path_emit for the same reason (ci_spec can import it
without the ci_materialization <-> ci_spec cycle). The Scaffold row and
its dissolution trigger are DELETED, not reworded -- that is the receipt.

Control flow is structural: If / Not / Or / StrNonempty / Let / Exit.
Every git leaf derives its argv from an extdeps.git shape declaration.

Both shell loops are dissolved rather than emitted, because PipelineStep.For
has no emitter (orch_emit_step refuses it, ^orch_emit_step_for_unsupported)
and adding one to a load-bearing pipeline stage to serve one caller is the
wrong trade. Each dissolution is the better model independently:

- classification: the space-joined GENERATED_ARTIFACTS string + `for`/`case`
  glob membership test is replaced by asking git for the complement --
  --diff-filter=U limited to `.` minus one ':(exclude)<path>' pathspec per
  registered artifact. A list serialized to a string and re-parsed was a
  dual representation (DESIGN §3); this reads the registry directly.
- resolution: the per-path loop becomes one NUL-delimited `xargs -0`
  application, correct for paths with spaces or newlines.

Both deletions dissolve review 44580's paths-with-spaces finding by
construction rather than deferring it.

Two fail-closed improvements over the prior shell, deliberate and noted:
- a failed `checkout --ours` now refuses instead of staging the path anyway
  (the prior `|| true` then `git add "$c"` would stage an unresolved file --
  the fabricated-plausible-output arm §5 forbids);
- `git merge --abort` runs after the diagnostics, so a refusal always prints
  its reason.

Verified by execution against the EMITTED string, never a hand copy:
bash -n clean; the operator truth table green in a fixture repo with a real
src/v1 skew and a real three-way conflict (ROADMAP.md -> resolve;
ROADMAP.md+DESIGN.md -> resolve; authored .dag -> refuse; seed .rs ->
refuse; mixed -> refuse, merge aborted, nothing partially resolved); two
mutation RED controls flip the verdict, including the dangerous direction.
13 .dag witnesses pass, with REDs. ci.yml regenerated and byte-idempotent;
witness_committed_is_fixed_point and its RED control pass.

Also adds docs/plans/for-sugar-over-fold.md: a brief for `for` as sugar over
fold, separating the .dag surface form from PipelineStep.For emission.

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

* WIP: heal deferral completion + BMC/srvN

* Merge main; keep the modeled guard and drop the duplicated note row

origin/main regained #7418's join([...]) shell when that PR merged, so the
conflict in gunbc_ci_heal_binary_source_skew_guard_script is exactly the
change this branch exists to make -- resolved to the modeled delegation.

Two things the auto-merge got wrong, both fixed here:

- ci_heal_skew_auto_remedy_note was DUPLICATED. Both sides added the
  byte-identical row independently (this branch via the heal-auto-remedy
  merge, main via #7418 landing), so git kept two copies -- a duplicate
  declaration and a second representation of one fact (DESIGN §3). One copy
  retained.
- .github/workflows/ci.yml is a generated artifact, so it was never
  hand-resolved: main's side was staged as a base and the file regenerated
  from its .dag authority. Verified the regenerated step carries the modeled
  form -- zero occurrences of the space-joined GENERATED_ARTIFACTS variable,
  zero `for c in $CONFLICTS` loops, and the quoted ':(exclude)...' pathspec
  present.

Re-verified after resolution: 13 guard witnesses pass; regen is byte-
idempotent with witness_committed_is_fixed_point and its RED control green.

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

* Cite xargs in extdeps and shrink the guard's hand-spelled shell to one pipe token

The resolve step spelled " | xargs -0 " as shell text, which introduced a whole
external program with no extdeps citation (DESIGN §3). xargs now has its own cited
module beside exec_arg_limit — the boundary that is the reason xargs exists — with
both of its authorities named and the fidelity fact that -0 is a GNU extension the
POSIX spec does not define.

Both pipe operands are now cited argv shapes joined by one local joiner, so the
only target-language token this module still spells is the two-character operator
between them, named and counted as ci_heal_skew_pipe_operator. Sourcing it from
the bash grammar that already models it would leak emit-layer vocabulary into a
workflow intent module, which v2.lens.realization_vocabulary_containment exists to
red; closing it properly is a PipelineStep/Run carrier decision on load-bearing
files that this brief explicitly excluded, so it stays declared with a dissolution
trigger rather than smuggled in.

Emission is byte-identical: regen leaves ci.yml unchanged.

* WIP: heal deferral completion + BMC/srvN

* Remove two empty junk files created by a shell quoting slip

An unquoted code example in a dashboard message let bash read '=> true,' and
'=> false' as redirections, creating empty files named 'true,' and 'false' at the
repo root; the session autocommit then picked them up. They were never part of the
change and carry no content.

* Make the heal remedy merge BUILT_FROM, not the moving base

The guard compared the tree against BUILT_FROM (github.sha, fixed for the run) but
remedied a skew by merging origin/BASE_REF — the LATEST base. Those are two
different revisions of the base, so whenever the base advanced between the build
and the heal job the remedy overshot its own comparison target, the post-remedy
re-check found a difference, and the job refused. Since the release build takes
~15 minutes on a base that merges more often than that, this is not a transient:
re-running rebuilds against a newer base and reopens the window, so the guard can
refuse indefinitely.

Merging BUILT_FROM makes the re-check pass by construction rather than by luck:
BUILT_FROM becomes an ancestor of HEAD, so the seed-ahead set is empty for every
input. The still-skewed arm stays as a fail-closed backstop, and its message no
longer speculates "the base moved again during this run" — an explanation the
receipt falsifies, since the two checks are 350ms apart.

Measured on the live failing run 30497545614: the merge ref's base parent was
b0c8eba while origin/main had already advanced to 37ae94b — exactly one
intervening base commit, and it touched src/v1.

BASE_REF, its binding and the origin/BASE_REF spelling are deleted rather than
left as dead scaffolding: BUILT_FROM is already fetched by the provenance step and
its resolvability is refused on upfront, so the base fetch bought nothing.

Truth table re-proven by execution against the emitted bytes: 17/17 over seven
fixtures — no-skew, clean remedy, the overshoot case with a control showing the
old remedy refuses where this one proceeds, generated-only conflicts (one and two
files) auto-resolving, authored .dag and seed .rs conflicts refusing with the
typed diagnostic and no MERGE_HEAD, and the mixed conflict refusing with nothing
staged. 15/15 structural witnesses pass, including a new pair asserting the remedy
targets BUILT_FROM with the moving-base spelling as the RED control.

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Brian <briansrls@MacBook-Pro.local>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Brian Searls <11205878+briansrls@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* WIP: BMC stack A: #7371 durability substrate + #7372 capability receipts — ma

* Ground jq external authority anchor

* Record mandatory anchor scaffold debt

---------

Co-authored-by: Brian <briansrls@MacBook-Pro.local>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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