Skip to content

Actuate BMC fan convergence with typed rollback - #7376

Closed
briansrls wants to merge 1 commit into
agent/bmc-access-ensurefrom
agent/bmc-live-convergence
Closed

briansrls wants to merge 1 commit into
agent/bmc-access-ensurefrom
agent/bmc-live-convergence

Conversation

@briansrls

@briansrls briansrls commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

What changed

Connects BMC fan-policy reconciliation to the host subsumption spine using the typed operation surface.

  • Observes firmware, topology, filesystem lifetime, active configuration, and fan-policy readback before mutation.
  • Refuses unsupported firmware and invalid topology before applying changes.
  • Stages, validates, atomically replaces, restarts, and reads back through typed operations.
  • Restores the prior configuration when post-mutation restart/readback fails.
  • Returns a typed rollback receipt distinguishing not-attempted, restored, and rollback-failed outcomes.
  • Records graceful BMC-restart durability without claiming untested forced restart, power-loss, firmware-replacement, or factory-reset boundaries.
  • Adds the operator runbook and host phase/status integration.

Why

This is the actuator layer intentionally separated from the generic carrier, observation facts, policy, operations, and access acquisition. It lets subsumption converge the admitted policy while retaining exact readback and rollback evidence.

Stack

Depends on #7375.

  1. Bind durability evidence to admitted state #7371 generic durability carrier and witnesses
  2. Record versioned BMC capabilities and live receipts #7372 BMC/Linux capability facts and typed live receipts
  3. Model BMC desired state and reconciliation #7373 BMC desired state and reconciliation
  4. Define typed OpenBMC fan operations #7374 typed OpenBMC operation realization
  5. Ensure BMC access only when demanded #7375 demand-derived BMC access ensure
  6. This PR: live actuator and rollback receipt

Together the stack supersedes draft #7338.

Validation

  • Actuator focused witnesses: 15/15
  • Host phase/status/subsumption-spine witnesses: 37/37
  • Entire stack focused suite: 122/122
  • External-authority corpus, non-fold residue, and cheap pooled gates: pass
  • Whole-tree compile-clean and build-artifact verification: pass
  • Full local floor has only three platform refusals on macOS: Linux VmHWM, install-media remastering, and Linux Go smoke
  • Manual Linux CI on exact stack-tip SHA dbaf88819: build, regeneration, full floor, affected-set control, and merge admission all pass
  • Live srv4 read-only observation returned ExitSuccess
  • Live srv4 convergence returned ExitSuccess through the independently verified no-op path; no config write or service restart was required

briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Superseded by #7428, which restructures the actuator and holds live mutation fail-closed. Per the review verdict, the roadmap node is deliberately NOT advanced: BmcFanPolicyConverge stays phase-partial behind a declared dissolution trigger naming the atomically published content-addressed backup manifest and the bounded thermal/tach monitoring receipt, and the earlier live no-op is not counted as validation of apply or rollback. Read-failure and genuinely-absent are now distinct arms throughout (Observed | Refused), so a failed threshold or digest read can no longer present as "unstated".

Closing loses nothing: this head (dbaf888193) is an ancestor of #7428, and the branch is retained.

— sent from quiet-wren-607

