From 4a3caa36a5d2bde8779ce8ea67eb99c374a1ac59 Mon Sep 17 00:00:00 2001 From: Self-Managing Codebase Manager <7004983+WillTaylor22@users.noreply.github.com> Date: Tue, 26 May 2026 10:29:56 +0000 Subject: [PATCH 1/2] ENG-28: kickoff templates emit plain-text session-id marker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ENG-25 / PR #20 changed the canonical session-id marker shape from `` (HTML comment, stripped by GitHub MCP's body filter) to a plain-text line on its own: session-id: sesn_xxxxxxxxxxxxxxxx …but PR #20 deliberately scoped itself to the convention + extractor and didn't touch the three kickoff/system-prompt sites that tell new sessions what marker to write. Result on main today: each new session gets a kickoff that points at the stripped HTML-comment shape, so agents that follow the kickoff verbatim (instead of the convention doc) emit unrecoverable markers — webhooks can't resume them. Sites updated: - ai-manager/src/tick.ts:43 — CLI kickoff template. - app/api/manager-tick/route.ts:49 — cron kickoff template. - ai-manager/manager.agent.yaml:190-194 — manager system-prompt step 4(l) (sentence rewritten from 'HTML comment' to 'plain-text marker', example updated, cross-ref to ENG-25 added). The webhook regex already accepts the new shape (lib/extract-session-id.ts landed via PR #20); the 13-case unit harness in tests/unit/extract-session-id.spec.ts covers it. Verified locally: - npm run lint — clean. - npm run build — green, route table unchanged. - (cd ai-manager && npx tsc --noEmit) — clean. - BASE_URL=http://localhost:3000 npx playwright test tests/unit — 13/13 pass. Out of scope (per ticket): the YAML→agent sync. ai-manager/src/bootstrap.ts applies manager.agent.yaml via Anthropic SDK; needs ANTHROPIC_API_KEY + existing AGENT_ID, neither available from the agent sandbox. A human needs to run `npm run bootstrap` after this PR merges; calling it out in the PR body. --- ai-manager/manager.agent.yaml | 8 +++++--- ai-manager/src/tick.ts | 2 +- app/api/manager-tick/route.ts | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ai-manager/manager.agent.yaml b/ai-manager/manager.agent.yaml index 667c556..48216a3 100644 --- a/ai-manager/manager.agent.yaml +++ b/ai-manager/manager.agent.yaml @@ -187,10 +187,12 @@ system: | For changes that don't touch the UI (build config, prompt tweaks, docs), skip steps (d)–(h) and (j) — just build + lint. - l. **Open the PR.** The PR body MUST end with this HTML comment - as the last line so future webhooks can resume this session: + l. **Open the PR.** The PR body MUST end with this plain-text + marker on its own line so future webhooks can resume this + session (HTML-comment shape is stripped by the GitHub MCP + body filter — ENG-25): - + session-id: SESSION_ID_PROVIDED_IN_KICKOFF **Editing a PR body later:** `gh pr edit` fails in this repo with a Projects-classic deprecation error (exit 1) even when diff --git a/ai-manager/src/tick.ts b/ai-manager/src/tick.ts index 2675213..56a9a85 100644 --- a/ai-manager/src/tick.ts +++ b/ai-manager/src/tick.ts @@ -40,7 +40,7 @@ The token is scoped to the public 'pr-media-2' Vercel Blob store — used by ste const baseGoal = customGoal || - `Wake up. Your session id is ${session.id} — when you open a PR, include "" as the last line of the PR body so future webhooks can resume this session. Run the operational loop in your system prompt. Stop when there is nothing left.`; + `Wake up. Your session id is ${session.id} — when you open a PR, include "session-id: ${session.id}" on its own line as the last line of the PR body so future webhooks can resume this session. Run the operational loop in your system prompt. Stop when there is nothing left.`; const goal = `${baseGoal}\n\n${sessionEnv}`; diff --git a/app/api/manager-tick/route.ts b/app/api/manager-tick/route.ts index 1d54c7d..677b696 100644 --- a/app/api/manager-tick/route.ts +++ b/app/api/manager-tick/route.ts @@ -46,7 +46,7 @@ export async function GET(req: Request) { content: [ { type: 'text', - text: `Wake up. Your session id is ${session.id} — when you open a PR, include "" as the last line of the PR body so future webhooks can resume this session. Run the operational loop in your system prompt. Stop when there is nothing left.`, + text: `Wake up. Your session id is ${session.id} — when you open a PR, include "session-id: ${session.id}" on its own line as the last line of the PR body so future webhooks can resume this session. Run the operational loop in your system prompt. Stop when there is nothing left.`, }, ], }, From 653bd048e71a621d0fe24b84fd281f23c4670801 Mon Sep 17 00:00:00 2001 From: Self-Managing Codebase Manager <7004983+WillTaylor22@users.noreply.github.com> Date: Tue, 26 May 2026 10:31:42 +0000 Subject: [PATCH 2/2] memory: manager.agent.yaml needs manual bootstrap run to land on live agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One-line memory entry surfaced during ENG-28 / PR #25. Editing the YAML and merging the PR does NOT push the change — bootstrap.ts is the sync layer and needs ANTHROPIC_API_KEY + AGENT_ID env vars that aren't available in the sandbox. Every future YAML-touching PR should flag this in the PR body so a human runs npm run bootstrap after merge. --- .claude/memory/MEMORY.md | 1 + .../2026-05-26-manager-agent-yaml-needs-manual-bootstrap.md | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 .claude/memory/learnings/2026-05-26-manager-agent-yaml-needs-manual-bootstrap.md diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index d7deb80..ecfe366 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -12,6 +12,7 @@ Keep this file under 200 lines — anything longer is content bloat, not memory. - [learnings/recheck-open-prs-at-pr-open](learnings/2026-05-26-recheck-open-prs-at-pr-open.md) — session-start grep is insufficient; re-grep `list_pull_requests` right before `create_pull_request` to catch parallel-session races (PR #18 vs #20 ENG-25) - [learnings/closed-pr-receives-review-after-close](learnings/2026-05-26-closed-pr-receives-review-after-close.md) — Closed PR can still get a REQUEST_CHANGES review seconds after dup-close; don't reopen, surface to sibling PR + Linear (PR #18 vs #20 ENG-25 race) - [learnings/review-feedback-fanout](learnings/2026-05-26-review-feedback-fanout.md) — multiple REQUEST_CHANGES comments fire multiple manager sessions; fetch + check head-branch commits newer than the reviewer comment before doing work (PR #20) +- [learnings/manager-agent-yaml-needs-manual-bootstrap](learnings/2026-05-26-manager-agent-yaml-needs-manual-bootstrap.md) — `manager.agent.yaml` edits do NOT auto-deploy; a human must run `npm run bootstrap` from `ai-manager/` with `ANTHROPIC_API_KEY`+`AGENT_ID` to push the prompt to the live agent (ENG-28) ## Decisions - [decisions/mcp-for-small-writes-checkout-for-big](decisions/2026-05-26-mcp-for-small-writes-checkout-for-big.md) — Single-file writes go through GitHub MCP; multi-file or test-needing changes use the mounted checkout + `git push` diff --git a/.claude/memory/learnings/2026-05-26-manager-agent-yaml-needs-manual-bootstrap.md b/.claude/memory/learnings/2026-05-26-manager-agent-yaml-needs-manual-bootstrap.md new file mode 100644 index 0000000..51704b5 --- /dev/null +++ b/.claude/memory/learnings/2026-05-26-manager-agent-yaml-needs-manual-bootstrap.md @@ -0,0 +1,3 @@ +# `manager.agent.yaml` changes need a manual bootstrap run to land + +Editing `ai-manager/manager.agent.yaml` (the live manager system prompt) and merging the PR does NOT push the change to the running agent. The YAML is just a source artifact — the actual update goes through `ai-manager/src/bootstrap.ts`, which calls `client.beta.agents.update(AGENT_ID, { system: ... })` on the Anthropic platform. That script needs `ANTHROPIC_API_KEY` and the existing `AGENT_ID` in env, neither of which is available from the agent sandbox. So after merging any PR that touches `manager.agent.yaml`, surface it: a human has to run `npm run bootstrap` (or `npm run bootstrap:reviewer` for `reviewer.agent.yaml`) from `ai-manager/` with those env vars set. Until they do, the live system prompt lags `main`. Hit on ENG-28 / PR #25 — runtime templates (`tick.ts`, `manager-tick/route.ts`) deploy automatically via Vercel, but the YAML doesn't, so the live prompt and the runtime kickoffs can drift across a merge. Call out the gap explicitly in the PR body whenever the YAML changes.