← ClaudeAtlas

prompt-architecturelisted

How ShipIt stores and composes LLM prompts: prompt text as .md data files loaded at module top level, composition in TypeScript, the byte-stability prompt-cache contract, and how to test prompts (composition and caching, never literal wording). Load when editing agent system instructions, voice cleanup, session naming, or any prompt-composing code.
nikzlabs/shipit · ★ 9 · AI & Automation · score 75
Install: claude install-skill nikzlabs/shipit
# Prompt architecture LLM prompts — agent system instructions, voice cleanup, session naming — are **content, not logic**. Keep the two separated. ## Prompt *text* is data: it lives in `.md` files Co-locate the `.md` with the code that composes it. Prose reviews as prose, diffs cleanly, and needs no backtick or `${}` escaping. Load it with `loadPrompt(import.meta.url, "./x.md")` (`orchestrator/load-prompt.ts`), **at module top level** — once at init, never per call. A missing file then throws at boot rather than mid-turn. **Not** a bundler `?raw` import: production runs TS via tsx with no bundler, so `fs.readFileSync(new URL(...))` is what actually works. Examples: `agents/<id>/system-prompt.md`, `voice/cleanup-prompt.md`, `orchestrator/prompts/*.md`. **A per-call hole is still data.** `session-namer.ts` loads `session-naming-prompt.md` at module level and fills its `{{MESSAGE}}` per call through `buildSessionNamePrompt`. The file read happens once; only the substitution is per call, which is composition and belongs in TypeScript. A prompt whose text varies per request is not a reason to inline it. ## Prompt *composition* is code Axis branching and fragment selection stay in TypeScript. In `agent-instructions.ts`, `renderInstructions` fills `{{TOKEN}}` holes in `prompts/skeleton.md` via `fillPromptTokens`, which **throws on an unfilled token** — that's the guard ensuring no literal `{{FOO}}` ever reaches the model. There are **two axes**: `agentId` (Parallel-session