Skip to content

Remove the raw-script arm from HostEffect and preserve typed gate witnesses - #10509

Merged
briansrls merged 9 commits into
mainfrom
session/quick-gull-442
Sep 5, 2026
Merged

briansrls merged 9 commits into
mainfrom
session/quick-gull-442

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

HostEffect.ShellCommand has no production producer with a real script. Delete the variant and ShellOnHost dispatch cell, and remove the empty-script effect fabricated by plan refusals. host_effect_plan_apply now returns an optional attempted intent: Absent before any effect is attempted at that step, Present for the actual Do result.

The structural guarantee is scoped to the HostEffect carrier: its canonical type has no ShellCommand arm, so a HostEffect can no longer carry an anemic script (DESIGN §4b rung 4 at this boundary). This does not claim the corpus-wide raw-shell class is extinct: retained scripts, shell.Exec.Run, and instrument transports still exist through other routes. A multiline shape search at main a29faba47f3 returns 30 positive-control matches: 26 witness constructions, the empty placeholder construction, the variant declaration, and two match arms. At 20712ad2c03 it returns zero. This separates actual constructions from declarations and destructuring; the placeholder helper also disappears. Remaining spelling matches include UEFI shell vocabulary, POSIX shell-language concepts, and historical plan narration; they are not surviving HostEffect.ShellCommand constructors.

Mutation-gate controls use the existing mutating LiveDeployRetract arm; permitted controls use harmless typed receipt data. Apply/plan controls preserve failure, captured-output reconciliation, target/transport refusal, drive policy, and fail-fast sequencing. Real execution controls use the existing effective-principal read and unreachable SSH transport. No test-only effect or v1 seed change is introduced. The four srv3 transport helpers already use typed argv; their dated migration rows require no implementation change.

The separately discovered unconditional-success SSH mock is recorded in gunbc.recurring_failure_mode.transport_mock_success_independent_of_request; its implementation is outside this PR.

The full named roster completed at 78226aa367d3941a6a84bff9c1e66b91e1fc678e. The current head adds only the syntax repair described below; closure equality and the paired parser control are complete.

Measured at 78226aa367d3941a6a84bff9c1e66b91e1fc678e: 103/103 named functions accounted for in each mode (206 verdicts total). All per-entry expected/observed counts agree; no missing, duplicate, unexpected, or runtime-error verdicts.

Entry Expected per mode Wet PASS / false Hermetic PASS / false
deploy_access_privilege 5 5 / 0 5 / 0
deploy_mutation_gate 9 9 / 0 9 / 0
host/host_effect_apply 20 20 / 0 17 / 3
host/host_effect_plan_real_execution 2 2 / 0 0 / 2
host/host_effect_plan 5 5 / 0 5 / 0
host/host_identity_observation 32 31 / 1 32 / 0
live_deploy/apply 3 3 / 0 3 / 0
runner/runner_replace_incarnation_seam 4 4 / 0 4 / 0
srv3/srv3_host_effect_apply 23 23 / 0 23 / 0

Receipts: 41-function group, 62-function group. Each invocation builds the current-source compiler, verifies head and all 5,532 tracked files, and runs a fresh process for each entry and mode.

The five hermetic assertion failures are the two local-principal success controls, the unreachable-SSH failure control, and the two real-execution plan controls. The local principal mock returns failure and the SSH portable-word mock returns unconditional success. Their enrollment records these observed typed-path outcomes. The sole wet assertion failure is the unchanged hostname CAS control: its outcome-variant match discriminates refusal behavior, while observed == "localhost" depends on the hermetic fixture. Neither mocks nor this witness were rewritten to manufacture passing counts.

CI found a parse error in the new expected-red roster: tail: followed immediately by a newline. Commit 20712ad2c0379545612026105e0a79de57887a3e uses the surrounding roster's same-line nested Cons form; it changes only whitespace in src/v2/workflow/floor_expected_red.dag. Closure comparison completed: all nine entry path sets and SHA256 maps are identical between 78226aa and 20712ad; the edited roster is absent from every closure. Both nonempty completion receipts contain 7,383 path rows. Per-entry file counts, in table order: 761, 1022, 761, 762, 762, 770, 1022, 761, 762.

