v1 host-boundary: complete closure of residual v0 debt - #80
Conversation
Pre-authorized by freeze-v1.md §4.2. - Removed effects: Vec<ActionEffect> from DecisionLogEntry - Removed effects parameter from Supervisor::log_decision - Updated seven call sites - Migrated two in-crate readers and capture test coverage Plan: docs/ledger/decisions/s2.1-plan.md
Pre-authorized by freeze-v1.md §4.3. - moved BufferingRuntimeInvoker, ContextStore, handler coverage, and effect-handler support into ergo-host::host - updated host imports and tests; no RuntimeHandle::run or RunResult seam change in this commit - refreshed the S2.3 planning artifact and the v1 boundary/freeze docs for the relocated paths Plan: docs/ledger/decisions/s2.3-plan.md
Per freeze-v1.md §6 acknowledgment: - RuntimeHandle::run (§3.2): public signature changed from returning RunResult to returning RunTermination only. - HostedRunner::new(...): deliberate companion break; constructor now accepts BufferingRuntimeInvoker instead of RuntimeHandle so the public host upgrade path is buffered, not raw. Pre-authorized by freeze-v1.md §4.1. Plan: docs/ledger/decisions/s2.2-plan.md
Banners, prepends, and cross-links landed alongside Session 1 Artifacts B and C but were not committed. - docs/invariants/08-replay.md: v1 architectural-framing prepend - docs/orchestration/adapter.md: v1 version-tag banner - docs/orchestration/supervisor.md: v1 version-tag banner - docs/system/kernel.md: v1 Workstream pointer + C.1 row - docs/system/kernel-prod-separation.md: reference cross-links Cross-reference: docs/system/host-boundary.md, docs/system/freeze-v1.md, docs/ledger/decisions/v1-host-boundary-migration.md
Reorganize the header comment to lead with who consumes the prelude (live_prep.rs, live_run.rs, and the usecases.rs facade) before noting the process_driver.rs exception. Prior wording omitted usecases.rs from the consumer list.
Header comment cited 'run_fixture_items_driver'; the function was renamed to 'run_prepared_fixture_driver'. Comment brought into sync with the actual function name at lines 658 and 669.
Re-anchors the three v1 boundary documents from original authoring HEAD 7784f46 to HEAD 0218a5f, reflecting the three Session 2 transformations (S2.1 DecisionLogEntry.effects removal, S2.2 runtime seam redesign, S2.3 host-module relocation). docs/system/freeze-v1.md - Sec 0: anchor hash updated to 0218a5f; pre-authorized bullet converted to historical note describing the re-anchor rationale. - Sec 3: HEAD reference updated to 0218a5f. - Sec 3.2: RuntimeHandle::run commitment rewritten to reflect the post-S2.2 termination-only public signature; new row added for ReportingRuntimeHandle carrying run_reporting as the adapter-layer reporting seam. - Sec 3.5: CapturedActionEffect line reference refreshed (replay.rs:328-345 -> 312-329). - Sec 4: title suffixed '(historical)'; Sec 4.1 converted to a discharged historical note anchored at HEAD 0218a5f; prior-signature framing retained; concrete-sink-shape and re-anchor bullets removed as no longer applicable; step-zero audit retained as historical. - Sec 5: RunResult non-scope bullet removed (no longer transitional). docs/system/host-boundary.md - Sec 0: Last Updated date advanced to 2026-04-20; anchor hash updated to 0218a5f with re-anchor rationale; file-table blob hashes and line counts refreshed for all 15 listed files. - Sec 3.1, 3.2, 3.3, 4, 5, 6, 7, 8, 9: line-level citations refreshed throughout (supervisor/lib.rs, capture.rs, replay.rs, runner.rs, buffering_invoker.rs). Key shifts: Supervisor struct 213->212; EpisodeInvocationRecord From impl 173-188 -> 172-187; CapturingDecisionLog::log 189-206 -> 187-196; validate_replay_provenance 245-271 -> 229-255; replay_checked_strict 200 -> 184; validate_unique_event_ids 273-284 -> 257-268; compare_decisions 290 -> 274; non-effect fields 299-309 -> 284-293; effect comparison 328-345 -> 312-329; rehydrate_event 356 -> 340; buffering_invoker replace-site 112 -> 132; drain-site 86 -> 99; SUP-6 comment 794 -> 793. - Sec 6.1: replace-site citation rewritten to reflect the S2.2 sink mechanism (guard.pending_effects = effects; populated by self.engine.run_reporting(..., &mut effects)). - Sec 10: converted to historical; narrates S2.2 discharge and enumerates the three post-execution guarantees; no outstanding v1 debt tracked at current HEAD. - Sec 11: intro softened to 'pre-merge gate at original authoring; re-anchored post-Session 2'; all 26 rows refreshed with verified line ranges at HEAD 0218a5f; Row 14 substantively rewritten for the S2.2 sink-parameter mechanism; Row 17 SUP-6 refreshed to 793. docs/ledger/decisions/v1-host-boundary-migration.md - Context: the three residual-v0-shapes paragraph past-tensed; new paragraph records the Session 2 discharge at HEAD 0218a5f; the 'Runtime behavior matches' paragraph updated to reflect that the type/layout encoding is now aligned too. - Ruling point 3: re-titled 'Residual debt schedule (discharged)'; S2.2 bullet expanded to name ReportingRuntimeHandle::run_reporting as the chosen effect-observation mechanism. - Methodology: output summary updated to note the host-boundary.md Sec 11 re-anchor from 7784f46 to 0218a5f.
Discharges the two non-blocker stale pointers surfaced by the Session 2 closure audit (commit 4791466): - docs/system/freeze-v1.md:167 — replaced the "Session 1 retrospective (Artifact A, forthcoming)" parenthetical with a markdown link to docs/ledger/decisions/v1-host-boundary-migration.md, which now exists. Also links host-boundary.md in the same sentence. - docs/system/host-boundary.md:398 — rewrote the SUP-2 evidence cell to remove the stale "§10 S2.2" adjacency and the "belt-and-braces hardening" framing. Now records that SUP-2 is type-enforced at the public seam post-S2.2: RunResult is private to ergo-adapter at crates/kernel/adapter/src/lib.rs:182, and RuntimeHandle::run's public signature returns RunTermination only. Sentence shape intentionally mirrors freeze-v1.md §4.1's historical note so the SUP-2 enforcement story uses matching language across both canonical docs. Doc edits only; no §3 symbol changes, so no §6 acknowledgment needed.
Greptile SummaryThis PR closes the v1 host-boundary migration by discharging three residual v0 code shapes: removing
Confidence Score: 5/5Safe to merge: cargo test is green, all three transformations are correctly implemented, no production panics/unwraps, and kernel invariant docs updated per the custom rule. All pre-authorized transformations execute cleanly. The seam split between RuntimeHandle (termination-only) and ReportingRuntimeHandle (effects-out) is architecturally correct and well-tested. DecisionLogEntry.effects removal is fully propagated through supervisor, capture, and replay. Host module relocation is complete with no dangling imports. No P0/P1 findings. No files require special attention. All changed files implement the stated goals correctly.
|
| Filename | Overview |
|---|---|
| crates/kernel/adapter/src/lib.rs | Split former monolithic RuntimeHandle into private RuntimeState + public RuntimeHandle (termination-only) + new public ReportingRuntimeHandle (effects seam); RunResult privatised; RuntimeInvoker impl simplified. |
| crates/kernel/supervisor/src/lib.rs | DecisionLogEntry.effects field removed; all log_decision call-sites drop the trailing vec![] argument; clippy::too_many_arguments allow removed since argument count decreased. |
| crates/prod/core/host/src/host/buffering_invoker.rs | New file: BufferingRuntimeInvoker wraps ReportingRuntimeHandle behind a private ReportingRuntime seam; replace-not-extend buffer semantics for retries; drain_pending_effects is single-use and correct. |
| crates/prod/core/host/src/host/effects.rs | Relocated from kernel/adapter; SetContextHandler validates declared key, writable, and type before writing; partial-write no-rollback semantics explicitly documented and tested. |
| crates/prod/core/host/src/runner.rs | HostedRunner::new and new_validated now accept BufferingRuntimeInvoker directly; graph_emittable_effect_kinds() uses .clone() correctly; EffectApplyError import moved to crate::host. |
| crates/kernel/supervisor/src/capture.rs | CapturingDecisionLog.log simplified: no longer hashes effects or populates record.effects at the kernel layer; effects are now host-enriched exclusively via capture_enrichment.rs. |
| crates/prod/core/host/src/usecases/live_prep.rs | All RuntimeHandle construction sites switched to ReportingRuntimeHandle wrapped in BufferingRuntimeInvoker; replay_owned_external_kinds updated to &ReportingRuntimeHandle; ensure_production_adapter_bound call sites unchanged. |
| docs/invariants/08-replay.md | Added v1 architectural framing banner cross-linking to freeze-v1.md and host-boundary.md; satisfies custom rule 598b1171 for kernel change documentation. |
Sequence Diagram
sequenceDiagram
participant Host as HostedRunner (prod)
participant BRI as BufferingRuntimeInvoker (prod/host)
participant RRH as ReportingRuntimeHandle (kernel/adapter)
participant Sup as Supervisor (kernel)
participant DL as DecisionLog (kernel)
participant CE as capture_enrichment (prod)
Host->>BRI: run(graph_id, event_id, ctx, deadline)
BRI->>RRH: run_reporting(..., effects_out)
RRH-->>BRI: RunTermination + effects_out filled
BRI-->>BRI: replace pending_effects buffer
BRI-->>Sup: RunTermination only
Sup->>DL: log(DecisionLogEntry) [no effects field]
Host->>BRI: drain_pending_effects()
BRI-->>Host: Vec<ActionEffect>
Host->>CE: enrich_bundle_with_host_artifacts(effects)
CE-->>Host: CaptureBundle with hashed CapturedActionEffects
Reviews (2): Last reviewed commit: "Extract oversized inline test modules to..." | Re-trigger Greptile
🤖 Augment PR SummarySummary: This PR finalizes the v1 host-boundary migration by removing remaining v0-shaped seams and introducing canonical v1 doctrine docs. Changes:
Technical Notes: Effect observation is now explicitly separated from supervisor invocation (SUP-2), with host-owned buffering/drain semantics preserved and host capture enrichment remaining authoritative for persisted effect records. 🤖 Was this summary useful? React with 👍 or 👎 |
| effects_out: &mut Vec<ActionEffect>, | ||
| ) -> RunTermination { | ||
| let result = execute_once(&self.state, graph_id, event_id, ctx, deadline); | ||
| *effects_out = result.effects; |
There was a problem hiding this comment.
ReportingRuntimeHandle::run_reporting overwrites effects_out via *effects_out = result.effects;. Since this is a new public seam, it seems worth documenting that the contract is replace-not-append so callers don’t accidentally lose previously collected effects when reusing the same buffer.
Severity: low
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
Extracts the oversized inline #[cfg(test)] mod tests { ... } blocks
in the three S2.3-relocated host files into sibling tests.rs files,
matching the project convention established by
crates/kernel/supervisor/src/capture.rs (and documented in AGENTS.md
§4.B: the default for out-of-line unit tests is foo.rs +
foo/tests.rs). Each of the three relocated modules carried an inline
test block well over the ~50-line threshold.
Files:
- crates/prod/core/host/src/host/buffering_invoker.rs — inline block
(~122 lines) replaced with `#[cfg(test)] mod tests;`; body moved
verbatim to crates/prod/core/host/src/host/buffering_invoker/tests.rs.
- crates/prod/core/host/src/host/effects.rs — inline block
(~137 lines) replaced with `#[cfg(test)] mod tests;`; body moved
verbatim to crates/prod/core/host/src/host/effects/tests.rs.
- crates/prod/core/host/src/host/coverage.rs — inline block
(~114 lines) replaced with `#[cfg(test)] mod tests;`; body moved
verbatim to crates/prod/core/host/src/host/coverage/tests.rs.
Pure layout extraction: no test logic changed; no imports changed
beyond being re-anchored at the new module root; `use super::*;`
still refers to the parent production module. Production module
shape stays as foo.rs with a sibling foo/ directory for tests,
matching capture.rs / capture/tests.rs.
These blocks were inline at the same sizes in the pre-S2.3 location
(crates/kernel/adapter/src/host/) and were carried over verbatim
during S2.3's pure-relocation scope. This commit discharges the
style debt surfaced by Greptile on PR #80.
Verification: cargo test -p ergo-host green (224 passed); cargo test
--workspace green (no failures). No §6 invocation: no §3 symbol
changes, only test-module layout.
PR #80 rebase-merged the eleven-commit session-2-v1-closure branch onto main. GitHub's server-side rebase rewrote every commit SHA, so every Session 2 SHA cited in the v1 docs no longer resolves on origin/main. This commit refreshes those citations so the forensic methodology that relies on greppable anchor hashes still works. Files updated (24 substitutions across 4 files): - docs/system/freeze-v1.md — 4 substitutions: 0218a5f -> dbd376f (3 as 7-char + 1 as full 40-char in the §0 HEAD line). - docs/system/host-boundary.md — 5 substitutions: 0218a5f -> dbd376f (3 as 7-char + 2 as full 40-char in the §0 and §11 HEAD lines). - docs/ledger/decisions/v1-host-boundary-migration.md — 3 substitutions: 0218a5f -> dbd376f (all 7-char). - docs/ledger/decisions/session-2-closure-audit.md — 12 substitutions: 0218a5f -> dbd376f (6 occurrences, the S2.2 commit) 62738f9 -> 6976c62 (2 occurrences, the re-anchor commit) 5f5c7dc -> 74fcbdb (1 occurrence, Session 1 doc-edits) 3fbbe2c -> 61cd96a (1 occurrence, shared.rs header) 07f29dc -> 529dfd5 (1 occurrence, live_run.rs header) d340846 -> f16fe69 (1 occurrence, .gitignore tooling) Treatment rationale. The v1 canonical docs also cite `7784f46f`, the pre-Session-2 authoring HEAD, in §0 preambles and §4.1 / §10 / §Context / §Methodology historical notes. Those citations are intentional historical anchors that frame the re-anchor journey ("re-anchor from original authoring HEAD `7784f46f` to ...") and are preserved unchanged. The SHAs rewritten in this commit are present-tense citations of post-S2.x commits that must resolve against current main to support forensic replay; the pre-rebase hashes no longer exist on main after the server-side rebase. Cross-reference: PR #80 (#80). No §6 invocation: doc edits, no §3 symbol changes.
Closes the v1 host-boundary migration by discharging the three residual v0 code shapes identified in the 2026-04-19 forensic audit. Session 1 produced the canonical v1 doctrine (invariant spec, freeze declaration, retrospective record); Session 2 discharged the residual debt in three commits with full §6 paper trails; post-session re-anchor pass brought the docs into consistency with the post-execution code state.
Session 1 — Doctrine (artifacts committed in subsequent sessions' commits)
Three canonical documents establishing the v1 boundary:
docs/system/host-boundary.md— CANONICAL v1 invariant specificationdocs/system/freeze-v1.md— CANONICAL v1 symbol-level freezedocs/ledger/decisions/v1-host-boundary-migration.md— retrospective forward decision record with reusable forensic methodologySession 2 — Code changes
Three pre-authorized transformations (per freeze-v1.md §4 as originally authored), each with §6 commit-body acknowledgment where applicable:
971185aS2.1 — remove vestigialDecisionLogEntry.effectsbece0b2S2.3 — relocate host behavior fromcrates/kernel/adapter/src/host/tocrates/prod/core/host/src/host/0218a5fS2.2 — redesign runtime observation seam;RuntimeHandle::runnow returnsRunTerminationonly; newReportingRuntimeHandlecarries the effect-reporting seam consumed byBufferingRuntimeInvoker. First real §6 invocation in the codebase.Each transformation has a plan artifact at
docs/ledger/decisions/s2.{1,2,3}-plan.mdwith the subagent review trail.Post-session work
5f5c7dc— Session 1 companion doc-edits (banners/cross-links on supervisor.md, adapter.md, 08-replay.md, kernel.md, kernel-prod-separation.md)3fbbe2c,07f29dc,d340846— hygiene and tooling62738f9— re-anchor pass: anchor hash updates, §3 post-execution shape, §11 26-row claim verification, §10 historical4791466— Session 2 closure audit report (no blockers; two known non-blocker doc-hygiene items surfaced)fc8eefc— discharge of the two known non-blocker items surfaced by the auditVerification
cargo test --workspacegreen at every code commit landing0218a5fKnown deferred items (Session 3 scope)
docs/orchestration/supervisor.mdstill carries pre-S2.2RunResultframing in lines 144-145, 173, 247-248, 271, 283, 344. Version-tagged v0, non-canonical for v1, correctly deferred to the Session 3 rewrite pass.Reading order for reviewers
docs/ledger/decisions/v1-host-boundary-migration.md— what the migration did and whydocs/system/freeze-v1.md— what's frozen at the symbol leveldocs/system/host-boundary.md— full invariant specification with §9 rule-ID reconciliation and §11 claim verificationdocs/ledger/decisions/s2.{1,2,3}-plan.mdfor per-change contextdocs/ledger/decisions/session-2-closure-audit.mdfor the closure verification