From dc7bfd0850d1c82748c25029c1b088c519189c7b Mon Sep 17 00:00:00 2001 From: Kostandin Angjellari Date: Thu, 2 Jul 2026 01:00:45 +0200 Subject: [PATCH] FE-1089: Sync planning docs at orchestrator-cutover close ln-sync at arc close: record the completed D101-L port cutover in SPEC (D101-L row, I56-L rewrite, requirement 26, ExecutionPorts lexicon row, worker content-quality blind spot), thin the five D101-L refinement blockquotes to src/executor/TOPOLOGY.md pointers, archive done frontier definitions to PLAN_HISTORY, close the orchestrator-cutover arc in PLAN, acknowledge in-flight FE-1116/FE-1115 (PRs #280/#281), reconcile executor topology headers, fix the stale I52-L comment to I56-L, and delete 11 exhausted scope cards. --- ...xecutor-agent-runner--agent-runner-port.md | 63 ---------- ...gent-runner--default-runner-composition.md | 16 --- ...ecutor-agent-runner--sealed-code-worker.md | 66 ----------- ...utor-agent-runner--worker-witness-probe.md | 16 --- ...xecutor-host-promotion--apply-hardening.md | 51 -------- .../executor-host-promotion--host-apply.md | 61 ---------- .../cards/executor-host-promotion--pi-tool.md | 61 ---------- .../executor-host-promotion--preflight.md | 59 --------- ...-promotion--promotion-metadata-recovery.md | 47 -------- ...utor-promotion--run-local-git-land-port.md | 65 ---------- ...orchestrator-tool-port--plan-check-tool.md | 112 ------------------ src/agents/runtime/executor/active-tools.ts | 4 +- src/executor/TOPOLOGY.md | 6 +- 13 files changed, 5 insertions(+), 622 deletions(-) delete mode 100644 memory/cards/executor-agent-runner--agent-runner-port.md delete mode 100644 memory/cards/executor-agent-runner--default-runner-composition.md delete mode 100644 memory/cards/executor-agent-runner--sealed-code-worker.md delete mode 100644 memory/cards/executor-agent-runner--worker-witness-probe.md delete mode 100644 memory/cards/executor-host-promotion--apply-hardening.md delete mode 100644 memory/cards/executor-host-promotion--host-apply.md delete mode 100644 memory/cards/executor-host-promotion--pi-tool.md delete mode 100644 memory/cards/executor-host-promotion--preflight.md delete mode 100644 memory/cards/executor-promotion--promotion-metadata-recovery.md delete mode 100644 memory/cards/executor-promotion--run-local-git-land-port.md delete mode 100644 memory/cards/orchestrator-tool-port--plan-check-tool.md diff --git a/memory/cards/executor-agent-runner--agent-runner-port.md b/memory/cards/executor-agent-runner--agent-runner-port.md deleted file mode 100644 index 9f48d22a1..000000000 --- a/memory/cards/executor-agent-runner--agent-runner-port.md +++ /dev/null @@ -1,63 +0,0 @@ -# executor-agent-runner — AgentRunnerPort contract slice - -## Orientation - -- Containing seam: `orchestrator-cutover` real-execution substrate, after `executor-sandbox` proved real git worktrees and real verify subprocesses behind injected capability ports. -- Frontier item: `executor-agent-runner` (FE-1111) on `ka/fe-1111-executor-agent-runner`, stacked on `ka/fe-1109-cook-sandbox`. -- Handoff state: no `HANDOFF.md` present; parent branch says FE-1109 is built and ready to tie off. -- Main open risk: the write-capable CODE worker must reuse the D90-L-D93-L sealed subagent substrate without punching an ambient write/shell hole into executor core or resurrecting prewritten `result.json` ingest. - -## Scope Weight - -Full scope card. This slice establishes the LLM-bearing execution-port seam and crosses executor core, Pi tool registration, app composition, and the sealed subagent substrate. - -## Target Behavior - -`execute_agent_result` runs an injected `AgentRunnerPort` for the active requested slice and records the runner's real output as the slice agent result. - -## Boundary Crossings - -```text -execute_agent_result Pi tool -→ src/executor/agent-result.ts -→ src/executor/execution-ports.ts AgentRunnerPort contract -→ injected app-layer runner implementation/fake -→ run worktree agent-output/report metadata -``` - -## Risks and Assumptions - -- RISK: implementing the real write-capable worker and the orchestration transition in one slice obscures whether the port boundary is right. → MITIGATION: first prove the port contract and Pi injection with a fake runner; leave the concrete CODE worker body/catalog for the next slice. -- RISK: the old prewritten-file path remains live and masks that no worker ran. → MITIGATION: remove `missing_agent_result` / `readFile(result.json)` behavior from the tool path; focused tests must fail if no runner is injected or if the runner is not invoked. -- ASSUMPTION: `slice_execution_requested` metadata already carries enough context for the runner contract: run id, active epic/slice, worktree path, and request artifact path. → VALIDATE: the port args asserted in executor tests include those fields and no app/Pi imports enter `src/executor`. -- ASSUMPTION: a runner execution failure should not advance run metadata, matching `GitWorktreePort` and `TestRunnerPort` failure posture. → VALIDATE: focused failure test returns an explicit failure status with `sideEffects: []` and leaves `run.json` unchanged. - -## Acceptance Criteria - -✓ `src/executor/__tests__/agent-result.test.ts` — `ingestAgentResult` invokes an injected `AgentRunnerPort`, appends `slice_agent_result`, records `agentResultPath` / runner summary, and never reads a prewritten `agent-output//result.json`. - -✓ `src/executor/__tests__/agent-result.test.ts` — runner failure returns an explicit non-advancing status with no side effects and preserves `status:"slice_execution_requested"`. - -✓ `src/.pi/extensions/__tests__/registry.test.ts` — the registered `execute_agent_result` tool is wired with the injected fake runner and no longer describes itself as prewritten-result ingestion. - -✓ `src/executor/execution-ports.ts` — `AgentRunnerPort` has concrete arg/result types and executor core still imports no `src/app`, `.pi`, git, subprocess, or SDK implementation modules. - -## Verification Approach - -- Inner: focused Vitest contract tests for `agent-result` and Pi registry injection prove the port call, metadata transition, side-effect report, and failure posture. -- Middle: `npm run fix` after edits proves lint/format and catches type-aware seam drift. -- Gate: `npm run verify` before commit. - -## Promotion Checklist - -- [x] Does this change a requirement? It materializes D99-L's `AgentRunnerPort` layer. -- [ ] Does this create, retire, or invalidate an assumption? -- [x] Does this make or reverse a non-trivial design decision? It chooses the first runner transition shape: injected runner result instead of prewritten file ingest. -- [x] Does this establish a new seam-level invariant? Runner failure must not advance run metadata; executor core remains implementation-free. -- [x] Does it cross more than two major seams? -- [x] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Build it with `ln-build`. diff --git a/memory/cards/executor-agent-runner--default-runner-composition.md b/memory/cards/executor-agent-runner--default-runner-composition.md deleted file mode 100644 index 5f58f11e5..000000000 --- a/memory/cards/executor-agent-runner--default-runner-composition.md +++ /dev/null @@ -1,16 +0,0 @@ -# executor-agent-runner — default runner composition proof - -## Objective - -Prove `execute_agent_result` uses the default app-composed `AgentRunnerPort` when sealed subagent deps are injected, instead of requiring a manually supplied fake port. - -## Acceptance Criteria - -✓ `src/.pi/extensions/__tests__/registry.test.ts` — `createBrunchPiExtensions` with `subagents` but without an explicit `agentRunner` registers `execute_agent_result` through the default runner. - -✓ The default runner launches the sealed `worker` over the run worktree, observes a real file change in that worktree, writes the result artifact, and preserves the existing metadata/report transition. - -## Verification Approach - -- Inner: focused registry test for default runner composition. -- Gate: `npm run verify`. diff --git a/memory/cards/executor-agent-runner--sealed-code-worker.md b/memory/cards/executor-agent-runner--sealed-code-worker.md deleted file mode 100644 index 3fac5a5f3..000000000 --- a/memory/cards/executor-agent-runner--sealed-code-worker.md +++ /dev/null @@ -1,66 +0,0 @@ -# executor-agent-runner — sealed CODE worker tracer slice - -## Orientation - -- Containing seam: `orchestrator-cutover` real-execution substrate; FE-1111 now has the `AgentRunnerPort` contract and Pi injection path, but the default app-layer runner still fails closed. -- Frontier item: `executor-agent-runner` (FE-1111) on `ka/fe-1111-executor-agent-runner`, stacked on `ka/fe-1109-cook-sandbox`. -- Handoff state: no `HANDOFF.md` present; the built port slice proved `execute_agent_result` no longer reads prewritten `result.json` and failure does not advance metadata. -- Main open risk: the real worker needs Pi execution context plus write capability without reopening ambient `~/.pi`, parent conversation, or unrestricted shell/write access. - -## Scope Weight - -Full scope card. This slice implements the first real write-capable worker over the sealed subagent substrate and may refine the `AgentRunnerPort` args to carry Pi model context. - -## Target Behavior - -`execute_agent_result` can launch a sealed CODE worker that writes a real sandbox-worktree change for the active slice. - -## Boundary Crossings - -```text -execute_agent_result Pi tool -→ AgentRunnerPort args carrying run/worktree/request/result paths plus Pi model context -→ src/app/agent-runner-port.ts concrete runner -→ src/.pi/extensions/subagents sealed child-session runner/catalog -→ src/agents/subagents/worker.md body/frontmatter -→ sandbox worktree file diff -``` - -## Risks and Assumptions - -- RISK: write-capable subagent grants accidentally expose ambient filesystem or shell authority. → MITIGATION: add only a bounded Brunch-owned worktree write/edit tool to the subagent catalog; do not grant shell in this slice. -- RISK: the app-layer runner cannot build a child session from the port args because model/modelRegistry/signal currently live in the Pi tool execution context, not the core run metadata. → MITIGATION: thread only the required Pi execution context through `execute_agent_result` into `AgentRunnerPort.run`; keep executor core unaware of SDK implementation types where possible and isolate SDK-specific types to the Pi/app boundary if needed. -- RISK: a live model run is too expensive/flaky for the inner loop. → MITIGATION: prove the worker through the existing injectable child-session/faux-provider path, with a deterministic fake child that calls the bounded write tool and returns a summary; leave real-provider/manual evidence for a later witness if needed. -- ASSUMPTION: a single bounded write/edit tool is enough to prove real sandbox diffs before adding shell or richer patch application. → VALIDATE: focused test observes an actual file change under the worktree after `execute_agent_result`. - -## Acceptance Criteria - -✓ `src/.pi/extensions/subagents/__tests__/agents.test.ts` or adjacent subagent tests — a `worker` background definition is registry-owned, validates frontmatter, and is not spawnable by SPEC/elicitor delegation. - -✓ `src/.pi/extensions/subagents/__tests__/agents.test.ts` or adjacent subagent tests — the worker grant resolves only bounded worktree read/write tools needed for this tracer and does not include shell, ambient discovery, graph mutation, or `subagent` nesting. - -✓ `src/app/__tests__/agent-runner-port.test.ts` — the concrete app-layer `AgentRunnerPort` launches the sealed worker over the requested worktree and produces an actual file change under that worktree using a deterministic fake child-session path. - -✓ `src/.pi/extensions/__tests__/registry.test.ts` — `execute_agent_result` threads the required Pi model context/signal into the injected runner while preserving the existing metadata/report transition and failure posture. - -✓ `src/executor/agent-result.ts` / architecture checks — executor core remains free of `src/app`, `.pi`, SDK, git, subprocess, and shell implementation imports. - -## Verification Approach - -- Inner: focused Vitest tests for subagent definition/catalog grants, app-layer runner contract, and Pi registry context threading. -- Middle: `npm run fix` after edits. -- Gate: `npm run verify` before commit. - -## Promotion Checklist - -- [x] Does this change a requirement? It materializes FE-1111's real change-producing worker layer. -- [x] Does this create, retire, or invalidate an assumption? It validates whether bounded write/edit authority is enough before shell. -- [x] Does this make or reverse a non-trivial design decision? It chooses a bounded worktree write/edit tracer rather than immediate shell authority. -- [x] Does this establish a new seam-level invariant? Worker write authority is catalog-bounded and op-mode/delegation-gated, not ambient. -- [x] Does it cross more than two major seams? -- [ ] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Build it with `ln-build`. diff --git a/memory/cards/executor-agent-runner--worker-witness-probe.md b/memory/cards/executor-agent-runner--worker-witness-probe.md deleted file mode 100644 index 43e65ccec..000000000 --- a/memory/cards/executor-agent-runner--worker-witness-probe.md +++ /dev/null @@ -1,16 +0,0 @@ -# executor-agent-runner — worker witness probe - -## Objective - -Add a runnable witness probe for the default executor agent-runner path. - -## Acceptance Criteria - -✓ `src/probes/__tests__/executor-agent-runner-witness.test.ts` — runs the default `AgentRunnerPort` through the sealed `worker` over a faux provider and observes an actual worktree write via `write_worktree_file`. - -✓ Probe artifact writer persists portable request/result/proof/report files under `runs/executor-agent-runner-witness//` when given a fixture root. - -## Verification Approach - -- Inner: focused witness probe tests. -- Gate: `npm run verify`. diff --git a/memory/cards/executor-host-promotion--apply-hardening.md b/memory/cards/executor-host-promotion--apply-hardening.md deleted file mode 100644 index 4799a7044..000000000 --- a/memory/cards/executor-host-promotion--apply-hardening.md +++ /dev/null @@ -1,51 +0,0 @@ -# executor-host-promotion — host apply hardening slice - -## Orientation - -- Containing seam: `executor-host-promotion` (FE-1118), after helper/app/Pi host promotion surfaces are built. -- Frontier item: `executor-host-promotion` on `ka/fe-1118-executor-host-promotion`, stacked on `ka/fe-1112-executor-promotion`. -- Review trigger: `ln-review` found the real `git apply` stdin boundary lacks an integration oracle, the apply result type admits an impossible state, and a dead path alias remains. - -## Scope Weight - -Light scope card. This is bounded hardening inside the established FE-1118 host-promotion seam. - -## Objective - -Harden host apply by proving the real git patch path and tightening the public apply result shape. - -## Acceptance Criteria - -✓ `src/app/__tests__/git-host-promotion-port.test.ts` uses real temp git repositories to prove a promoted commit patch applies to host files without changing host HEAD or staging the index. - -✓ `src/app/__tests__/git-host-promotion-port.test.ts` uses real temp git repositories to prove conflicting host edits fail at `git apply --check` without mutating host files. - -✓ `HostPromotionApplyResult` excludes the impossible `preflight_ready` pass-through state. - -✓ The unused `hostPromotionReportPath` alias is deleted unless a real caller exists. - -## Verification Approach - -- Inner: focused Vitest tests for `git-host-promotion-port` and `host-promotion` type/behavior coverage. -- Gate: `npm run verify`. - -## Build Result - -- Done: real temp-git success and conflict tests cover the app-layer patch path. -- Done: `HostPromotionApplyResult` excludes `preflight_ready`. -- Done: unused `hostPromotionReportPath` alias deleted. -- Verification: focused host-promotion tests pass; full gate pending at the time this card was reconciled. - -## Promotion Checklist - -- [ ] Does this change a requirement? -- [ ] Does this create, retire, or invalidate an assumption? -- [ ] Does this make or reverse a non-trivial design decision? -- [ ] Does this establish a new seam-level invariant? -- [ ] Does it cross more than two major seams? -- [ ] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Build it with `ln-build`. diff --git a/memory/cards/executor-host-promotion--host-apply.md b/memory/cards/executor-host-promotion--host-apply.md deleted file mode 100644 index 2c7c063ec..000000000 --- a/memory/cards/executor-host-promotion--host-apply.md +++ /dev/null @@ -1,61 +0,0 @@ -# executor-host-promotion — explicit host apply slice - -## Orientation - -- Containing seam: `executor-host-promotion` (FE-1118), after preflight established read-only diff inspection. -- Frontier item: `executor-host-promotion` on `ka/fe-1118-executor-host-promotion`, stacked on `ka/fe-1112-executor-promotion`. -- Main risk: this is the first deliberate host-file mutation; branch/ref/index mutation must still stay out of scope. - -## Scope Weight - -Full scope card. This crosses the hard host-mutation boundary and establishes the explicit-acceptance apply seam. - -## Target Behavior - -Host apply mutates the host worktree to match a validated promoted run diff after explicit acceptance. - -## Boundary Crossings - -```text -future host-promotion Pi tool or core helper -→ run metadata / promotion.json -→ host-promotion preflight -→ run worktree promoted commit patch -→ host worktree file mutation report -``` - -## Risks and Assumptions - -- RISK: apply mutates the wrong host state or stale promotion. → MITIGATION: rerun preflight inside apply and require the accepted commit SHA to match the current promoted SHA before mutation. -- RISK: apply clobbers local host edits. → MITIGATION: app-layer apply must run a no-write check first and fail closed when the patch cannot apply cleanly. -- RISK: apply accidentally creates a commit, branch, ref, or staged index state. → MITIGATION: tests assert host HEAD/ref and index remain unchanged; only host worktree files may change. -- ASSUMPTION: applying the promoted commit patch to the host worktree without committing is the right first host-mutation layer. → VALIDATE: focused tests prove accepted apply changes files and leaves branch/ref/index unchanged. - -## Acceptance Criteria - -✓ Core apply returns `needs_acceptance` without side effects when no accepted commit SHA is supplied. - -✓ Core apply reruns preflight and refuses stale or mismatched accepted commit SHA before mutation. - -✓ App/core apply checks the promoted patch before writing and reports `apply_failed` without host file/index/ref mutation on conflicts. - -✓ App/core apply changes only host worktree files for the promoted diff; it does not commit, create refs, switch branches, or stage the host index. - -## Verification Approach - -- Inner: focused Vitest tests for explicit acceptance, stale metadata, conflict/no-write failure, and successful host file mutation with unchanged HEAD/ref/index. -- Gate: `npm run verify`. - -## Promotion Checklist - -- [x] Does this change a requirement? It materializes FE-1118's first accepted host-file mutation layer. -- [x] Does this create, retire, or invalidate an assumption? It validates that patch-to-worktree without commit/ref/index mutation is the right first host apply layer. -- [x] Does this make or reverse a non-trivial design decision? It chooses host worktree patch application before any host commit/ref operation. -- [x] Does this establish a new seam-level invariant? Host apply requires accepted commit SHA confirmation and reruns preflight before mutation. -- [x] Does it cross more than two major seams? -- [ ] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Scope Pi tool exposure if FE-1118 needs user-drivable CODE-mode host apply before tie-off. diff --git a/memory/cards/executor-host-promotion--pi-tool.md b/memory/cards/executor-host-promotion--pi-tool.md deleted file mode 100644 index a25822dc2..000000000 --- a/memory/cards/executor-host-promotion--pi-tool.md +++ /dev/null @@ -1,61 +0,0 @@ -# executor-host-promotion — Pi tool exposure slice - -## Orientation - -- Containing seam: `executor-host-promotion` (FE-1118), after helper-level preflight and accepted host-file apply are built. -- Frontier item: `executor-host-promotion` on `ka/fe-1118-executor-host-promotion`, stacked on `ka/fe-1112-executor-promotion`. -- Main risk: exposing host mutation to CODE mode must preserve explicit acceptance and make side effects inspectable at the Pi tool boundary. - -## Scope Weight - -Full scope card. This exposes the host-mutation helper through the user/agent tool surface and crosses the Pi adapter boundary. - -## Target Behavior - -CODE mode can run host-promotion preflight and accepted host apply through explicit Pi tools. - -## Boundary Crossings - -```text -CODE-mode Pi tool call -→ .pi agent-runtime registrar -→ executor host-promotion helper -→ GitHostPromotionPort -→ tool result details / side-effect report -``` - -## Risks and Assumptions - -- RISK: host apply becomes callable without explicit acceptance. → MITIGATION: the apply tool must require `acceptedCommitSha` and return `needs_acceptance` / `acceptance_mismatch` without mutation when absent or stale. -- RISK: tool result hides host mutation side effects. → MITIGATION: details must preserve the helper result and sideEffects array exactly, and content must summarize changed files and side effects. -- RISK: default app composition forgets the new port/tool wiring. → MITIGATION: registry tests inject a fake `GitHostPromotionPort` and prove both tools register and call it. -- ASSUMPTION: two explicit tools (`execute_host_promotion_preflight`, `execute_host_promotion_apply`) are clearer than overloading `execute_promotion_prepare`. → VALIDATE: focused registry tests prove separate no-mutation and mutation surfaces with distinct parameter shapes. - -## Acceptance Criteria - -✓ Pi registry exposes `execute_host_promotion_preflight` when `GitHostPromotionPort` is injected and returns the preflight helper result with `sideEffects: []`. - -✓ Pi registry exposes `execute_host_promotion_apply` when `GitHostPromotionPort` is injected and requires `acceptedCommitSha` before host mutation. - -✓ Apply tool result preserves `host_worktree_apply` side effects and changed files in machine-readable details. - -✓ Default extension composition wires the concrete app `GitHostPromotionPort` alongside existing execution ports without changing existing execute tool behavior. - -## Verification Approach - -- Inner: focused Vitest registry tests for tool registration, parameter handling, result details, and explicit-acceptance failure. -- Gate: `npm run verify`. - -## Promotion Checklist - -- [x] Does this change a requirement? It makes FE-1118 host promotion user-drivable from CODE mode. -- [x] Does this create, retire, or invalidate an assumption? It validates that separate preflight/apply tools are clearer than overloading run-local promotion prepare. -- [x] Does this make or reverse a non-trivial design decision? It exposes accepted host-file mutation at the Pi adapter boundary while preserving the helper seam. -- [x] Does this establish a new seam-level invariant? Host apply remains explicit-acceptance gated at the tool boundary and reports side effects in details. -- [x] Does it cross more than two major seams? -- [ ] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Review or tie off FE-1118. diff --git a/memory/cards/executor-host-promotion--preflight.md b/memory/cards/executor-host-promotion--preflight.md deleted file mode 100644 index 47e851d0e..000000000 --- a/memory/cards/executor-host-promotion--preflight.md +++ /dev/null @@ -1,59 +0,0 @@ -# executor-host-promotion — host preflight slice - -## Orientation - -- Containing seam: `executor-host-promotion` (FE-1118), after FE-1112 built run-local promotion and recovery. -- Frontier item: `executor-host-promotion` on `ka/fe-1118-executor-host-promotion`, stacked on `ka/fe-1112-executor-promotion`. -- Main risk: host branch mutation is the externally visible, hard-to-reverse seam; first slice must inspect only. - -## Scope Weight - -Full scope card. This establishes the host-promotion boundary while deliberately keeping mutation out of scope. - -## Target Behavior - -Host promotion preflight validates a run-local promotion and reports the host diff that would be applied without changing the host branch. - -## Boundary Crossings - -```text -future host-promotion Pi tool or core helper -→ run metadata / promotion.json -→ run worktree git commit/diff inspection -→ host preflight report -``` - -## Risks and Assumptions - -- RISK: preflight accidentally mutates host files, refs, branch, or index. → MITIGATION: tests assert host cwd contents and git status are unchanged. -- RISK: preflight trusts stale promotion metadata. → MITIGATION: validate `promotionCommitSha` / `promotion.json` against the run worktree before producing an applyable diff report. -- ASSUMPTION: a diff/report-only slice is enough to make the host apply seam reviewable before mutation. → VALIDATE: focused tests prove the report contains the promoted SHA and changed files while host state is unchanged. - -## Acceptance Criteria - -✓ Core preflight returns `missing_run`, `run_not_promoted`, or `promotion_not_found` without side effects for invalid inputs. - -✓ Core preflight validates `run.json.promotionCommitSha` and `promotion.json.land.commitSha` agree. - -✓ App/core preflight computes the promoted worktree diff against its parent/base and reports changed files / patch summary without mutating the host cwd. - -✓ No host branch/ref/index/file mutation occurs in this slice. - -## Verification Approach - -- Inner: focused Vitest tests for preflight success, stale metadata, and no host mutation. -- Gate: `npm run verify`. - -## Promotion Checklist - -- [x] Does this change a requirement? It materializes FE-1118's inspection-only host-promotion boundary. -- [x] Does this create, retire, or invalidate an assumption? It validates that a preflight-only slice can make host apply reviewable before mutation. -- [x] Does this make or reverse a non-trivial design decision? It chooses read-only run-worktree diff inspection before explicit host apply. -- [x] Does this establish a new seam-level invariant? Host-promotion preflight must not mutate host files, refs, or index state. -- [x] Does it cross more than two major seams? -- [ ] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Scope the explicit host-apply slice with `ln-scope`. diff --git a/memory/cards/executor-promotion--promotion-metadata-recovery.md b/memory/cards/executor-promotion--promotion-metadata-recovery.md deleted file mode 100644 index 77f6de0ab..000000000 --- a/memory/cards/executor-promotion--promotion-metadata-recovery.md +++ /dev/null @@ -1,47 +0,0 @@ -# executor-promotion — promotion metadata recovery - -## Orientation - -- Containing seam: `executor-promotion` (FE-1112), after run-local `GitLandPort` landed. -- Review finding: `preparePromotion` performs the run-local git commit before writing `promotion.json` and updating `run.json`. -- Main risk: if `promotion.json` or `run.json` persistence fails after the git commit, retry sees a clean worktree and returns `promotion_no_changes`, leaving the run stuck at `petri_exported` despite a promoted commit existing. - -## Scope Weight - -Full scope card. This fixes a failure-mode invariant at the first real git mutation seam. - -## Target Behavior - -`execute_promotion_prepare` can recover or idempotently complete promotion metadata after a prior successful run-local git commit. - -## Boundary Crossings - -```text -execute_promotion_prepare Pi tool -→ src/executor/promotion.ts -→ GitLandPort result/recovery contract -→ promotion.json / run.json persistence -``` - -## Risks and Assumptions - -- RISK: no-change retry hides a prior successful promotion commit. → MITIGATION: teach the promotion path to distinguish “no changes because already promoted” from “nothing was ever promoted,” using durable promotion metadata or a port-reported current commit. -- RISK: recovery logic re-derives run topology. → MITIGATION: recovery may use only existing run metadata, worktree commit identity, and promotion artifact paths; it must not inspect or rewrite plan/Petri topology. -- ASSUMPTION: recording the promoted commit SHA before or during report persistence is enough to make retry safe. → VALIDATE: focused test simulates commit success followed by persistence failure, then reruns promotion and observes `promotion_prepared` with the same SHA. - -## Acceptance Criteria - -✓ `src/executor/__tests__/promotion.test.ts` — simulates successful `GitLandPort` commit followed by failed promotion metadata persistence; retry completes `promotion.json` / `run.json` instead of returning `promotion_no_changes`. - -✓ `src/app/__tests__/git-land-port.test.ts` — app-layer port exposes enough commit identity on a clean already-promoted worktree, or the core recovery path does not require app-layer changes because commit identity is already durable. - -✓ Failure paths that truly have no prior promoted commit still do not advance metadata. - -## Verification Approach - -- Inner: focused promotion recovery tests. -- Gate: `npm run verify`. - -## Recommended Next Route - -Build it with `ln-build`. diff --git a/memory/cards/executor-promotion--run-local-git-land-port.md b/memory/cards/executor-promotion--run-local-git-land-port.md deleted file mode 100644 index 1c2fee6a9..000000000 --- a/memory/cards/executor-promotion--run-local-git-land-port.md +++ /dev/null @@ -1,65 +0,0 @@ -# executor-promotion — run-local GitLandPort slice - -## Orientation - -- Containing seam: `orchestrator-cutover` real-execution substrate; `executor-sandbox` supplies a real git worktree and real verify runner, and `executor-agent-runner` supplies a sealed worker that can make sandbox diffs. -- Frontier item: `executor-promotion` (FE-1112) on `ka/fe-1112-executor-promotion`, stacked on `ka/fe-1111-executor-agent-runner`. -- Handoff state: FE-1111 is complete; `execute_promotion_prepare` is still descriptive and `execute_status.pendingTools` still reports `land`. -- Main open risk: promotion is the first hard-to-reverse git seam, so the first slice must stay run-local and consume existing run artifacts instead of touching host branches. - -## Scope Weight - -Full scope card. This slice establishes the `GitLandPort` capability boundary and changes the promotion seam from descriptive-only to a real, run-local git mutation. - -## Target Behavior - -`execute_promotion_prepare` promotes a completed run's verified sandbox worktree diff through an injected `GitLandPort` without mutating host branches. - -## Boundary Crossings - -```text -execute_promotion_prepare Pi tool -→ src/executor/promotion.ts -→ src/executor/execution-ports.ts GitLandPort contract -→ src/app/git-land-port.ts app-layer git implementation -→ run worktree git state / promotion artifact -``` - -## Risks and Assumptions - -- RISK: host branch/ref mutation sneaks into the first land slice. → MITIGATION: `GitLandPort` first supports run-local promotion only; tests assert no host `.git` branch/ref mutation and no writes outside the run/worktree/promotion paths. -- RISK: promotion re-derives run state and diverges from Petri/report artifacts. → MITIGATION: require `promotion_prepared` inputs to come from existing run metadata, Petri artifact, completed slices, and worktree path; no fresh plan topology derivation. -- RISK: no-op worktrees make promotion look successful without a diff. → MITIGATION: first port result must report an explicit `no_changes` / failure-style status that does not advance metadata, or a real promoted commit/ref artifact with changed files. -- ASSUMPTION: run-local commit/ref is enough to unlock the next reviewable layer before host promotion. → VALIDATE: focused tests prove a diff in the run worktree becomes a run-local promotion artifact, while host branch promotion remains absent. - -## Acceptance Criteria - -✓ `src/executor/__tests__/promotion.test.ts` — `preparePromotion` invokes an injected `GitLandPort` for a Petri-exported run with a worktree and records a real run-local promotion result. - -✓ `src/executor/__tests__/promotion.test.ts` — `GitLandPort` failure or no changes do not advance run metadata and report no side effects. - -✓ `src/app/__tests__/git-land-port.test.ts` — app-layer `GitLandPort` performs only run-local git operations inside the worktree/promotion area and returns the promoted commit/ref metadata. - -✓ `src/.pi/extensions/__tests__/registry.test.ts` — `execute_promotion_prepare` is wired with injected `GitLandPort`; `execute_status.pendingTools` remains `land` until the run-local layer is accepted as enough to drop it. - -✓ `src/executor/promotion.ts` / architecture checks — executor core imports no app, Pi, git, subprocess, or UI modules. - -## Verification Approach - -- Inner: focused Vitest tests for promotion core, app-layer git port, and Pi registry injection. -- Middle: `npm run fix`. -- Gate: `npm run verify`. - -## Promotion Checklist - -- [x] Does this change a requirement? It materializes FE-1112's first real promotion layer. -- [x] Does this create, retire, or invalidate an assumption? It validates whether run-local promotion is enough before host promotion. -- [x] Does this make or reverse a non-trivial design decision? It chooses run-local git promotion before host branch mutation. -- [x] Does this establish a new seam-level invariant? First promotion slice must not mutate host branches/refs. -- [x] Does it cross more than two major seams? -- [ ] Is this the first touch in an unfamiliar seam from a fresh thread? -- [ ] Can you not name the containing seam or current rationale from the live docs? - -## Recommended Next Route - -Build it with `ln-build`. diff --git a/memory/cards/orchestrator-tool-port--plan-check-tool.md b/memory/cards/orchestrator-tool-port--plan-check-tool.md deleted file mode 100644 index 52341ca7a..000000000 --- a/memory/cards/orchestrator-tool-port--plan-check-tool.md +++ /dev/null @@ -1,112 +0,0 @@ -# Orchestrator Plan Check Tool - -Frontier: orchestrator-tool-port -Status: active -Mode: single -Created: 2026-06-25 - -## Orientation - -- Containing seam: the foreground `executor` agent in target-CODE / current-`execute` mode and the `.pi/extensions` adapter boundary; this slice replaces the branch-local standup stub with the first real cook-plan inspection tool. -- Relevant frontier item: `orchestrator-tool-port` / FE-1107, inherited as the Linear issue and branch boundary from `memory/PLAN.md`. -- Volatile handoff state: none in `HANDOFF.md` (absent); source context comes from the prior port analysis and the external `../brunch` orchestrator docs/source. -- Main open risk: accidentally importing the CLI's execution side effects before the read-only tool boundary is proved; preserve the D39-L sealed profile and D90-L-D93-L/I49-L code-owned authority model. - -Posture: proving (inherited from `orchestrator-tool-port`) - -## Target Behavior - -The foreground executor can inspect a cook plan through a product-registered, read-only `cook_plan_check` tool whose result contains plan shape plus contract findings. - -## Full-card cold-start reads - -- `memory/SPEC.md` — decisions / invariants: D39-L, D40-L, D90-L, D91-L, D92-L, D93-L, I49-L. -- `memory/PLAN.md` — frontier: `orchestrator-tool-port`. -- `src/.pi/extensions/TOPOLOGY.md` — adapter-only ownership and boundary rules. -- `src/agents/prompts/executor.md` — current execute-mode foreground prompt and stub wording to retire. -- `src/agents/runtime/executor/TOPOLOGY.md` and `src/agents/runtime/TOPOLOGY.md` — current CODE-mode runtime split; execute tool policy is a live runtime seam under `runtime/executor/`, and new execute seams should stay in that live runtime tree. -- `src/session/schema/tool-names.ts` — shared tool-name constants. -- `/Users/lunelson/Code/hashintel/brunch/ORCHESTRATOR.md` — source CLI behavior and plan format. -- `/Users/lunelson/Code/hashintel/brunch/src/orchestrator/src/{types.ts,plan-loader.ts,plan-contract.ts,cook-cli.ts}` — portable plan model, loader, contract, and plan-resolution behavior to adapt. -- `docs/design/CUELOOP_PATTERN_LIFTOUT.md` — second, independent prior-art reference: patterns worth stealing from CueLoop (phase model, runnability, resumable runs, preflight gates, ledger-vs-supervisor decoupling) with steal/skip verdicts against D98-L, D39-L, D4-L/D6-L/D16-L. Advisory only. - -## Boundary Crossings - -```text -→ foreground `executor` prompt/control assembly -→ executor active-tool allowlist + blocked-tool guard (do not reintroduce a second legacy runtime-policy tree) -→ `.pi/extensions/agent-runtime` Pi tool adapter -→ product-owned `src/orchestrator` plan loader + contract core -→ workspace cook plan path -→ typed Pi tool result content/details -``` - -## Risks and Assumptions - -- RISK: CLI code pulls in process exits, git worktree creation, model auth, or child Pi sessions too early → MITIGATION: port only pure/read-only plan loading and contract checking in this slice; no sandbox, engine, Petrinaut stream, or worker session imports. -- RISK: The foreground `executor` gains accidental write authority while replacing the stub → MITIGATION: keep `bash`, `edit`, and `write` blocked in the Pi runtime tool-call guard; register only the read-only `cook_plan_check` tool for this card. -- RISK: External source names leak as temporary compatibility aliases → MITIGATION: canonicalize the product-facing tool name now; delete the `orchestrator_stub` tool path when the real tool is registered. -- ASSUMPTION: The external cook plan contract is the right first tracer boundary for the port. - → IMPACT IF FALSE: the later `cook_run` surface may need a different plan source/result model, but this slice's blast radius is limited to read-only validation and prompt/tool naming. - → VALIDATE: focused tests over valid, malformed, and design-invalid plan fixtures plus runtime-policy assertions. - -## Posture check - -This is a proving tracer. It scores on proof of life by making execute mode call real cook-plan product code, on invariants by locking the foreground no-direct-write boundary while still exposing orchestration capability, and on uncertainty by testing that the external `brunch cook` plan contract can be ported without shell-wrapping the CLI. - -No separate spike is cheaper than this slice: the useful proof is whether the product registry, prompt, runtime policy, and plan contract all line up through the real execute-mode tool boundary. - -## Acceptance Criteria - -✓ `cook_plan_check` is product-registered for execute mode and returns a typed result for a valid plan path containing mode, epic count, slice count, policy-relevant findings, and source path. -✓ Invalid or contract-failing plans return deterministic typed findings/errors without creating `.brunch/cook/runs`, git worktrees, Petrinaut artifacts, or child Pi sessions. -✓ The branch-local executor stub is no longer advertised to the foreground executor, and the old stub registration path is retired. -✓ The Pi runtime tool-call guard still blocks direct `bash`, `edit`, and `write` for the foreground executor, with tests or assertions covering the new tool grant. -✓ `src/agents/prompts/executor.md` tells the foreground agent to use the real plan-check tool and preserves the no-direct-write instruction. - -## Verification Approach - -- Inner: focused unit/contract tests — plan loader/contract result shape, tool execution result, runtime policy grant/block invariants. -- Middle: `npm run fix` — project lint/format after edits. -- Gate: `npm run verify` — full fix/test/build before tying off the branch. - -## Cross-cutting obligations - -- Preserve D39-L sealed-profile discipline: no ambient Pi discovery, dynamic import scanning, or shell-wrapped CLI escape hatch. -- Preserve D90-L-D93-L/I49-L authority: foreground `executor` remains low-privilege; any future write-capable worker must be code-owned and explicitly allowlisted. -- Keep `.pi/extensions` adapter-only: reusable plan-contract logic belongs in product core, not hidden extension memory. -- Treat `.brunch/cook/runs/` as an execution artifact for later `cook_run`, not an artifact this read-only slice creates. - -## Expected touched paths (tentative) - -```text -memory/ -├── PLAN.md ~ -└── cards/ - └── orchestrator-tool-port--plan-check-tool.md + -src/ -├── orchestrator/ -│ ├── plan-contract.ts + -│ ├── plan-loader.ts + -│ ├── types.ts + -│ └── __tests__/ -│ └── plan-check.test.ts + -├── agents/ -│ ├── prompts/ -│ │ └── executor.md ~ -│ └── runtime/ -│ ├── TOPOLOGY.md ~ -│ └── shared/ or executor/ ? (new live execute policy seam if earned) -├── .pi/ -│ ├── extensions/ -│ │ ├── agent-runtime/ ~ -│ │ └── agent-runtime/orchestrator-stub/ - -│ └── __tests__/ ? -├── app/ -│ └── pi-extensions.ts ~ -└── session/ - └── schema/ - └── tool-names.ts ~ -package.json ? -package-lock.json ? -``` diff --git a/src/agents/runtime/executor/active-tools.ts b/src/agents/runtime/executor/active-tools.ts index 67a102918..5caf4b8b4 100644 --- a/src/agents/runtime/executor/active-tools.ts +++ b/src/agents/runtime/executor/active-tools.ts @@ -12,8 +12,8 @@ export const EXECUTOR_ALLOWED_TOOL_NAMES = [ 'read_session_context', 'read_graph', 'orchestrator_stub', - // Execute-mode orchestration footholds (FE-1089). Registered-but-inactive - // unless the executor admits them; side-effect-bounded per I52-L. + // Execute-mode orchestration tools (FE-1089..FE-1118). Registered tools are + // inactive unless admitted here; side-effect-bounded per I56-L. 'execute_status', 'execute_snapshot', 'execute_plan_check', diff --git a/src/executor/TOPOLOGY.md b/src/executor/TOPOLOGY.md index e88c2fb14..6b62f3b33 100644 --- a/src/executor/TOPOLOGY.md +++ b/src/executor/TOPOLOGY.md @@ -1,10 +1,10 @@ # executor/ — execute-mode projection contracts -SPEC decisions: FE-1089 cutover frontier; `brunch-orchestrator-cutover-to-next.md` Arc 1 data bridge. +SPEC decisions: D101-L (executor cutover over injected ports), D52-L (layer boundary) / I56-L (bounded execute-mode ports). ## Owns -Pure contracts and projection helpers that turn `next` graph facts into execute-mode orchestration inputs. This subtree is product core: it imports graph DTOs and emits stable orchestration DTOs, but it does not register Pi tools, read SQLite, run Petri nets, execute slices, or promote/land changes. +Pure contracts and orchestration helpers that turn `next` graph facts into execute-mode cook runs. This subtree is product core: it imports graph DTOs, owns run metadata/report transitions and the `ExecutionPorts` contract types, but it does not register Pi tools, read SQLite, or own subprocess/git/SDK effects — real capabilities enter only through app-layer port implementations (`src/app/*-port.ts`) injected by Pi composition. ```text executor/ @@ -45,7 +45,7 @@ rules: executor/ x> db/, .pi/, app/, rpc/, web/ [no storage, adapter, transport, or UI effects] ``` -`ExecutionSpecSnapshot` is the durable projection seam between the spec/graph product and the native execute-mode orchestrator. Both `main`-derived imports and `next` graph reads can target this shape while their internal models continue to evolve. Artifact writers in this subtree may write only explicit execution artifacts under `.brunch/execution-reports`; cook helpers may create only the side effects accepted below. They must not run agents, compile Petri nets, write report logs, promotion refs, land branches, or graph mutations. +`ExecutionSpecSnapshot` is the durable projection seam between the spec/graph product and the native execute-mode orchestrator. Both `main`-derived imports and `next` graph reads can target this shape while their internal models continue to evolve. Every helper advances run metadata with at most one explicit, declared side effect (I56-L): plan/outline artifact writers touch only `.brunch/execution-reports`; cook helpers write only the declared files under `.brunch/cook` or the run worktree described per module below; agent/test/promotion effects are delegated to injected ports; port failure leaves run metadata unadvanced. No helper mutates the graph, and host mutation is limited to the accepted-SHA file apply in `host-promotion.ts`. ## Cook plan preview compatibility