/ce-compound

SkillDocs & knowledge

Document a recently solved problem or durable project vocabulary in docs/solutions/ or CONCEPTS.md. Use when capturing a learning after work.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the /ce-compound skill

What this skill tells your AI

The instructions your AI receives, as published by nota-america/forgecat-agent-profiles in profiles/everyinc/compound-engineering-plugin/for-forgecat/skills/ce-compound/SKILL.md and read by ahel’s review.

Coordinate multiple subagents working in parallel to document a recently solved problem.

Purpose

Captures problem solutions while context is fresh, creating structured documentation in docs/solutions/ with YAML frontmatter for searchability and future reference. Uses parallel subagents.

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.

Usage

/ce-compound                            # Document the most recent fix
/ce-compound [brief context]            # Provide additional context hint
/ce-compound mode:headless              # Non-interactive run for automations
/ce-compound mode:headless [context]    # Non-interactive run with context hint

CONCEPTS.md bootstrap requests

If invoked specifically to create or bootstrap CONCEPTS.md from scratch rather than to document a solved problem, do not run the normal phases — ce-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 ce-compound-refresh's job. Redirect a standalone bootstrap request to ce-compound-refresh (which asks whether to build the concept map or run a refresh cycle), then exit.

Mode Detection

Check $ARGUMENTS for a mode:headless token. Tokens starting with mode: are flags, not context — strip mode:headless from arguments before treating the remainder as the brief context hint.

ModeWhenBehavior
Interactive (default)No mode token presentAsk Full vs Lightweight, ask about session history (Full only), prompt for Discoverability Check consent, end with "What's next?"
Headlessmode:headless in argumentsNo blocking questions. Run Full mode without session history. Apply the Discoverability Check edit silently if a gap exists. Skip Phase 3 specialized reviews. 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.

Pre-resolved context

Git branch (pre-resolved): !git rev-parse --abbrev-ref HEAD 2>/dev/null || true

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 or is empty, derive the branch at runtime.

Repo root (pre-resolved): !git rev-parse --show-toplevel 2>/dev/null || pwd

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 or is empty, derive the repo root at runtime with git rev-parse --show-toplevel 2>/dev/null || pwd.

Support Files

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 the user opts into session history)
  • 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 deleted ce-sessions public skill
  • scripts/validate-frontmatter.py — frontmatter parser-safety validator (run in Phase 2 step 8 through the existence guard documented there; resolves only on Claude Code via ${CLAUDE_SKILL_DIR}, with a manual-checklist fallback elsewhere)

When spawning subagents, pass the relevant file contents into the task prompt so they have the contract without needing cross-skill paths.

Execution Strategy

In headless mode, skip both questions below and go directly to Full Mode with session history disabled. Phase 1's session-history step (step 4) is omitted. Proceed straight to research.

In interactive mode, present the user with two options before proceeding, using the platform's blocking question tool: AskUserQuestion in Claude Code (call ToolSearch with select:AskUserQuestion first if its schema isn't loaded), request_user_input in Codex, ask_question in Antigravity CLI (agy), ask_user in Pi (requires the pi-ask-user extension). Fall back to presenting options 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.

1. Full (recommended) — the complete compound workflow. Researches,
   cross-references, and reviews your solution to produce documentation
   that compounds your team's knowledge.

2. Lightweight — same documentation, single pass. Faster and uses
   fewer tokens, but won't detect duplicates or cross-reference
   existing docs. Best for simple fixes or long sessions nearing
   context limits.

In interactive mode, do NOT pre-select a mode, do NOT skip this prompt, and wait for the user's choice before proceeding. (Headless mode bypasses this prompt per the "In headless mode" rule above and runs Full directly — these "do not skip" directives do not apply to headless.)

If the user chooses Full (interactive mode only), ask one follow-up question before proceeding. Detect which harness is running (Claude Code, Codex, or Cursor) and ask:

Would you also like to search your [harness name] session history
for relevant knowledge to help the Compound process? This adds
time and token usage.

If the user says yes, run the internal session-history step in Phase 1 (see step 4). If no, skip it. Do not ask this in lightweight mode or headless mode. There is no standalone ce-sessions product surface; this support exists only inside the compounding workflow.


Full Mode

<critical_requirement> The primary deliverable is ONE file - the final documentation.

Phase 1 subagents write their full structured output to a per-run scratch artifact under /tmp/compound-engineering/ce-compound/<run-id>/ and return only a compact confirmation containing the artifact path. The orchestrator Reads those artifacts back in Phase 2 assembly. This is scratch space, identical in spirit to ce-code-review's per-reviewer run artifacts; it does not make the scratch files additional deliverables. 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 — create or update in Phase 2.4 (Vocabulary Capture) when a qualifying domain term surfaces.
  • A project instruction file (AGENTS.md or CLAUDE.md) — a small edit when the Discoverability Check finds a gap.

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>

