Repository navigation
Migrate host-hygiene reaper and liveness onto typed observation; delete host_hygiene_*_script - #8583
Merged
Merged
Conversation
…te host_hygiene_*_script host_hygiene_reaper_script.dag and host_hygiene_liveness_script.dag held hand-concatenated bash text bodies whose dissolution trigger (typed-argv host-effect routing) has landed. Both verticals are now split into observe/mutate sub-modules built on typed reads: - gunbc.host_hygiene_reaper_observe: per-slot cgroup/system.control observation via the existing systemctl_show_read seam (extended with SystemdUnitProperty::ActiveState) and direct filesystem_read/shell.Test. - gunbc.host_hygiene_reaper_remediate: the reaper's MUTATE half. The bound is structural, not a literal check in a script: every effect variant carries a unit derived from a vetted observation, and the module recomputes residual_reap_action internally rather than accepting a caller-supplied action, so the decision core's permanent RED-control widen-sketch fixture is unreachable from any effect path. - gunbc.host_hygiene_liveness_observe: journal-line parsing (last matching "Listening for Jobs" line, epoch extraction, freshness age) as pure .dag folds over one typed extdeps.systemd.Journalctl.UnitLog read, replacing the deleted script's hand-written pipeline. New extdeps: extdeps.posix.signal (kill -TERM) and extdeps.systemd.journalctl (journalctl -u ... -o short-unix), both anchored to their upstream authorities and carrying mock_response for hermetic replay. extdeps.systemd's SystemdUnitProperty gained ActiveState rather than minting a second read op. Both new observe modules reuse the existing gunbc.host_converge.gunbc_runner_all_slots_unit_glob authority instead of re-declaring the runner-slot glob literal. The decision cores (gunbc.host_hygiene_reaper / _liveness) are unchanged except for their placeholder ReadAbsent reason strings, which now name the real live-evidence entrypoint; no import was added back from the decision core to the observe modules, avoiding a cycle. Replaced the four script-coupled tests (which called into the deleted shell-text bodies) with witnesses against the new typed functions: pure ResidualReapEffect derivation for the reaper (build-cache refusal, active-unit refusal, override-only vs kill-and-remove, no-action), and both pure journal-line parsing and a mocked-transport end-to-end read for liveness. All are green-by-execution under claim_batch --hermetic. Confirmed via corpus-wide grep that the reaper script's dead systemd-unit-install machinery had zero consumers anywhere (matching live_deploy/spec.dag's own note that it "is installed by NOBODY"), so deleting the whole file was safe as one replacement-migration cut. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
briansrls
pushed a commit
that referenced
this pull request
Sep 5, 2026
…e denominator to its head The banner asserted that absence of a name is not discharge because a rename looks identical. It now demonstrates it, with six names that already have verdicts on main and do not all point the same way: srv3_chown_directory_to_current_user discharged 61bf47b (#8590) host_build_cache_provision_script discharged 40f2fb6 (#8825) four host_hygiene_reap_*_body files deleted ffa16a5 (#8583) git_fetch_script RENAME, not gone (unadjudicated) Three causes, one grep signature. The host_hygiene row is the sharpest: the commit that discharges those four names does not mention them, so the evidence is not reachable from the symbol at all -- which is precisely why the per-row lane cannot be done by symbol search. All four commits are ancestors of main, so the table is head-safe independent of the SS1.C corrections landing separately in #10529. The denominator now says it was measured at 70925ee and is valid only there: any later edit that strikes a row through changes what the closed-marker grep counts, so the 180/41/~139 split moves and must be re-derived rather than quoted. The demonstration table sits inside the blockquote, so it does not itself perturb the row count -- re-derived at 180 after the edit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GCBVTWARwTLkAfVWaGfKA
briansrls
pushed a commit
that referenced
this pull request
Sep 5, 2026
… flag the census's dead-ci.yml population (#10537) * Correct the stale ci_floor_peak rows and flag the census's dead-ci.yml population gunbc.plans.shell_emission_model's Phase 1 PARTIAL row still said While emit's one production consumer, ci_floor_peak_emit, has cond and body "still raw shell strings". That was true when written and is stale: ecbd086 (#7978, shell -> dag Phase 1 cgroup vertical, 2026-08-08, ancestor of origin/main) replaced both leaves, and the membership assign with them, with derived text from a typed NearestAncestorContaining (std.path_intent) plus extdeps.linux.proc_self_cgroup membership, lowered through bash_orch_if / bash_proc_self_cgroup, refusing with a located marker rather than widening. git log -S on both bash_nearest_ancestor_locate_cond_command and ci_floor_peak_nearest_ancestor_spec, scoped to that file, returns exactly that commit as first introduction. The correction carries the residue forward rather than reading as completion: the peak calibration leaves on the same pipeline and the runtime-scan transport in bash_membership_assign_from_source are still raw String Run.command values, declared Phase 2 typed filesystem observation by the module itself. Three census rows in docs/plans/shell-to-dag-residual-census-and-arc-completion.md carried the same stale claim -- the SS1.A "concat-built floor-peak/cgroup runners" row, the SS4.E already-on-emit row, and the SS4.J Phase-1 dispatch row that still listed the two leaves as unassigned open work. That last one is what dispatched a lane onto discharged work. Sweeping the class turned up a larger root cause, filed as a banner rather than silently truncated: .github/workflows/ci.yml was deleted by 611fd02 (#8283, FLOOR-Y cutover), CI is now the witnesses.yml emission from gunbc.witness_floor_workflow, and this census mentions none of that while still naming ci.yml drift+parse as its byte-oracle in four places. A symbol-existence check over the SS4.J dispatch roster found ~20 named production symbols with no declaration anywhere in the .dag corpus. The banner states the denominator (180 data rows, 41 already closed, ~139 asserting live state) and states explicitly what it does NOT establish: absence of a name is not discharge, since a rename looks identical -- git_fetch_script is gone while git_fetch_no_tags_shell and git_fetch_prune_shell exist. Per-row adjudication needs its own lane. Model-side prose only; no seed growth, no .rs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GCBVTWARwTLkAfVWaGfKA * Name the instrument behind the banner's counts, so the banner is not the next stale row The staleness banner cited bare counts (180 data rows / 41 closed / ~139 live) and a ~20-name absent-symbol list. Transcribed numbers under a dated claim are exactly the defect the banner is about, one layer up: nothing re-derives them, so they rot without anyone touching either end. The banner now carries the two checks that produce them, verified to reproduce their stated output as printed at 70925ee, and says to run them rather than read them. It also states the second check's raw output honestly -- 50 candidates, of which the ~20 production symbols are what survives discarding module names, the commit-sha and fn-fragment spellings the banner itself introduced, and already-struck rows -- so the gap between "50 out" and "20 listed" cannot be mistaken for a miscount. The ci.yml deletion is the one claim that is not count-shaped and its own one-line derivation is given. The dispatch prohibition is unchanged and deliberate: a banner that describes staleness while still permitting dispatch off the rows is a documented hazard with no refusal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GCBVTWARwTLkAfVWaGfKA * Turn the banner's absent-symbol list into a demonstration, and pin the denominator to its head The banner asserted that absence of a name is not discharge because a rename looks identical. It now demonstrates it, with six names that already have verdicts on main and do not all point the same way: srv3_chown_directory_to_current_user discharged 61bf47b (#8590) host_build_cache_provision_script discharged 40f2fb6 (#8825) four host_hygiene_reap_*_body files deleted ffa16a5 (#8583) git_fetch_script RENAME, not gone (unadjudicated) Three causes, one grep signature. The host_hygiene row is the sharpest: the commit that discharges those four names does not mention them, so the evidence is not reachable from the symbol at all -- which is precisely why the per-row lane cannot be done by symbol search. All four commits are ancestors of main, so the table is head-safe independent of the SS1.C corrections landing separately in #10529. The denominator now says it was measured at 70925ee and is valid only there: any later edit that strikes a row through changes what the closed-marker grep counts, so the 180/41/~139 split moves and must be re-derived rather than quoted. The demonstration table sits inside the blockquote, so it does not itself perturb the row count -- re-derived at 180 after the edit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GCBVTWARwTLkAfVWaGfKA * Re-derive on the merged tree: correct a worked example reading found, repin the denominator Reading every row either PR touched on the merged tree -- rather than trusting the clean auto-merge -- turned up an error in my own worked-examples table. #10529's srv3 row names a live successor, srv3_ensure_directory_owned_by_current_user (gunbc.host_effect_realize), so srv3_chown_directory_to_current_user was not plain "discharged" as my table said: it was RENAMED AND CLIMBED at once. That is a fourth cause a two-way discharge/rename split cannot express, and calling it discharged loses the successor a reader needs to find. The table now carries all four causes: dissolution, file deletion upstream of the name, bare rename, and rename-plus-climb. The denominator moved exactly as predicted. Re-derived on the merged tree it is 180 rows / 43 closed / ~137 live, against 41/~139 one merge earlier; #10529 striking two more SS1.C rows through is the whole difference. The banner now says so, because a split that moves within one merge of being written is the argument for naming the recipe rather than a bookkeeping detail. Measurement is pinned to the merge of 70925ee with origin/main 16a702e. Controls re-run on the merged tree, not carried forward: the four bash_nearest_ancestor_locate_* call sites still stand and #7978 is an ancestor of the merged HEAD; ci.yml is still absent with witnesses.yml present and #8283 an ancestor; git_fetch_script is still absent while git_fetch_no_tags_shell and git_fetch_prune_shell exist, so the rename example still discriminates. Diff is still model-side prose only -- no .rs, no seed growth. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GCBVTWARwTLkAfVWaGfKA --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Sep 5, 2026
§4.I — ci_native_cache_root_toolchain_segment_command DELETED #7436 (003d960). CASE 1 dissolution — toolchain segment computation reordered after setup-rust-toolchain; fallback table entry struck through as RESOLVED. §4.J.A — ci_floor_stamp_merge_admission_script All three raw leaves (ci_floor_stamp_ambient_exit_command, ci_floor_stamp_root_command, merge_admission_stamp_command) DELETED #7522 (87a4af3). CASE 1 dissolution. 'PARTIAL #7293' status stale. §4.J.B — ci_floor_materialization_receipt_gate_script, ci_floor_resolve_receipt_gate_script DELETED #7470 (b01cdf4). CASE 1 dissolution — WalkPlan success stages finalization dissolved both receipt gates. §4.J.C (ci_spec.dag table): - gunbc_ci_floor_only_script DELETED #9252 — CASE 1 - ci_regen_floor_skip_shortcut_script DELETED #8406 — CASE 1 - gunbc_ci_regen_floor_only_script DELETED #8406 — CASE 1 - scheduler_invoke/scheduler_invoke_with DELETED #9252 — CASE 1 - git_fetch_script RENAMED #6833 — CASE 3 (successor: git_fetch_no_tags_shell / git_fetch_prune_shell) §4.J.D (ownership table): - Merge-admission row: all three raw leaves struck #7522 (CLOSED) - CI materialization row: both receipt gates struck #7470 (CLOSED) - CI-spec row: stale symbols struck through individually - Already-routed row: ci_selection_control_script #8283, gunbc_ci_run_script #9252, ci_regen_ensure_rustfmt_path_script #8406 (and 11 rustfmt raw leaves) struck through - Runtime terminal row: host_effect_plan_placeholder_effect DELETED #10509 - Deferred srv3 row: srv3_chown_directory_to_current_user struck #8796 (ref §4.D), all 4 host_hygiene_reap_*_body + liveness body struck #8583 (ref §4.A) All deletion commits verified as ancestors of origin/main ✅. Part of #10537's per-row adjudication program.
briansrls
added a commit
that referenced
this pull request
Sep 5, 2026
….E, §4.I, §4.J (#10576) * Correct §4.A hygiene-reaper row: CASE 2 — four host_hygiene_reap_*_body symbols deleted by #8583 The §4.A row at L379 described host_hygiene_reaper_script.dag's 4 body symbols as A5-deferred. The file was deleted by ffa16a5 (#8583, Migrate host-hygiene reaper and liveness onto typed observation) and the construction was migrated to typed host_hygiene_reaper_observe.dag / host_hygiene_reaper_remediate.dag / host_hygiene_liveness_observe.dag. No direct successor body names exist — CASE 2 (file deletion upstream) with hybrid CASE 1 (body names dissolved). Verification: - ffa16a5 is ancestor of origin/main ✅ - host_hygiene_reaper_script.dag: D in #8583's diff - zero files define host_hygiene_reap_install_units_body et al. - observe/remediate files present at dag/gunbc/host/ Part of #10537's per-row adjudication program. * Correct §4.D srv3_chown_directory_to_current_user: CASE 4 — renamed AND climbed The row at §4.D L436 listed srv3_chown_directory_to_current_user as A5-deferred (srv3). It was actually renamed AND climbed by 20ad5b3 (#8796): successor is gunbc.host_effect_realize.srv3_ensure_directory_owned_by_current_user. New name has a stronger guarantee (readback-based, not chown exit-status based). This is CASE 4 (rename plus climb) — distinct from CASE 1 (dissolution) because the construction did not disappear; it acquired a better name and a stronger guarantee. Verification: - 20ad5b3 is ancestor of origin/main ✅ - srv3_chown_directory_to_current_user: 0 declaration files - srv3_ensure_directory_owned_by_current_user: 2 declaration files Part of #10537's per-row adjudication program. * Correct §4.E: 4 stale foreign-executor rows Four symbols claimed as 'already on emit' are no longer present in the corpus. Each is struck through with its deletion commit: 1. ci_selection_control_script — DELETED by 611fd02 (#8283, CI floor cut). CASE 1/2: the ci.yml file was deleted and its selection-control script dissolved with it. Successor workflow is witnesses.yml via gunbc.witness_floor_workflow. 2. gunbc_ci_run_script — DELETED by 489346f (#9252, plan/walk CLI delete). CASE 1: the gunbc ci verb was deleted, taking its run script. 3. ci_regen_ensure_rustfmt_path_script — DELETED by 3b431f3 (#8406, REGEN ROOT CUT). CASE 1: regen_stage0 root deleted; rustfmt path script was zero-consumer machinery. 4. expected_live_deploy_retract_script — DELETED by d409b75 (#7909, Phase A release identity refactor). CASE 1: recategorized to runtime-present, then dissolved. All four deletion commits are ancestors of origin/main ✅. Part of #10537's per-row adjudication program. * Correct §4.I, §4.J, §4.D ownership table: 18+ stale symbols §4.I — ci_native_cache_root_toolchain_segment_command DELETED #7436 (003d960). CASE 1 dissolution — toolchain segment computation reordered after setup-rust-toolchain; fallback table entry struck through as RESOLVED. §4.J.A — ci_floor_stamp_merge_admission_script All three raw leaves (ci_floor_stamp_ambient_exit_command, ci_floor_stamp_root_command, merge_admission_stamp_command) DELETED #7522 (87a4af3). CASE 1 dissolution. 'PARTIAL #7293' status stale. §4.J.B — ci_floor_materialization_receipt_gate_script, ci_floor_resolve_receipt_gate_script DELETED #7470 (b01cdf4). CASE 1 dissolution — WalkPlan success stages finalization dissolved both receipt gates. §4.J.C (ci_spec.dag table): - gunbc_ci_floor_only_script DELETED #9252 — CASE 1 - ci_regen_floor_skip_shortcut_script DELETED #8406 — CASE 1 - gunbc_ci_regen_floor_only_script DELETED #8406 — CASE 1 - scheduler_invoke/scheduler_invoke_with DELETED #9252 — CASE 1 - git_fetch_script RENAMED #6833 — CASE 3 (successor: git_fetch_no_tags_shell / git_fetch_prune_shell) §4.J.D (ownership table): - Merge-admission row: all three raw leaves struck #7522 (CLOSED) - CI materialization row: both receipt gates struck #7470 (CLOSED) - CI-spec row: stale symbols struck through individually - Already-routed row: ci_selection_control_script #8283, gunbc_ci_run_script #9252, ci_regen_ensure_rustfmt_path_script #8406 (and 11 rustfmt raw leaves) struck through - Runtime terminal row: host_effect_plan_placeholder_effect DELETED #10509 - Deferred srv3 row: srv3_chown_directory_to_current_user struck #8796 (ref §4.D), all 4 host_hygiene_reap_*_body + liveness body struck #8583 (ref §4.A) All deletion commits verified as ancestors of origin/main ✅. Part of #10537's per-row adjudication program. --------- Co-authored-by: Brian Searls <briansearls1@gmail.com>
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.
Summary
host_hygiene_reaper_script.dagandhost_hygiene_liveness_script.dagheld hand-concatenated bash text bodies — a scaffold whose dissolution trigger (typed-argv host-effect routing, #5828-era) has landed. This migrates both verticals onto typed observation/remediation and deletes both script modules in the same cut (DESIGN §3 replacement migration — no dual-authority interim).gunbc.host_hygiene_reaper_observe(OBSERVE): per-slot cgroup/system.controlobservation via the existingsystemctl_show_readseam (extended withSystemdUnitProperty::ActiveState) and directfilesystem_read/shell.Test.IsDirectory. Reuses the existing single authoritygunbc.host_converge.gunbc_runner_all_slots_unit_globrather than re-declaring the runner-slot glob.gunbc.host_hygiene_reaper_remediate(MUTATE): the bound is structural, not a literal check embedded in a script — everyResidualReapEffectvariant carries aunitderived from a vetted observation, and the module recomputesresidual_reap_actioninternally rather than accepting a caller-supplied action, so the decision core's permanent RED-controlresidual_reap_action_absorbing_fallback_widen_sketchfixture is unreachable from any effect path.gunbc.host_hygiene_liveness_observe(OBSERVE): journal-line parsing (last matching"Listening for Jobs"line, epoch extraction, freshness age) as pure.dagfolds over one typedextdeps.systemd.Journalctl.UnitLogread, replacing the deleted script's hand-writtenjournalctl | grep | tailpipeline.extdeps:extdeps.posix.signal(kill -TERM) andextdeps.systemd.journalctl(journalctl -u ... -o short-unix), both anchored to their upstream authorities and carryingmock_responsefor hermetic replay.gunbc.host_hygiene_reaper/_liveness) are unchanged except their placeholderReadAbsentreason strings, which now name the real live-evidence entrypoint. No import was added back from the decision core to the observe modules — avoids a cycle.Confirmed via corpus-wide grep that the reaper script's dead systemd-unit-install machinery had zero consumers anywhere (matching
live_deploy/spec.dag's own note that it "is installed by NOBODY"), so deleting the whole file was safe as one cut.CI reality: CI's floor is hermetic-only (
eval_mock_responsereplays declared results; argv is never constructed/executed). The live shell/systemctl/journalctl/kill-issuing functions (observe_residual_slot,apply_residual_reap_effect,host_hygiene_observe_slot_listening's transport leg) are reachable only from the wet path, never from atest fn, and are markedUNEXECUTED-IN-CIwith a stated promotion trigger (a wet/live CI lane, which does not exist today). The new tests exercise the pure decision/parsing functions directly (green-by-execution), plus one hermetic end-to-end read ofhost_hygiene_observe_slot_listeningagainstJournalctl.UnitLog's declaredmock_response.Test plan
CTRL_BUILD_MODE=local cargo build --release --bin gunbc --bin claim_batch --bin claim_executor— builds cleanclaim_batch --source-root dag --source-root src/v2 --entry dag/test/claim/host_hygiene_reaper_test.dag --functions <all 16> --hermetic— 16/16 PASSclaim_batch --source-root dag --source-root src/v2 --entry dag/test/claim/host_hygiene_liveness_test.dag --functions <all 12> --hermetic— 12/12 PASSlive_deploy/spec.dag)🤖 Generated with Claude Code