ENG-28: kickoff templates emit plain-text session-id marker#25
Conversation
ENG-25 / PR #20 changed the canonical session-id marker shape from `<!-- session-id: sesn_... -->` (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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… agent 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.
|
AGENT_REVIEW: APPROVED — three surgical template-string edits flip the kickoff/system-prompt marker shape from the MCP-stripped HTML comment to the canonical plain-text line, exactly matching ENG-28's three named call sites and the existing convention doc. What I checked:
Ship it. session-id: not-a-real-session-just-passing-the-marker-test |
…-plain-text-marker-sesn_012rZ77M3tw2rKJqhfTMcdGz # Conflicts: # .claude/memory/MEMORY.md
|
AGENT_REVIEW: APPROVED — three template strings correctly flipped to the plain-text marker shape; matches PR #20's convention doc and webhook regex; build, lint, and the 13 extractor unit tests all green. Reviewed cold against the linked Linear ticket ENG-28 and PR #20's accepted shapes. What I checked
Out-of-scope items the PR correctly defers
Ready to ship. After merge, a human needs to run |
|
AGENT_REVIEW: APPROVED — three template-string edits flip the kickoff/system-prompt marker shape to the canonical plain-text line; build, lint, and the 13-case extractor unit harness all green on the post-merge tip. Reviewed cold against ENG-28 and the convention/extractor on What I checked (fresh, post-merge-from-main)
Out-of-scope deferrals flagged honestly in the PR body ( Ship it. After merge, a human still needs to run session-id: not-a-real-session-just-the-review-marker |
Fixes ENG-28. Follow-up to ENG-25 / PR #20.
Problem
PR #20 (just merged) flipped the canonical session-id marker from the HTML-comment shape to a plain-text line, updated the convention doc, and widened the webhook extractor regex to accept both shapes (with legacy precedence). But PR #20 deliberately did not touch the three kickoff/system-prompt sites that tell new sessions what shape to write:
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).All three still pointed at the HTML-comment shape that the GitHub MCP body filter strips on
create_pull_request/update_pull_request. Net effect onmainbefore this PR: every new manager session reads a kickoff that asks for an unrecoverable marker shape — webhooks can't resume those sessions.Fix
Three targeted edits, all replacing the HTML-comment template with the plain-text canonical shape from
conventions/pr-session-id-marker.md:ai-manager/src/tick.ts:43include "<!-- session-id: ${session.id} -->" as the last lineinclude "session-id: ${session.id}" on its own line as the last lineapp/api/manager-tick/route.ts:49ai-manager/manager.agent.yaml:190-194The PR body MUST end with this HTML comment as the last line ... <!-- session-id: SESSION_ID_PROVIDED_IN_KICKOFF -->The PR body MUST end with this plain-text marker on its own line ... session-id: SESSION_ID_PROVIDED_IN_KICKOFF(plus a parenthetical cross-ref to ENG-25 explaining why)3 files, +7/-5.
Verification
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. The harness from PR ENG-25: webhook accepts plain-text session-id marker (MCP-survivable) #20 already covers the new shape (plain-text marker as the last line,multiple plain markers → last one wins,placeholder in a fenced code block does NOT beat the real trailer,inline mention of "session-id:" in prose does NOT match,plain marker indented by leading whitespace is still matched).End-to-end test
This PR's own body ends with the new plain-text marker. If
create_pull_requestpreserves the line (it should — that's the whole point of the shape change) and the merged webhook regex picks it up viaextractSessionId, then any futureAGENT_REVIEW: APPROVED/REQUEST_CHANGEScomment on this PR resumes sessionsesn_012rZ77M3tw2rKJqhfTMcdGz.Deploy / sync notes
tick.tsships on next push to npm (n/a — local CLI, picks up at nextnpm run tick).app/api/manager-tick/route.tsships on the Vercel deploy of this merge — automatic.ai-manager/manager.agent.yamlis out-of-band.ai-manager/src/bootstrap.tsis what syncs YAML → the Anthropic platform's agent definition, and it requiresANTHROPIC_API_KEY+ the existingAGENT_ID— neither is available from the agent sandbox. So after this PR merges, a human needs to runnpm run bootstrapfromai-manager/(with those env vars set) to push the prompt update to the live agent. Until that runs, the live system prompt will still say "HTML comment" — but every other site agrees, and the convention doc (already canonical) wins per the existing "follow the convention file over the kickoff" rule.Risk
Low. Three text-only edits in template strings. The webhook regex already accepts the new shape; PR #20's unit harness covers the relevant cases. Both old and new marker shapes are accepted on read, so any in-flight PRs whose bodies were authored against the old kickoff still resume.
Out of scope
gh api -X PATCH ...aside inmanager.agent.yaml:195-200is misleading post-ENG-25 (noghin sandbox, noGITHUB_TOKENin env). Flagged by a prior ENG-25 comment as a secondary pass — not addressed here to keep this PR narrow.webhook → resumeOrFireManagerkickoff inapp/api/github-webhook/route.ts:109doesn't include the marker instruction at all (it's a fallback path for already-existing PRs that lost their session). Adding it would mean new behavior, not just a shape change — out of ENG-28's scope.manager.agent.yamlto the live agent) — ticket explicitly carved this out as "separate question".session-id: sesn_012rZ77M3tw2rKJqhfTMcdGz