Phase 0.5: Auto Memory Scan

Before launching Phase 1 subagents, check the auto-memory block injected into your system prompt for notes relevant to the problem being documented.

  1. Look for a block labeled "user's auto-memory" (Claude Code only) already present in your system prompt context — MEMORY.md's entries are inlined there
  2. If the block is absent, empty, or this is a non-Claude-Code platform, skip this step and proceed to Phase 1 unchanged
  3. Scan the entries for anything related to the problem being documented -- use semantic judgment, not keyword matching
  4. If relevant entries are found, prepare a labeled excerpt block:
## 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]
  1. Pass this block as additional context to the Context Analyzer and Solution Extractor task prompts in Phase 1. If any memory notes end up in the final documentation (e.g., as part of the investigation steps or root cause analysis), tag them with "(auto memory [claude])" so their origin is clear to future readers.

If no relevant entries are found, proceed to Phase 1 without passing memory context.

Phase 1: Research

Launch research subagents. Each writes its full output to a per-run scratch artifact and returns only the artifact path to the orchestrator.

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 ' ')
mkdir -p "/tmp/compound-engineering/ce-compound/$RUN_ID"

Pass {run_id} (the resolved $RUN_ID value) into every Phase 1 subagent prompt. Each subagent writes its full structured output to its own file under /tmp/compound-engineering/ce-compound/{run_id}/, 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:

  • Context Analyzer/tmp/compound-engineering/ce-compound/{run_id}/context.json (frontmatter skeleton, category path, filename, track)
  • Solution Extractor/tmp/compound-engineering/ce-compound/{run_id}/solution.md (the full doc-body prose sections)
  • Related Docs Finder/tmp/compound-engineering/ce-compound/{run_id}/related.json (links, refresh candidates, overlap assessment)
  • Session History synthesis subagent (when run) → /tmp/compound-engineering/ce-compound/{run_id}/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.

Dispatch order:

  • Launch Context Analyzer, Solution Extractor, and Related Docs Finder in parallel (background)
  • Then run the internal session-history discovery/extraction/synthesis flow (see step 4 below) — only if the user opted in to session history. This flow is synchronous from this orchestrator's main-context turn, but the already-dispatched background subagents continue running in parallel underneath, so the wall-clock benefit is preserved (max(session-history, slowest background subagent), not their sum). Running session history before the parallel block would serialize it in front of the research subagents and regress wall-clock time.

<parallel_tasks>

