Vercel Composition Patterns
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
Document a recently solved problem or durable project vocabulary in docs/solutions/ or CONCEPTS.md.
$ npx skills add leo-kuang-ai/spec-first --skill spec-compound -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install leo-kuang-ai/spec-first spec-compound --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/leo-kuang-ai/spec-first.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/spec-compound .claude/skills/spec-compound && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "spec-compound" agent skill from https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compound into .claude/skills/spec-compound/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "spec-compound", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compoundType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add leo-kuang-ai/spec-first --skill spec-compound -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install leo-kuang-ai/spec-first spec-compound --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leo-kuang-ai/spec-first.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/spec-compound .agents/skills/spec-compound && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "spec-compound" agent skill from https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compound into .agents/skills/spec-compound/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "spec-compound", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add leo-kuang-ai/spec-first --skill spec-compound -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install leo-kuang-ai/spec-first spec-compound --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leo-kuang-ai/spec-first.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/spec-compound .cursor/skills/spec-compound && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "spec-compound" agent skill from https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compound into .cursor/skills/spec-compound/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "spec-compound", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/leo-kuang-ai/spec-first.git --path skills/spec-compound--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add leo-kuang-ai/spec-first --skill spec-compound -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install leo-kuang-ai/spec-first spec-compound --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leo-kuang-ai/spec-first.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/spec-compound .gemini/skills/spec-compound && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "spec-compound" agent skill from https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compound into .gemini/skills/spec-compound/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "spec-compound", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install leo-kuang-ai/spec-first spec-compoundInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add leo-kuang-ai/spec-first --skill spec-compound -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/leo-kuang-ai/spec-first.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/spec-compound .github/skills/spec-compound && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "spec-compound" agent skill from https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compound into .github/skills/spec-compound/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "spec-compound", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add leo-kuang-ai/spec-first --skill spec-compound -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install leo-kuang-ai/spec-first spec-compound --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leo-kuang-ai/spec-first.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/spec-compound .opencode/skills/spec-compound && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "spec-compound" agent skill from https://github.com/leo-kuang-ai/spec-first/tree/master/skills/spec-compound into .opencode/skills/spec-compound/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "spec-compound", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
spec-compoundDocument a recently solved problem or durable project vocabulary in docs/solutions/ or CONCEPTS.md.
Spec Compound is an agent skill from leo-kuang-ai/spec-first. Document a recently solved problem or durable project vocabulary in docs/solutions/ or CONCEPTS.md. Use when capturing a learning after work.
Its SKILL.md is about 18k tokens, which your agent loads only when the skill is triggered. The skill folder holds 39 other files, including scripts, reference files and assets (for example `assets/resolution-template.md`, `evals/cases/bootstrap-routes-refresh.yaml` and `evals/cases/unsolved-no-write.yaml`).
It sits in Development. The repository describes itself as: 仓库原生 AI Coding Harness —— 把一次性 AI 对话变成可治理、可验证、可沉淀的工程闭环 · spec-first.cn. The licence is MIT.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 74655dc. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (JavaScript and Shell, from the files we listed), which the agent can run.
Shell commands in SKILL.md call:
gitbashghFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git and gh, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Spec Compound loads about 18k tokens when it runs, and up to ~35k if it reads all its reference files. Until then it costs about 39 tokens; SKILL.md has 8,766 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from leo-kuang-ai/spec-first at commit 74655dc, republished under its MIT licence (© leo-kuang-ai). 8,766 words, ~18,261 tokens.
.claude/skills/spec-compound/SKILL.md (or your agent's skills folder). This skill also uses 29 other files; get the full folder from GitHub.Document a recently solved problem through role-based research; use parallel subagents only when dispatch is explicitly authorized and callable, otherwise run the same roles inline or serially.
Captures problem solutions while context is fresh, creating structured documentation in docs/solutions/ with YAML frontmatter for searchability and future reference. Authorized dispatch can parallelize read-only research; correctness does not depend on it.
Why "compound"? Each documented solution compounds your team's knowledge. The first time you solve a problem takes research. Document it, and the next occurrence takes minutes. Knowledge compounds.
docs/solutions/ 下带 provenance、适用范围与失效条件的 learning,以及必要时对 CONCEPTS.md 的局部补充。spec-plan、spec-work、spec-debug、spec-code-review 与项目维护者。spec-compound # Document the most recent fix
spec-compound [brief context] # Provide additional context hint
spec-compound mode:headless # Non-interactive run for automations
spec-compound mode:headless [context] # Non-interactive run with context hintOne learning per run. The workflow's grounding, overlap detection, and cross-referencing all assume a single solved problem. When a session produced multiple distinct learnings, run the skill once per learning, sequentially — each run grounds fresh against the tree. Do not batch several learnings through one run and stitch cross-references between the drafts afterward; drafting-context numbering ("Learning 3") leaking into written docs is the failure this rule prevents.
If invoked specifically to create or bootstrap CONCEPTS.md from scratch rather than to document a solved problem, do not run the normal phases — spec-compound populates CONCEPTS.md only as a side effect of documenting a real learning (it seeds the learning's area, not the whole repo; see Phase 2.4). Repo-wide concept-map creation is spec-compound-refresh's job. Redirect a standalone bootstrap request to spec-compound-refresh (which asks whether to build the concept map or run a refresh cycle), then exit.
Check the invocation arguments supplied by the current host for the exact mode:headless token. Tokens starting with mode: are flags, not context — strip only recognized mode tokens while preserving the remainder, quoted paths, and token order before treating it as the brief context hint.
| Mode | When | Behavior |
|---|---|---|
| Interactive (default) | No mode token present | Auto-pick Full vs Lightweight and report the choice; run the Full-mode session-history probe only with explicit restricted-read authorization; prompt for Discoverability Check consent; end with a plain summary (no "What's next?" menu) |
| Headless | mode:headless in arguments | No blocking questions. Run Full mode without session history. Report discoverability gaps without editing instruction files. Skip Phase 2.46 optional candidate enhancement. End with a structured terminal report — no "What's next?" menu. |
Headless mode is intended for automations and skill-to-skill invocation where no human is present to answer questions. The doc itself is identical to what an interactive Full run would produce — classification work (track, category, overlap) follows the same rules and writes nothing extra into the artifact. Once detected, headless mode applies for the entire run.
Git branch (pre-resolved): !git rev-parse --abbrev-ref HEAD
If the line above resolved to a plain branch name (like feat/my-branch), use it in Phase 1 session-history filtering so the orchestrator does not waste a turn deriving it. If it still contains a backtick command string, shows an error, or is empty, derive the branch at runtime.
Repo root (pre-resolved): !git rev-parse --show-toplevel
If the line above resolved to an absolute path, use it as the session-history repo filter in Phase 1. If it still contains a backtick command string, shows an error, or is empty, derive the repo root at runtime with the shell tool (git rev-parse --show-toplevel, falling back to the working directory outside a git repo).
These files are the durable contract for the workflow. Read them on-demand at the step that needs them — do not bulk-load at skill start.
references/schema.yaml — canonical frontmatter fields and enum values (read when validating YAML)references/yaml-schema.md — category mapping from problem_type to directory (read when classifying)references/concepts-vocabulary.md — CONCEPTS.md format and inclusion rules (read in Phase 2.4 when domain terms surface)references/agents/session-historian.md — skill-local synthesis prompt for optional session-history compounding context (read only when explicit restricted-read authorization exists and the relevance gate escalates)references/grounding-validation.md — grounding-validation protocol: flag adjudication rules and the semantic validator prompt (read in Phase 2.45)assets/resolution-template.md — section structure for new docs (read when assembling)scripts/session-history/ — session discovery and extraction scripts copied into this skill so session-history support does not depend on the bundled session-history supportscripts/validate-frontmatter.py — frontmatter parser-safety validator plus the opt-in --promotion exit gate for provenance/invalidation (run against the private candidate in Phase 2 step 6 through the existence guard documented there; resolves via the loaded skill directory anchor SKILL_DIR, with a manual-checklist fallback elsewhere)scripts/validate-doc-claims.py — mechanical claims validator: cited paths, commit SHAs, relative links, dangling drafting scaffold (run in Phase 2.45 via the SKILL_DIR anchor)When spawning subagents, pass the relevant file contents into the task prompt so they have the contract without needing cross-skill paths.
在派发 repo profiler、research role、session-history synthesizer、semantic validator 或 specialized reviewer 前,记录:
worker_dispatch_authorization: authorized | missing
capability_probe: not_applicable | attempted | unavailable
worker_dispatch_capability: available | missing | unknown
worker_context_isolation: isolated | inherited | unknown
worker_model_override: supported | unsupported | unknown
worker_bounded_parallelism: supported | unsupported | unknownworkflow invocation does not authorize dispatch。Full/headless mode、上下文预算、scratch directory、权限设置或 prompt asset 存在都不构成授权。只有当前用户或可见 upstream handoff 明确请求 subagent、delegated work、persona 或 parallel work 时才可派发。缺授权时不得探测 tool schema,固定为 capability_probe: not_applicable + worker_dispatch_capability: unknown,依次 inline 或 serial 执行相同 role prompts 并记录 dispatch_authorization_missing。只有授权后才把 current-session registry/schema 作为 provider_untrusted evidence 检查:确认缺失时记录 subagent_capability_missing;surface 不可用、schema 不完整或候选不唯一时记录 worker_capability_unproven,均使用同一 fallback。隔离、模型覆盖和有界并发只取 live facts;required isolation 未满足时保持依赖 gate 打开,model unknown 时继承,parallelism unknown 时串行。记录 worker_dispatch_outcome。Fallback 保留 Context Analyzer、Solution Extractor、Related Docs Finder 等角色合同,但不得声称 independent subagent、fresh-context 或 parallel coverage。无论哪种路径,只有 orchestrator 可以写 docs/solutions/、CONCEPTS.md、instruction files 或任何 tracked path。
spec-compound does not ask the user which mode to run. Mode depends on context budget the agent can observe. Cross-session history is different: reading private session stores is a restricted-read boundary, so the workflow probes it only when the current user or visible upstream handoff explicitly authorizes that read; it never infers authorization from a compound request, Full mode, local file access, or tool availability. Missing authorization skips the probe with restricted_read_authorization_missing rather than opening another question. The only interactive prompt in the normal workflow is the Discoverability Check consent, because that one edits a tracked instruction file.
Mode selection (Full vs Lightweight) — decide it, don't ask it.
Documentation skipped instead of writing durable knowledge.In headless mode, skip mode selection entirely and run Full Mode with session history disabled (Phase 1 step 4 omitted). Headless does not elevate dispatch authority; when the package-local boundary is not satisfied, proceed through the serial inline Full fallback.
Session history — an authorization-gated probe in Full mode. When explicit restricted-read authorization exists, Full mode runs the cheap discovery+metadata probe (Phase 1 step 4) and escalates to extraction+synthesis only when the probe surfaces genuinely relevant candidate sessions. Without that authorization, record restricted_read_authorization_missing and continue without session context; do not inspect session roots or tool schemas. Lightweight and headless modes skip session history entirely. There is no standalone session-history product surface; this support exists only inside the compounding workflow.
<critical_requirement> The primary deliverable is ONE file - the final documentation.
When dispatch is authorized, Phase 1 subagents write their full structured output to the caller-provided owner-only <private-scratch-dir> and return only a compact confirmation containing the artifact path. In inline fallback, the orchestrator runs the same roles serially and writes the same scratch artifacts itself. Phase 2 reads those artifacts in either path. Scratch is ephemeral and never the only durable deliverable or handoff evidence. Only the orchestrator writes product files — the final solution doc and the maintenance side effects below. Subagents must not touch docs/, project instruction files, or any tracked path. Beyond the Phase 2 solution doc, the orchestrator's other writes are maintenance side effects — not additional deliverables, and creating one when absent is expected, not a violation of this rule:
CONCEPTS.md — prepare a private candidate in Phase 2.4 (Vocabulary Capture) when a qualifying domain term surfaces; publish it only through the shared promotion boundary in Phase 2.47.Both ensure future agents can discover and ground in the knowledge store; neither makes the documentation any less the single deliverable.
Why the scratch artifact (issue #956): a subagent asked to return a long prose body as its inline response intermittently returns an executive summary instead ("Doc body complete — six sections filled. Returning above."), and the original prose is then unrecoverable from the orchestrator side. Writing to disk first means the full output always survives; the inline confirmation is just a pointer, and the orchestrator falls back to whatever the subagent did return inline only when the artifact is missing. </critical_requirement>
Before launching Phase 1 subagents, check the auto-memory block injected into your system prompt for notes relevant to the problem being documented.
## Supplementary notes from auto memory
Treat as additional context, not primary evidence. Conversation history
and codebase findings take priority over these notes.
[relevant entries here]If no relevant entries are found, proceed to Phase 1 without passing memory context.
Run the research roles. When the Dispatch Authorization Boundary is satisfied, launch research subagents and have each write its full output to a per-run scratch artifact. Otherwise execute Context Analyzer, Solution Extractor, and Related Docs Finder serially inline, writing their run-local scratch artifacts from the orchestrator so Phase 2 keeps the same input contract.
Run ID and run dir (before dispatching any subagent): generate a unique run identifier and create the run directory. This scopes every Phase 1 artifact file to the same directory so the orchestrator can Read them back in Phase 2.
RUN_ID=$(date +%Y%m%d-%H%M%S)-$(head -c4 /dev/urandom | od -An -tx1 | tr -d ' ')
umask 077
SCRATCH_DIR="$(mktemp -d "${TMPDIR:-/tmp}/spec-first-compound.XXXXXX")"
[ -d "$SCRATCH_DIR" ] && [ ! -L "$SCRATCH_DIR" ] || { echo 'private scratch creation failed' >&2; exit 1; }
chmod 700 "$SCRATCH_DIR"
echo "$SCRATCH_DIR"Resolve current project orientation before dispatching subagents. Record the current target repo/worktree identity and dirty state when available, then read root instruction files and CONCEPTS.md directly for the vocabulary and conventions needed by the Context Analyzer. Keep this as run-local input with direct source refs; never persist or reuse it across runs, branches, or worktrees. If a source cannot be read, record that degraded fact and let the Context Analyzer limit its claims rather than substituting stale orientation.
Current source is the authority for code-behavior claims. Every promoted learning must retain direct source refs, observed revision/freshness, applicability scope, and an invalidation condition; session history, cached summaries, and external provider output are advisory leads only and cannot close grounding on their own.
CRITICAL — glob docs/solutions/ fresh every run. spec-compound writes new learnings there, so even a run-local orientation assembled earlier cannot stand in for the live enumeration in step 3.
Pass {run_id} and the verified <private-scratch-dir> into every Phase 1 subagent prompt. Recheck that the directory remains owned and non-symlink before publishing each file with same-directory temp + atomic rename. Each subagent writes its full structured output to its own file there, confirms the write succeeded (the file exists and is non-empty), and then returns only a one-line confirmation containing the artifact path — not the prose body inline. Artifact filenames by subagent:
<private-scratch-dir>/context.json (frontmatter skeleton, category path, filename, track)<private-scratch-dir>/solution.md (the full doc-body prose sections)<private-scratch-dir>/related.json (links, refresh candidates, overlap assessment)<private-scratch-dir>/session-history.md (prose findings)Return the full output inline whenever the artifact write did not succeed. This covers both cases where the orchestrator's Phase 2 inline fallback would otherwise have nothing to read: (a) {run_id} is empty or did not resolve (non-Claude-Code platforms where the pre-resolution failed), so there is no path to write to; and (b) {run_id} resolved but the write itself failed — tool permission denied, absolute-path writes unavailable, disk error, or the post-write existence check came back empty. In either case the subagent must return its complete structured output inline instead of a path, because the path would point at a file that does not exist. Return only the bare path when — and only when — the write is confirmed on disk. The artifact pattern is a reliability improvement, not a hard requirement; the orchestrator handles a missing artifact in Phase 2 by using the inline return.
Execution order:
Context Analyzer, Solution Extractor, and Related Docs Finder in bounded parallel. Without it, run the same roles serially inline and preserve their separate artifacts/results without presenting them as independent agents.restricted_read_authorization_missing and do not inspect session roots or related tool schemas.references/schema.yaml for enum validation and track classificationreferences/yaml-schema.md for category mapping into docs/solutions/[sanitized-problem-slug].md — no date suffix, even if existing files in the target directory have one; the date: frontmatter field is the canonical creation datecontext.json: YAML frontmatter skeleton (must include category: plus the promotion exit fields source_refs: and invalidation_condition:), category directory path, suggested filename, and which track applies. Returns only the artifact path.references/schema.yaml for track classification (bug vs knowledge)solution.md and returns only the artifact path. This is the subagent most prone to the issue #956 summary-collapse, so its prose must land on disk rather than only in the inline return.file:line alongside the claim. A claim that cannot be verified against the tree is softened or attributed ("per this session's conclusion…"), never stated as factBug track output sections:
Knowledge track output sections:
docs/solutions/ for related documentationrelated.json: Links, relationships, refresh candidates, and overlap assessment (score + which dimensions matched). Returns only the artifact path.Search strategy (grep-first filtering for efficiency):
docs/solutions/<category>/ directorytitle:.*<keyword>tags:.*(<keyword1>|<keyword2>)module:.*<module name>component:.*<component>GitHub issue search:
Prefer the gh CLI for searching related issues: gh issue list --search "<keywords>" --state all --limit 5. If gh is not installed, fall back to the GitHub MCP tools (e.g., unblocked data_retrieval) if available. If neither is available, skip GitHub issue search and note it was skipped in the output.
restricted_read_authorization_missing, do not inspect session roots or related tool schemas, and continue to Phase 2 without session context. Skip entirely in lightweight mode or headless mode. After authorization, run a two-stage probe: the cheap discovery+metadata pass executes first, and the expensive extraction+synthesis executes only when the probe clears the relevance gate (see Escalation gate below).scripts/session-history/.references/agents/session-historian.md, then dispatch a generic subagent using that prompt content. Do not dispatch a standalone agent by type/name.Session-history payload — keep tight. A long, keyword-rich payload licenses widening. Use this shape:
Pre-resolved context (only if values resolved cleanly above; otherwise omit): repo name, current git branch.
Time window: explicit 7 days unless the documented problem clearly spans a longer arc.
Problem topic: one sentence naming the concrete issue — error message, module name, what broke and how it was fixed. Not a paragraph; not a bullet list of related topics.
Filter rule (one line): "Only surface findings directly relevant to this specific problem. Ignore unrelated work from the same sessions or branches."
Output schema:
Structure your response with these sections (omit any with no findings):
- What was tried before
- What didn't work
- Key decisions
- Related contextDo not append additional context blocks, exclusion lists, or topic-keyword bullets — verbose payloads give the session-history flow license to keep widening the search and rapidly compound wall time. If keyword search is needed, the internal flow owns that decision based on the topic.
Script resolution. Set SKILL_DIR to the absolute path of the directory containing the SKILL.md you just read, and run the bundled scripts from "$SKILL_DIR/scripts/session-history/". Set SKILL_DIR inline in each bash block below (shell state does not persist between commands). If the bundled scripts are genuinely not present on disk under "$SKILL_DIR/scripts/session-history/", skip session history visibly with: "Session history bundled scripts were not found in this skill's directory; skipping the session-history probe for this run." Continue Phase 2 without session context.
Discovery pipeline. Infer the scan window from the problem topic, starting with 7 days. Run discovery and metadata extraction:
SKILL_DIR="<absolute path of the directory containing the SKILL.md you just read>"
if [ -f "$SKILL_DIR/scripts/session-history/discover-sessions.sh" ] && [ -f "$SKILL_DIR/scripts/session-history/extract-metadata.py" ]; then
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
REPO_NAME=$(basename "$REPO_ROOT")
SCAN_DAYS="7"
bash "$SKILL_DIR/scripts/session-history/discover-sessions.sh" "$REPO_NAME" "$SCAN_DAYS" --cwd "$REPO_ROOT" | tr '\n' '\0' | xargs -0 bash "$SKILL_DIR/scripts/run-python.sh" "$SKILL_DIR/scripts/session-history/extract-metadata.py" --cwd-filter "$REPO_ROOT"
else
echo "Session history bundled scripts were not found in this skill's directory; skipping the session-history probe for this run."
fi Pi sessions are included when present under ~/.pi/agent/sessions/; they carry cwd like Codex but no git branch. If _meta.files_processed is 0, return no relevant prior sessions. If the first pass finds no relevant branch matches, or if processing Codex or Pi sessions, derive 2-4 keywords from the topic and re-run metadata extraction with --keyword K1,K2,.... Keep at most 5 sessions across Claude Code, Codex, Cursor, and Pi, ranked by branch match, keyword match count, file size over 30KB, and recency. Exclude the current session.
Escalation gate. After restricted-read authorization, the discovery+metadata pass above is the cheap probe. Escalate to the extraction and synthesis stages below only when at least one retained candidate clears the relevance bar: a current-branch match, or ≥2 topic-keyword matches. If no candidate clears the bar (including the _meta.files_processed is 0 case), stop here, record no relevant prior sessions as the session-history input, and skip extraction and synthesis. This gate keeps the authorized probe cheap — the expensive synthesis is paid for only when a prior session is genuinely relevant.
Extraction pipeline. Create SCRATCH=$(mktemp -d -t spec-compound-sessions-XXXXXX). For each selected session, write extracted content to scratch files:
SKILL_DIR="<absolute path of the directory containing the SKILL.md you just read>"
if [ -f "$SKILL_DIR/scripts/session-history/extract-skeleton.py" ]; then
bash "$SKILL_DIR/scripts/run-python.sh" "$SKILL_DIR/scripts/session-history/extract-skeleton.py" --output "$SCRATCH/<session-id>.skeleton.txt" < <session-file>
else
echo "Session history bundled scripts were not found in this skill's directory; skipping the session-history probe for this run."
fi Use extract-errors.py selectively when dead ends or recurring errors are likely useful. Pass only the scratch file paths and metadata to the synthesis subagent.
Synthesis dispatch. Build a generic subagent prompt containing:
references/agents/session-historian.mdproblem_topicscratch_diroutput_path: <private-scratch-dir>/session-history.mdsessions array with extracted file paths and metadata The subagent reads only the scratch paths, writes its prose findings to <private-scratch-dir>/session-history.md, and returns only that artifact path once the atomic write is confirmed. If {run_id} or the private scratch directory did not resolve, ownership/symlink recheck failed, or the artifact write failed, it returns the prose inline instead. If synthesis fails, note the failure and continue without session context.
<sequential_tasks>
WAIT for all Phase 1 inputs to complete before proceeding — the three research roles (parallel only under authorized dispatch) and, when separately authorized in Full mode, the internal session-history flow, which may stop at no relevant prior sessions. An authorization skip is a terminal Phase 1 fact, not an empty permission to inspect private session roots.
The orchestrating agent (main conversation) performs these steps:
Collect Phase 1 results from the run artifacts. Read context.json, solution.md, related.json, and session-history.md when that flow ran. Under authorized dispatch, fall back to the subagent's inline return only when its artifact is absent or empty. Under inline fallback, the orchestrator owns both role execution and artifact writes. The artifact is authoritative when present.
Check the overlap assessment from the Related Docs Finder before deciding what to write:
| Overlap | Action |
|---|---|
| High — existing doc covers the same problem, root cause, and solution | Update the existing doc with fresher context (new code examples, updated references, additional prevention tips) rather than creating a duplicate. The existing doc's path and structure stay the same. |
| Moderate — same problem area but different angle, root cause, or solution | Create the new doc normally. Flag the overlap for Phase 2.5 to recommend consolidation review. |
| Low or none | Create the new doc normally. |
The reason to update rather than create: two docs describing the same problem and solution will inevitably drift apart. The newer context is fresher and more trustworthy, so fold it into the existing doc rather than creating a second one that immediately needs consolidation.
When updating an existing doc, preserve its file path and existing frontmatter structure, but add source_refs and invalidation_condition when absent because this path materially rewrites the learning. Update the solution, code examples, prevention tips, and any stale references. Add a last_updated: YYYY-MM-DD field to the frontmatter. Do not change the title unless the problem framing has materially shifted.
Incorporate session history findings (if available). When the internal session-history flow returned relevant prior-session context:
Assemble the complete markdown into <private-scratch-dir>/learning-candidate.md, reading assets/resolution-template.md for the section structure of new docs. Do not create or modify the final docs/solutions/** path yet. For an existing target, record its current existence and SHA-256 before assembly so publication can detect concurrent drift.
Validate the candidate frontmatter against references/schema.yaml, including non-empty source_refs and invalidation_condition promotion exit fields and the YAML-safety quoting rule for array items (see references/yaml-schema.md > YAML Safety Rules). The references must be grounded and the invalidation condition must be semantically specific; the script in step 6 checks only their mechanical shape.
Validate parser-safety and the knowledge-promotion exit contract on the candidate after every new or materially rewritten learning. Promotion mode catches malformed --- delimiter lines, unquoted # in scalar values (silent comment truncation), unquoted : in scalar values (silent mapping confusion), and mechanically requires a non-empty top-level source_refs array plus a non-empty top-level invalidation_condition. The bundled validator ships inside the skill bundle; SKILL_DIR resolves to the skill directory, but the runtime Bash tool's CWD is the user's project, so a project-relative path (without the $SKILL_DIR prefix) would miss. Run it through an existence guard so platforms that cannot locate the script (harnesses where $SKILL_DIR is unset) fall back to the same manual gate instead of silently skipping the protection:
if [ -n "${SKILL_DIR:-}" ] && [ -f "$SKILL_DIR/scripts/validate-frontmatter.py" ]; then
bash "$SKILL_DIR/scripts/run-python.sh" "$SKILL_DIR/scripts/validate-frontmatter.py" --promotion <candidate-path>
else
echo "Bundled validate-frontmatter.py not resolvable on this platform; applying the parser-safety and promotion checklist manually."
fi--- (trailing whitespace is fine; ---- or ---extra is not a valid delimiter).key: value, no leading indentation) whose value is not already quoted or structured (does not start with ", ', [, {, |, or >): the value must contain no unquoted # (space-then-hash — YAML treats it as a comment and silently truncates) and no unquoted : (colon-then-space — strict YAML may read it as a nested mapping). Quote the whole value if either appears.source_refs appears exactly once as a top-level non-empty block or flow array, and every item is a non-empty string. Plain tokens that common YAML parsers type as null, boolean, number, sexagesimal, date, or timestamp do not count as strings; quote them.invalidation_condition appears exactly once as a top-level non-empty scalar or block string, with the same implicit-type quoting rule for plain scalar values.
Nested parser-safety values, semantic source credibility, and semantic invalidation adequacy remain outside this mechanical fallback. Then state in the completion output that the bundled script validator was unavailable on this platform and the checks were applied manually.Default validator mode remains parser-safety-only for legacy compatibility. --promotion adds only the two promotion exit shapes; it does not judge reference credibility, invalidation adequacy, other schema fields, or enum values. It also does not flag YAML reserved-indicator characters (those produce loud parser errors downstream rather than silent corruption — out of scope). Uses Python 3 stdlib only (no PyYAML or other deps).
When creating a new doc, preserve the section order from assets/resolution-template.md unless the user explicitly asks for a different structure. A candidate passing this mechanical check is not promoted yet.
</sequential_tasks>
First, read references/concepts-vocabulary.md. This is unconditional. Do not pre-judge from memory that nothing qualifies — the reference's criteria are non-obvious and qualifying terms often live in the surrounding conversation rather than the new doc itself. Reading the reference is what makes the rest of the phase possible.
Then, applying those criteria, scan the learning candidate and the surrounding conversation for qualifying domain terms. Prepare any resulting CONCEPTS.md change as <private-scratch-dir>/concepts-candidate.md; do not modify the durable file before Phase 2.47. If CONCEPTS.md exists at repo root, base the candidate on its current contents and record its SHA-256; if it does not exist and at least one qualifying term surfaced, prepare a new candidate.
Verify behavior assertions against source before writing them. When an entry asserts how code behaves (states, transitions, limits, semantics), Read the defining source at the current tree first — an entry drafted from a session-level summary is exactly how wrong semantics enter the glossary. Phase 2.45 re-checks these entries, but the cheap fix is to not write the error.
Seed the learning's area at creation — don't write a lone term. When CONCEPTS.md does not yet exist, alongside the surfaced term also seed the core domain nouns of the area this learning touched, following the Seed goal and Scope of a seed rules in references/concepts-vocabulary.md. The seed is scoped to the learning's area (the modules and domain the fix touched) and defines only terms investigated here — it does not reach for repo-wide nouns. This anchors the surfaced term so it does not dangle against undefined siblings. A repo-wide concept map is spec-compound-refresh's bootstrap path, not this one.
At creation, hold the qualifying bar conservatively for borderline terms. A borderline term, or a class/table/file name dressed up as an entity, defers to a later run — clear core nouns are seeded, borderline ones wait. The conservatism is about quality, not count; updates to an existing file follow the normal criteria.
When bootstrapping the file, start with this preamble under the # Concepts heading, then add the qualifying entries below it:
Shared domain vocabulary for this project — entities, named processes, and status concepts with project-specific meaning. Seeded with core domain vocabulary, then accretes as spec-compound and spec-compound-refresh process learnings; direct edits are fine. Glossary only, not a spec or catch-all.
Refresh the coherence neighborhood of any entry you touch. When adding or editing an entry, also inspect its coherence neighborhood — its cluster siblings and the terms it cross-references or that reference it. Within that neighborhood, do two things: fix glossary violations (implementation specifics — file paths, class names, function signatures, current-config values), and refresh entries the learning's own evidence shows have drifted. Bounds: neighborhood only, never a full-file audit; refresh only on evidence already in hand; if judging a neighbor would require investigation this learning did not do, flag it for spec-compound-refresh rather than editing on a guess. The test: after the edit, would a reader find the touched entry's siblings or referenced terms inconsistent with it? Broader audit is spec-compound-refresh's job.
If no terms qualified after applying the reference's criteria, record that outcome explicitly in the success output (e.g., "Vocabulary capture: scanned, no qualifying terms"). Do not silently skip — the visible scan-and-no-result record is the audit signal that the reference was consulted.
Prepare the vocabulary candidate silently in every mode — no user prompt in interactive, lightweight, or headless. Vocabulary capture is a declared side effect of compounding, not a separate decision per run; the durable write still waits for the shared promotion decision and target-hash recheck. Lightweight mode reaches this through its own single-pass step (see Lightweight Mode), and runs an update-only version — it refines an existing CONCEPTS.md but defers creation/seeding to a Full run.
The candidate (and any CONCEPTS.md candidate entries from Phase 2.4) may become permanent, trusted knowledge. Validate its claims against the tree before it compounds. Read references/grounding-validation.md now — it holds the adjudication rules and the validator prompt; the steps below are only the trigger.
Mechanical claims check (every mode, including headless). Do not run git fetch unless the current user or visible upstream handoff separately authorized network access and remote-ref mutation; otherwise use existing local refs and mark remote merge-state claims degraded when they cannot be confirmed. Then run the bundled validator against the candidate:
SKILL_DIR="<absolute path of the directory containing the SKILL.md you just read>"
bash "$SKILL_DIR/scripts/run-python.sh" "$SKILL_DIR/scripts/validate-doc-claims.py" <candidate-path>Exit 0 means nothing flagged. Exit 1 means flags to adjudicate, not auto-fix — each flagged path, SHA, link, or scaffold pattern is fixed, annotated as historical, or confirmed intentional per the reference's adjudication table. A doc may legitimately cite a path deleted by the very fix it documents; a flag is a question, not a failure. If the script cannot be resolved on this platform, apply the reference's manual checklist and say so in the output — never silently skip.
Semantic grounding validator (Full and headless; lightweight skips this separate pass). When the Dispatch Authorization Boundary is satisfied, dispatch one read-only generic subagent built from the prompt template in the reference, covering the learning candidate plus any CONCEPTS.md candidate entries added or edited this run. Otherwise apply that validator prompt inline, record the matching fallback reason, and do not claim independent semantic validation. In either path, verify code-behavior claims by quoting the defining source line, merge-state claims against remote truth (gh primary, git reachability fallback), and internal completeness of countable assertions. Apply verdicts per the reference, then re-run the mechanical check if the body changed.
Full interactive runs may apply the problem-specific review prompts below to the private candidate before promotion. Headless and Lightweight skip this phase to keep their cost bounded. Dispatch generic read-only reviewers only when the Dispatch Authorization Boundary is satisfied; otherwise run the selected review inline or serially and label it non-independent.
references/agents/performance-oracle.mdreferences/agents/security-sentinel.mdreferences/agents/data-integrity-guardian.mdspec-simplify-code or mutate product code from this workflow.Apply accepted suggestions only to <private-scratch-dir>/learning-candidate.md or <private-scratch-dir>/concepts-candidate.md. If either candidate changes, rerun the applicable frontmatter and claims checks plus semantic grounding for affected claims. No optional reviewer may edit a durable target or run after publication and still count toward the promotion decision.
The orchestrator now makes the semantic promotion decision; scripts do not make it. Choose promote only when the problem is demonstrably resolved, the cited evidence is relevant to the claims, contradictions with current source are resolved in favor of source, and the invalidation condition describes a concrete re-check trigger. A transcript assertion such as “fixed” or “tests passed” is not outcome evidence. A separate reviewer is useful for high-risk material when dispatch is authorized, but is not a universal prerequisite for ordinary low-risk promotion; record whether semantic validation was independent or inline.
skip, leave every final durable path unchanged, best-effort remove the private candidates, and emit Documentation skipped with the failed semantic or evidence condition.promote, first recompute the recorded existence/SHA-256 of every final target. If any target drifted, stop and rebuild/review the affected candidates against the new source; do not overwrite it. Prepare and validate every same-directory temporary file before the first rename. Publish an approved CONCEPTS.md candidate first and the primary learning last; each target replacement is atomic, but a multi-target run is not an all-or-nothing filesystem transaction. If a later rename fails after an earlier target was published, report the exact partial publication, keep the run incomplete, and do not emit Documentation complete or attempt an unverified overwrite.The final docs/solutions/** path remains untouched until this phase. This is the durable candidate -> review -> promote boundary; scratch artifacts are not durable knowledge and are never returned as a successful deliverable.
After publishing the new learning, decide whether this new solution is evidence that older docs should be refreshed.
spec-compound-refresh is not a default follow-up. Use it selectively when the new learning suggests an older learning or pattern doc may now be inaccurate.
It makes sense to invoke spec-compound-refresh when one or more of these are true:
It does not make sense to invoke spec-compound-refresh when:
Use these rules:
spec-compound-refresh with a narrow scope hint after the new learning is writtenspec-compound-refresh as the next step with a scope hintspec-compound-refresh and never ask the user. Surface the recommended scope hint in the terminal report's "Refresh recommendation" line and let the caller decideWhen invoking or recommending spec-compound-refresh, be explicit about the argument to pass. Prefer the narrowest useful scope:
docs/solutions/patterns/Examples:
spec-compound-refresh plugin-versioning-requirementsspec-compound-refresh paymentsspec-compound-refresh performance-issuesspec-compound-refresh critical-patternsA single scope hint may still expand to multiple related docs when the change is cross-cutting within one domain, category, or pattern area.
Do not invoke spec-compound-refresh without an argument unless the user explicitly wants a broad sweep.
Always capture the new learning first. Refresh is a targeted maintenance follow-up, not a prerequisite for documentation.
After the learning is written and the refresh decision is made, check whether the project's instruction files would lead an agent to discover and search docs/solutions/ before starting work in a documented area. This runs every time — the knowledge store only compounds value when agents can find it.
Identify which root-level instruction files exist (AGENTS.md, CLAUDE.md, or both). Read the file(s) and determine which holds the substantive content — one file may just be a shim that @-includes the other (e.g., CLAUDE.md containing only @AGENTS.md, or vice versa). The substantive file is the assessment and edit target; ignore shims. If neither file exists, skip this check entirely.
Assess whether an agent reading the instruction files would learn three things:
module, tags, problem_type)This is a semantic assessment, not a string match. The information could be a line in an architecture section, a bullet in a gotchas section, spread across multiple places, or expressed without ever using the exact path docs/solutions/. Use judgment — if an agent would reasonably discover and use the knowledge store after reading the file, the check passes.
If the spirit is already met, no action needed — move on.
If not: a. Based on the file's existing structure, tone, and density, identify where a mention fits naturally. Before creating a new section, check whether the information could be a single line in the closest related section — an architecture tree, a directory listing, a documentation section, or a conventions block. A line added to an existing section is almost always better than a new headed section. Only add a new section as a last resort when the file has clear sectioned structure and nothing is even remotely related. b. Draft the smallest addition that communicates the three things. Match the file's existing style and density. The addition should describe the knowledge store itself, not the plugin — an agent without the plugin should still find value in it.
Keep the tone informational, not imperative. Express timing as description, not instruction — "relevant when implementing or debugging in documented areas" rather than "check before implementing or debugging." Imperative directives like "always search before implementing" cause redundant reads when a workflow already includes a dedicated search step. The goal is awareness: agents learn the folder exists and what's in it, then use their own judgment about when to consult it.
Examples of calibration (not templates — adapt to the file):
When there's an existing directory listing or architecture section — add a line:
docs/solutions/ # documented solutions to past problems (bugs, best practices, workflow patterns), organized by category with YAML frontmatter (module, tags, problem_type)When nothing in the file is a natural fit — a small headed section is appropriate:
## Documented Solutions
`docs/solutions/` — documented solutions to past problems (bugs, best practices, workflow patterns), organized by category with YAML frontmatter (`module`, `tags`, `problem_type`). Relevant when implementing or debugging in documented areas.c. In full interactive mode, explain to the user why this matters — agents working in this repo (including fresh sessions, other tools, or collaborators without the plugin) won't know to check docs/solutions/ unless the instruction file surfaces it. Show the proposed change and where it would go, then use the platform's blocking question tool to get consent before making the edit: AskUserQuestion in Claude Code (call ToolSearch with select:AskUserQuestion first if its schema isn't loaded), request_user_input in Codex. Fall back to presenting the proposal in chat only when no blocking tool exists in the harness or the call errors (e.g., Codex edit modes) — not because a schema load is required. Never silently skip the question. In lightweight mode, output a one-line note and move on. In headless mode, do not edit instruction files; emit the proposed change under Discoverability recommendation in the structured terminal report.
If CONCEPTS.md exists at repo root, run a parallel discoverability check for it. Assess whether the instruction file would lead an agent to discover the project's shared domain vocabulary. Use the same workflow as the docs/solutions/ check above: same target file, same edit-placement judgment, same consent-then-edit interaction shape per mode. A line in an existing section is almost always better than a new headed section. Example calibration when nothing else fits:
CONCEPTS.md # shared domain vocabulary (entities, named processes, status concepts) — relevant when orienting to the codebase or discussing domain conceptsSkip this step entirely if CONCEPTS.md does not exist — never nag for an artifact the project has not adopted. When skipped, this step produces no output and no edit.
<critical_requirement> Single-pass alternative — same documentation, fewer tokens.
This mode skips parallel subagents entirely. The orchestrator performs all work in a single pass, producing the same solution document without cross-referencing or duplicate detection.
Headless mode forces Full and does not enter Lightweight — automations get the cross-reference and overlap detection benefits without the interactive overhead.
Lightweight is valid only when the mode-selection eligibility above is satisfied. Security/authorization, data-integrity, migration/release, privacy/compliance, or irreversible-mutation learnings never enter Lightweight merely because context is tight. </critical_requirement>
The orchestrator (main conversation) performs ALL of the following in one sequential pass:
references/schema.yaml and references/yaml-schema.md, then determine track (bug vs knowledge), category, and filename<private-scratch-dir>/learning-candidate.md using the appropriate track template from assets/resolution-template.md. Record the intended final path and its current existence/SHA-256, but do not create or modify that path yet. Include:source_refs array, and a concrete non-empty invalidation_condition, applying the YAML-safety quoting rule for array items (see references/yaml-schema.md > YAML Safety Rules)CONCEPTS.md exists at repo root, read references/concepts-vocabulary.md, then scan the learning candidate and the conversation for qualifying terms and prepare any refinement as <private-scratch-dir>/concepts-candidate.md (same criteria as Phase 2.4). Record the original SHA-256 and leave the final file untouched. Do not bootstrap or seed in lightweight mode — if CONCEPTS.md does not exist, defer creation to a Full run, which owns seeding. Record the outcome in the output (e.g., "Vocabulary: 1 entry refined" or "scanned, no qualifying terms"). If you prepared a refinement and a quick read of AGENTS.md/CLAUDE.md shows CONCEPTS.md is not surfaced there, add the discoverability tip to the output below — lightweight tips, it does not edit instruction files (a Full run owns that edit).if [ -n "${SKILL_DIR:-}" ] && [ -f "$SKILL_DIR/scripts/validate-frontmatter.py" ]; then
bash "$SKILL_DIR/scripts/run-python.sh" "$SKILL_DIR/scripts/validate-frontmatter.py" --promotion <candidate-path>
else
echo "Bundled validate-frontmatter.py not resolvable on this platform; applying the parser-safety and promotion checklist manually."
fiscripts/validate-doc-claims.py against the candidate exactly as in Phase 2.45 step 1 (same SKILL_DIR anchor, same adjudicate-not-auto-fix rule — read references/grounding-validation.md for the adjudication table when it flags anything).promote decision may publish the candidate through the per-target atomic boundary. Any failed check, target drift, or unresolved contradiction leaves final paths unchanged and emits Documentation skipped.Lightweight output:
✓ Documentation complete (lightweight mode)
File created:
- docs/solutions/[category]/[filename].md
[If discoverability check found instruction files don't surface the knowledge store:]
Tip: Your AGENTS.md/CLAUDE.md doesn't surface docs/solutions/ to agents —
a brief mention helps all agents discover these learnings.
[If CONCEPTS.md was refined this run and isn't surfaced in the instruction files:]
Tip: Your AGENTS.md/CLAUDE.md doesn't surface CONCEPTS.md —
a one-line mention helps agents find the shared vocabulary.
Note: This was created in lightweight mode. For richer documentation
(cross-references, detailed prevention strategies, specialized reviews,
semantic grounding validation), re-run spec-compound in a fresh session.No subagents are launched. No parallel tasks. The solution doc is the one deliverable (Phase 2.4's update-only vocabulary capture may also refine an existing CONCEPTS.md).
In lightweight mode, the overlap check is skipped (no Related Docs Finder subagent). This means lightweight mode may create a doc that overlaps with an existing one. That is acceptable — spec-compound-refresh will catch it later. Only suggest spec-compound-refresh if there is an obvious narrow refresh target. Do not broaden into a large refresh sweep from a lightweight session.
<preconditions enforcement="advisory">
<check condition="problem_solved">
Problem has been solved (not in-progress)
</check>
<check condition="solution_verified">
Solution has been verified working
</check>
<check condition="non_trivial">
Non-trivial problem (not simple typo or obvious error)
</check>
</preconditions>
Organized documentation:
docs/solutions/[category]/[filename].mdCategories auto-detected from problem:
Bug track:
Knowledge track:
| ❌ Wrong | ✅ Correct |
|---|---|
Subagents write product files into docs/ or edit tracked paths | Subagents write only atomic artifacts under the verified owner-only <private-scratch-dir> and return the path; orchestrator writes the one final doc |
| Subagent returns a long prose body only as its inline response | Subagent writes full output to its run artifact; orchestrator Reads it back (inline return is fallback only) |
| Research and assembly run in parallel | Research completes → then assembly runs |
| Multiple files created during workflow | One solution doc written or updated: docs/solutions/[category]/[filename].md (plus optional maintenance writes: a CONCEPTS.md create/update from Phase 2.4 and a small instruction-file edit for discoverability) |
| Creating a new doc when an existing doc covers the same problem | Check overlap assessment; update the existing doc when overlap is high |
| Asserting code behavior or merge-state from conversation memory | Read the defining source line before asserting; cite PR numbers over SHAs; soften unverifiable claims (Phase 1 extractor rules, re-checked in Phase 2.45) |
| Batching several learnings through one run and stitching cross-references between drafts | One learning per run; run the skill sequentially for each additional learning |
Emit a structured terminal report and end the turn. No "What's next?" question, no blocking prompt. End with Documentation complete as the terminal signal so callers can detect completion.
✓ Documentation complete (headless mode)
File: docs/solutions/<category>/<filename>.md (created | updated)
Track: <bug | knowledge>
Category: <category>
Overlap: <none | low | moderate — see <path> | high — existing doc updated>
Grounding: <clean | N flags adjudicated (X fixed, Y annotated, Z confirmed) | N claims softened or corrected | degraded — merge-state claims unverified offline>
Instruction-file edit: <none needed | applied to <path> | gap noted, not applied>
CONCEPTS.md: <scanned, no qualifying terms | created with N entries (M seeded from the learning's area) | updated — N added, N refined>
Refresh recommendation: <none | scope hint for spec-compound-refresh>
Documentation completeWhen no doc was written (e.g., headless invoked on a session where the problem is not yet solved), emit a structured failure instead and end with Documentation skipped so callers can distinguish success from no-op:
✗ Documentation skipped (headless mode)
Reason: <one-sentence explanation — e.g., "no solved problem detected in
conversation history" or "solution not yet verified">
Documentation skipped✓ Documentation complete
Ran Full mode.
Auto memory: 2 relevant entries used as supplementary evidence
Execution: <dispatched | inline-serial (`dispatch_authorization_missing` | `subagent_capability_missing` | `worker_capability_unproven`)>
Research Results:
✓ Context Analyzer: Identified performance_issue in brief_system, category: performance-issues/
✓ Solution Extractor: 3 code fixes, prevention strategies
✓ Related Docs Finder: 2 related issues
✓ Session History: 3 prior sessions on same branch, 2 failed approaches surfaced
Grounding Validation:
✓ Mechanical check: 14 paths, 2 SHAs, 3 links checked — 1 flag annotated as historical
✓ Semantic validator: 9 claims verified, 1 merge-state claim softened to pending
Specialized Reviews (execution posture inherited from above):
✓ performance-oracle: Validated query optimization approach
✓ Code simplification review: Code examples are appropriately minimal
Files written:
- docs/solutions/performance-issues/n-plus-one-brief-generation.md (created)
- CONCEPTS.md (created with 3 entries: BriefSystem, EmailQueue, Brief Status)
This documentation will be searchable for future reference when similar
issues occur in the Email Processing or Brief System modules.
Refresh recommendation: noneEnd the turn after the summary — spec-compound does not present a "What's next?" menu. The doc is written and any cross-references the workflow found are already in it. Cross-doc maintenance (fixing references in other docs, consolidation) is deferred to spec-compound-refresh via the Refresh recommendation line above — the skill designed for it — not auto-applied here, which would edit tracked docs beyond the one deliverable. If the user wants to view the file or take a follow-up action, they will ask. (Interactive mode only.)
Alternate interactive output (when updating an existing doc due to high overlap): in headless mode, this case is communicated via the Overlap: high — existing doc updated line of the headless terminal report above, not as a separate output block.
✓ Documentation updated (existing doc refreshed with current context)
Overlap detected: docs/solutions/performance-issues/n-plus-one-queries.md
Matched dimensions: problem statement, root cause, solution, referenced files
Action: Updated existing doc with fresher code examples and prevention tips
File updated:
- docs/solutions/performance-issues/n-plus-one-queries.md (added last_updated: 2026-03-24)This creates a compounding knowledge system:
The feedback loop:
Build → Test → Find Issue → Research → Improve → Document → Validate → Deploy
↑ ↓
└──────────────────────────────────────────────────────────────────────┘Each unit of engineering work should make subsequent units of work easier—not harder.
<auto_invoke> <trigger_phrases> - "that worked" - "it's fixed" - "working now" - "problem solved" </trigger_phrases>
<manual_override> Use spec-compound [context] to document immediately without waiting for auto-detection. </manual_override> </auto_invoke>
Publishes the approved learning into docs/solutions/ only after candidate validation and the semantic promotion decision succeed. A skipped or failed promotion leaves every durable target unchanged.
Based on problem type, these local prompt assets can enhance documentation:
spec-simplify-code after spec-compound completes for deeper code review and mutationspec-plan - Planning workflow (references documented solutions)© leo-kuang-ai, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 29 other files (scripts, references, assets) in skills/spec-compound of leo-kuang-ai/spec-first.
Open the folder on GitHubat commit 74655dc
Spec Compound next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Spec Compound this skillleo-kuang-ai/spec-first | 107 | — | ~18k | Automated safety check: Pass | MIT | |
| Vercel Composition Patternssupabase/supabase | 111k | 58 repos | ~726 | Automated safety check: Pass | MIT | |
| Finishing a Development Branchobra/superpowers | 297k | 5 repos | ~1.9k | Automated safety check: Pass | MIT | |
| Typescript Advanced Typesrolling-scopes/rsschool-app | 10k | 25 repos | ~4.2k | Automated safety check: Pass | MPL-2.0 | |
| PR Babysitteropeninterpreter/openinterpreter | 69k | 3 repos | ~4.2k | Automated safety check: Pass | Apache-2.0 | |
| Code Review ChecklistshareAI-lab/learn-claude-code | 78k | 4 repos | ~1.1k | Automated safety check: Pass | MIT |
supabase/supabase
React composition patterns that scale. An agent skill from supabase/supabase.
obra/superpowers
Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.
rolling-scopes/rsschool-app
Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications.
openinterpreter/openinterpreter
Watches an open GitHub pull request until it merges, handling review comments, diagnosing CI failures and retrying flaky checks along the way.
shareAI-lab/learn-claude-code
Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.
onyx-dot-app/onyx
Iteratively improves a PR (GitHub), MR (GitLab), or shelved changelist (Perforce) until Greptile gives it a 5/5 confidence score with zero unresolved comments.
leo-kuang-ai/spec-first
Audit mobile App PRD/Figma/local-source consistency across page routes, KMP/Clean Architecture, components, analytics, i18n, engineering quality, and industry lenses before runtime validation; use…
leo-kuang-ai/spec-first
Create a durable cross-session handoff or resume from a user-selected continuity source.
leo-kuang-ai/spec-first
Give a decisive, project-grounded verdict on an external input — judged against the current project, not in the abstract.
leo-kuang-ai/spec-first
Resolve PR review feedback by evaluating validity and fixing issues with conflict-aware resolver dispatch.
leo-kuang-ai/spec-first
Analyze explicit Riffrec product-feedback captures, including riffrec-.zip, the Riffrec session.json + events.json + recording.webm + voice.webm bundle, or media/notes the user identifies as a…
leo-kuang-ai/spec-first
Public workflow entrypoint (spec-prd): create, write, refine, or validate planning-readiness of brownfield PRD-grade requirements for existing systems before implementation planning.
Categories
Document a recently solved problem or durable project vocabulary in docs/solutions/ or CONCEPTS.md. Spec Compound is an agent skill from leo-kuang-ai/spec-first.md.
Spec Compound fits situations like: capturing a learning after work.
Run `npx skills add leo-kuang-ai/spec-first --skill spec-compound -a claude-code`. Or copy the skill folder (skills/spec-compound in leo-kuang-ai/spec-first) into .claude/skills/spec-compound in your project. Claude Code loads it when a task matches its description.
Run `npx skills add leo-kuang-ai/spec-first --skill spec-compound -a codex`. Or copy the skill folder (skills/spec-compound in leo-kuang-ai/spec-first) into .agents/skills/spec-compound in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add leo-kuang-ai/spec-first --skill spec-compound -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/spec-compound, .gemini/skills/spec-compound, .github/skills/spec-compound and .opencode/skills/spec-compound in your project.
Going by SKILL.md and its folder, Spec Compound needs JavaScript and a shell for the scripts in its folder and the command-line tools its instructions call (git, bash and gh). Our summary lists: Node.js; A Bash shell.
SKILL.md contains no URLs. Its commands use git and gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Spec Compound is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 18k tokens (SKILL.md is roughly 73k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 16k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Spec Compound: Vercel Composition Patterns (supabase/supabase, 111k stars), Finishing a Development Branch (obra/superpowers, 297k stars), Typescript Advanced Types (rolling-scopes/rsschool-app, 10k stars) and PR Babysitter (openinterpreter/openinterpreter, 69k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
leo-kuang-ai (a GitHub user) maintains it in leo-kuang-ai/spec-first, which has 107 GitHub stars. The repository holds 35 skills in this directory. The repository was last updated on October 8, 2026.
Source: leo-kuang-ai/spec-first on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.