docs(specs): add sf-prompt-modularization.md operator guide
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
92ff8186ba
commit
a8a28bd7c0
1 changed files with 129 additions and 0 deletions
129
docs/specs/sf-prompt-modularization.md
Normal file
129
docs/specs/sf-prompt-modularization.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# SF Prompt Modularization
|
||||
|
||||
Human-readable contract for the manifest-driven prompt context system.
|
||||
|
||||
## Status
|
||||
|
||||
M004 — Phase 3 complete. All builders migrated to `composeUnitContext` v2.
|
||||
|
||||
## Overview
|
||||
|
||||
Every autonomous unit type (plan-milestone, execute-task, deploy, …) declares
|
||||
what context it needs in a **manifest**. The composer reads the manifest and
|
||||
orchestrates artifact resolution, producing the `## Inlined Context` block that
|
||||
each prompt template receives.
|
||||
|
||||
This replaces the pre-Phase-3 approach where each builder hand-wired file reads
|
||||
and DB queries inline.
|
||||
|
||||
## Two composer APIs
|
||||
|
||||
| API | Purpose | When to use |
|
||||
|-----|---------|-------------|
|
||||
| `composeInlinedContext(unitType, resolveArtifact)` | v1 — resolves `artifacts.inline` keys only | **Deprecated.** Retained in `unit-context-composer.js` for external consumers. Do not use in new builders. |
|
||||
| `composeUnitContext(unitType, opts)` | v2 — resolves `prepend`, `inline`, `excerpt`, and `computed` artifacts | **Use for all new builders.** All in-tree builders now call this. |
|
||||
|
||||
### `composeUnitContext` contract
|
||||
|
||||
```ts
|
||||
composeUnitContext(unitType: string, opts: {
|
||||
base: string; // repo root
|
||||
resolveArtifact?: (key: string) => Promise<string | null>;
|
||||
resolveExcerpt?: (key: string) => Promise<string | null>;
|
||||
computed?: Record<string, { build: (inputs, base) => string | null }>;
|
||||
}) => Promise<{ prepend: string; inline: string }>
|
||||
```
|
||||
|
||||
- **prepend** — computed blocks that should appear before the main inline content.
|
||||
- **inline** — the joined context block suitable for `{{inlinedContext}}` substitution.
|
||||
- Unknown `unitType` returns `{ prepend: "", inline: "" }` — callers fall through to default behavior.
|
||||
- Missing resolvers or registry entries are skipped silently (no error).
|
||||
|
||||
## Manifest schema
|
||||
|
||||
```ts
|
||||
interface UnitManifest {
|
||||
skills: { mode: "all" | "planning" | string[] };
|
||||
knowledge: "full" | "scoped" | "critical-only" | "none";
|
||||
memory: "prompt-relevant" | "critical-only" | "none";
|
||||
codebaseMap: boolean;
|
||||
preferences: "active-only" | "none";
|
||||
tools: string[];
|
||||
prepend?: string[]; // computed artifact ids (e.g. ["overrides"])
|
||||
artifacts: {
|
||||
inline: string[]; // static artifact keys, resolved in order
|
||||
excerpt: string[]; // excerpt artifact keys
|
||||
onDemand: string[]; // referenced but not auto-inlined
|
||||
computed?: string[]; // async computed artifact ids (e.g. ["knowledge", "graph"])
|
||||
};
|
||||
maxSystemPromptChars: number;
|
||||
}
|
||||
```
|
||||
|
||||
### Stable artifact keys (`ARTIFACT_KEYS`)
|
||||
|
||||
Keys are **stable identifiers**, not paths. The resolver maps a key to its
|
||||
source (file, DB row, computed block).
|
||||
|
||||
Milestone-scoped: `roadmap`, `milestone-context`, `milestone-summary`,
|
||||
`milestone-validation`, `milestone-research`, `milestone-plan`
|
||||
|
||||
Slice-scoped: `slice-context`, `slice-research`, `slice-plan`, `slice-summary`,
|
||||
`slice-summaries`, `slice-uat`, `slice-assessment`
|
||||
|
||||
Task-scoped: `task-plan`, `task-summary`, `prior-task-summaries`,
|
||||
`dependency-summaries`, `blocker-summaries`
|
||||
|
||||
Project-scoped: `requirements`, `decisions`, `project`, `templates`, `queue`
|
||||
|
||||
Validation-scoped: `verification-classes`, `outstanding-items`, `previous-validation`
|
||||
|
||||
History-scoped: `prior-milestone-summary`
|
||||
|
||||
## Migration decision matrix
|
||||
|
||||
| Builder complexity | Recommendation | Example |
|
||||
|-------------------|------------------|---------|
|
||||
| Simple (1–3 static artifacts, no knowledge splice) | Full v2 via `composeUnitContext` | deploy, release, rollback, challenge |
|
||||
| Medium (4–6 static artifacts, optional knowledge/graph) | v2 inline + imperative knowledge splice | research-milestone, complete-slice, reassess-roadmap |
|
||||
| Complex (many artifacts, computed prepend, conditional logic) | v2 with full computed registry | plan-milestone, research-slice, plan-slice, replan-slice |
|
||||
| Fully imperative (no composer call) | Keep imperative; add manifest for documentation | execute-task, reactive-execute |
|
||||
|
||||
## Budget and caching
|
||||
|
||||
- `resolvePromptBudgets()` computes context-window-scaled budgets once per
|
||||
dispatch tick (1-second TTL). Do not add additional caches.
|
||||
- `capPreamble()` caps inlined context at `min(30K chars, scaled inline budget)`.
|
||||
- Exceeding `maxSystemPromptChars` logs a telemetry event; the composer does not
|
||||
truncate.
|
||||
|
||||
## Verification
|
||||
|
||||
- `auto-prompts-phase3.test.mjs` — v2 contracts for plan-milestone,
|
||||
replan-slice, validate-milestone, research-slice.
|
||||
- `auto-prompts-complete-slice.test.mjs` — complete-slice closeout contract.
|
||||
- `auto-prompts-v2-migration.test.mjs` — regression guard for all migrated
|
||||
builders (research-milestone, run-uat, deploy, smoke-production, release,
|
||||
rollback, challenge).
|
||||
- `unit-context-manifest-computed.test.mjs` — manifest `computed` keys match
|
||||
builder behavior.
|
||||
|
||||
## Adding a new artifact key
|
||||
|
||||
1. Add the key to `ARTIFACT_KEYS` in `unit-context-manifest.js`.
|
||||
2. Add the key to the `inline` / `excerpt` / `onDemand` / `computed` list of
|
||||
every manifest that needs it.
|
||||
3. Implement the resolver in the builder's `resolveArtifact` function.
|
||||
4. Add a regression test that asserts the artifact appears in the prompt.
|
||||
|
||||
## Adding a new computed artifact type
|
||||
|
||||
1. Define the builder function (e.g. `inlineKnowledgeBudgeted`).
|
||||
2. Register it in the `computed` registry passed to `composeUnitContext`:
|
||||
```js
|
||||
computed: {
|
||||
knowledge: { build: (inputs, base) => inlineKnowledgeBudgeted(base, inputs.keywords) }
|
||||
}
|
||||
```
|
||||
3. Add the id to `manifest.artifacts.computed`.
|
||||
4. Add a test that asserts the computed block appears in the output.
|
||||
Loading…
Add table
Reference in a new issue