Convert the remaining process::exit sites in the assembly crate to RunnerError propagation #297

Open
opened 2026-07-21 05:20:05 +02:00 by claude · 4 comments
Collaborator

Motivation

The shell-boundary extraction (#295) moved the member-run recipe into the aura-runner assembly crate with bodies verbatim, so roughly twenty refusal sites inside library code (family.rs, member.rs, measure.rs, translate.rs — the single-run verb paths, e.g. the real-data-opening refusals) still call std::process::exit directly. Behaviour is byte-identical for the CLI, but an embedding World program gets its host process killed on a refusal instead of receiving a Result.

Problem

Finish what reproduce.rs already models: convert the remaining process::exit sites in aura-runner to RunnerError { exit_code, message } propagation, with the shell dispatch arms remapping to byte-identical stderr output and exit codes. The campaign path is unaffected (refusals there are already MemberFaults — never a process exit inside a sweep worker). The shell E2E suites pin the observable bytes, so the conversion is regression-guarded.

refs #295

## Motivation The shell-boundary extraction (#295) moved the member-run recipe into the `aura-runner` assembly crate with bodies verbatim, so roughly twenty refusal sites inside library code (`family.rs`, `member.rs`, `measure.rs`, `translate.rs` — the single-run verb paths, e.g. the real-data-opening refusals) still call `std::process::exit` directly. Behaviour is byte-identical for the CLI, but an embedding World program gets its host process killed on a refusal instead of receiving a `Result`. ## Problem Finish what `reproduce.rs` already models: convert the remaining `process::exit` sites in `aura-runner` to `RunnerError { exit_code, message }` propagation, with the shell dispatch arms remapping to byte-identical stderr output and exit codes. The campaign path is unaffected (refusals there are already `MemberFault`s — never a process exit inside a sweep worker). The shell E2E suites pin the observable bytes, so the conversion is regression-guarded. refs #295
Author
Collaborator

Fieldtest evidence (cycle #283, example refusal_probe)

The tap-subscribers fieldtest hit exactly this edge from the downstream side. A World-program consumer that subscribes an unknown fold label —

plan.subscribe("signal", TapSubscription::named("median")); // not in the roster
run_signal_r(signal, &[], RunData::Synthetic, 0, &env, plan);

— gets its own process terminated: aura: unknown fold 'median' — available: count, first, last, max, mean, min, record, sum on stderr + exit 1, with nothing written. The refusal message is excellent (roster-enumerating, no half-write), but a library caller cannot catch it. These are the four TapPlanError refusal sites #283 added (typed before the exit), part of the ~24 this issue tracks. Carrying the fieldtest finding here rather than filing a duplicate.

## Fieldtest evidence (cycle #283, example `refusal_probe`) The tap-subscribers fieldtest hit exactly this edge from the downstream side. A World-program consumer that subscribes an unknown fold label — ```rust plan.subscribe("signal", TapSubscription::named("median")); // not in the roster run_signal_r(signal, &[], RunData::Synthetic, 0, &env, plan); ``` — gets its *own* process terminated: `aura: unknown fold 'median' — available: count, first, last, max, mean, min, record, sum` on stderr + exit 1, with nothing written. The refusal *message* is excellent (roster-enumerating, no half-write), but a library caller cannot catch it. These are the four `TapPlanError` refusal sites #283 added (typed before the exit), part of the ~24 this issue tracks. Carrying the fieldtest finding here rather than filing a duplicate.
claude added this to the Safe to embed — a Result-clean library surface under a stated compatibility contract milestone 2026-07-23 13:42:57 +02:00
Author
Collaborator

Inventory note (2026-07-24, stderr-honesty cycle)

Commit 51096a3 on the worktree-issue-278-stderr-markers branch deliberately ADDS one eprintln! + std::process::exit(3) site to the assembly crate: exit_on_member_panic in crates/aura-runner/src/family.rs (the contained synthetic member-panic path — aura: warning: + the C14 failed-cells exit). Chosen as the minimal fix consistent with the crate's current shipped pattern rather than fighting this issue's future RunnerError propagation mid-bugfix.

When this issue's sweep converts the assembly crate's exit sites, include this one: the natural target shape is the fault propagating as a RunnerError/failed-count to the shell, which already owns the exit mapping (exit_on_campaign_result).

## Inventory note (2026-07-24, stderr-honesty cycle) Commit 51096a3 on the `worktree-issue-278-stderr-markers` branch deliberately ADDS one `eprintln!` + `std::process::exit(3)` site to the assembly crate: `exit_on_member_panic` in `crates/aura-runner/src/family.rs` (the contained synthetic member-panic path — `aura: warning: ` + the C14 failed-cells exit). Chosen as the minimal fix consistent with the crate's current shipped pattern rather than fighting this issue's future RunnerError propagation mid-bugfix. When this issue's sweep converts the assembly crate's exit sites, include this one: the natural target shape is the fault propagating as a `RunnerError`/failed-count to the shell, which already owns the exit mapping (`exit_on_campaign_result`).
Author
Collaborator

C14 exit-class evidence from the #310 cycle audit (2026-07-24)

The #310 architect review flagged: tap-bind refusals reached from argv content exit through the assembly crate's runner-side exit-1 registers, while C14's partition assigns command-line faults — including the content of an argv-named blueprint file — to class 2. Concrete sites for this issue's conversion: the bind_tap_plan refusals (unknown fold label / undeclared tap) surfacing via run_signal_r (crates/aura-runner/src/member.rs:526) and run_measurement (crates/aura-runner/src/measure.rs:93). Same register family as the pre-existing duplicate-tap refusal (#283) and the exposes neither refusal (#286) — both likewise blueprint-content faults on the exit-1 path today, so the tension predates #310.

When this issue converts the assembly crate's process::exit sites to RunnerError propagation, the CLI regains class authority: adjudicate these refusals to exit 2 per C14 and pin the classes in the binary tests (the #310 tests deliberately pin !success only, not the class). A CLI-side shadow pre-validation was considered in the #310 audit and rejected — it would duplicate the bind_tap_plan validation seam and can drift.

## C14 exit-class evidence from the #310 cycle audit (2026-07-24) The #310 architect review flagged: tap-bind refusals reached from argv content exit through the assembly crate's runner-side exit-1 registers, while C14's partition assigns command-line faults — *including the content of an argv-named blueprint file* — to class 2. Concrete sites for this issue's conversion: the `bind_tap_plan` refusals (unknown fold label / undeclared tap) surfacing via `run_signal_r` (crates/aura-runner/src/member.rs:526) and `run_measurement` (crates/aura-runner/src/measure.rs:93). Same register family as the pre-existing duplicate-tap refusal (#283) and the `exposes neither` refusal (#286) — both likewise blueprint-content faults on the exit-1 path today, so the tension predates #310. When this issue converts the assembly crate's `process::exit` sites to RunnerError propagation, the CLI regains class authority: adjudicate these refusals to exit 2 per C14 and pin the classes in the binary tests (the #310 tests deliberately pin `!success` only, not the class). A CLI-side shadow pre-validation was considered in the #310 audit and rejected — it would duplicate the `bind_tap_plan` validation seam and can drift.
Author
Collaborator

Scope note from the harvest-sweep audit (2026-07-24)

The runner-side print register family this issue will migrate grew by two sites in the sweep: the #334 skipped-tap note (aura: note: declared tap "…" unbound this run, emitted in bind_tap_plan's unbound arm) and the #333 roster-carrying UnknownTap refusal (Display now appends the declared-tap roster; still surfaced through the pre-existing exit-1 register). Both are deliberate residents of the same seam — include them in the RunnerError propagation sweep so the CLI regains class authority over their exit/marker classes.

## Scope note from the harvest-sweep audit (2026-07-24) The runner-side print register family this issue will migrate grew by two sites in the sweep: the #334 skipped-tap note (`aura: note: declared tap "…" unbound this run`, emitted in `bind_tap_plan`'s unbound arm) and the #333 roster-carrying `UnknownTap` refusal (Display now appends the declared-tap roster; still surfaced through the pre-existing exit-1 register). Both are deliberate residents of the same seam — include them in the RunnerError propagation sweep so the CLI regains class authority over their exit/marker classes.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Brummel/Aura#297