@gunbai-bot gunbai-bot Bot closed this Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
briansrls pushed a commit that referenced this pull request Jul 29, 2026
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 pushed a commit that referenced this pull request Jul 30, 2026
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>
briansrls pushed a commit that referenced this pull request Jul 30, 2026
briansrls pushed a commit that referenced this pull request Jul 30, 2026
briansrls pushed a commit that referenced this pull request Jul 30, 2026
briansrls pushed a commit that referenced this pull request Jul 30, 2026
briansrls pushed a commit that referenced this pull request Jul 30, 2026
…LOCK redesign. Delete the exported generic List<String>->rendered-remote-shell aperture and caller-authored jq/TSV string protocol; closed OpenBmcOperation algebra with structured typed responses and explicit zero/one/many cardinal (#7454)

* Bind durability evidence to admitted state

* Model BMC desired state and reconciliation

* Define typed OpenBMC fan operations

* Ensure BMC access only when demanded

* Record versioned BMC capabilities and live receipts

* Actuate BMC fan convergence with typed rollback

* 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 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 A: #7371 durability substrate + #7372 capability receipts — ma

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

* Use canonical carriers in BMC proof receipts

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

* 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

* Use canonical HTTP status carrier for BMC reset

* 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 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 B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Treat fan hysteresis as a temperature delta

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

* Split typed OpenBMC operations from blocked actuator

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

* 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 B: #7374 typed OpenBMC operations + #7376 actuator — HARD BLOC

* Regenerate signed temperature delta carriers

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

* Remove parallel OpenBMC argv interpreter

* Document fixed OpenBMC transport boundary

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

* Mark OpenBMC observations readonly

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

* Regenerate canonical positive measure carrier

* Anchor OpenBMC extdeps authorities

* Model BMC desired state and reconciliation

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: repair fleet_bmc_state parse error blocking CI regen

The durability-evidence constructor used else-if chains and multiline ||
conditions the .dag parser rejects; refactor to bool-match helpers and
define GoogleCloudInteractiveAuthenticationRequired as a closed type.

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

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: resolve BMC credential materialization typecheck failures

Move shell.GCloud.AuthPrintAccessToken into extdeps.shell with an exit_success
field, add credential materialization helpers, and update srv3 actuate paths to
match on BmcCredentialMaterialization instead of Optional Present/Absent.

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

* fix: firmware-track Conflict precedes projection gate; align witness verdict

Refuse off-track observed firmware with Conflict before the projection-absent
arm, and expect UnknownRefused when major-3 firmware carries a wrong minor
projection capability.

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

* docs: declare bmc_bootstrap_provision eager token fork as dissolve-on follow-on

Name the pre-existing shell.GCloud.AuthPrintAccessToken site beside
ensure_access_token so the second authority is counted, not forgotten (#7425).

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

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: align fan hysteresis with frozen carrier PositiveCelsiusDelta

Mechanical follow-on to rebasing #7423 onto carrier base 5dee646.

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

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: migrate firmware intent check to typed verdict on carrier b70c484

Replace deleted Bool predicate with bmc_firmware_observation_intent_verdict;
Mismatch arms thread required/observed into located refusal reasons.

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

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

* fix: migrate fleet BMC durability evidence to sunny-crab typed-order receipts

Rebase consumer onto carrier d8d15c5: drop StateDurabilityTimeline, use
StateBefore/AfterReadbackReceipt and perturbation timing fields derived from
the reboot receipt without storing instants twice.

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

* fix: refuse AdmittedConfigDigestUnavailable instead of fabricating digest

Replace the non-fleet bmc_fan_admitted_config_digest else-branch sentinel
with a typed Unavailable variant; capability construction now takes an
explicit admitted digest. Witness sentinel renamed for observation-only
mismatch controls.

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

* fix: construction-wall linux publication commit + derive capability hash

Replace hand-rolled record field matching with a unit variant
(LinuxSynchronizedRenameReplacePublication) as the single synchronized
authority; derive durability capability definition_hash from the
publication variant. Mark realization definition hashes as label-backed
scaffold pending swift-boar actuator mechanical derivation.

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

* Make durability proof gaps explicit

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

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* Repair positive measure seed realization

* fix: repair std_measure.rs enum variant broken by carrier regen

Restore PositiveMeasureCountBuilt after a mechanical regen rewrite
mistook the enum arm for a Measure constructor, which broke cargo fmt
and the build gate on 199a777.

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

* fix: refuse non-positive reboot timing; dissolve linux Bool predicate

Address review 44783 (codex REQUEST_CHANGES):
- Replace fabricated 1ms fallback in bmc_fan_receipt_elapsed_millisecond
  with BmcFanRebootTimingReceipt that typed-refuses
  DurabilityReceiptNonPositiveInterval for zero/negative intervals.
- Delete linux_file_publication_has_synchronized_commit Bool predicate;
  match LinuxFilePublicationProtocol coproduct directly at consumers.
- Add reboot_durability_evidence_refuses_non_positive_interval witness.

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

* Close positive measure and parser review gaps

* WIP: BMC stack C: #7373 policy reconciliation (HARD BLOCK: evidence relabelin

* fix: dissolve coproduct Bool predicates flagged in review 44803

Route firmware intent and durability commit decisions through canonical
typed verdict/query surfaces: bmc_firmware_version_intent_verdict for
pin/track checks, DurabilityCommitBarrier match for synchronized commit,
and remove publication-protocol Bool re-encoding from apply suitability.

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

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

* fix: repair bmc_converge.dag parse error from mismatched braces

Close the nested match arms in firmware classification and fan-policy
classification that caused heal/regen to fail with expected LParen.

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

* fix: restore secret_manager module import for AccessVersion binding

The stack C migration deleted import extdeps.cloud.gcp.gcp but left
gcp.SecretManager.AccessVersion in fetch_secret_ref_credential; bind
the service through extdeps.cloud.gcp.secret_manager where it is defined
(review 44815).

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

* Close durability qualification bypass

* fix: close review 44832 gaps and bind durability evidence to receipt capability

Record perturbation_capability on BmcFanRebootPersistenceReceipt so evidence
construction cannot relabel via a separate caller argument; consume
asrock_altrad8ud_factory_fan_config_digest for previous_config_digest;
dissolve remaining Bool predicates into typed persistence and durability
verdict matches (review 44832).

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

* fix: break bmc_fan_projection <-> fleet_bmc_observation import cycle

Move srv4 projection capability and reboot receipt back to fleet_bmc_state;
relocate bmc_fan_admitted_config_digest to fleet_bmc_observation beside the
digest authority; drop bmc_fan_projection's observation import so combined
actuator compile is acyclic (swift-boar-810).

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

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

* fix: parameterize bmc_fan_admitted_config_digest per reconcile spine

Projection takes caller-supplied digest (optional absence → Unavailable);
observation no longer owns admission logic or srv4 hardcoding. Breaks the
bmc_fan_projection ↔ fleet_bmc_observation cycle without a third module.

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

* test: witness typed OpenBMC observation decoding

* fix: distinguish negative BMC probes from transport refusal

* fix: reject inconsistent BMC transport projections

* test: reject forged BMC backup manifest identity

* fix: derive projection config digest from curve+realization

Ground projected_config_digest in bmc_fan_projection from intent curve
and realization identity, not srv4_bmc_fan_active_config_digest observation.
Restores non-tautological live-digest and durability admission checks
(review 44861).

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

* docs: name backup manifest identity consistently

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

* revert: inherit canonical anchor scanner fix from stack A

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

* fix: converge actuator onto landed BMC carriers

* test: import typed OpenBMC refusal constructor

* refactor: trust typed BMC observation inputs

* fix: refuse multi-path BMC projections

* fix: retain pinned firmware realization gate

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

* fix: refuse error-bearing BMC probes

* fix: preserve refused BMC probe evidence

* refactor: consolidate BMC substrate authorities

* fix: refuse inconsistent BMC transport success

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

* test: bind every BMC manifest identity field

* fix: require continuous BMC monitoring coverage

---------

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