Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions memory/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ Brunch-next has delivered the original composition spine: the host, sealed Pi pr

### Active

- `executor-promotion` (FE-1112, `orchestrator-cutover` arc) — **ready to scope.** Last real-execution frontier: inject `GitLandPort` so verified sandbox worktree diffs get promoted, run-local first. Stacks on `ka/fe-1111-executor-agent-runner`.
- `elicitation-gap-guidance` — **proving frontier.** Generate "what next?" gap guidance from graph shape/readiness, distinct from ranking already-registered gaps.

### Recently Completed

- 2026-07-01 `portable-resource-paths--manifest-location` (bugfix, `ln-induct` from PR #273) — skill manifest `location` is now the loader-resolved absolute `Skill.filePath` instead of a hardcoded repo-relative string, so it resolves under any process cwd or `dist/`-only install; dead `liveBrunchSkillRepoPath`/`bundledAgentBodyRepoPath` builders removed; the two prompt-composition goldens normalize the machine root to a `<PKG>/…` token. See SPEC §Acknowledged Blind Spots "Live-vs-harness wiring divergence".
- 2026-07-01 `promoted-run-path-normalization` (tooling) — `.fixtures/runs/**` no longer leaks developer-workstation absolute paths; `npm run check:promoted-run-paths` guards committed evidence going forward. `.fixtures/seeds/**` is untouched (separate seed-curation concern). Not a `fixture-vs-real-audit` sweep.
- 2026-06-30 `orchestrator-alpha-cutover` (FE-1089) — **descriptive cutover scaffold done** (arc member of `orchestrator-cutover`). Landed the `ExecutionSpecSnapshot` projection seam plus the full `fs`-only cook lifecycle simulation through `execute_promotion_prepare`, establishing the thin-Pi-adapter / one-explicit-side-effect-per-tool pattern with zero real execution. Scoping real land surfaced the D101-L land-substrate finding (copied-dir worktree, prewritten-ingested results, no git in core), so real execution + land were reordered into the `executor-sandbox` → `executor-agent-runner` → `executor-land` frontiers.
- 2026-07-01 `executor-promotion` (FE-1112) — **run-local promotion built** (arc member of `orchestrator-cutover`). Added injected `GitLandPort`, app-layer run-local git commit promotion, promotion report commit SHA recording, failure/no-change non-advancement, and `execute_status.pendingTools: []`. Host branch promotion remains explicitly deferred beyond this frontier.
- 2026-07-01 `executor-agent-runner` (FE-1111) — **sealed worker runner built** (arc member of `orchestrator-cutover`). Replaced prewritten `execute_agent_result` ingest with injected `AgentRunnerPort`; added sealed `worker` subagent with bounded `read` + `write_worktree_file` authority; proved default app composition and portable faux-provider witness (`executor-agent-runner-witness`) for worker tool use and sandbox worktree writes. Real-provider content-quality evidence is not a frontier blocker; richer write/shell authority, if needed, should be scoped separately before or after promotion.
- 2026-07-01 `executor-sandbox` (FE-1109) — **real runnable sandbox built** (arc member of `orchestrator-cutover`). Landed `GitWorktreePort` for real per-run git worktrees and `TestRunnerPort` for real verify-subprocess ingestion, completing the no-LLM substrate needed by `executor-agent-runner`.
- 2026-06-30 `structured-exchange-affordance` (FE-1108) — exchange authoring guidance now teaches present-side response rules and review-set nested companions at the boundary; one unearned exchange projection adapter was inlined into its RPC consumer, and topology inventories name the retained model-facing/projection homes.
Expand Down Expand Up @@ -170,18 +170,20 @@ Brunch-next has delivered the original composition spine: the host, sealed Pi pr

### executor-promotion

- **Name:** Reconcile executor promotion
- **Linear:** [FE-1112](https://linear.app/hash/issue/FE-1112/reconcile-executor-promotion) — reconcile executor promotion
- **Branch:** tbd (stacked on `executor-agent-runner`)
- **Name:** Reconcile run-local executor promotion
- **Linear:** [FE-1112](https://linear.app/hash/issue/FE-1112/reconcile-run-local-executor-promotion) — reconcile run-local executor promotion
- **Branch:** `ka/fe-1112-executor-promotion` (stacked on `ka/fe-1111-executor-agent-runner`)
- **Kind:** structural / execute-mode runner substrate (`orchestrator-cutover` arc)
- **Status:** last; the only externally-visible, hard-to-reverse seam.
- **Status:** done.
- **Current execution pointer:** none — frontier complete. Run-local `GitLandPort` and promotion metadata recovery built (`memory/cards/executor-promotion--run-local-git-land-port.md`, `memory/cards/executor-promotion--promotion-metadata-recovery.md`); host promotion remains explicitly deferred beyond this frontier.
- **Certainty:** proving.
- **Why now / unlocks:** only once a run produces real, verified diffs does a truthful land have a source (D99-L land-substrate finding). This layer lands last so the hard-to-reverse git mutation is the final, independently-reviewable step.
- **Objective:** Implement and inject `GitLandPort` so a run's real diffs are promoted — run-local promotion first, host promotion later — consuming/validating the Petri + promotion artifacts rather than re-deriving run state.
- **Acceptance (to refine via `ln-scope`):**
- `GitLandPort` implementation (app layer) performs a run-local promotion of the verified worktree diffs first; host promotion is a later, explicitly-accepted slice.
- The land path consumes/validates the existing Petri + `promotion.json` artifacts rather than re-deriving run state.
- `execute_status` `pendingTools` drops `land` once a real (at minimum run-local, real-git) land exists.
- Done: `GitLandPort` implementation (app layer) performs a run-local promotion of verified worktree diffs first; host promotion is a later, explicitly-accepted slice.
- Done: the promotion path consumes existing Petri/run metadata and writes `promotion.json` with the run-local commit SHA rather than re-deriving run state.
- Done: `execute_status` `pendingTools` drops `land` because real run-local git promotion exists; host promotion remains explicitly deferred beyond this frontier.
- Done: recover/idempotently complete promotion metadata if the run-local git commit succeeds but `promotion.json` or `run.json` persistence fails before status advancement.
- **Traceability:** D39-L, D40-L, D52-L, D98-L, D99-L (land-substrate finding) / I49-L, I52-L; depends on `executor-agent-runner`; `src/executor/TOPOLOGY.md`.

### elicitor-project
Expand Down Expand Up @@ -246,12 +248,6 @@ Brunch-next has delivered the original composition spine: the host, sealed Pi pr
```text
frontiers:
Active:
executor-promotion (FE-1112, orchestrator-cutover arc)
status: ready to scope
depends_on: executor-agent-runner, D99-L land-substrate finding, D52-L, I52-L
ports: GitLandPort
stacks_on: ka/fe-1111-executor-agent-runner

executor-agent-runner (FE-1111, orchestrator-cutover arc)
status: done; sealed worker runner and faux-provider witness built
depends_on: executor-sandbox (FE-1109), D90-L..D93-L, D52-L, I49-L, I56-L
Expand All @@ -269,7 +265,7 @@ frontiers:
depends_on: readiness bands, data-model legibility, elicitor-generate, and a stable exchange affordance surface for asking/proposal loops

Recently Completed:
executor-agent-runner (FE-1111), executor-sandbox (FE-1109), orchestrator-alpha-cutover (FE-1089), structured-exchange-affordance, elicitor-project, spec-structural-relief, renderer-golden-coverage, data-model-legibility
executor-promotion (FE-1112), executor-agent-runner (FE-1111), executor-sandbox (FE-1109), orchestrator-alpha-cutover (FE-1089), structured-exchange-affordance, elicitor-project, spec-structural-relief, renderer-golden-coverage, data-model-legibility

Next:
executor-land (orchestrator-cutover arc)
Expand Down
4 changes: 3 additions & 1 deletion memory/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ The POC's purpose is to prove three things: (a) that pi's coding-agent harness c

> D101-L AgentRunnerPort implementation refinement (2026-07-01, FE-1111): `execute_agent_result` now runs an injected `AgentRunnerPort` for the active requested slice rather than reading a prewritten `agent-output/<sliceId>/result.json`. The executor core (`src/executor/agent-result.ts`) owns only the port type, active run/slice/worktree/request/result paths, Pi model-runtime handoff, the `slice_agent_result` report append, and the metadata transition; the app layer (`src/app/agent-runner-port.ts`) launches the registry-owned sealed `worker` subagent when subagent deps are injected, otherwise failing closed. The worker is a code-owned background definition (`src/agents/subagents/worker.md`) with bounded `read` + `write_worktree_file` authority over the sandbox worktree, no shell, no graph mutation, and no subagent nesting. Runner failure returns `status:"agent_run_failed"` and leaves metadata unchanged (no side effects). The prewritten-file `missing_agent_result` path is removed from this layer; focused tests and the portable faux-provider witness probe prove the contract and a deterministic worker file change, while real-provider/manual worker evidence remains frontier work.

> D101-L GitLandPort run-local promotion refinement (2026-07-01, FE-1112): `execute_promotion_prepare` now runs an injected `GitLandPort` before writing `promotion.json`. The executor core (`src/executor/promotion.ts`) owns only the port type, existing run/Petri/report metadata, promotion report append, and metadata transition; the app layer (`src/app/git-land-port.ts`) owns run-local git operations in the run worktree (`git status --porcelain`, `git add -A`, `git commit`, `git rev-parse HEAD`). This first promotion layer commits verified sandbox worktree diffs locally and records the promoted commit SHA in `promotion.json` / `run.json`; host branch/ref promotion remains deferred. `no_changes` and port failures do not advance run metadata and report no side effects. Because real run-local git promotion exists, `execute_status.pendingTools` is empty; host promotion is explicitly deferred rather than a remaining pending execute foothold.

<!-- Detailed oracle notes were thinned on 2026-06-29. See §Invariant Oracle Coverage and docs/archive/SPEC_HISTORY.md for the pre-slim coverage table. -->

| # | Invariant | Status / oracle anchor | Decision anchor |
Expand Down Expand Up @@ -328,7 +330,7 @@ The POC's purpose is to prove three things: (a) that pi's coding-agent harness c
| I53-L | `session.submitExchangeResponse` review-set approval validates the rehydrated pending `reviewSet` against the canonical `zReviewSetDetailsPayload` schema (owned by `src/.pi/extensions/exchanges/schemas/present.ts`) before constructing a `ReviewSetProposalPayload`; malformed persisted details surface as `structural_illegal` diagnostics rather than an unsafe-cast runtime throw. | covered (`src/rpc/__tests__/handlers.test.ts` malformed-pending-review-set and valid-approval RPC tests) | D27-L; I15-L, I20-L |
| I54-L | Every id in `LIVE_BRUNCH_SKILL_IDS` (`src/agents/skills/registry.ts`) has a packaged `dist/agents/skills/<id>/SKILL.md` after `npm run build`; `scripts/copy-skill-resources.mjs` derives the copy/cleanup list from the compiled registry rather than a second hardcoded id list, so a published install cannot silently miss a live skill's runtime-loaded resource or retain a retired one. | covered (`src/agents/skills/__tests__/registry.test.ts` source-file check always runs; dist-file check runs whenever `dist/` is present, i.e. after `npm run build`) | D39-L, D52-L, D95-L, D100-L |
| I55-L | No committed `.fixtures/runs/**` promoted-evidence file contains an absolute developer-workstation path (`/Users/<user>/…`, `/home/<user>/…`); leaked cwd/prompt-resource/tool-call paths are normalized to a portable placeholder (`<repo>`, `<workbench>`, `<ephemeral-workspace>`, `<external-source>`) that preserves replay/review value without machine-specific roots. `.fixtures/seeds/**` is out of scope — curated source-domain input, not run evidence. | covered (`npm run check:promoted-run-paths` enumerates via `git ls-files .fixtures/runs`, wired into `npm run check`) | requirement 24 |
| I56-L | Execute-mode orchestration footholds remain bounded until the runner frontier explicitly accepts host git mutation. Active CODE-mode tools are read-only and report `sideEffects: []`; writer/lifecycle scaffold tools remain registered/testable but inactive until the real-execution stack lands. Those inactive tools write only declared files under `.brunch/execution-reports` or `.brunch/cook` when invoked directly by tests; `execute_worktree_create` uses injected `GitWorktreePort` for the real `git_worktree_add`, `execute_agent_result` uses injected `AgentRunnerPort` for the active slice's worktree/request/result paths and sealed worker launch, `execute_test_result` uses injected `TestRunnerPort` for the real verify subprocess in the run worktree, and the remaining lifecycle tools update run metadata, markers, reports, Petri export, or promotion-preparation artifacts without mutating the graph, creating host git branches, promoting, or landing. The worker may write only through bounded worktree tools (`write_worktree_file` in this tracer). | covered (`src/.pi/extensions/__tests__/agent-runtime-runtime.test.ts` proves lifecycle tools are inactive in execute mode; `src/.pi/extensions/__tests__/registry.test.ts` and `src/executor/__tests__/*` cover tool registration, side-effect details, bounded paths, port injection, run metadata transitions, and path traversal guards; `src/.pi/extensions/__tests__/subagents.test.ts` proves the worker registry/grant boundary; `src/app/__tests__/agent-runner-port.test.ts`, `src/app/__tests__/git-worktree-port.test.ts`, and `src/app/__tests__/test-runner-port.test.ts` cover app-layer runner/git/verify contracts) | D39-L, D40-L, D52-L, D58-L, D90-L, D91-L, D92-L, D93-L, D98-L, D101-L |
| I56-L | Execute-mode orchestration footholds remain bounded until the runner frontier explicitly accepts host git mutation. Active CODE-mode tools are read-only and report `sideEffects: []`; writer/lifecycle scaffold tools remain registered/testable but inactive until the real-execution stack lands. Those inactive tools write only declared files under `.brunch/execution-reports` or `.brunch/cook` when invoked directly by tests; `execute_worktree_create` uses injected `GitWorktreePort` for the real `git_worktree_add`, `execute_agent_result` uses injected `AgentRunnerPort` for the active slice's worktree/request/result paths and sealed worker launch, `execute_test_result` uses injected `TestRunnerPort` for the real verify subprocess in the run worktree, `execute_promotion_prepare` uses injected `GitLandPort` for run-local worktree promotion, and the remaining lifecycle tools update run metadata, markers, reports, Petri export, or promotion artifacts without mutating the graph, creating host git branches, or promoting to the host. The worker may write only through bounded worktree tools (`write_worktree_file` in this tracer). | covered (`src/.pi/extensions/__tests__/agent-runtime-runtime.test.ts` proves lifecycle tools are inactive in execute mode; `src/.pi/extensions/__tests__/registry.test.ts` and `src/executor/__tests__/*` cover tool registration, side-effect details, bounded paths, port injection, run metadata transitions, and path traversal guards; `src/.pi/extensions/__tests__/subagents.test.ts` proves the worker registry/grant boundary; `src/app/__tests__/agent-runner-port.test.ts`, `src/app/__tests__/git-land-port.test.ts`, `src/app/__tests__/git-worktree-port.test.ts`, and `src/app/__tests__/test-runner-port.test.ts` cover app-layer runner/git/verify contracts) | D39-L, D40-L, D52-L, D58-L, D90-L, D91-L, D92-L, D93-L, D98-L, D101-L |

## Future Direction Register

Expand Down
47 changes: 47 additions & 0 deletions memory/cards/executor-promotion--promotion-metadata-recovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 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`.
Loading
Loading