Both closure measurements used the same comparator binary, claim_batch SHA256 becbbc9d62c516d557f2af6b5c0410e5adcaaf66f95f0c0f0403fa16b781acfc, built at 20712ad. The witness executions used current-source builds at 78226aa; no compiler source or Cargo inputs changed, but build.rs embeds Git head, so byte-identical builds across those heads are not claimed. The -dirty build identity reflects temporary untracked dispatch tooling; all tracked source bytes were independently verified.

The first parser-control harness reproduced the old syntax error and evaluated the fixed roster, then incorrectly expected gunbc run to accept a FreeMonoid result. The CLI correctly refused that result type. That invocation is therefore a completed closure receipt, not an overall green syntax-control run. The corrected syntax pair passed using floor_expected_red_is_live with --claim-run: old head refuses with the specific newline error; fixed head exits 0. Its terminal receipt is ENROLLMENT_SYNTAX_CONTROL_COMPLETE old_refuses=true new_executes=true. No repository change was involved in correcting the harness.

Explicit projection regeneration executed at merge head d69e1c6979244cb17c299e4a33b708f2261d1e79; its exact 770,098 output bytes are committed in 78226aa367d. The combined projection has 131 identities. Lost identities versus c09324e86ff, previous repair d6b5af54382, and incoming main a29faba47f3: empty in every case. Gained identities versus main: exactly transport_mock_success_independent_of_request. Positive control absorbing_fallback retains 11 hits. These checks detect both dropped rows and accidental resurrection.

Two earlier preflight defects produced no test results: Git excluded an ignored, untracked .py harness from upload; then a reused isolated clone's stale branch tip caused BuildBuddy to check out an older head and apply the candidate as a patch. The first is corrected by embedding the temporary Python harness in the uploaded script and writing it under /tmp; the second by refreshing the named branch and upstream ref. Both subject-head and source-byte assertions remain required.

The standard generator's own source (dag/gunbc/instruments/generated_artifact_gate.dag) records 8.37 GiB peak RSS on 2026-09-01, exceeding the default runner's measured 7 GiB machine memory here. This is dated infrastructure evidence, not a new RSS measurement of this candidate. The larger runner reported MemTotal: 17170168 kB; the dispatch asserts capacity before building.

Verify the worktree on a remote runner

BuildBuddy initially selected the common checkout instead of this worktree. Use an isolated clone and verify its head and source bytes inside the same remote dispatch. For a committed candidate:

set -euo pipefail
subject_root=$(git rev-parse --show-toplevel)
subject_head=$(git rev-parse HEAD)
subject_branch=$(git branch --show-current)
validation_root=$(mktemp -d /tmp/gunbc-validation.XXXXXX)
git clone --shared "$subject_root" "$validation_root"
git -C "$validation_root" checkout -B "$subject_branch" "$subject_head"
git -C "$validation_root" remote set-url origin https://github.com/gunb-ai/gunbc.git
cd "$validation_root"
# The committed candidate must already be pushed. Refresh reused clones too.
git fetch origin "refs/heads/$subject_branch:refs/remotes/origin/$subject_branch"
test "$(git rev-parse "origin/$subject_branch")" = "$subject_head"
printf '%s\n' "$subject_head" > validation.head
git ls-files -z | xargs -0 sha256sum > validation.sha256
cat > validate.sh <<'SCRIPT'
set -euo pipefail
test "$(git rev-parse HEAD)" = "$(cat validation.head)"
sha256sum --check --quiet validation.sha256
sha256sum --check --quiet tooling.sha256
awk '/MemTotal/ { print; if ($2 < 14000000) exit 1 }' /proc/meminfo
if cargo check -Z definitely-not-a-real-flag; then exit 2; fi
# Export ON the runner; this does not rely on forwarding GUNBC_* variables.
# The bound must be below the runner's measured memory capacity.
export GUNBC_BIND_MEMORY_CGROUP_BYTES=12884901888
cargo build --release -p v1-compiler --features interp_test_witness,test_hooks --bin claim_batch
# Replace with the intended entry and its explicit function roster.
target/release/claim_batch --wet --source-root dag --source-root src/v2 \
  --entry dag/test/claim/host/host_effect_plan_real_execution_witness_test.dag \
  --functions host_effect_plan_typed_read_witness_holds_by_real_execution,host_effect_plan_ssh_failure_reason_carries_exit_code_by_real_execution