1. Context Analyzer
  • Extracts conversation history
  • Reads references/schema.yaml for enum validation and track classification
  • Determines the track (bug or knowledge) from the problem_type
  • Identifies problem type, component, and track-appropriate fields:
    • Bug track: symptoms, root_cause, resolution_type
    • Knowledge track: applies_when (symptoms/root_cause/resolution_type optional)
  • Incorporates auto memory excerpts (if provided by the orchestrator) as supplementary evidence
  • Reads references/yaml-schema.md for category mapping into docs/solutions/
  • Suggests a filename using the pattern [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 date
  • Writes to context.json: YAML frontmatter skeleton (must include category: field mapped from problem_type), category directory path, suggested filename, and which track applies. Returns only the artifact path.
  • Does not invent enum values, categories, or frontmatter fields from memory; reads the schema and mapping files above
  • Does not force bug-track fields onto knowledge-track learnings or vice versa
2. Solution Extractor
  • Reads references/schema.yaml for track classification (bug vs knowledge)
  • Adapts output structure based on the problem_type track
  • Writes the full doc-body prose (all track-appropriate sections below) to 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.
  • Incorporates auto memory excerpts (if provided by the orchestrator) as supplementary evidence -- conversation history and the verified fix take priority; if memory notes contradict the conversation, note the contradiction as cautionary context

Bug track output sections:

  • Problem: 1-2 sentence description of the issue
  • Symptoms: Observable symptoms (error messages, behavior)
  • What Didn't Work: Failed investigation attempts and why they failed
  • Solution: The actual fix with code examples (before/after when applicable)
  • Why This Works: Root cause explanation and why the solution addresses it
  • Prevention: Strategies to avoid recurrence, best practices, and test cases. Include concrete code examples where applicable (e.g., gem configurations, test assertions, linting rules)

Knowledge track output sections:

  • Context: What situation, gap, or friction prompted this guidance
  • Guidance: The practice, pattern, or recommendation with code examples when useful
  • Why This Matters: Rationale and impact of following or not following this guidance
  • When to Apply: Conditions or situations where this applies
  • Examples: Concrete before/after or usage examples showing the practice in action
3. Related Docs Finder
  • Searches docs/solutions/ for related documentation
  • Identifies cross-references and links
  • Finds related GitHub issues
  • Flags any related learning or pattern docs that may now be stale, contradicted, or overly broad
  • Assesses overlap with the new doc being created across five dimensions: problem statement, root cause, solution approach, referenced files, and prevention rules. Score as:
    • High: 4-5 dimensions match — essentially the same problem solved again
    • Moderate: 2-3 dimensions match — same area but different angle or solution
    • Low: 0-1 dimensions match — related but distinct
  • Writes to related.json: Links, relationships, refresh candidates, and overlap assessment (score + which dimensions matched). Returns only the artifact path.

Search strategy (grep-first filtering for efficiency):

  1. Extract keywords from the problem context: module names, technical terms, error messages, component types
  2. If the problem category is clear, narrow search to the matching docs/solutions/<category>/ directory
  3. Use the native content-search tool (e.g., Grep in Claude Code) to pre-filter candidate files BEFORE reading any content. Run multiple searches in parallel, case-insensitive, targeting frontmatter fields. These are template patterns -- substitute actual keywords:
    • title:.*<keyword>
    • tags:.*(<keyword1>|<keyword2>)
    • module:.*<module name>
    • component:.*<component>
  4. If search returns >25 candidates, re-run with more specific patterns. If <3, broaden to full content search
  5. Read only frontmatter (first 30 lines) of candidate files to score relevance
  6. Fully read only strong/moderate matches
  7. Return distilled links and relationships, not raw file contents

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.

</parallel_tasks>

4. Session History (internal flow after launching the parallel block — only if the user opted in)
  • Skip entirely if the user declined session history in the follow-up question, if running in lightweight mode, or if running in headless mode.
  • Run session discovery, branch/keyword filtering, scan-window selection, deep-dive selection, and per-session extraction directly inside this skill using scripts/session-history/.
  • Read the skill-local synthesis prompt at 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 context
    

Do 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.

  • Returns: structured digest of findings from prior sessions, or "no relevant prior sessions" if none found.
  • Session history is the final Phase 1 input, not a workflow stop. When it returns, proceed directly to Phase 2 with its output as the last input — do not emit a summary and do not pause for the user. A "no relevant prior sessions" return is still a valid input; the documentation gets written without session context.

Script resolution. On Claude Code, run the bundled scripts through ${CLAUDE_SKILL_DIR}/scripts/session-history/. On platforms where ${CLAUDE_SKILL_DIR} is unavailable and the script path cannot be resolved from the loaded skill directory, skip session history visibly with: "Session history was requested, but this platform did not expose the bundled session-history scripts to the runtime." 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:

if [ -n "${CLAUDE_SKILL_DIR}" ] && [ -f "${CLAUDE_SKILL_DIR}/scripts/session-history/discover-sessions.sh" ] && [ -f "${CLAUDE_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 "${CLAUDE_SKILL_DIR}/scripts/session-history/discover-sessions.sh" "$REPO_NAME" "$SCAN_DAYS" --cwd "$REPO_ROOT" | tr '\n' '\0' | xargs -0 python3 "${CLAUDE_SKILL_DIR}/scripts/session-history/extract-metadata.py" --cwd-filter "$REPO_ROOT"
else
  echo "Session history was requested, but this platform did not expose the bundled session-history scripts to the runtime."
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.

Extraction pipeline. Create SCRATCH=$(mktemp -d -t ce-compound-sessions-XXXXXX). For each selected session, write extracted content to scratch files:

if [ -n "${CLAUDE_SKILL_DIR}" ] && [ -f "${CLAUDE_SKILL_DIR}/scripts/session-history/extract-skeleton.py" ]; then
  python3 "${CLAUDE_SKILL_DIR}/scripts/session-history/extract-skeleton.py" --output "$SCRATCH/<session-id>.skeleton.txt" < <session-file>
else
  echo "Session history was requested, but this platform did not expose the bundled session-history scripts to the runtime."
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:

  • the full content of references/agents/session-historian.md
  • problem_topic
  • scratch_dir
  • a sessions array with extracted file paths and metadata
  • the output schema above
  • the filter rule above

The subagent reads only the scratch paths, writes its prose findings to /tmp/compound-engineering/ce-compound/{run_id}/session-history.md, and returns only that artifact path once the write is confirmed (same #956 reliability rationale — session-history findings are long-form prose prone to summary-collapse). If {run_id} did not resolve or the artifact write failed, it returns the prose inline instead (per the inline-fallback rule above). If synthesis fails, note the failure and continue without session context.

Phase 2: Assembly & Write

<sequential_tasks>

WAIT for all Phase 1 inputs to complete before proceeding — the three parallel subagents and, when the user opted in, the internal session-history flow. Session history is a Phase 1 input even though it runs in the orchestrator rather than as a public skill.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
67
Forks
4
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
ce-compound-nota-america
Source
github.com/nota-america/forgecat-agent-profiles