diff --git a/personas/infrastructure/agents/infrastructure.md b/personas/infrastructure/agents/infrastructure.md index 2418063..167b77a 100644 --- a/personas/infrastructure/agents/infrastructure.md +++ b/personas/infrastructure/agents/infrastructure.md @@ -168,4 +168,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/infrastructure/instance/mandate.md`, with accumulated lessons in `.truecast/agents/infrastructure/instance/work.md`. **If `.truecast/agents/infrastructure/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/infrastructure/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/product-manager/agents/product-manager.md b/personas/product-manager/agents/product-manager.md index 2bd165c..399b1ba 100644 --- a/personas/product-manager/agents/product-manager.md +++ b/personas/product-manager/agents/product-manager.md @@ -107,4 +107,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/product-manager/instance/mandate.md`, with accumulated lessons in `.truecast/agents/product-manager/instance/work.md`. **If `.truecast/agents/product-manager/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/product-manager/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/product-marketer/agents/product-marketer.md b/personas/product-marketer/agents/product-marketer.md index 080bb18..78f13ea 100644 --- a/personas/product-marketer/agents/product-marketer.md +++ b/personas/product-marketer/agents/product-marketer.md @@ -159,4 +159,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/product-marketer/instance/mandate.md`, with accumulated lessons in `.truecast/agents/product-marketer/instance/work.md`. **If `.truecast/agents/product-marketer/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/product-marketer/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/product-researcher/agents/product-researcher.md b/personas/product-researcher/agents/product-researcher.md index 89c908e..94937b9 100644 --- a/personas/product-researcher/agents/product-researcher.md +++ b/personas/product-researcher/agents/product-researcher.md @@ -118,4 +118,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/product-researcher/instance/mandate.md`, with accumulated lessons in `.truecast/agents/product-researcher/instance/work.md`. **If `.truecast/agents/product-researcher/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/product-researcher/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/qa/agents/qa.md b/personas/qa/agents/qa.md index 6cb88d1..6d17862 100644 --- a/personas/qa/agents/qa.md +++ b/personas/qa/agents/qa.md @@ -154,4 +154,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/qa/instance/mandate.md`, with accumulated lessons in `.truecast/agents/qa/instance/work.md`. **If `.truecast/agents/qa/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/qa/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/sales/agents/sales.md b/personas/sales/agents/sales.md index e0059f6..eb8efbe 100644 --- a/personas/sales/agents/sales.md +++ b/personas/sales/agents/sales.md @@ -136,4 +136,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/sales/instance/mandate.md`, with accumulated lessons in `.truecast/agents/sales/instance/work.md`. **If `.truecast/agents/sales/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/sales/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/security-engineer/agents/security-engineer.md b/personas/security-engineer/agents/security-engineer.md index 9517a11..0333e8f 100644 --- a/personas/security-engineer/agents/security-engineer.md +++ b/personas/security-engineer/agents/security-engineer.md @@ -141,4 +141,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/security-engineer/instance/mandate.md`, with accumulated lessons in `.truecast/agents/security-engineer/instance/work.md`. **If `.truecast/agents/security-engineer/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/security-engineer/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/software-architect/agents/software-architect.md b/personas/software-architect/agents/software-architect.md index e2ec671..24fb1fe 100644 --- a/personas/software-architect/agents/software-architect.md +++ b/personas/software-architect/agents/software-architect.md @@ -163,4 +163,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/software-architect/instance/mandate.md`, with accumulated lessons in `.truecast/agents/software-architect/instance/work.md`. **If `.truecast/agents/software-architect/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/software-architect/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/software-engineer/agents/software-engineer.md b/personas/software-engineer/agents/software-engineer.md index 12a7038..59041da 100644 --- a/personas/software-engineer/agents/software-engineer.md +++ b/personas/software-engineer/agents/software-engineer.md @@ -99,4 +99,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/software-engineer/instance/mandate.md`, with accumulated lessons in `.truecast/agents/software-engineer/instance/work.md`. **If `.truecast/agents/software-engineer/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/software-engineer/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/ui-ux-designer/agents/ui-ux-designer.md b/personas/ui-ux-designer/agents/ui-ux-designer.md index 2e3674b..80a593a 100644 --- a/personas/ui-ux-designer/agents/ui-ux-designer.md +++ b/personas/ui-ux-designer/agents/ui-ux-designer.md @@ -154,4 +154,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/ui-ux-designer/instance/mandate.md`, with accumulated lessons in `.truecast/agents/ui-ux-designer/instance/work.md`. **If `.truecast/agents/ui-ux-designer/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/ui-ux-designer/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/personas/vc-seed/agents/vc-seed.md b/personas/vc-seed/agents/vc-seed.md index 22a75cd..1f4d267 100644 --- a/personas/vc-seed/agents/vc-seed.md +++ b/personas/vc-seed/agents/vc-seed.md @@ -116,4 +116,4 @@ Reference material — Read when relevant. - **Verify before you call it done** — check it against reality, never state as fact what you haven't confirmed, and never invent a result. ## Your job in this project -Your job here lives in `.truecast/agents/vc-seed/instance/mandate.md`, with accumulated lessons in `.truecast/agents/vc-seed/instance/work.md`. **If `.truecast/agents/vc-seed/instance/mandate.md` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work. +Work from the user's brief for this project if they've given you one — a `.truecast/agents/vc-seed/instance/mandate.md`, a `CLAUDE.md`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the `truecast` CLI; you run fine without it. diff --git a/src/api/publish.test.ts b/src/api/publish.test.ts index 4463766..d42be35 100644 --- a/src/api/publish.test.ts +++ b/src/api/publish.test.ts @@ -105,12 +105,13 @@ describe("planPublish — the pure file plan", () => { expect(manifest.author.name).toBe("Ada Lovelace"); }); - it("agent body uses the plugin craft root and the self-onboarding job prose, carries tools", () => { + it("agent body uses the plugin craft root and the missing-mandate-is-optional job prose, carries tools", () => { const plan = planPublish({ repoRoot: repo }); const agent = fileAt(plan, "personas/alpha-agent/agents/alpha-agent.md"); // biome-ignore lint/suspicious/noTemplateCurlyInString: asserting the literal token appears in output. expect(agent).toContain("${CLAUDE_PLUGIN_ROOT}/core/skills/do-the-thing/SKILL.md"); - expect(agent).toContain("that is your first task"); + expect(agent).toContain("ask the user what they need"); // optional mandate, asks (read-only safe) + expect(agent).not.toContain("write that mandate"); // never tell a read-only persona to write expect(agent).not.toContain("symlinked core"); expect(agent).toContain("tools: Read, Grep"); // frontmatter least-privilege (security F2) }); diff --git a/src/materialize/index.ts b/src/materialize/index.ts index e1d4985..d5c1d81 100644 --- a/src/materialize/index.ts +++ b/src/materialize/index.ts @@ -130,7 +130,7 @@ export function renderSystemPrompt( sections.push(ENGINE_PRINCIPLES); sections.push( transport.kind === "plugin" - ? `## Your job in this project\nYour job here lives in \`${instanceBase}/mandate.md\`, with accumulated lessons in \`${instanceBase}/work.md\`. **If \`${instanceBase}/mandate.md\` does not exist yet, that is your first task:** ask what this project needs from you, write that mandate, then start the work.` + ? `## Your job in this project\nWork from the user's brief for this project if they've given you one — a \`${instanceBase}/mandate.md\`, a \`CLAUDE.md\`, or direction in this conversation. **If there's no brief, that's not an error: ask the user what they need from you here, then proceed from your craft.** For a standing mandate that persists across sessions, they can install you with the \`truecast\` CLI; you run fine without it.` : `## Your job in this project\nRead \`${instanceBase}/mandate.md\` for what to do here, and \`${instanceBase}/work.md\` for accumulated lessons. A direct \`Read\` is transparent through the symlink; to search, target \`${craftBase}/\` and \`${instanceBase}/\` explicitly (a bare \`rg .\` misses the symlinked core).`, ); return sections.join("\n\n"); diff --git a/src/materialize/render.golden.test.ts b/src/materialize/render.golden.test.ts index 4cf1f5d..1b16f6b 100644 --- a/src/materialize/render.golden.test.ts +++ b/src/materialize/render.golden.test.ts @@ -83,10 +83,13 @@ describe("renderSystemPrompt — plugin transport differs only where it must", ( expect(body).not.toContain("symlinked core"); }); - it("tells a plugin-only persona to establish its mandate first (self-onboarding seam)", () => { + it("treats a missing mandate as optional, not an error — asks instead of failing (read-only safe)", () => { const body = renderPlugin(sample); - expect(body).toContain("If `.truecast/agents/"); - expect(body).toContain("that is your first task"); + expect(body).toContain("ask the user what they need"); + expect(body).toContain("that's not an error"); + // must NOT instruct a (read-only) persona to write a file it can't, nor present the path as broken + expect(body).not.toContain("write that mandate"); + expect(body).not.toContain("does not exist yet, that is your first task"); }); it("keeps the per-project job path project-relative (the job lives in the consuming repo)", () => {