M8 H1: owner-runnable power-pull rig + storage_probe calibration (§14.8 H1 / D1)#22
Open
guyo13 wants to merge 2 commits into
Open
M8 H1: owner-runnable power-pull rig + storage_probe calibration (§14.8 H1 / D1)#22guyo13 wants to merge 2 commits into
guyo13 wants to merge 2 commits into
Conversation
Build the H1 power-pull automation — the last open M8 gate and the only one that fundamentally needs physical hardware (a real mains cut on storage that genuinely loses un-synced data, >=50 consecutive PASS with zero acked-LSN loss, D1). No src/ change: this is orchestration + CI + docs around the proven power_pull_workload/power_pull_verify bins, storage-check.sh, and evidence.sh. - scripts/m8/h1-cycle.sh: deploy/calibrate/cycle/run/config. The §3.4 vacuous-pass calibration GATE runs first (un-synced marker must be GONE after a real cut, else abort loudly — no cycle counts). Cycle loop drives the target over ssh, cuts via a pluggable smart-plug local API, restores, and verifies every acked LSN survived. INCONCLUSIVE never counts; a FAIL stops the run; verdict=PASS only when h2_probe proved loss AND fail==0. Emits the §5 ledger. - Smart-plug driver: shelly (Gen2/Gen3/Plus RPC — default, the Shelly Plug S Gen3; aliases shelly-gen2/gen3), shelly-gen1, tasmota. H1_PLUG_DRY_RUN for no-hardware dry runs. - .github/workflows/m8-h1.yml: workflow_dispatch-only, runs-on [self-hosted, h1-rig]; cross-compiles aarch64 bins, deploys, runs the calibration + cycle loop, uploads the §5 evidence artifact, posts to #18 (dispatch-gated sign-off). Loud-skips (OPEN, not green) if the rig is unwired or unreachable. - .github/actionlint.yaml: declare the h1-rig custom runner label. - docs: runbook H1 "Automated rig" + "Rig setup" (Pi 3 read-only overlay, dedicated DUT partition, BeagleBone-eMMC + USB-SSD media, controller wiring, smart-plug table); infra-plan §3.2/§3.4 corrected to storage-check.sh probe-write/probe-verify (no separate storage_probe binary); README + CLAUDE.md status. H1 stays OPEN-pending-owner-run: the owner triggers m8-h1.yml on the wired rig, observes >=50 PASS with the H2 probe proven + evidence on #18, and closes #18. The agent never self-certifies H1. Verified: shellcheck + actionlint clean, bash -n, plug-URL/config/evidence dry-runs, the abort path emits a valid ABORTED ledger, cargo build of the bins. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VW9DW3Lu7dVmargSY1gbZk
…D1 / #18) Apply the designer's approve-with-conditions feedback on the H1 rig. Delta A — build src/bin/storage_probe.rs as the §3.4 calibration instrument (reverse the shell-probe choice). The "no src/ change" rule guards against durability-logic drift, not against the measurement instrument being real code. The calibration must prove the DUT loses un-synced data on the SAME kernel write path the WAL uses, so the marker is written via a plain write(2) with NO fdatasync (the WAL's data path minus the durability step); a shell echo could differ subtly and mis-measure the very thing this gate exists to catch. It does NOT use the WAL append (pure in-memory until commit — would never reach the cache). Test-only, auto publish-excluded by the existing exclude=["src/bin"], like crash_child. Subcommands write-unsynced-marker (exit 0) and verify-marker-gone (0 = gone/honest, 1 = survived/vacuous). h1-cycle.sh calibrate now uses it for the loss-probe; storage-check.sh classify stays as the deny-by-default FS/cache check. deploy + the workflow cross-compile + scp it alongside power_pull_{workload,verify}. infra-plan §3.2/§3.4 keep the binary as originally written. Delta B — per-path §5 verdict + hard, distinct-code calibration abort. The prior EXIT trap emitted ABORTED for every non-clean exit, mislabeling a D1 FAIL. Replaced with finish()/VERDICT emitting the ledger exactly once on every terminal path, with distinct exit codes: 0=PASS, 1=FAIL (verdict=FAIL), 2=INCONCLUSIVE/ infra (verdict=INCONCLUSIVE), 3=VACUOUS calibration (verdict=OPEN, marker survived — a HARD abort before any cycle counts). The workflow maps 1/2/3 to distinct error annotations. Delta C — runbook makes the calibration-instrument choice and pin-downs 1-4 explicit (verify-on-target-over-ssh + scp transport; per-cycle fresh capture; three-way outcome; evidence-on-every-path), plus an H2-section pointer so the manual shell probe and the storage_probe binary don't read as contradictory. Verified: storage_probe build + cargo +1.85.0 MSRV + fmt/clippy clean and its exit semantics (0/1/2); all four h1-cycle.sh verdict paths driven end-to-end with stubbed ssh/scp/socat (PASS=0, FAIL=1, vacuous=3/verdict=OPEN, unreachable loud-skip), each emitting a valid §5 ledger; shellcheck + actionlint clean; cargo test green (LazyFS/hardware suites remain #[ignore]). H1 stays OPEN-pending-owner-run; the owner triggers m8-h1.yml on the wired rig, observes >=50 PASS with the H2 probe proven + evidence on #18, and closes #18. The agent never self-certifies H1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VW9DW3Lu7dVmargSY1gbZk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
Builds the M8 H1 power-pull rig — the last open M8 gate and the only one that fundamentally needs physical hardware: a real mains power cut on storage that genuinely loses un-synced data, ≥50 consecutive cycles with zero acked-LSN loss (invariant D1). This is orchestration + a
workflow_dispatchCI job + one test-only calibration bin + docs around the already-provenpower_pull_workload/power_pull_verifybinaries.Commits
ed4e833— the rig:scripts/m8/h1-cycle.sh,.github/workflows/m8-h1.yml,.github/actionlint.yaml, docs.6204a75— designer feedback:src/bin/storage_probe.rsas the calibration instrument + per-path §5 verdicts.Pieces
scripts/m8/h1-cycle.sh—deploy/calibrate/cycle/run/config. The §3.4 vacuous-pass calibration gate runs first; the cycle loop drives the target over ssh, cuts via a pluggable smart-plug local API, restores, boot-waits, and runspower_pull_verifyon the target against the recovered WAL (afterscping that cycle's fresh capture). Emits the §5 evidence ledger.src/bin/storage_probe.rs(test-only; auto publish-excluded by the existingexclude = ["src/bin"], likecrash_child) — the §3.4 calibration instrument.write-unsynced-markerwrites via a plainwrite(2)with nofdatasync— the WAL's data path minus the sync — so the calibration measures loss on the same kernel write path the WAL uses (a shellechocould mis-measure).verify-marker-gone: exit 0 = gone / 1 = survived..github/workflows/m8-h1.yml—workflow_dispatch-only,runs-on: [self-hosted, h1-rig](the owner's never-cut controller laptop). Cross-compiles the aarch64 bins, deploys, runs calibration + cycles, uploads the §5 artifact, posts to M8/H1: power-pull durability — ≥50 cycles, zero acked loss (D1) #18 (dispatch-gated). Loud-skips (OPEN, not green) if the rig Variables are unset or the target is unreachable.Honesty rails
storage_probeproves the DUT loses un-synced data on a real cut; a surviving marker is a HARD abort.0=PASS/1=FAIL (verdict=FAIL, D1 loss)/2=INCONCLUSIVE/3=VACUOUS (verdict=OPEN).verdict=PASSonly whenh2_probeproved loss andfail==0.sysrq-b/reboot/shutdownare explicitly NOT valid.Smart-plug driver
Pluggable via
H1_PLUG_TYPE:shelly(Gen2/Gen3/Plus RPC/rpc/Switch.Set— default; the owner's Shelly Plug S Gen3, aliasesshelly-gen2/shelly-gen3),shelly-gen1(/relay/0),tasmota(/cm?cmnd=Power).H1_PLUG_DRY_RUN=1for no-hardware dry runs.Verified in-sandbox
storage_probe: build +cargo +1.85.0MSRV +fmt/clippyclean; exit semantics (0 gone / 1 survived / 2 usage).h1-cycle.shverdict paths driven end-to-end with stubbed ssh/scp/socat — PASS(0), FAIL(1→verdict=FAIL), vacuous(3→verdict=OPEN), and the unreachable-rig loud-skip — each emitting a valid §5 ledger.shellcheck+actionlint+bash -nclean;cargo clippy --all-targets -D warnings,cargo fmt --check, fullcargo testgreen (LazyFS/hardware suites remain#[ignore]).Refs §14.8 H1 / D1 / #18.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VW9DW3Lu7dVmargSY1gbZk
Generated by Claude Code