SCRIPT
# Hash uploaded harness inputs too; use names not excluded by .gitignore.
sha256sum validation.head validate.sh > tooling.sha256
CTRL_BUILD_RUNNER_EXEC_PROPERTIES=EstimatedMemory=16GB \
  ctrl-build --remote --no-fallback -- bash validate.sh

For uncommitted work, apply git diff --binary HEAD to the isolated clone and copy explicitly selected untracked source files before writing the hashes. The sha256sum input must include those files. A matching head alone does not verify a dirty candidate. Credit execution only after the runtime's memory-cgroup-bind diagnostic confirms an enforceable bound; the baked image's gunbc is not a substitute for the current-source binary.

@gunbai-bot
gunbai-bot Bot force-pushed the session/quick-gull-442 branch from ad865c5 to 5b02006 Compare September 5, 2026 04:56
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 5, 2026 06:59
@gunbai-bot gunbai-bot Bot changed the title Dissolve HostEffect.ShellCommand and fabricated plan effects Remove the raw-script arm from HostEffect and preserve typed gate witnesses Sep 5, 2026
@briansrls
briansrls merged commit 03a3b91 into main Sep 5, 2026
4 checks passed
@briansrls
briansrls deleted the session/quick-gull-442 branch September 5, 2026 07:40
@gunbai-bot

gunbai-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Census lane finding, offered as a widening of this row's framing — not a request to hold or change this PR, which should land as-is.

This row reads the defect as "the surviving SSH instance". The census says the framing is narrower than the mechanism, in a way that matters for how the class gets sized later.

It is not per-service, it is structural. eval_mock_response (in v1_interpreter) evaluates a mock arm in an empty environment — the operation's declared inputs are not in scope at the point the arm is evaluated. So a request-dependent arm is not merely unwritten for ssh.Session.ExecPortableWords; it is unwritable anywhere in this seed. Every unconditional arm in the tree is one observation of that single cause, and ssh.Session.ExecPortableWords is a specimen rather than a survivor.

Two consequences worth carrying:

  • PublishedMockCase is an enrolment roster, not a response. It says which operations a corpus-governed service admits hermetically; the answer is the mock_response property on the operation. The two populations overlap only in part — most published operations carry no arm at all and refuse fail-closed with HermeticEffectGround.NoMockResponse, which is a different class from this one. Reading either population as an answer to the other mis-sizes this row in whichever direction the reader happens to guess.

  • Both error directions are real, and this row already says so — success assertions passing vacuously, failure assertions turning false. The census confirms the first by execution and finds the second largely already visible: refusal-shaped witnesses over a mocked op decide their refusal before the mock is consulted, and the one live instance this row names is enrolled in v2.workflow.floor_expected_red, so it is held and counted rather than silently green.

The widening is carried in #10549, against gunbc.hermetic_mock_fidelity — the authority that already owns mock-arm honesty and whose shell.Exec rows this row cites. That PR adds no rows and mints no class: it records the cause as structural, fixes two next-rung triggers that named a state of the world no author could reach, and names the missing capability that blocks counting the population from the corpus. One class, one row; this row stays the authority for the class.

Measured, not read — one witness, one binary, one tree. witness_os_id_uid_realizes_hermetically asserts r.value == "1000" against an arm answering "1000". Perturbing the arm literal reds hermetically and stays green wet; perturbing the realization argv from id -u to id -G stays green hermetically and reds wet. The receipt and its method note are in #10549.

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>
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