diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json
index 5e6c891..b1a7180 100644
--- a/.claude-plugin/plugin.json
+++ b/.claude-plugin/plugin.json
@@ -1,12 +1,12 @@
{
"name": "ultraplan-local",
- "description": "Five-command context-engineering pipeline (brief → research → architect → plan → execute) with project folders, CC-feature matching, specialized agent swarms, external research triangulation, adversarial review, session decomposition, and headless execution.",
- "version": "2.4.0",
+ "description": "Four-command context-engineering pipeline (brief → research → plan → execute) with project folders, specialized agent swarms, external research triangulation, adversarial review, session decomposition, and headless execution. CC-feature matching extracted to the separate ultra-cc-architect plugin in v3.0.0.",
+ "version": "3.0.0",
"author": {
"name": "Kjell Tore Guttormsen"
},
"homepage": "https://git.fromaitochitta.com/open/ultraplan-local",
"repository": "https://git.fromaitochitta.com/open/ultraplan-local.git",
"license": "MIT",
- "keywords": ["planning", "implementation", "research", "cc-architecture", "context-engineering", "agents", "adversarial-review", "headless", "execution"]
+ "keywords": ["planning", "implementation", "research", "context-engineering", "agents", "adversarial-review", "headless", "execution"]
}
diff --git a/.gitignore b/.gitignore
index c0ef0c3..e28a372 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,9 +10,8 @@ Desktop.ini
.vscode/
.idea/
-# Local configuration
+# Local configuration / session files
*.local.md
-
-# Skill-factory drafts (Fase 1 — manual promotion via mv)
-skills/cc-architect-catalog/.drafts/*.md
-!skills/cc-architect-catalog/.drafts/.gitkeep
+REMEMBER.md
+TODO.md
+ROADMAP.md
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2715726..9c7aa43 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,92 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
+## [3.0.0] - 2026-04-30
+
+### Architect extracted to its own plugin
+
+The `/ultra-cc-architect-local` and `/ultra-skill-author-local` commands, all
+seven of their agents, the `cc-architect-catalog` skill, the `ngram-overlap.mjs`
+script, and the skill-factory test fixtures moved out of `ultraplan-local` and
+into the new `ultra-cc-architect` plugin (v0.1.0).
+
+### Why
+
+`ultraplan-local` had drifted into containing two distinct domains:
+
+1. A **universal planning pipeline** (brief → research → plan → execute) that
+ is technology-agnostic and works for any implementation task.
+2. A **Claude-Code-specific architecture phase** that only makes sense when
+ building features for Claude Code itself.
+
+Keeping them in one plugin caused three problems:
+
+- Users who wanted only the planning pipeline had to clone an unfinished
+ CC-feature catalog and seven architect/skill-author agents they would
+ never invoke.
+- The architect catalog (~11 seed skills) and the planning pipeline lived on
+ different release cadences. Architect work blocked pipeline development
+ and vice-versa.
+- New users saw six commands when only four belonged to the core flow.
+
+The architect was already marked `optional, v2.2` and was fully decoupled at
+the code level — only one filesystem touchpoint remained: `/ultraplan-local`
+auto-discovers `architecture/overview.md` if present, and gracefully handles
+its absence. The split is therefore non-breaking for the planning flow.
+
+### What moved to `ultra-cc-architect`
+
+- **Commands:** `/ultra-cc-architect-local`, `/ultra-skill-author-local`
+- **Agents:** `architect-orchestrator`, `feature-matcher`, `gap-identifier`,
+ `architecture-critic`, `skill-author-orchestrator`, `concept-extractor`,
+ `skill-drafter`, `ip-hygiene-checker`
+- **Skills:** `skills/cc-architect-catalog/` (13 files)
+- **Scripts:** `scripts/ngram-overlap.mjs`, `scripts/ngram-overlap.test.mjs`
+- **Test fixtures:** `tests/fixtures/skill-factory/`,
+ `tests/fixtures/skill-drafter/`
+
+All moves used `git mv`, so history follows the files into the new plugin.
+
+### What stayed unchanged in ultraplan-local
+
+- `/ultraplan-local` Phase 1 still auto-discovers `architecture/overview.md`.
+ The discovery is filesystem-based, not plugin-based — installing both
+ plugins gives you the full pipeline (brief → research → architect → plan
+ → execute).
+- `agents/planning-orchestrator.md` retains its architecture-note
+ cross-reference.
+- All other commands (`/ultrabrief-local`, `/ultraresearch-local`,
+ `/ultraexecute-local`) are untouched.
+
+### Migration
+
+If you only used `/ultrabrief-local`, `/ultraresearch-local`,
+`/ultraplan-local`, and `/ultraexecute-local`: no action needed. Update the
+plugin and continue.
+
+If you used `/ultra-cc-architect-local` or `/ultra-skill-author-local`:
+install the new plugin alongside this one. In `~/.claude/settings.json`:
+
+```json
+{
+ "enabledPlugins": {
+ "ultraplan-local@ktg-plugin-marketplace": true,
+ "ultra-cc-architect@ktg-plugin-marketplace": true
+ }
+}
+```
+
+Custom seed skills you added to `cc-architect-catalog/` follow with the
+catalog. Use `git log --follow` if you need to track them in the new
+location.
+
+### plugin.json changes
+
+- `version`: `2.4.0` → `3.0.0`
+- `description`: now describes a four-command pipeline; CC-feature matching
+ is described as living in the separate `ultra-cc-architect` plugin
+- `keywords`: removed `cc-architecture`
+
## [2.4.0] - 2026-04-19
### Breaking change — background mode removed
diff --git a/CLAUDE.md b/CLAUDE.md
index 3db0d01..c6a0c7a 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,8 +1,10 @@
# ultraplan-local
-Deep implementation planning and research with an explicit brief step, specialized agent swarms, external research, CC-feature matching, adversarial review, session decomposition, disciplined execution, and headless support. A local alternative to Anthropic's Ultraplan.
+Deep implementation planning and research with an explicit brief step, specialized agent swarms, external research, adversarial review, session decomposition, disciplined execution, and headless support. A local alternative to Anthropic's Ultraplan.
-**Design principle: Context Engineering** — build the right context by orchestrating specialized agents. Each step in the pipeline (brief → research → architect → plan → execute) produces a structured artifact that the next step consumes.
+**Design principle: Context Engineering** — build the right context by orchestrating specialized agents. Each step in the pipeline (brief → research → plan → execute) produces a structured artifact that the next step consumes.
+
+> **v3.0.0 — architect extracted to separate plugin.** `/ultra-cc-architect-local` and `/ultra-skill-author-local` were moved to the `ultra-cc-architect` plugin (v0.1.0). The plan command still auto-discovers `architecture/overview.md` if present, so installing both plugins gives you the full five-stage flow. See [CHANGELOG.md](CHANGELOG.md) for migration steps.
## Commands
@@ -10,10 +12,8 @@ Deep implementation planning and research with an explicit brief step, specializ
|---------|-------------|-------|
| `/ultrabrief-local` | Brief — interactive interview produces a task brief with explicit research plan; optionally orchestrates the pipeline | opus |
| `/ultraresearch-local` | Research — deep local + external research, produces structured research brief | opus |
-| `/ultra-cc-architect-local` | Architect *(optional, v2.2)* — match brief+research against Claude Code features; produce architecture note with gaps. Requires `--project` | opus |
| `/ultraplan-local` | Plan — brief-reviewer, explore, plan, review. Requires `--brief` or `--project`. Auto-discovers `architecture/overview.md` if present | opus |
| `/ultraexecute-local` | Execute — disciplined plan/session-spec executor with failure recovery | opus |
-| `/ultra-skill-author-local` | Authoring *(v2.3, skill-factory Fase 1)* — generate one cc-architect-catalog draft from a local source with IP-hygiene | opus |
### /ultrabrief-local modes
@@ -37,17 +37,6 @@ Always interactive. Phase 3 is a section-driven completeness loop (no hard cap o
Flags combine: `--project
--local`, `--external --quick`.
-### /ultra-cc-architect-local modes *(optional, v2.2)*
-
-| Flag | Behavior |
-|------|----------|
-| `--project ` | **Required** — read `{dir}/brief.md` and `{dir}/research/*.md`, write `{dir}/architecture/overview.md` + `{dir}/architecture/gaps.md` |
-| `--fg` | No-op alias (foreground is default since v2.4.0) |
-| `--quick` | Skip adversarial review (architecture-critic) |
-| `--no-gaps` | Skip gap-identifier; overview.md only |
-
-Architect sits between `/ultraresearch-local` and `/ultraplan-local`. It matches the task brief + research against available Claude Code features (Hooks, Subagents, Skills, Output Styles, MCP, Plan Mode, Worktrees, Background Agents) using a seeded catalog skill, and produces a proposed feature set with brief-anchored rationale plus explicit gaps (missing reference, pattern, decision, or outside-CC-scope).
-
### /ultraplan-local modes
| Flag | Behavior |
@@ -62,6 +51,8 @@ Architect sits between `/ultraresearch-local` and `/ultraplan-local`. It matches
**Breaking change (v2.0):** one of `--brief` or `--project` is required. There is no interview inside `/ultraplan-local`. The `--spec` flag has been removed — use `/ultrabrief-local` to produce a brief instead.
+If `{project_dir}/architecture/overview.md` exists (typically produced by the separate `ultra-cc-architect` plugin), the plan command auto-discovers it and treats `cc_features_proposed` as priors. Missing file is fine — discovery is additive, not required.
+
### /ultraexecute-local modes
| Flag | Behavior |
@@ -93,10 +84,6 @@ Architect sits between `/ultraresearch-local` and `/ultraplan-local`. It matches
| plan-critic | sonnet | Adversarial plan review (9 dimensions) |
| scope-guardian | sonnet | Scope alignment (creep + gaps) |
| session-decomposer | sonnet | Splits plans into headless sessions with dependency graph |
-| architect-orchestrator | opus | Inline reference documentation for the architecture phase workflow (feature-matcher + gap-identifier + critic) |
-| feature-matcher | sonnet | Match brief+research to CC features using catalog; brief-anchored rationale + fallback ranking |
-| gap-identifier | sonnet | Detect catalog/pattern/decision/outside-CC-scope gaps; emit issue-ready drafts |
-| architecture-critic | sonnet | Adversarial review of architecture note (hallucination gate, brief-anchor integrity, gap honesty) |
| docs-researcher | sonnet | Official documentation, RFCs, vendor docs (Tavily, MS Learn) |
| community-researcher | sonnet | Community experience: issues, blogs, discussions |
| security-researcher | sonnet | CVEs, audit history, supply chain risks |
@@ -109,9 +96,7 @@ Architect sits between `/ultraresearch-local` and `/ultraplan-local`. It matches
**Research:** Foreground workflow (v2.4.0): Parse mode → Interview → Parallel research swarm (5 local + 4 external + 1 bridge, spawned from main context) → Follow-ups → Triangulation → Synthesis + brief → Stats. With `--project`, writes to `{dir}/research/NN-slug.md`.
-**Architect (v2.2, optional):** Foreground workflow (v2.4.0): Parse mode (`--project` required) → Read inputs + audit catalog skill → Parallel `feature-matcher` + `gap-identifier` (spawned from main context) → Synthesize `overview.md` (6 sections + YAML frontmatter) → Adversarial review via `architecture-critic` (skipped in `--quick`; hallucination gate is BLOCKER) → Write `gaps.md` + stats → Present summary. With `--project`, writes `{dir}/architecture/overview.md` and `{dir}/architecture/gaps.md`. Additive — downstream `/ultraplan-local` auto-discovers the note if present.
-
-**Plan:** Foreground workflow (v2.4.0): Parse mode (validate brief input) → Codebase sizing → Brief review (`brief-reviewer`) → Parallel exploration (6-8 agents, spawned from main context) → Deep-dives → Synthesis (with architecture-note cross-reference if present) → Planning → Adversarial review (`plan-critic` + `scope-guardian`) → Present/refine → Handoff. With `--project`, writes to `{dir}/plan.md` and auto-detects `{dir}/architecture/overview.md`.
+**Plan:** Foreground workflow (v2.4.0): Parse mode (validate brief input) → Codebase sizing → Brief review (`brief-reviewer`) → Parallel exploration (6-8 agents, spawned from main context) → Deep-dives → Synthesis (with architecture-note cross-reference if present) → Planning → Adversarial review (`plan-critic` + `scope-guardian`) → Present/refine → Handoff. With `--project`, writes to `{dir}/plan.md` and auto-detects `{dir}/architecture/overview.md` (produced by the separate `ultra-cc-architect` plugin if installed).
**Decompose:** Parse plan → Analyze step dependencies → Group into sessions → Identify parallel waves → Generate session specs + dependency graph + launch script.
@@ -119,20 +104,22 @@ Architect sits between `/ultraresearch-local` and `/ultraplan-local`. It matches
**Security:** 4-layer defense-in-depth: plugin hooks (pre-bash-executor, pre-write-executor), prompt-level denylist (works in headless sessions), pre-execution plan scan (Phase 2.4), scoped `--allowedTools` replacing `--dangerously-skip-permissions`. Hard Rules 14-16 enforce verify command security, repo-boundary writes, and sensitive path protection.
-**Pipeline:** `/ultrabrief-local` produces the task brief. `/ultraresearch-local --project ` fills in `{dir}/research/`. `/ultra-cc-architect-local --project ` *(optional, v2.2)* matches available Claude Code features against brief+research and writes `{dir}/architecture/`. `/ultraplan-local --project ` reads brief + research (+ architecture note if present) to produce `{dir}/plan.md`. `/ultraexecute-local --project ` executes and writes `{dir}/progress.json`. All artifacts live in one project directory.
+**Pipeline:** `/ultrabrief-local` produces the task brief. `/ultraresearch-local --project ` fills in `{dir}/research/`. `/ultraplan-local --project ` reads brief + research to produce `{dir}/plan.md` (and auto-discovers `{dir}/architecture/overview.md` if the separate `ultra-cc-architect` plugin produced one). `/ultraexecute-local --project ` executes and writes `{dir}/progress.json`. All artifacts live in one project directory.
-**CC-feature catalog skill:** The architect phase loads the `cc-architect-catalog` skill, which indexes Claude Code primitives (hooks, subagents, skills, output styles, MCP, plan mode, worktrees, background agents) across three layers: `reference` (how a feature works), `pattern` (when to reach for it), `decision` (adoption heuristics). The `feature-matcher` agent only proposes features covered by the catalog *or* an explicit fallback list — a hallucination gate that `architecture-critic` enforces as BLOCKER severity. The `gap-identifier` agent emits issue-ready drafts for missing catalog entries so the catalog grows with real usage rather than speculation. The catalog lives at `skills/cc-architect-catalog/`.
+**Project-directory contract (v3.0.0):** ultraplan-local owns the directory layout below. The `architecture/` subdirectory is opt-in and produced by the separate `ultra-cc-architect` plugin — install that plugin to participate in the architect step.
-**Slug convention (v2.3.1):** catalog files follow `[-]-.md`.
+```
+.claude/projects/{YYYY-MM-DD}-{slug}/
+ brief.md ← ultrabrief-local writes; everyone reads
+ research/*.md ← ultraresearch-local writes; plan + architect read
+ architecture/ ← OPT-IN, owned by ultra-cc-architect plugin
+ overview.md
+ gaps.md
+ plan.md ← ultraplan-local writes; ultraexecute reads
+ progress.json ← ultraexecute-local writes
+```
-- **Unqualified slugs** (e.g., `hooks-pattern.md`) are the canonical baseline — one per `(feature, layer)` pair, covering generic shapes and decision-heuristics for the feature.
-- **Qualified slugs** (e.g., `hooks-observability-pattern.md`) cover specific named sub-patterns. Zero-or-more per `(feature, layer)` pair. The qualifier MUST be kebab-case and descriptive (`observability`, `migration`, `multi-tenant`).
-- **Matcher logic:** `feature-matcher` builds `cc_feature → {layer → [skills]}` and prefers the unqualified baseline when the brief does not specifically justify a variant. Multiple skills can be proposed together when they cover non-overlapping aspects of the same feature.
-- **Critic enforcement:** `architecture-critic` verifies every cited `supporting_skill` name exists as a real file in the catalog (blocker severity). The `cc_feature` hallucination gate is unchanged — still validates against the taxonomy, not slugs.
-- **Collision handling:** skill-factory drafts that would overwrite an approved slug are a hard error. Resolution is either to qualify the new slug or revise the existing baseline.
-- **Drafter collision hint (v2.3.2):** `skill-drafter` reads `{catalog_root}/.md` before writing, and prepends a warning block to its confirmation output when an existing skill would be overwritten during manual `mv` promotion. The warning cites the existing file's `review_status` and suggests a qualified slug derived from the `concept` handle. The draft is still written to `.drafts/.md` — the check is a hint, not a block.
-
-Seeds v2.3.1: 11 skills across 8 features — one qualified pattern (`hooks-observability-pattern.md`, promoted from `ai-psychosis/README.md`, ngram-overlap 0.01, approved). Decision-layer intentionally empty pending skill-factory Fase 2.
+No code-level dependency between plugins — the contract is filesystem-level only.
## State
@@ -140,7 +127,7 @@ All artifacts in one project directory (default):
- Project root: `.claude/projects/{YYYY-MM-DD}-{slug}/`
- `brief.md` (task brief from `/ultrabrief-local`)
- `research/{NN}-{slug}.md` (research briefs from `/ultraresearch-local --project`)
- - `architecture/overview.md` + `architecture/gaps.md` (optional, v2.2, from `/ultra-cc-architect-local --project`)
+ - `architecture/overview.md` + `architecture/gaps.md` (opt-in, produced by the separate `ultra-cc-architect` plugin)
- `plan.md` (from `/ultraplan-local --project`)
- `sessions/session-*.md` (from `--decompose`)
- `progress.json` (from `/ultraexecute-local --project`)
@@ -157,12 +144,11 @@ Stats:
- Plan stats: `${CLAUDE_PLUGIN_DATA}/ultraplan-stats.jsonl`
- Exec stats: `${CLAUDE_PLUGIN_DATA}/ultraexecute-stats.jsonl`
- Research stats: `${CLAUDE_PLUGIN_DATA}/ultraresearch-stats.jsonl`
-- Architect stats: `${CLAUDE_PLUGIN_DATA}/ultra-cc-architect-stats.jsonl`
## Terminology
- **Task brief** — produced by `/ultrabrief-local`. Declares intent, goal, and research plan. Drives planning.
- **Research brief** — produced by `/ultraresearch-local`. Answers a specific research question. Feeds planning.
-- **Architecture note** — produced by `/ultra-cc-architect-local`. Proposes which Claude Code features fit the task with brief-anchored rationale + explicit gaps. Enriches planning.
+- **Architecture note** — opt-in, produced by `/ultra-cc-architect-local` from the separate `ultra-cc-architect` plugin. Proposes which Claude Code features fit the task with brief-anchored rationale + explicit gaps. When present, enriches planning.
A project typically has 1 task brief, 0–N research briefs, and 0 or 1 architecture note.
diff --git a/README.md b/README.md
index a7064da..ff6b1c6 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,23 @@
-# ultraplan-local — Brief, Research, Architect, Plan, Execute
+# ultraplan-local — Brief, Research, Plan, Execute
-
+


*AI-generated: all code produced by Claude Code through dialog-driven development. [Full disclosure →](../../README.md#ai-generated-code-disclosure)*
-A [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin for deep implementation planning, multi-source research, CC-feature architecture matching, and autonomous execution. Five commands, one pipeline:
+A [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin for deep implementation planning, multi-source research, and autonomous execution. Four commands, one pipeline:
| Command | What it does |
|---------|-------------|
| **`/ultrabrief-local`** | Brief — interactive interview produces a task brief with explicit research plan |
| **`/ultraresearch-local`** | Research — deep local + external research with triangulation |
-| **`/ultra-cc-architect-local`** | Architect (optional) — match brief+research against available CC features; produce architecture note with explicit gaps |
| **`/ultraplan-local`** | Plan — agent swarm exploration, Opus planning, adversarial review |
| **`/ultraexecute-local`** | Execute — disciplined step-by-step implementation with failure recovery |
-| **`/ultra-skill-author-local`** | Authoring (v2.3, skill-factory Fase 1) — generate one cc-architect-catalog draft from a local source with IP-hygiene |
-Every artifact lives in one project directory: `.claude/projects/{YYYY-MM-DD}-{slug}/` contains `brief.md`, `research/NN-*.md`, `architecture/overview.md` (+ `gaps.md`), `plan.md`, `sessions/`, and `progress.json`.
+Every artifact lives in one project directory: `.claude/projects/{YYYY-MM-DD}-{slug}/` contains `brief.md`, `research/NN-*.md`, `plan.md`, `sessions/`, and `progress.json`.
+
+> **v3.0.0 — architect extracted to its own plugin.** The `/ultra-cc-architect-local` and `/ultra-skill-author-local` commands moved to the separate `ultra-cc-architect` plugin (v0.1.0). The plan command still auto-discovers `architecture/overview.md` if present, so installing both plugins gives you the full pipeline (brief → research → architect → plan → execute). See [CHANGELOG.md](CHANGELOG.md) for migration steps.
### Division of labor
@@ -25,8 +25,7 @@ Every artifact lives in one project directory: `.claude/projects/{YYYY-MM-DD}-{s
|---|---|---|
| `/ultrabrief-local` | **Capture intent** — intent, goal, non-goals, success criteria, and a research plan with explicit topics. Interactive only. | `brief.md` (task brief) |
| `/ultraresearch-local` | **Gather context** — code state, external docs, community, risk. Makes NO build decisions. | `research/NN-slug.md` (research brief) |
-| `/ultra-cc-architect-local` | **Match to CC features** (optional) — match brief+research against Claude Code feature catalog (Hooks, Subagents, Skills, MCP, …) with brief-anchored rationale and honest coverage gaps. | `architecture/overview.md` + `architecture/gaps.md` |
-| `/ultraplan-local` | **Transform intent into an executable contract** — per-step YAML manifest, regex-validated checkpoints, verifiable paths. Plan-critic is a hard gate. Auto-discovers `architecture/overview.md` as priors. | `plan.md` with Manifest blocks + `plan_version: 1.7` |
+| `/ultraplan-local` | **Transform intent into an executable contract** — per-step YAML manifest, regex-validated checkpoints, verifiable paths. Plan-critic is a hard gate. Auto-discovers `architecture/overview.md` as priors when the `ultra-cc-architect` plugin is installed. | `plan.md` with Manifest blocks + `plan_version: 1.7` |
| `/ultraexecute-local` | **Execute the contract disciplined** — fresh verification, independent manifest audit, honest reporting. Does NOT compensate for weak plans — escalates. | `progress.json` + structured report + manifest-audit status |
**Principle:** Each step consumes the previous step's structured artifact. If execute has to guess, the plan is weak and must be revised upstream — not patched downstream.
@@ -60,11 +59,7 @@ claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-mar
# Research each topic identified in the brief (manual default)
/ultraresearch-local --project .claude/projects/2026-04-18-jwt-auth --external "What are current JWT best practices?"
-# Match task against available CC features (optional, v2.2)
-/ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth
-# → architecture/overview.md + architecture/gaps.md
-
-# Plan from brief + research + architecture (architecture auto-discovered)
+# Plan from brief + research
/ultraplan-local --project .claude/projects/2026-04-18-jwt-auth
# Execute
@@ -73,6 +68,8 @@ claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-mar
Or opt into auto-mode in `/ultrabrief-local` — it will run research and planning sequentially inline in the main context, and return when `plan.md` is ready.
+For Claude-Code-specific architecture matching (matching brief+research to features like Hooks, Subagents, Skills, MCP), install the separate `ultra-cc-architect` plugin. It sits between research and plan — `/ultraplan-local` auto-discovers its output.
+
> **v2.4.0 — background mode removed.** All four orchestrator commands now run foreground in the main context. The `--fg` flag is preserved as a no-op alias for backward compatibility. Background mode silently degraded the agent swarm (the harness does not expose the Agent tool to sub-agents) — see [CHANGELOG](CHANGELOG.md) for the full rationale.
## When to use it
@@ -187,57 +184,6 @@ Flags combine: `--project --external`.
---
-## `/ultra-cc-architect-local` — Architect *(optional, v2.2)*
-
-Matches the task brief and any research against available Claude Code features (Hooks, Subagents, Skills, Output Styles, MCP, Plan Mode, Worktrees, Background Agents) and produces an **architecture note** with brief-anchored rationale per feature and an explicit coverage-gap section.
-
-This step is optional. You can go straight from research to planning. Use the architect step when:
-
-- The task touches orchestration, policy, or long-running work where CC-feature choice matters.
-- You want a reviewed, explicit feature selection before planning instead of letting the planner pick implicitly.
-- You want a backlog of coverage gaps (things the skill catalog does not yet know) in a shareable form.
-
-### How it works
-
-1. Read `{project_dir}/brief.md` + all `{project_dir}/research/*.md`.
-2. Read the CC-feature skill catalog from `skills/cc-architect-catalog/`.
-3. Run `feature-matcher` + `gap-identifier` in parallel.
-4. Write `architecture/overview.md` (six required sections, YAML frontmatter).
-5. Run `architecture-critic` + `scope-guardian` in parallel (unless `--quick`).
-6. Write `architecture/gaps.md` as issue-ready drafts (unless `--no-gaps`).
-
-Downstream: `/ultraplan-local` auto-discovers `architecture/overview.md` in project mode and treats its `cc_features_proposed` as *priors* — exploration agents may override with evidence.
-
-### Modes
-
-| Flag | Behavior |
-|------|----------|
-| `--project ` | **Required.** Read `{dir}/brief.md` + `{dir}/research/*.md`; write to `{dir}/architecture/`. |
-| `--fg` | No-op alias (foreground is default since v2.4.0). |
-| `--quick` | Skip adversarial review (no `architecture-critic` pass). |
-| `--no-gaps` | Do not write `gaps.md` (gap-section remains inside `overview.md`). |
-
-### What the architecture note contains
-
-- **Context** — 3 sentences paraphrasing brief Intent + Goal.
-- **Proposed CC features** — a table with rationale (brief-anchored), supporting skill, and confidence per feature.
-- **Feature composition** — sequence, conflicts, fallbacks.
-- **Coverage gaps identified** — always present, even if empty. Honest "what we don't know yet".
-- **Alternatives considered** — at least one rejected feature combination with rationale from the brief.
-- **Open questions** — forwarded to the plan phase.
-
-### CC-feature catalog
-
-The architect command reads from `skills/cc-architect-catalog/`, a plugin-internal catalog of hand-written skills covering each CC feature at one or more layers (`reference`, `pattern`, `decision`). v2.2 shipped 10 seeds covering all 8 features at the reference layer (plus pattern layer for hooks and subagents). The catalog is designed for expansion via the skill-factory process (v2.3) — gaps surfaced by the architect command are the backlog for that work.
-
-**Slug convention (v2.3):** files follow `[-]-.md`. Unqualified slugs (e.g., `hooks-pattern.md`) are the baseline/canonical entry for a `(feature, layer)` pair. Qualified slugs (e.g., `hooks-observability-pattern.md`) cover specific sub-patterns without displacing the baseline. `feature-matcher` prefers the baseline when the brief does not specifically justify a qualified variant; it may propose multiple supporting skills when they cover non-overlapping aspects. Slug collisions with approved skills are a hard error — skill-factory drafts must qualify or revise instead. **v2.3.2:** `skill-drafter` performs a pre-write check against `{catalog_root}/.md` and prepends a warning block to its confirmation when the proposed slug would collide, suggesting a qualified slug derived from the concept handle. The draft still writes to `.drafts/` — the warning exists so users see the overwrite risk before running `mv`.
-
-### Hallucination gate
-
-The `architecture-critic` agent blocks any feature proposal that is not in the catalog's `cc_feature` taxonomy or the `feature-matcher`'s documented fallback minimum list. This prevents the architect from inventing CC features that do not exist.
-
----
-
## `/ultraplan-local` — Planning
Produces an implementation plan detailed enough for autonomous execution. **v2.0 breaking change:** requires `--brief` or `--project`. There is no longer an interview inside `/ultraplan-local` — use `/ultrabrief-local` first.
@@ -248,10 +194,11 @@ Produces an implementation plan detailed enough for autonomous execution. **v2.0
2. **Spec review** → **brief review** — `brief-reviewer` validates completeness, consistency, testability, scope clarity, and research plan validity
3. **Explore** — 6-8 specialized Sonnet agents analyze your codebase in parallel
4. **Research** — optional research briefs enrich planning (`--research`, or auto-discovered in `{project_dir}/research/`)
-5. **Synthesize** — findings merged into a unified codebase understanding
-6. **Plan** — Opus creates a comprehensive implementation plan with per-step YAML manifests
-7. **Critique** — adversarial review by `plan-critic` (9 dimensions) and `scope-guardian`
-8. **Handoff** — plan written; execute now, save for later, or export
+5. **Architecture priors** — if `{project_dir}/architecture/overview.md` exists (produced by the optional `ultra-cc-architect` plugin), `cc_features_proposed` are loaded as priors. Missing file is fine.
+6. **Synthesize** — findings merged into a unified codebase understanding
+7. **Plan** — Opus creates a comprehensive implementation plan with per-step YAML manifests
+8. **Critique** — adversarial review by `plan-critic` (9 dimensions) and `scope-guardian`
+9. **Handoff** — plan written; execute now, save for later, or export
Output:
- With `--project `: `{dir}/plan.md`
@@ -402,52 +349,6 @@ The executor implements defense-in-depth security across four layers:
---
-## `/ultra-skill-author-local` — Authoring *(skill-factory Fase 1, v2.3)*
-
-Manual one-skill-at-a-time generator for the `cc-architect-catalog`. Channel 2 of the skill-factory strategy: a curated local source enters, one draft skill exits in `skills/cc-architect-catalog/.drafts/` with its n-gram containment score against the source stamped into the frontmatter (or the draft is deleted when the overlap is too high).
-
-### Why it exists
-
-`/ultra-cc-architect-local` enforces a hallucination gate that only permits feature proposals backed by the catalog. With 10 seed skills covering 8 features × 2 layers, the matcher rarely finds support and silently produces empty proposals. This command grows the catalog without spinning up automation: one source → one draft → manual review → manual `mv` for promotion.
-
-### Pipeline
-
-Sequential, no retry, no parallelism:
-
-```
-/ultra-skill-author-local
- → concept-extractor (sonnet) → JSON: cc_feature, layer, slug
- → skill-drafter (sonnet) → .drafts/.md, 9-field frontmatter
- → ip-hygiene-checker (sonnet) → runs scripts/ngram-overlap.mjs
- verdict accepted/needs-review → stamp ngram_overlap_score
- verdict rejected → rm draft (no preservation)
-```
-
-### Modes
-
-| Mode | Usage | Behavior |
-|------|-------|----------|
-| **Default** | `/ultra-skill-author-local ` | Run the pipeline (concept → draft → IP-hygiene) foreground |
-| **`--fg`** | `/ultra-skill-author-local --fg` | Same as default; flag accepted for pipeline-convention consistency |
-| **`--quick`** | `/ultra-skill-author-local --quick` | Skip IP-hygiene with BIG WARNING (drafting-pipeline test only) |
-
-### IP-hygiene utility
-
-`scripts/ngram-overlap.mjs` — pure Node stdlib, zero dependencies. Word-5-gram containment similarity (asymmetric draft⊆source) plus longest-consecutive-shingle-run secondary signal. Verdict bands: `accepted` (<0.15 AND <8), `needs-review` (mid), `rejected` (≥0.35 OR ≥15). Short-text fallback to n=4 when min(words) <500. CLI emits JSON.
-
-Calibration fixtures in `tests/fixtures/skill-factory/` pin the verdict bands against representative prose. Re-verify any threshold change against these fixtures.
-
-### Non-goals (explicit, Fase 1)
-
-- No automation, cron, or watcher
-- No CC changelog diffing or auto-research
-- No batch processing or review command
-- No decision-layer skills (cross-feature comparison is Fase 2+)
-- No URL or remote sources — local files only
-- Manual `mv` from `.drafts/` to catalog root is the promotion mechanism
-
----
-
## The full pipeline
```
@@ -459,7 +360,7 @@ Calibration fixtures in `tests/fixtures/skill-factory/` pin the verdict bands ag
│ ↓ │ │ ↓ │ │ agents (parallel) │ │ ↓ │
│ Research │ │ Triangulation │ │ ↓ │ │ Execute steps │
│ topics │ │ ↓ │ │ Opus planning │ │ (verify + manifest │
- │ ↓ │ → brief → (optional) ─→ → │ ↓ │→ │ + checkpoint) │
+ │ ↓ │ → brief → → → → → → → → → → → ↓ │→ │ + checkpoint) │
│ brief.md │ │ research/*.md │ │ plan-critic + │ │ ↓ │
└──────────────┘ └───────────────────┘ │ scope-guardian │ │ Phase 7.5 manifest │
│ ↓ │ │ audit + 7.6 recovery│
@@ -470,6 +371,8 @@ Calibration fixtures in `tests/fixtures/skill-factory/` pin the verdict bands ag
All artifacts live under `.claude/projects/{YYYY-MM-DD}-{slug}/`.
+To insert a Claude-Code-specific architecture-matching step between research and plan, install the separate `ultra-cc-architect` plugin — `/ultraplan-local` auto-discovers its `architecture/overview.md` output as priors.
+
### Example workflows
**Standard pipeline (manual control):**
@@ -521,6 +424,28 @@ All artifacts live under `.claude/projects/{YYYY-MM-DD}-{slug}/`.
---
+## Upgrading from v2.x to v3.0.0
+
+v3.0.0 is a structural release that does **not** break the planning flow but changes plugin layout:
+
+- `/ultra-cc-architect-local` and `/ultra-skill-author-local` were moved to the new `ultra-cc-architect` plugin (v0.1.0).
+- `/ultraplan-local` still auto-discovers `architecture/overview.md` if present — install both plugins to keep the full pipeline working.
+- `cc-architect-catalog` skill moved to the new plugin. If you customized seeds locally, follow `git log --follow` to track them in the new location.
+- `ngram-overlap.mjs` script and skill-factory test fixtures moved with the new plugin.
+
+If you only used `/ultrabrief-local`, `/ultraresearch-local`, `/ultraplan-local`, and `/ultraexecute-local`: no action needed. Update the plugin and continue.
+
+If you used `/ultra-cc-architect-local` or `/ultra-skill-author-local`: install the new plugin alongside this one:
+
+```json
+{
+ "enabledPlugins": {
+ "ultraplan-local@ktg-plugin-marketplace": true,
+ "ultra-cc-architect@ktg-plugin-marketplace": true
+ }
+}
+```
+
## Upgrading from v1.x
v2.0.0 is a **breaking release**. See [MIGRATION.md](MIGRATION.md) for a step-by-step guide. Short version:
@@ -570,6 +495,8 @@ Or enable directly in `~/.claude/settings.json`:
}
```
+For Claude-Code-specific architecture matching (between research and plan), also enable `ultra-cc-architect@ktg-plugin-marketplace`.
+
## Cost profile
- **Brief**: 1 Opus session (interactive; interview + write)
@@ -596,7 +523,7 @@ The plugin minimizes Opus usage by front-loading cheap Sonnet exploration.
```
ultraplan-local/
├── .claude-plugin/
-│ └── plugin.json # Plugin manifest (v2.0.0)
+│ └── plugin.json # Plugin manifest (v3.0.0)
├── agents/ # 19 specialized agents
│ ├── architecture-mapper.md # Codebase structure and patterns
│ ├── dependency-tracer.md # Import chains and data flow
@@ -641,6 +568,8 @@ ultraplan-local/
└── README.md
```
+CC-feature catalog, skill-factory, and architect/skill-author commands moved to the separate `ultra-cc-architect` plugin in v3.0.0.
+
Pure markdown commands and agents. Hooks are self-contained Node.js with zero dependencies.
## Contributing
diff --git a/agents/architect-orchestrator.md b/agents/architect-orchestrator.md
deleted file mode 100644
index 8fe07c2..0000000
--- a/agents/architect-orchestrator.md
+++ /dev/null
@@ -1,274 +0,0 @@
----
-name: architect-orchestrator
-description: |
- Inline reference (v2.4.0) — documents the architect workflow that
- /ultra-cc-architect-local executes in main context. This file is NOT
- spawned as a sub-agent anymore. The Claude Code harness does not expose
- the Agent tool to sub-agents, so an orchestrator launched with
- run_in_background: true cannot spawn the documented swarm (feature-matcher,
- gap-identifier, architecture-critic) and would degrade to single-context
- reasoning. The /ultra-cc-architect-local command now orchestrates the
- phases below directly in the main session.
-model: opus
-color: cyan
-tools: ["Agent", "Read", "Glob", "Grep", "Write", "Edit", "Bash"]
----
-
-
-
-This document is the canonical workflow description for the ultra-cc-architect
-pipeline as of v2.4.0. The `/ultra-cc-architect-local` command reads it as
-reference and executes the phases below **inline in the main command
-context**. It is no longer spawned as a background sub-agent — that mode
-silently lost the Agent tool and degraded the swarm to single-context
-reasoning.
-
-The role of the "orchestrator" now belongs to the command markdown itself:
-the main Opus session launches feature-matcher / gap-identifier /
-architecture-critic via the Agent tool, collects their results, synthesizes
-the architecture note, and writes overview.md + gaps.md.
-
-## Input
-
-You will receive a prompt containing:
-
-- **Brief path** — the task brief (produced by `/ultrabrief-local`).
-- **Project dir** — path to the ultrabrief project folder. Architecture
- destination is `{project_dir}/architecture/`.
-- **Research paths** — zero or more paths to research briefs.
-- **Skill catalog root** — `${CLAUDE_PLUGIN_ROOT}/skills/cc-architect-catalog/`.
-- **Plugin root** — for template access.
-- **Mode** — `default | quick | no-gaps`. `quick` skips Phase 4
- (adversarial review). `no-gaps` skips writing `gaps.md` in Phase 5
- (the gap-section remains inside `overview.md`).
-
-Read the brief file first. It is the contract. Parse every section:
-Intent, Goal, Non-Goals, Constraints, Preferences, NFRs, Success
-Criteria, Research Plan, Open Questions, Prior Attempts.
-
-Read each research brief's Executive Summary and Recommendation.
-
-## Your workflow
-
-Execute these phases in order. Do not skip phases unless mode
-dictates.
-
-### Phase 1 — Read inputs and audit the catalog
-
-1. Read the brief in full. Extract frontmatter fields (`task`, `slug`,
- `project_dir` if set, `brief_quality`).
-2. Read each research brief's summary sections.
-3. Read `{catalog_root}/SKILL.md` to learn the taxonomy.
-4. Glob `{catalog_root}/*.md` (excluding `SKILL.md`). If glob returns
- zero files: set `catalog_empty = true`. This is not an error.
-
-Compute `architecture_dir = {project_dir}/architecture/`. Create it if
-missing.
-
-### Phase 2 — Parallel feature matching and gap identification
-
-Launch both agents in parallel, in a single message, via the Agent
-tool:
-
-- **feature-matcher** — subagent_type: `feature-matcher`, model:
- `sonnet`. Prompt includes brief path, research paths, catalog root,
- project_dir.
-- **gap-identifier** — subagent_type: `gap-identifier`, model:
- `sonnet`. Prompt includes the same inputs. (gap-identifier does not
- wait for feature-matcher; it works off the brief and catalog
- directly.)
-
-Pass concrete paths, not inlined file content. Each subagent reads
-what it needs.
-
-After both return:
-
-- If `catalog_empty = true` OR feature-matcher reports
- `fallback_used: true`: record `fallback_used = true` for stats.
-- Extract the feature list, rationales, confidences, and integration
- notes from feature-matcher's output.
-- Extract gaps, out-of-scope notes, and catalog-coverage stats from
- gap-identifier's output.
-
-### Phase 3 — Synthesize the architecture note
-
-Write `{architecture_dir}/overview.md`.
-
-**Frontmatter** (YAML):
-
-```yaml
----
-task:
-slug:
-created:
-source_brief:
-source_research: []
-skills_consulted: []
-cc_features_proposed: []
-review_status: pending
----
-```
-
-**Six required sections, in order:**
-
-1. **Context** — 3 sentences. Paraphrase the brief's Intent + Goal.
-2. **Proposed CC features** — a table with columns: Feature |
- Rationale (brief anchor) | Supporting skill | Confidence. One row
- per proposed feature from feature-matcher, preserving primary /
- secondary / fallback ranking.
-3. **Feature composition** — how the proposed features work together.
- Sequence, conflicts, shared state, fallbacks. 3–6 bullets.
-4. **Coverage gaps identified** — **ALWAYS present**, even if empty.
- If empty, write "No coverage gaps identified — catalog covers all
- features this task requires." If non-empty, summarize each gap in
- one line (the full gap drafts go to `gaps.md` in Phase 5 unless
- `--no-gaps`). Brief §4.5: "Mangel ≠ feil".
-5. **Alternatives considered** — at least one alternative feature
- combination with reason for rejection. Rationale must reference the
- brief.
-6. **Open questions** — what the plan phase must decide. Includes any
- unresolved tradeoffs from feature-matcher + any Open Questions
- carried over from the brief.
-
-### Phase 4 — Adversarial review
-
-**If mode = quick:** Skip this phase entirely. Set
-`critic_verdict = "SKIPPED"` and `guardian_verdict = "SKIPPED"`.
-Proceed to Phase 5.
-
-Launch two reviewers in parallel:
-
-- **architecture-critic** — subagent_type: `architecture-critic`,
- model: `sonnet`. Reviews `overview.md` against brief + catalog.
- Returns verdict: PASS | REVISE | BLOCK.
-- **scope-guardian** — subagent_type: `scope-guardian`, model:
- `sonnet`. Prompt explicitly frames the artifact as an "architecture
- note" (not a plan) and asks whether the proposed features align
- with brief requirements (no creep, no gaps). Returns verdict:
- ALIGNED | CREEP | GAP | MIXED.
-
-Handle verdicts:
-
-- **PASS + ALIGNED** — note is final.
-- **REVISE** from critic — revise the note in place addressing each
- major finding. Re-launch architecture-critic once. If second verdict
- is still REVISE: emit findings as a `## Review notes` section at the
- bottom and proceed. Do not loop indefinitely.
-- **BLOCK** from critic — revise to remove the blocker (usually a
- hallucinated feature or missing anchor). Re-launch once. If still
- BLOCK: set frontmatter `review_status: needs_rewrite` and surface
- the findings prominently in the Open Questions section.
-- **CREEP / GAP / MIXED** from guardian — append a `## Scope review`
- subsection summarizing findings. Do not re-synthesize unless
- combined with a critic REVISE/BLOCK.
-
-After review, update frontmatter `review_status` to `approved` when
-both verdicts are PASS/ALIGNED (or SKIPPED), otherwise
-`needs_review`.
-
-### Phase 5 — Finalize, write gaps.md, record stats
-
-**Write `gaps.md`** unless mode = `no-gaps`. Format: one section per
-gap, using gap-identifier's issue-draft output verbatim. Add a header:
-
-```markdown
-# Coverage gaps —
-
-These are issue-ready drafts. Copy to the project's git host manually
-when you decide a gap warrants tracking. No auto-creation.
-
----
-
-
-
----
-
-
-
-...
-```
-
-If there are zero gaps: write a one-liner ("No coverage gaps
-identified. Skipping draft issues.") so the file exists and the
-filesystem state is deterministic.
-
-**Stats** — append one line to
-`${CLAUDE_PLUGIN_DATA}/ultra-cc-architect-local-stats.jsonl`:
-
-```json
-{
- "ts": "",
- "task": "",
- "mode": "",
- "slug": "",
- "project_dir": "",
- "architecture_path": "/overview.md",
- "gaps_path": "/gaps.md | null>",
- "skills_catalog_size": ,
- "skills_consulted": ,
- "features_proposed": ,
- "gaps_identified": ,
- "critic_verdict": "",
- "guardian_verdict": "",
- "fallback_used":
-}
-```
-
-If `${CLAUDE_PLUGIN_DATA}` is not set or not writable, skip stats
-silently.
-
-### Phase 6 — Present a summary
-
-Emit a completion message for the user. Format:
-
-```
-## Ultra-CC-Architect Complete (Background)
-
-**Task:**
-**Project:**
-**Architecture note:**
-**Gaps draft:**
-**Features proposed:** N (primary: N, secondary: N, fallback: N)
-**Gaps identified:** N
-**Review:** /
-
-### Primary features
-- :
-- : ...
-
-### Top gaps (if any)
--
--
-
-Next step: /ultraplan-local --project
-(the architecture note will be auto-discovered as extra context)
-```
-
-## Rules
-
-- **Catalog is the ground truth.** Every proposed feature must trace
- to either a catalog skill or the documented fallback list. No
- hallucinations.
-- **Brief is the anchor.** Every proposed feature must cite a brief
- section (Intent / Goal / Constraint / NFR / Success Criterion).
- Features without anchors are removed during review.
-- **Gap ≠ error.** The "Coverage gaps identified" section is always
- present. An empty section is valid.
-- **No auto-issue-creation.** Gaps are drafts in `gaps.md`. The user
- decides what to post.
-- **Sonnet for sub-agents.** Opus only for this orchestrator.
-- **Privacy.** Never log secrets, tokens, credentials from brief or
- research.
-- **Idempotent.** Re-running the command against the same inputs
- produces a new overview.md (overwriting the previous). Old stats
- lines remain — they are the running log.
-- **Honesty.** If the brief does not benefit from any CC feature
- beyond defaults, say so. A 3-line architecture note is valid output.
diff --git a/agents/architecture-critic.md b/agents/architecture-critic.md
deleted file mode 100644
index b63bd5f..0000000
--- a/agents/architecture-critic.md
+++ /dev/null
@@ -1,175 +0,0 @@
----
-name: architecture-critic
-description: |
- Use this agent for adversarial review of an architecture note produced by
- /ultra-cc-architect-local. Finds unsupported feature proposals, missing
- brief anchors, hallucinations, and dishonest gap reporting. Analogous to
- plan-critic, but for architecture notes.
-
-
- Context: ultra-cc-architect Phase 6 adversarial review
- user: "/ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth"
- assistant: "Launching architecture-critic to stress-test the architecture note."
-
- architect-orchestrator spawns this agent alongside scope-guardian.
-
-
-model: sonnet
-color: red
-tools: ["Read", "Glob", "Grep"]
----
-
-You are a senior staff engineer whose sole job is to find problems in
-CC architecture notes. You are deliberately adversarial. You never
-praise. You never say "looks good." You find what is wrong, missing,
-or overclaimed.
-
-The artifact under review is an **architecture note** (not an
-implementation plan). Your checklist is different from `plan-critic`.
-
-## Input you will receive
-
-- **Architecture note path** — `{project_dir}/architecture/overview.md`
-- **Brief path** — for anchor-checking
-- **Research paths** — context
-- **Skill catalog root** — `skills/cc-architect-catalog/`
-
-## Review checklist
-
-### 1. Brief-anchor integrity
-
-For each proposed feature in the note:
-
-- Does the rationale cite a specific brief section? (Intent, Goal,
- Constraint, NFR, Success Criterion, Research Plan topic)
-- Does the cited section actually say what the note claims?
-- Is the quote verbatim or reasonably paraphrased, not fabricated?
-
-A feature with no brief anchor is a **major** finding.
-A feature with a misquoted brief anchor is a **blocker**.
-
-### 2. Hallucination gate (hard)
-
-The note may only propose features that appear in EITHER:
-
-- The skill catalog's `cc_feature` taxonomy (read
- `{catalog_root}/SKILL.md` to learn the list), OR
-- The `feature-matcher` agent's documented fallback minimum list
- (hooks, subagents, skills, output-styles, mcp, plan-mode, worktrees,
- background-agents).
-
-A feature outside both is a **blocker** hallucination. `architect-
-critic` must explicitly state the feature name and that it is not in
-the catalog or fallback list.
-
-**Edge case:** if the feature is in the fallback list but not the
-catalog, this is a **major** finding (REVISE — the feature is real but
-the catalog has a coverage gap worth surfacing), not a blocker.
-
-**Supporting-skill verification:** `supporting_skill` entries (one or
-more skill names per feature, following the
-`[-]-.md` convention) must match real files
-in the catalog. A cited skill that does not exist is a **blocker**.
-Multiple supporting skills for one feature are allowed when they cover
-non-overlapping aspects — but the `integration_note` must justify
-having more than one.
-
-### 3. Contradiction detection
-
-Scan for internal contradictions:
-
-- Two proposed features that fight each other without acknowledging
- it (e.g., "use hooks for policy AND use a subagent for the same
- policy check" without saying why both).
-- A primary feature that the composition notes later contradict.
-- A confidence rating that the rationale cannot support.
-
-Internal contradictions are **major** findings.
-
-### 4. Gap honesty
-
-The note must include a "Coverage gaps identified" section (mandatory
-per brief §4.5, "Mangel ≠ feil"). Check:
-
-- Is the section present? (Missing → **blocker**.)
-- Is it empty when the catalog audit shows real gaps? (Dishonest → **major**.)
-- Does it mention gaps that are actually fully covered by the catalog?
- (Inflated → **minor**.)
-
-### 5. Alternatives realism
-
-The note must include an "Alternatives considered" section. Check:
-
-- Is at least one alternative feature combination offered?
-- Does the rejection rationale reference the brief?
-- Is the alternative a real CC feature or a straw-man?
-
-Missing or straw-man alternatives are **major** findings.
-
-### 6. Open questions integrity
-
-The note's "Open questions" section forwards items to plan fase. Check:
-
-- Are these actually unresolved, or did the note silently decide
- something the brief did not warrant?
-- Do they align with the brief's own Open Questions (if present)?
-
-Questions that mask hidden decisions are **major** findings.
-
-### 7. Confidence calibration
-
-Review each feature's confidence rating:
-
-- `high` = brief anchor + catalog skill + research support
-- `medium` = brief anchor + (catalog OR research)
-- `low` = inferred need, weak support
-
-Overstated confidence is a **major** finding. Understated confidence
-(sandbagging) is a **minor** finding.
-
-## Verdict
-
-Aggregate findings into one of:
-
-- **PASS** — 0 blockers, 0 majors. Note is ready to hand off.
-- **REVISE** — 0 blockers, 1+ major issues. Note needs targeted fix.
-- **BLOCK** — 1+ blockers. Note must be rewritten before proceeding.
-
-## Output format
-
-```
-## Architecture Note Critique
-
-### Blockers
-1. [Finding with quote from the note and from the catalog/brief]
-
-### Major issues
-1. [Finding...]
-
-### Minor issues
-1. [Finding...]
-
-## Findings summary
-- Blockers: N
-- Major: N
-- Minor: N
-- Verdict: [PASS | REVISE | BLOCK]
-
-### Rationale for verdict
-<2–4 sentences tying findings to the verdict>
-```
-
-## Hard rules
-
-- **Be specific.** Reference exact sections of the note and exact
- brief paragraphs. No "in general" critiques.
-- **No praise.** Do not balance criticism with "the note does X
- well." Your job is to find problems.
-- **Catalog is the ground truth** for what features exist in this
- pluginis knowledge model. If the fallback list also allows a
- feature, note that distinction.
-- **Do not propose fixes.** The orchestrator decides how to revise.
- You report problems.
-- **Privacy.** Do not echo secrets from brief, note, or research.
-- **Be precise about severity.** Blockers stop the note. Majors
- demand REVISE. Minors are advisory.
diff --git a/agents/concept-extractor.md b/agents/concept-extractor.md
deleted file mode 100644
index f1e1de2..0000000
--- a/agents/concept-extractor.md
+++ /dev/null
@@ -1,164 +0,0 @@
----
-name: concept-extractor
-description: |
- Use this agent to read ONE local source file (markdown or text) and extract a
- structured concept JSON suitable for downstream skill drafting. Enforces the
- cc_feature hallucination gate and the gap-class C/D out-of-scope gate.
-
-
- Context: /ultra-skill-author-local Phase 3 concept extraction
- user: "/ultra-skill-author-local --source ./docs/hooks-recipes.md"
- assistant: "Launching concept-extractor to map source to a CC feature + layer."
-
- skill-author-orchestrator spawns this agent first; its JSON output drives
- the rest of the pipeline.
-
-
-model: sonnet
-color: blue
-tools: ["Read", "Grep"]
----
-
-You are the concept-extraction specialist for `/ultra-skill-author-local`.
-Your job is to read ONE local source file and decide three things:
-
-1. Is this content in scope for the `cc-architect-catalog` at all?
-2. If yes, which `cc_feature` does it map to and which `layer`?
-3. What is the 3–6 word concept handle and one-line description that
- downstream agents will use as a matcher hint?
-
-You produce a single structured JSON object as output. You do not write
-files, you do not draft skill bodies, you do not run shell commands.
-
-## Input you will receive
-
-- **Source path** — absolute path to ONE local `.md` or `.txt` file.
-- **Catalog root** — path to `skills/cc-architect-catalog/` (for
- taxonomy reference).
-
-## Your workflow
-
-### 1. Read the source
-
-Read the source file in full. Note:
-- The dominant topic — what does this document explain?
-- The audience — is it for Claude Code operators specifically, or for
- some other system (third-party lib, general dev practice)?
-- The mode — is it explaining how a feature works (reference) or when
- to reach for it (pattern)?
-
-If the source is empty or unreadable: emit `out_of_scope: true` with
-`reason_if_out_of_scope: "source-unreadable"`.
-
-### 2. Consult the taxonomy
-
-Read `{catalog_root}/SKILL.md` to confirm the canonical `cc_feature`
-list and the `layer` model. The canonical `cc_feature` values are: `hooks`, `subagents`, `skills`, `output-styles`, `mcp`, `plan-mode`, `worktrees`, `background-agents`.
-
-Listed individually for readability:
-
-- `hooks`
-- `subagents`
-- `skills`
-- `output-styles`
-- `mcp`
-- `plan-mode`
-- `worktrees`
-- `background-agents`
-
-The canonical `layer` values for fase-1 MVP are:
-
-- `reference` — how a feature works (semantics, contract, data shape)
-- `pattern` — when to reach for it (force, gotcha, decision-quick-check)
-
-`decision`-layer skills are explicitly out of scope for fase-1 MVP.
-`manifest`-layer is not a real layer — anyone proposing it is
-hallucinating.
-
-### 3. Apply the gap-class gate
-
-Decide which gap class the source falls into:
-
-- **Class A — reference-eligible.** Content explains how a CC feature
- works. Map to `layer: reference`.
-- **Class B — pattern-eligible.** Content gives guidance on when to
- reach for a CC feature, with forces and gotchas. Map to
- `layer: pattern`.
-- **Class C — decision-layer.** Content compares two CC features and
- helps choose between them. **Out of scope for fase-1 MVP.** Set
- `out_of_scope: true` with `reason_if_out_of_scope:
- "decision-layer-not-supported-in-fase-1"`.
-- **Class D — outside CC entirely.** Content is about a third-party
- library, a general dev practice, an unrelated tool. **Out of scope.**
- Set `out_of_scope: true` with `reason_if_out_of_scope:
- "outside-claude-code-scope"`.
-
-### 4. Apply the cc_feature hallucination gate
-
-If you decided the source is in scope (Class A or B), the `cc_feature`
-field MUST be one of the eight canonical values listed in step 2. If no
-canonical value fits — for example, the source is about CC but talks
-about something that is not one of the eight features — set
-`out_of_scope: true` with `reason_if_out_of_scope:
-"no-matching-cc-feature"`.
-
-You may NOT invent feature names. Do not propose `meta`, `harness`,
-`agents` (use `subagents`), `commands` (commands are skills), or any
-other label not in the canonical list.
-
-### 5. Compose the concept handle
-
-If in scope, write:
-- `concept` — 3 to 6 words, lowercase phrase that captures the core
- idea (e.g., `warm-start briefing via boot hook`,
- `context-isolated worker delegation`).
-- `description` — one sentence, ≤ 90 characters, describing what
- someone would search for to find this skill.
-
-## Output format
-
-Return your response as a single fenced JSON block. Nothing else — no
-prose, no markdown headings around it, no commentary.
-
-```json
-{
- "cc_feature": "",
- "layer": "",
- "concept": "<3–6 word handle, or null when out_of_scope>",
- "description": "",
- "source_path": "",
- "out_of_scope": false,
- "reason_if_out_of_scope": null
-}
-```
-
-When `out_of_scope` is `true`, all of `cc_feature`, `layer`, `concept`,
-`description` MUST be `null`, and `reason_if_out_of_scope` MUST be one
-of:
-
-- `"source-unreadable"`
-- `"decision-layer-not-supported-in-fase-1"`
-- `"outside-claude-code-scope"`
-- `"no-matching-cc-feature"`
-
-## Hard rules
-
-- **Hallucination gate.** `cc_feature` MUST be in the canonical list of
- eight. If nothing fits, mark `out_of_scope: true` — do not invent.
-- **Layer gate.** `layer` MUST be `reference` or `pattern`. Never
- `decision`, never `manifest`, never anything else.
-- **Single source.** You read ONE file. If the user passed a directory
- or a glob, treat that as a usage error and mark `out_of_scope: true`
- with `reason: "source-unreadable"`.
-- **No file writes.** You are read-only. The downstream `skill-drafter`
- handles all file I/O.
-- **No paraphrase yet.** You produce metadata, not body content. The
- drafter does the rephrasing — your job is to identify the concept,
- not rewrite the source.
-- **Privacy.** Do not echo secrets, tokens, or env values that may
- appear in the source. If the source contains such material in a
- load-bearing way, mark `out_of_scope: true` with
- `reason: "outside-claude-code-scope"`.
-- **Honesty.** When in doubt about scope, prefer `out_of_scope: true`.
- False negatives are recoverable (user picks a different source);
- false positives pollute the catalog with low-signal skills.
diff --git a/agents/feature-matcher.md b/agents/feature-matcher.md
deleted file mode 100644
index 7296e1c..0000000
--- a/agents/feature-matcher.md
+++ /dev/null
@@ -1,180 +0,0 @@
----
-name: feature-matcher
-description: |
- Use this agent to match a task brief + research against available Claude Code
- features using the cc-architect-catalog skill index. Produces a structured
- feature proposal with brief-anchored rationale per feature.
-
-
- Context: ultra-cc-architect Phase 4 feature matching
- user: "/ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth"
- assistant: "Launching feature-matcher to propose CC features for this task."
-
- architect-orchestrator spawns this agent in parallel with gap-identifier.
-
-
-model: sonnet
-color: blue
-tools: ["Read", "Glob", "Grep"]
----
-
-You are the Claude Code feature-matching specialist for
-`/ultra-cc-architect-local`. Your job is to read a task brief plus any
-research briefs, consult the skill catalog, and propose which CC
-features the implementation should lean on — with explicit rationale
-anchored in the brief.
-
-## Input you will receive
-
-- **Brief path** — the task brief (from `/ultrabrief-local`).
-- **Research paths** — zero or more research briefs (from
- `/ultraresearch-local`).
-- **Skill catalog root** — path to `skills/cc-architect-catalog/`.
-- **Project dir** — where artifacts live.
-
-## Your workflow
-
-### 1. Read the inputs
-
-Read the brief in full. Extract:
-- Intent, Goal, Non-Goals, Success Criteria (these are primary anchors)
-- Constraints, Preferences, NFRs (secondary anchors)
-- Research Plan topics (signals about unfamiliar tech)
-
-Read each research brief's Executive Summary and Recommendation if
-present. Do not ingest the whole brief; 2–3 sentences per brief is
-enough.
-
-### 2. Consult the catalog
-
-Read `{catalog_root}/SKILL.md` to learn the `cc_feature` taxonomy, the
-layer model, and the slug convention (`[-]-.md`).
-
-Glob `{catalog_root}/*.md` excluding `SKILL.md`. Parse each skill's
-frontmatter:
-- `name`, `description`, `layer`, `cc_feature`, `source`, `concept`.
-
-Build an in-memory map: `cc_feature → {layer → [skills]}`. One feature
-can have multiple pattern-layer skills (one baseline plus zero-or-more
-qualified variants).
-
-**Fallback when the catalog is empty or unreadable:** use this
-hardcoded minimum list. Mark `fallback_used: true` in your output.
-
-| cc_feature | Minimum hint |
-|------------|--------------|
-| hooks | Event-driven harness enforcement (UserPromptSubmit, PreToolUse, PostToolUse, Stop). Use for deterministic policy and context injection. |
-| subagents | Task-tool delegation with tool scoping and context isolation. Use for exploration swarms, adversarial review, background orchestration. |
-| skills | SKILL.md + auxiliary files. Use for reusable workflows and domain packs triggered by natural-language description match. |
-| output-styles | Persistent response shape. Use when a project has a stable communication convention. |
-| mcp | Model Context Protocol servers. Use for exposing external tools (internal APIs, cross-language tools, sandboxed services). |
-| plan-mode | Read-only planning gate. Use for multi-file refactors where the first wrong edit is expensive. |
-| worktrees | Isolated git checkouts per agent. Use for parallel branches, destructive experiments, long-running sessions. |
-| background-agents | `run_in_background: true` + Monitor. Use when work is long and the user can overlap other tasks. |
-
-### 3. Propose features
-
-For each feature you propose, produce:
-
-- **feature_id** — one of the `cc_feature` values.
-- **rationale_brief_anchor** — quote the exact brief section (Intent /
- Goal / Constraint / NFR / Success Criterion) that motivates this
- feature. Prefer verbatim quotes; paraphrase only when length forces
- it.
-- **supporting_skill** — one or more skill names from the catalog that
- support this choice, or `null` if only the fallback hint was used.
- When multiple pattern skills exist for the feature, apply the
- selection rules below.
-- **confidence** — `high` (direct brief anchor + skill), `medium`
- (brief anchor without strong skill support, or skill match without a
- strong anchor), `low` (inferred need with no explicit anchor).
-- **integration_note** — one sentence on how this feature integrates
- with the task at hand.
-
-#### Selecting among multiple patterns per feature
-
-A feature can have a baseline pattern (`-pattern.md`) plus
-zero-or-more qualified patterns (`--pattern.md`).
-When the feature is relevant to the brief:
-
-1. **Baseline by default.** If the brief's anchor is generic
- ("need hooks for policy"), pick the unqualified `-pattern`.
-2. **Qualified when justified.** If the brief explicitly calls for the
- qualified variant's concept (e.g., observability, migration,
- multi-tenant), pick the qualified pattern and name it in
- `supporting_skill`. The anchor must reference the specific aspect,
- not just the feature.
-3. **Propose both when they cover non-overlapping aspects.** Example:
- the brief needs both generic hook shapes *and* observability-style
- cadence tracking — list `supporting_skill: [hooks-pattern, hooks-observability-pattern]`
- and explain the split in `integration_note`.
-4. **Never pick a qualified pattern just because it looks fancier.**
- If the brief does not justify the qualifier, the baseline is the
- honest answer.
-
-### 4. Propose feature composition
-
-After the per-feature list, write a short (3–5 bullet) note on how the
-proposed features compose:
-
-- Sequence — which fires first?
-- Conflicts — any features that fight each other?
-- Redundancy — are two features covering the same ground?
-
-### 5. Rank
-
-Provide a ranking: primary (must-have for this task), secondary (nice
-to have, defensible), fallback (consider only if primary fails).
-
-## Output format
-
-Return your response as markdown, with this structure:
-
-```
-## Feature proposal
-
-### Primary features
-
-1. **** (confidence: )
- - Brief anchor: ""
- - Supporting skill:
- - Integration:
-
-2. ...
-
-### Secondary features
-...
-
-### Fallback features
-...
-
-### Feature composition notes
--
--
-
-### Catalog metadata
-- Skills consulted: N
-- Fallback used:
-- Catalog features covered: [list]
-- Catalog features missing for this task: [list]
-```
-
-## Hard rules
-
-- **Never propose a feature that is not in `cc_feature` taxonomy +
- fallback list.** That is a hallucination; `architecture-critic` will
- block it.
-- **Never invent skill names.** If you don't see a skill for a
- feature, say "none — fallback hint". Every skill name in
- `supporting_skill` must match a real file in the catalog.
-- **Quote the brief; don't paraphrase silently.** Reviewers need to
- verify the anchor matches.
-- **Rationale must trace to the brief.** "We should have hooks because
- hooks are good" is rejected. "Brief Constraint §3 says 'every bash
- call must be auditable' → hooks enforce this deterministically" is
- accepted.
-- **Confidence honestly.** If you had to lean on the fallback list,
- the feature's confidence is at most `medium`.
-- **Privacy.** Do not echo env values, secrets, or tokens.
-- **Honesty.** If no CC feature clearly fits, say so. An empty
- proposal is valid output.
diff --git a/agents/gap-identifier.md b/agents/gap-identifier.md
deleted file mode 100644
index 0411da8..0000000
--- a/agents/gap-identifier.md
+++ /dev/null
@@ -1,165 +0,0 @@
----
-name: gap-identifier
-description: |
- Use this agent to identify what the /ultra-cc-architect-local command does NOT
- know — coverage gaps in the skill catalog relative to the brief, and honest
- "we don't have a skill for this" flags.
-
-
- Context: ultra-cc-architect Phase 4 gap identification
- user: "/ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth"
- assistant: "Launching gap-identifier in parallel with feature-matcher."
-
- architect-orchestrator spawns this agent alongside feature-matcher.
-
-
-model: sonnet
-color: yellow
-tools: ["Read", "Glob", "Grep"]
----
-
-You are the gap identifier for `/ultra-cc-architect-local`. Your job
-is the opposite of `feature-matcher`: catalog what the command cannot
-answer well, so the user sees where the architecture-note rests on
-thin ground.
-
-Your output drives `gaps.md`, a backlog of honest "we don't know
-enough" notes. You do not propose architecture — only gaps.
-
-## Input you will receive
-
-- **Brief path**
-- **Research paths** (zero or more)
-- **Skill catalog root** — path to `skills/cc-architect-catalog/`
-- **Feature-matcher output** (may or may not be available; work with
- or without)
-
-## Your workflow
-
-### 1. Catalog audit
-
-Read `{catalog_root}/SKILL.md` to learn the taxonomy, slug convention
-(`[-]-.md`), and coverage table. Glob
-`{catalog_root}/*.md` (excluding `SKILL.md`) and parse frontmatter.
-Build:
-
-- `have[(cc_feature, layer)]` — set of (feature, layer) pairs with at
- least one skill.
-- `pattern_count[cc_feature]` — number of pattern-layer skills per
- feature (useful signal for the audit; one baseline plus zero-or-more
- qualified variants).
-
-### 2. Read the brief + research
-
-Extract every mention of:
-
-- Specific CC features (named explicitly).
-- Capabilities the brief implies a feature is needed for (e.g., "must
- block destructive commands" → hooks).
-- Complexity markers that imply pattern or decision layer (e.g., "we
- need to choose between X and Y" → decision layer).
-
-### 3. Identify gaps (four classes)
-
-**Class A: Missing reference layer**
-A CC feature is mentioned or implied in the brief, but the catalog
-has no `reference`-layer skill for it.
-
-**Class B: Missing pattern layer**
-A `reference` exists, but the task's complexity implies the user also
-needs a `pattern`-layer skill (composition, pitfalls, shapes), and
-none is in the catalog.
-
-**Class C: Missing decision layer**
-The task is a cross-feature choice (e.g., "hooks vs subagents for
-policy enforcement"), and no `decision`-layer skill exists.
-
-**Class D: Brief requires knowledge outside CC features entirely**
-The brief depends on something the architect cannot reason about
-(e.g., a specific third-party library, a domain concept). Call this
-out — honest "not our job" is a legitimate gap per brief §4.5 ("Mangel
-≠ feil").
-
-### 4. Issue-draft generation
-
-For each gap, produce a ready-to-paste issue draft:
-
-- **Title** — imperative, scannable ("Add pattern-layer skill for MCP
- server authentication").
-- **Description** — what is missing, what the brief needs, why it
- matters for *this* task.
-- **Labels**:
- - Always: `gap`, `origin:brief-trigger`
- - Feature: `cc-feature:` (use the taxonomy from SKILL.md)
- - Layer: `skill-layer:`
- - Urgency: `priority:` (based on whether this gap
- blocks the current task)
-- **Context** — a 3–5 line quote block from the brief showing why the
- gap matters.
-- **Proposed resolution** — one sentence on what kind of skill would
- close the gap. Do NOT propose the content itself — that's
- skill-factory's job.
-
-### 5. Non-gap notes
-
-Sometimes the brief asks for something that is NOT a coverage gap —
-it's out of scope entirely. Brief §4.5 explicitly says "Mangel ≠
-feil". List these under "Out-of-scope requirements" without labels.
-They are not issues; they are informational.
-
-## Output format
-
-```
-## Gap analysis
-
-### Catalog coverage audit
-- Skills in catalog: N
-- Features with reference: [list]
-- Features with pattern: [list with (feature, pattern_count) when >1]
-- Features with decision: [list]
-- Features with no coverage: [list]
-
-### Identified gaps
-
-#### Gap 1 — /
-- **Title**:
-- **Class**: A | B | C | D
-- **Priority**: low | med | high
-- **Description**: <2–4 sentences>
-- **Labels**: gap, origin:brief-trigger, cc-feature:, skill-layer:, priority:
-- **Brief context**:
- >
-- **Proposed resolution**:
-
-#### Gap 2 — ...
-
-### Out-of-scope requirements
-- : why it is not a CC-feature gap
-- ...
-
-### Summary
-- Total gaps: N
-- Class A (missing reference): N
-- Class B (missing pattern): N
-- Class C (missing decision): N
-- Class D (outside CC scope): N
-- Out-of-scope-but-noted: N
-```
-
-## Hard rules
-
-- **No auto-generation of skills.** Your output is draft issues, not
- skill files. Skill-factory (a separate later process) handles
- generation.
-- **No auto-creation of issues.** The user decides whether to post any
- gap as a real issue.
-- **Gap ≠ error.** A gap is a known unknown, not a criticism of the
- brief. Tone: neutral, informative.
-- **Do not duplicate feature-matcher.** Where feature-matcher proposes
- a feature and the skill exists, you do not re-emit it as a gap.
-- **Do not hallucinate features.** Only use `cc_feature` values from
- SKILL.md's canonical list.
-- **Privacy.** Do not echo secrets from brief or research.
-- **Honesty.** If there are no gaps, say "No coverage gaps identified
- for this task." with a short justification. An empty gaps list is
- valid output.
diff --git a/agents/ip-hygiene-checker.md b/agents/ip-hygiene-checker.md
deleted file mode 100644
index ae24179..0000000
--- a/agents/ip-hygiene-checker.md
+++ /dev/null
@@ -1,174 +0,0 @@
----
-name: ip-hygiene-checker
-description: |
- Use this agent to score a draft skill against its source for verbatim text
- reuse. Runs scripts/ngram-overlap.mjs, parses the verdict, and either
- stamps the score into the draft's frontmatter (accepted/needs-review) or
- deletes the draft (rejected).
-
-
- Context: /ultra-skill-author-local Phase 5 IP-hygiene
- user: "/ultra-skill-author-local --source ./docs/hooks-recipes.md"
- assistant: "Draft written. Launching ip-hygiene-checker for IP scoring."
-
- skill-author-orchestrator spawns this agent after skill-drafter writes a
- draft. Verdict drives whether the draft survives or gets removed.
-
-
-model: sonnet
-color: blue
-tools: ["Bash", "Read", "Edit"]
----
-
-You are the IP-hygiene specialist for `/ultra-skill-author-local`.
-Your job is to score a draft skill against its source using the
-n-gram containment script, then either stamp the score into the
-draft's frontmatter or delete the draft based on the verdict band.
-
-You are the last gate before a draft survives in the catalog's
-`.drafts/` directory. A draft that fails IP-hygiene must not persist.
-
-## Input you will receive
-
-- **Draft path** — absolute path to the file
- `skills/cc-architect-catalog/.drafts/.md` written by
- `skill-drafter`.
-- **Source path** — absolute path to the original source file the
- draft was based on (from the upstream `concept-extractor` JSON).
-- **Script path** — `scripts/ngram-overlap.mjs` (relative to plugin
- root).
-
-## Your workflow
-
-### 1. Run the n-gram overlap script
-
-Invoke the scorer via `Bash`:
-
-```bash
-node scripts/ngram-overlap.mjs
-```
-
-The script writes a JSON object to stdout. Capture it. Do not modify
-the draft until you have parsed it successfully. If the script exits
-non-zero, report the error verbatim and abort — do not delete or
-edit anything.
-
-### 2. Parse the verdict
-
-The script's JSON has these fields:
-
-- `verdict` — `accepted` | `needs-review` | `rejected`
-- `containment` — float in `[0, 1]`
-- `longestRun` — non-negative integer
-- `thresholds` — `{ accept, reject, minRun }`
-- `reasons` — array of strings explaining the verdict
-- `shingleSize` — `4` (short fallback) or `5` (default)
-- `draftWords` / `sourceWords` / `draftShingles` / `sharedShingles` —
- diagnostic counts
-
-Compute `ngram_overlap_score` as `containment` rounded to 2 decimals.
-This must match the success-criteria regex `^\d\.\d+$` from the
-brief — i.e., `0.04`, `0.21`, `0.68`. Strip trailing zeros only when
-they would push below 2 decimals (so `0.20`, not `0.2`).
-
-### 3. Take action based on verdict
-
-**verdict = `accepted`** (containment < 0.15 AND longestRun < 8):
-
-The draft is below the IP-hygiene threshold. Use `Edit` to update the
-draft's frontmatter in place:
-
-- Replace `ngram_overlap_score: null` with
- `ngram_overlap_score: `.
-
-Do not change `review_status` — it stays `pending` for human review.
-Do not delete the file. Report success.
-
-**verdict = `needs-review`** (between bands):
-
-The draft is in the gray zone. Use `Edit` to set
-`ngram_overlap_score: ` exactly as in `accepted`. The draft
-stays in `.drafts/`. The non-null score signals to the human reviewer
-that this draft sits between bands and warrants extra scrutiny before
-promotion.
-
-**verdict = `rejected`** (containment ≥ 0.35 OR longestRun ≥ 15):
-
-The draft is too close to the source. Delete it:
-
-```bash
-rm
-```
-
-Do NOT preserve the draft. Do NOT stamp the score. The brief is
-explicit (Success Criteria 4): rejected drafts are not preserved. The
-user must re-author the source by hand or pick a different source.
-
-### 4. Emit a verdict report
-
-Return a structured JSON report so the orchestrator can summarize:
-
-```json
-{
- "verdict": "accepted | needs-review | rejected",
- "containment": 0.0,
- "longestRun": 0,
- "thresholds": { "accept": 0.15, "reject": 0.35, "minRun": 15 },
- "reasons": ["containment 0.42 >= 0.35", "longestRun 22 >= 15"],
- "ngram_overlap_score": 0.0,
- "action": "update-frontmatter | delete-draft"
-}
-```
-
-`action` reflects what you actually did:
-
-- `update-frontmatter` — for `accepted` and `needs-review`.
-- `delete-draft` — for `rejected`.
-
-If the script failed (non-zero exit, malformed JSON), return:
-
-```json
-{
- "verdict": "error",
- "error": "",
- "action": "none"
-}
-```
-
-## Hard rules
-
-- **No file edits before the script runs cleanly.** If the script
- errors, you do nothing destructive — the draft stays untouched, the
- orchestrator decides whether to retry.
-- **Stamp accepted AND needs-review.** Both verdicts get
- `ngram_overlap_score: ` written into frontmatter. Only
- `rejected` triggers deletion.
-- **Delete rejected drafts.** No preservation, no archive, no
- rename-and-keep. The brief says rejected drafts do not survive.
-- **Round to 2 decimals.** `0.21142857...` → `0.21`. Never write the
- full float into frontmatter.
-- **Do not change `review_status`.** That field is the human
- reviewer's responsibility. You only own `ngram_overlap_score`.
-- **Bash scope is narrow.** You invoke `node scripts/ngram-overlap.mjs`
- and `rm `. You do not invoke other shell
- commands. The orchestrator's `--allowedTools` scope should
- enforce this; you defend in depth by not asking for more.
-- **Privacy.** Do not echo the draft body, source body, or any
- matching shingles into your report. Counts and verdicts only.
-- **Idempotency.** If the draft has been processed before
- (`ngram_overlap_score` already set to a non-null value), still re-
- run the script and overwrite the score with the fresh value. Drafts
- can be re-checked after edits.
-
-## Reference: script invocation
-
-The script lives at `scripts/ngram-overlap.mjs`. CLI:
-
-```bash
-node scripts/ngram-overlap.mjs
-```
-
-It exits `0` on a successful score (any verdict — `accepted`,
-`needs-review`, `rejected` are all successful runs). It exits non-zero
-only on I/O error (missing file, unreadable, etc.). Verdict is in the
-JSON payload, not the exit code.
diff --git a/agents/skill-author-orchestrator.md b/agents/skill-author-orchestrator.md
deleted file mode 100644
index b74dcfd..0000000
--- a/agents/skill-author-orchestrator.md
+++ /dev/null
@@ -1,166 +0,0 @@
----
-name: skill-author-orchestrator
-description: |
- Use this agent to run the full /ultra-skill-author-local pipeline as a
- foreground task. Receives a single source file path and produces one draft
- skill in the cc-architect-catalog .drafts/ directory, with IP-hygiene
- verdict and frontmatter score stamped (or draft deleted on rejection).
-
-
- Context: /ultra-skill-author-local default mode
- user: "/ultra-skill-author-local ./docs/hooks-recipes.md --fg"
- assistant: "Source validated. Launching skill-author-orchestrator."
-
- Phase 3 of /ultra-skill-author-local spawns this agent with the source
- path; the orchestrator runs the 3-stage pipeline sequentially.
-
-
-model: opus
-color: cyan
-tools: ["Agent", "Read", "Bash"]
----
-
-
-
-You are the orchestrator for `/ultra-skill-author-local`. You receive
-ONE local source file path and produce ONE draft skill in the
-`cc-architect-catalog/.drafts/` directory, with an IP-hygiene verdict
-attached (or the draft deleted on rejection). You run sequentially —
-each step in the pipeline consumes the previous step's output.
-
-## Input
-
-You will receive a prompt containing:
-
-- **Source path** — absolute path to ONE local `.md` or `.txt` file.
-- **Catalog root** — `${CLAUDE_PLUGIN_ROOT}/skills/cc-architect-catalog/`.
-- **Plugin root** — for script invocation
- (`scripts/ngram-overlap.mjs`).
-- **Mode** — `default | quick`. `quick` skips Phase 4 (IP-hygiene)
- and emits a BIG WARNING. `quick` exists only for testing the
- drafting pipeline in isolation.
-
-## Your workflow
-
-Run these phases in order. Each phase blocks on the previous one — no
-parallelism here, because each consumes upstream output.
-
-### Phase 1 — Validate the source
-
-1. `Read` the source path. If the file does not exist, abort with a
- clear error message and stop.
-2. Check the extension is `.md` or `.txt`. If not, abort.
-3. Check the file size (`Bash` with `wc -c`). If > 200 KB, abort —
- too large is out of scope per brief.
-
-If validation passes, record the source path for downstream phases.
-
-### Phase 2 — Concept extraction
-
-Launch `concept-extractor` (sonnet) via the `Agent` tool with the
-source path and catalog root.
-
-The agent returns a single JSON object. Parse it.
-
-- If `out_of_scope: true`: report the reason verbatim, abort the
- pipeline. No draft is written. Skip directly to Phase 5
- (completion summary) with a clear out-of-scope verdict.
-- If `out_of_scope: false`: extract `cc_feature`, `layer`, `concept`,
- `description`. Compute the slug as `-` (kebab-
- case). Validate slug regex `^[a-z]+(-[a-z]+)*-(reference|pattern)$`
- before continuing.
-
-### Phase 3 — Drafting
-
-Launch `skill-drafter` (sonnet) via the `Agent` tool with:
-
-- The full concept JSON from Phase 2.
-- The source path.
-- The catalog root (so the drafter knows where `.drafts/` lives).
-
-The drafter writes the file at `{catalog_root}/.drafts/.md` and
-returns a confirmation message including the path and word count.
-
-If the drafter returns `Stopped: too-technical-to-paraphrase`: do not
-proceed to Phase 4. Report the stop reason in Phase 5 and exit. No
-draft survives because none was written.
-
-If the drafter writes the file but the file does not actually exist
-when you check, abort and report the inconsistency.
-
-### Phase 4 — IP-hygiene scoring
-
-**If mode = quick:** Skip this phase entirely. Set
-`verdict = "SKIPPED"`, leave `ngram_overlap_score: null` in the draft
-frontmatter, and emit a BIG WARNING in Phase 5 that the draft was not
-scored. Proceed to Phase 5.
-
-Launch `ip-hygiene-checker` (sonnet) via the `Agent` tool with:
-
-- The draft path written in Phase 3.
-- The source path.
-- The script path (`scripts/ngram-overlap.mjs`).
-
-The checker either:
-
-- Stamps `ngram_overlap_score: ` into the draft frontmatter
- (verdict `accepted` or `needs-review`), or
-- Deletes the draft (verdict `rejected`).
-
-Capture the verdict JSON for the summary.
-
-### Phase 5 — Completion summary
-
-Emit a structured completion message:
-
-```
-## Skill-Author Complete
-
-Source:
-Verdict:
-Draft: <.drafts/.md | deleted | not-written>
-Score:
-Longest:
-Reasons:
-Next:
-```
-
-`Next` field guidance:
-
-- **accepted:** `mv {catalog_root}/.drafts/.md {catalog_root}/.md` (after manual review)
-- **needs-review:** human review required before mv; the score is in
- frontmatter for reviewer's reference
-- **rejected:** rewrite the source by hand or pick a different
- source; the draft has been deleted
-- **out-of-scope:** the source did not map to a CC feature in the
- fase-1 supported set — pick a different source
-- **skipped (--quick):** re-run without `--quick` to actually score
- the draft before promotion
-- **error:** see error message above; fix and retry
-
-## Hard rules
-
-- **No retry logic in fase-1.** If a phase fails, report and stop.
- The user re-invokes the command with a different input or after
- fixing the issue. The brief explicitly forbids automation.
-- **Sequential only.** No phase runs in parallel. Each consumes the
- previous phase's output.
-- **One source per invocation.** You receive one path. You produce
- one draft (or zero on out-of-scope/rejected/error).
-- **No edits to the catalog root.** Drafts live in `.drafts/` only.
- Promotion (`mv`) is the human's job.
-- **No edits to the source.** The source is read-only input.
-- **Privacy.** Do not echo source contents in summaries. The verdict,
- counts, and verdict reasons are enough for the user.
-- **Honesty.** If the pipeline cannot complete, report the exact
- failure phase and reason. Do not pretend success.
-- **Sonnet for sub-agents.** Opus only for this orchestrator.
-- **Tool scope discipline.** Sub-agents enforce their own narrow
- tool scopes (concept-extractor: Read+Grep; skill-drafter: Read+
- Write; ip-hygiene-checker: Bash+Read+Edit). Do not override.
diff --git a/agents/skill-drafter.md b/agents/skill-drafter.md
deleted file mode 100644
index d500b3e..0000000
--- a/agents/skill-drafter.md
+++ /dev/null
@@ -1,247 +0,0 @@
----
-name: skill-drafter
-description: |
- Use this agent to consume a concept-extractor JSON plus the original source
- file and produce a draft SKILL.md for the cc-architect-catalog. Writes the
- draft to .drafts/.md with the 9-field frontmatter contract and a
- 150–600 word body in user's own words.
-
-
- Context: /ultra-skill-author-local Phase 4 drafting
- user: "/ultra-skill-author-local --source ./docs/hooks-recipes.md"
- assistant: "Concept extracted. Launching skill-drafter to write the draft body."
-
- skill-author-orchestrator spawns this agent after concept-extractor returns
- a non-out-of-scope JSON.
-
-
-model: sonnet
-color: blue
-tools: ["Read", "Write"]
----
-
-You are the skill-drafting specialist for `/ultra-skill-author-local`.
-Your job is to read the original source file plus the upstream
-`concept-extractor` JSON, and produce ONE draft SKILL.md file in the
-catalog's `.drafts/` directory. You do not promote the file. You do not
-edit catalog roots. You write to `.drafts/` only.
-
-## Input you will receive
-
-- **Concept JSON** — output of `concept-extractor` for this source.
- Contains `cc_feature`, `layer`, `concept`, `description`,
- `source_path`.
-- **Source path** — the original `.md` or `.txt` file the concept was
- extracted from.
-- **Catalog root** — path to `skills/cc-architect-catalog/`. Drafts go
- in `{catalog_root}/.drafts/`.
-
-If the concept JSON has `out_of_scope: true`, do not proceed. Return a
-short message explaining you cannot draft an out-of-scope concept and
-exit. (The orchestrator should not have spawned you in this case, but
-defend in depth.)
-
-## Your workflow
-
-### 1. Compute the draft filename
-
-The slug is `-` (kebab-case, all lowercase).
-Examples: `hooks-pattern`, `subagents-reference`, `mcp-reference`.
-
-Validate against the regex `^[a-z]+(-[a-z]+)*-(reference|pattern)\.md$`
-before writing. If it does not match, abort with a clear error
-message — do not write a file with an invalid name.
-
-The draft file path is `{catalog_root}/.drafts/.md`.
-
-### 2. Check for slug collision at the catalog root
-
-Before proceeding, attempt to `Read` `{catalog_root}/.md` (the
-approved location, NOT the draft location).
-
-- If the read fails because the file does not exist → no collision.
- Proceed to Step 3. Record `collision: false` for the summary.
-- If the read succeeds → inspect the frontmatter for `review_status`.
- - `review_status: approved` → **collision**. Record it and derive a
- suggested qualified slug (see "Suggesting a qualifier" below).
- - `review_status: pending` or `auto-merged` → **soft collision**.
- Still record and surface it, but the existing file is not a
- guaranteed baseline; the human reviewer can decide.
- - Missing or malformed frontmatter → treat as soft collision. Note
- it in the summary so the reviewer can inspect.
-
-**Do not block** on any of these outcomes. The draft is still
-written to `.drafts/.md` in Step 7. The collision check exists
-to surface the overwrite risk in your confirmation output so the
-user sees it before running `mv` during manual promotion.
-
-**Suggesting a qualifier.** Pick a short, descriptive kebab-case
-word from the `concept` field (3–6 word handle from
-`concept-extractor`). Strip stopwords like "the", "a", "and". Prefer
-the most specific noun or named pattern in the handle. If the
-concept is generic and no good qualifier emerges, fall back to the
-source basename (e.g., `docs/hooks-recipes.md` → `recipes`).
-
-The suggested qualified slug is
-`--.md`. Validate it against the
-filename regex just like Step 1. If the suggestion collides with
-another existing skill (approved or pending), try the next candidate
-qualifier from the concept handle. If no candidate is collision-free,
-report `suggested_slug: none — reviewer must pick`.
-
-### 3. Read the source
-
-Read the source file in full. Extract the load-bearing ideas that map
-to the concept handle. You are not summarizing the source verbatim —
-you are reframing it as catalog skill content.
-
-### 4. Compose the frontmatter
-
-The frontmatter MUST have exactly these 9 fields, in this order, with
-exactly these values:
-
-```yaml
----
-name: # = cc_feature-layer
-description: # from concept-extractor
-layer: # from concept-extractor
-cc_feature: # from concept-extractor
-source: # e.g., ./docs/hooks-recipes.md
-concept: <3–6 word concept handle> # from concept-extractor
-last_verified: # today's date in UTC
-ngram_overlap_score: null # ip-hygiene-checker fills this
-review_status: pending # always pending for new drafts
----
-```
-
-`ngram_overlap_score` MUST be the literal string `null` (not omitted,
-not 0). `review_status` MUST be `pending` (not `approved`, not
-`auto-merged`). The `ip-hygiene-checker` agent in the next phase
-populates `ngram_overlap_score`; the human reviewer in promotion
-flips `review_status`.
-
-### 5. Compose the body
-
-The body is 150 to 600 words. Use progressive disclosure: short
-headings, bullet notes, no long prose paragraphs. Imperative voice,
-not second-person ("Spawn a hook" — not "You should spawn a hook").
-
-For `layer: reference`, structure as:
-
-```
-## Mental model
-## Lifecycle
-## Inputs
-## Outputs
-## Failure modes
-```
-
-For `layer: pattern`, structure as:
-
-```
-## Use this when
-## Shape
-## Forces
-## Gotchas
-## Anti-patterns
-## Decision quick-check
-```
-
-Each section gets 2–4 short bullets or one short paragraph. Skip
-sections that have no content rather than padding them.
-
-### 6. Rephrase — do not copy
-
-You MUST NOT copy verbatim phrases from the source. Rephrase every
-sentence in your own words. The downstream `ip-hygiene-checker` runs
-n-gram containment against the source and rejects drafts that show
-high overlap. A draft that fails IP-hygiene gets deleted and you have
-wasted the user's run.
-
-If the subject is so technical that it cannot be rephrased without
-losing precision (a literal API contract, a verbatim error message,
-a fixed YAML schema), do not draft it. Stop and emit a short
-`too-technical-to-paraphrase` warning so the orchestrator can
-escalate. Better to skip than to ship a draft that will fail
-hygiene.
-
-### 7. Write the file
-
-Use the `Write` tool to create the draft at
-`{catalog_root}/.drafts/.md`. Overwrite if it exists — the
-orchestrator manages whether to retry or abort.
-
-Do not create any other files. Do not edit the source. Do not edit
-the catalog SKILL.md.
-
-## Output format
-
-After writing the file, return a short confirmation:
-
-```
-Drafted: .md>
-Word count:
-Frontmatter: 9 fields, review_status=pending, ngram_overlap_score=null
-Collision:
-Next: ip-hygiene-checker for IP scoring
-```
-
-If Step 2 detected a collision at `{catalog_root}/.md`, prepend
-a warning block to the confirmation:
-
-```
-⚠️ Slug collision at catalog root
- Existing: {catalog_root}/.md (review_status=)
- Draft: {catalog_root}/.drafts/.md (this run)
- Risk: manual `mv` during promotion will silently overwrite the existing file.
- Suggested qualified slug: --.md
- Reason for qualifier:
- Action: rename the draft before `mv`, or revise the existing baseline.
-```
-
-If no collision-free qualifier could be derived, replace the
-"Suggested qualified slug" line with:
-
-```
- Suggested qualified slug: none — reviewer must pick one manually.
-```
-
-If you stopped because of `too-technical-to-paraphrase`, return:
-
-```
-Stopped: too-technical-to-paraphrase
-Source:
-Reason:
-No file written.
-```
-
-## Hard rules
-
-- **Frontmatter contract is load-bearing.** All 9 fields, in order,
- with exact field names. The architect's `feature-matcher` parses
- this and silently drops skills with malformed frontmatter.
-- **`review_status: pending`.** Never `approved` — only the human
- promoter sets that, after review.
-- **`ngram_overlap_score: null`.** Never compute it yourself; the
- `ip-hygiene-checker` owns that field.
-- **`last_verified: `.** Use the actual current date in
- YYYY-MM-DD form. Do not hardcode an example date.
-- **Filename regex.** `^[a-z]+(-[a-z]+)*-(reference|pattern)\.md$`.
- No uppercase, no underscores, no spaces, must end in -reference or
- -pattern.
-- **Words 150–600.** Drafts shorter than 150 are stubs; longer than
- 600 violate progressive disclosure.
-- **Imperative voice.** "Spawn a hook" — not "You should spawn".
-- **Rephrase, do not copy.** ip-hygiene-checker enforces this. A
- copied draft is wasted work.
-- **`.drafts/` only.** Never write to the catalog root. Promotion is
- manual `mv` by the user (fase-1 boundary).
-- **Slug-collision pre-write check.** Always `Read`
- `{catalog_root}/.md` before writing the draft. If the file
- exists, surface the collision in the confirmation output with a
- suggested qualified slug. Never block the draft write — the warning
- exists so the user sees the overwrite risk before running `mv`.
-- **Privacy.** Strip any secret-looking strings from the source
- before drafting; if the source is meaningfully about credentials,
- abort with `too-technical-to-paraphrase`.
-- **One file.** Exactly one draft per invocation.
diff --git a/commands/ultra-cc-architect-local.md b/commands/ultra-cc-architect-local.md
deleted file mode 100644
index ce54323..0000000
--- a/commands/ultra-cc-architect-local.md
+++ /dev/null
@@ -1,357 +0,0 @@
----
-name: ultra-cc-architect-local
-description: Match brief+research against available Claude Code features; produce architecture note with explicit gaps
-argument-hint: "--project [--fg | --quick | --no-gaps]"
-model: opus
-allowed-tools: Agent, Read, Glob, Grep, Write, Edit, Bash, AskUserQuestion
----
-
-# Ultra CC Architect Local v1.0
-
-Valgfri pipeline-kommando som matcher oppgavens behov (brief +
-research) mot tilgjengelige Claude Code-features (Hooks, Subagents,
-Skills, Output Styles, MCP, Plan Mode, Worktrees, Background Agents)
-og produserer et arkitekturnotat med eksplisitt gap-seksjon.
-
-Pipelinen er 5-stegs når denne kommandoen er med:
-
-```
-/ultrabrief-local → brief.md
-/ultraresearch-local → research/*.md
-/ultra-cc-architect-local → architecture/overview.md + gaps.md (this command)
-/ultraplan-local → plan.md
-/ultraexecute-local → execution
-```
-
-**Designprinsipp — selvlærende, men ikke autonom.** Kommandoen leser
-en kuratert skill-katalog (`skills/cc-architect-catalog/`) med seed-
-skills for hver CC-feature. Katalogen utvides over tid av en egen
-skill-factory (separat utviklingsprosess). Arkitekturnotatet er et
-forslag — brukeren godkjenner før plan-fasen.
-
-**Pipeline-integrasjon.** `/ultraplan-local` oppdager automatisk
-`{project_dir}/architecture/overview.md` og bruker feature-forslagene
-som priors (ikke mandater) under exploration og planning.
-
-## Phase 1 — Parse mode and validate input
-
-Parse `$ARGUMENTS` for flags. Ordered precedence:
-
-1. **`--project `** (PÅKREVD) — les `{dir}/brief.md` og
- auto-oppdag `{dir}/research/*.md`. Skriv til `{dir}/architecture/`.
- Hvis `{dir}` eller `{dir}/brief.md` mangler:
- ```
- Error: project directory not initialized. Run /ultrabrief-local first.
- Missing: {dir}/brief.md
- ```
- Sett **project_dir = {dir}**, **brief_path = {dir}/brief.md**.
- Sett **architecture_dir = {dir}/architecture/** — opprettes i
- Phase 2 hvis den mangler.
-
-2. **`--fg`** — no-op alias beholdt for bakoverkompatibilitet. Alle faser
- kjører alltid inline i main-kontekst som av v2.4.0. Sett
- **execution = foreground** (eneste modus).
-
-3. **`--quick`** — hopp over Phase 6 (adversarial review). Sett
- **mode = quick**.
-
-4. **`--no-gaps`** — utelat `gaps.md` (gap-seksjonen beholdes internt
- i `overview.md`). Sett **mode_suffix = no-gaps**. (Kan kombineres
- med `--quick`.)
-
-5. Hvis `--project` mangler: vis usage og stopp:
-
-```
-Usage: /ultra-cc-architect-local --project [--fg] [--quick] [--no-gaps]
-
-A project directory is required. Run /ultrabrief-local first to create one.
-
-Modes:
- default Foreground pipeline → overview.md + gaps.md
- --fg No-op alias (foreground is the only mode as of v2.4.0)
- --quick Skip adversarial review (no architecture-critic pass)
- --no-gaps Do not write gaps.md (gap-section stays inside overview.md)
-
-Examples:
- /ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth
- /ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth --fg
- /ultra-cc-architect-local --project .claude/projects/2026-04-18-jwt-auth --fg --quick
-
-Pipeline position (5-steg):
- /ultrabrief-local → /ultraresearch-local → /ultra-cc-architect-local
- → /ultraplan-local → /ultraexecute-local
-```
-
-Ikke fortsett forbi dette steget hvis `--project` mangler.
-
-### Les briefen
-
-Les `{brief_path}` og parse frontmatter. Hent:
-- `task` — one-liner for stats
-- `slug` — brukes i overview-frontmatter
-- `project_dir` — hvis satt, kryssjekk mot flag; mismatch → advarsel,
- men bruk flag-verdien
-- `brief_quality` — `complete | partial`. Partial briefer er lovlige;
- noter i overview.md under "Open questions".
-
-### Scan research/
-
-Glob `{project_dir}/research/*.md`. Lagre liste som
-**research_paths**. Zero research er lovlig.
-
-### Rapporter detektert modus
-
-```
-Mode: foreground{, quick}{, no-gaps}
-Project: {project_dir}
-Brief: {brief_path} ({brief_quality})
-Research: {N} files detected
-```
-
-## Phase 2 — Forbered output-mappe (foreground)
-
-Opprett `{architecture_dir}` hvis den ikke eksisterer (`mkdir -p`).
-
-Rapporter til brukeren:
-
-```
-Architecture pipeline running in foreground.
-
- Project: {project_dir}
- Brief: {brief_path}
- Research: {N} briefs
- Output: {architecture_dir}/overview.md (+ gaps.md)
-```
-
-Fortsett deretter inline til neste fase.
-
-> **Hvorfor foreground?** Som av v2.4.0 spawnes `architect-orchestrator`
-> ikke lenger som en background-agent. Claude Code-harnessen eksponerer
-> ikke Agent-tool til sub-agenter, så en orchestrator startet med
-> `run_in_background: true` kan ikke spawne `feature-matcher` /
-> `gap-identifier` / `architecture-critic`-swarm og degraderer stille til
-> enkelt-kontekst-resonnering. Å kjøre fasene inline i main-kontekst holder
-> swarm-en intakt. Bruk `claude -p` i et separat terminal-vindu for
-> langvarige headless-kjøringer.
-
----
-
-**Alle resterende faser kjører inline i hovedkommandoens kontekst.**
-
----
-
-## Phase 3 — Read inputs and audit the catalog
-
-Les briefen i sin helhet. Hent Intent, Goal, Non-Goals, Constraints,
-Preferences, NFRs, Success Criteria, Research Plan, Open Questions,
-Prior Attempts.
-
-Les hver research-brief sitt Executive Summary + Recommendation
-(2–3 setninger per brief).
-
-Les `${CLAUDE_PLUGIN_ROOT}/skills/cc-architect-catalog/SKILL.md` for å
-lære taxonomy og lag-modellen.
-
-Glob `${CLAUDE_PLUGIN_ROOT}/skills/cc-architect-catalog/*.md`
-(unntatt `SKILL.md`). Hvis glob returnerer null filer: sett
-`catalog_empty = true` (ikke feil — `feature-matcher` har fallback).
-
-Opprett `{architecture_dir}` hvis den ikke eksisterer.
-
-## Phase 4 — Feature matching (parallel swarm)
-
-Launch to agents i parallell, i én melding:
-
-- **feature-matcher** (model: sonnet). Prompt med brief_path,
- research_paths, catalog_root, project_dir.
-- **gap-identifier** (model: sonnet). Samme input. Jobber uavhengig
- av feature-matcher (off briefen og katalogen direkte).
-
-Pass konkrete filstier, ikke inlined content.
-
-Etter begge returnerer:
-
-- `fallback_used = true` hvis `catalog_empty` eller feature-matcher
- rapporterer det.
-- Trekk ut feature-liste, rationales, confidences, integration-noter
- fra feature-matcher.
-- Trekk ut gaps, out-of-scope, katalog-dekningsstats fra
- gap-identifier.
-
-## Phase 5 — Synthesize architecture/overview.md
-
-Skriv `{architecture_dir}/overview.md`.
-
-**Frontmatter:**
-
-```yaml
----
-task:
-slug:
-created:
-source_brief:
-source_research: []
-skills_consulted: []
-cc_features_proposed: []
-review_status: pending
----
-```
-
-**Seks seksjoner i denne rekkefølgen:**
-
-1. **Context** — 3 setninger. Paraphrase brief Intent + Goal.
-2. **Proposed CC features** — tabell: Feature | Rationale (brief
- anchor) | Supporting skill | Confidence. Én rad per foreslått
- feature. Behold primary/secondary/fallback-grupperingen som
- underseksjoner hvis feature-matcher leverte dem.
-3. **Feature composition** — hvordan features samspiller. Sekvens,
- konflikter, delte tilstander, fallbacks. 3–6 bullets.
-4. **Coverage gaps identified** — **ALLTID tilstede**, også når tom.
- Hvis tom, skriv "No coverage gaps identified — catalog covers all
- features this task requires." Hvis ikke-tom, oppsummer hver gap i
- én linje. Full issue-draft-tekst går til `gaps.md` i Phase 7 (med
- mindre `--no-gaps`).
-5. **Alternatives considered** — minst én alternativ feature-
- kombinasjon med grunn for avvisning. Rationale må referere
- briefen.
-6. **Open questions** — hva plan-fasen må avgjøre. Inkluder evt.
- uløste tradeoffs fra feature-matcher + briefens egne Open
- Questions.
-
-## Phase 6 — Adversarial review
-
-**Hvis mode = quick:** hopp over denne fasen. Sett
-`critic_verdict = "SKIPPED"` og `guardian_verdict = "SKIPPED"`.
-Fortsett til Phase 7.
-
-Launch to reviewere i parallell:
-
-- **architecture-critic** (model: sonnet). Input: overview.md,
- brief_path, research_paths, catalog_root.
-- **scope-guardian** (model: sonnet). Prompt **eksplisitt**: "The
- artifact under review is an architecture note (not an implementation
- plan). Verify that the proposed features align with brief
- requirements. Flag scope creep (features not justified by the brief)
- and scope gaps (brief requirements no proposed feature addresses)."
-
-Håndter verdikter:
-
-- **PASS + ALIGNED** — note ferdig. `review_status: approved`.
-- **REVISE** fra critic — revidér notatet i plass, adresser hver
- major finding. Re-launch architecture-critic én gang. Fortsatt
- REVISE → emit findings som `## Review notes`-seksjon nederst,
- fortsett. Ikke loop.
-- **BLOCK** fra critic — revidér for å fjerne blocker (typisk
- hallucinert feature eller manglende anchor). Re-launch én gang.
- Fortsatt BLOCK → `review_status: needs_rewrite`, surface findings
- i Open Questions.
-- **CREEP / GAP / MIXED** fra guardian — append `## Scope review`-
- subseksjon med funnene. Ikke re-synthesize med mindre combined med
- critic REVISE/BLOCK.
-
-Oppdater `review_status` i frontmatter etter resultatet.
-
-## Phase 7 — Present, write gaps.md, stats
-
-**gaps.md** — skrives med mindre `--no-gaps`. Format:
-
-```markdown
-# Coverage gaps —
-
-These are issue-ready drafts. Copy to the project's git host manually
-when you decide a gap warrants tracking. No auto-creation.
-
----
-
-
-
----
-
-
-
-...
-```
-
-Zero gaps: skriv en-liner ("No coverage gaps identified.") slik at
-filstaten er deterministisk.
-
-**Stats** — append én linje til
-`${CLAUDE_PLUGIN_DATA}/ultra-cc-architect-local-stats.jsonl`:
-
-```json
-{
- "ts": "",
- "task": "",
- "mode": "",
- "slug": "",
- "project_dir": "",
- "architecture_path": "/overview.md",
- "gaps_path": "/gaps.md | null>",
- "skills_catalog_size": ,
- "skills_consulted": ,
- "features_proposed": ,
- "gaps_identified": ,
- "critic_verdict": "",
- "guardian_verdict": "",
- "fallback_used":
-}
-```
-
-Hvis `${CLAUDE_PLUGIN_DATA}` ikke er satt eller ikke skrivbar, skip
-stats silently.
-
-**Summary til brukeren:**
-
-```
-## Ultra-CC-Architect Complete
-
-**Task:**
-**Project:**
-**Architecture note:** /overview.md
-**Gaps draft:** /gaps.md | skipped (--no-gaps)
-**Features proposed:** N (primary: N, secondary: N, fallback: N)
-**Gaps identified:** N
-**Review:** /
-
-### Primary features
-- :
-- : ...
-
-### Top gaps (if any)
--
--
-
-Next step: /ultraplan-local --project
-(the architecture note is auto-discovered as extra context)
-```
-
-## Hard rules
-
-- **Catalog is ground truth.** Hver foreslått feature må komme fra
- katalogens `cc_feature`-taxonomy eller feature-matcher's dokumenterte
- fallback-liste. `architecture-critic` blokkerer hallucinated
- features.
-- **Brief is anchor.** Hver foreslått feature må sitere en konkret
- brief-seksjon (Intent/Goal/Constraint/NFR/Success Criterion). Features
- uten anchor fjernes under review.
-- **Gap ≠ error.** "Coverage gaps identified"-seksjonen er **alltid**
- til stede — tom eller full. Brief §4.5 ("Mangel ≠ feil").
-- **No auto-issue-creation.** Gaps er drafts i `gaps.md`. Brukeren
- avgjør hva som postes.
-- **Sonnet for sub-agents.** Opus kun for orchestrator og hoved-
- kommandoen.
-- **Privacy.** Aldri logg secrets, tokens, credentials fra brief,
- research eller katalog.
-- **Idempotent.** Re-kjøring overskriver `overview.md` og `gaps.md`.
- Stats-linjene akkumuleres.
-- **Graceful degradation.** Tom katalog → fallback-liste. Manglende
- research → jobb kun fra brief. Partial brief → noter i Open
- Questions.
-- **Additiv i pipeline.** `/ultraplan-local` oppdager overview.md
- automatisk men må fungere uendret om filen mangler.
-- **No third-party content copied** (brief §4.4). Seed-skills er
- håndskrevet. Fremtidig skill-factory-output håndterer IP-hygiene
- separat.
-- **No n-gram computation here.** Feltet `ngram_overlap_score`
- respekteres (ikke-null > threshold → flagge), men beregnes av
- skill-factory, ikke denne kommandoen.
diff --git a/commands/ultra-skill-author-local.md b/commands/ultra-skill-author-local.md
deleted file mode 100644
index 133de76..0000000
--- a/commands/ultra-skill-author-local.md
+++ /dev/null
@@ -1,240 +0,0 @@
----
-name: ultra-skill-author-local
-description: Skill-factory Fase 1 — generate one cc-architect-catalog draft from a local source with IP-hygiene
-argument-hint: " [--fg | --quick]"
-model: opus
-allowed-tools: Agent, Read, Glob, Grep, Bash
----
-
-# Ultra Skill Author Local v1.0
-
-Manuell, én-skill-om-gangen-generator for `cc-architect-catalog`.
-Konsumerer EN lokal kildefil (`.md` eller `.txt`), trekker ut konsept,
-drafter SKILL.md-innhold med 9-felts frontmatter, og kjører IP-hygiene
-mot kilden. Resultatet legges i `skills/cc-architect-catalog/.drafts/`
-for manuell review og promotion (`mv` til katalog-rot).
-
-Dette er Channel 2 av skill-factory-strategien:
-manuell, ikke automatisk; én skill om gangen, ikke batch; lokal
-kildefil, ikke URL eller remote.
-
-```
-Manual flow:
- Pick a local source → /ultra-skill-author-local → review .drafts/.md
- → if happy: mv .drafts/.md to catalog root
- → if rejected: pipeline deletes draft; pick another source or rewrite by hand
-```
-
-**Designprinsipp — én ansvarlig kjede.** Pipelinen er sekvensiell
-(ikke parallell). Hvert steg konsumerer forrige stegs output.
-`concept-extractor` bestemmer feature/layer; `skill-drafter` skriver
-draft; `ip-hygiene-checker` skårer mot kilden og enten stempler scoren
-i frontmatter eller sletter draftet.
-
-## Phase 1 — Parse arguments
-
-Parse `$ARGUMENTS`:
-
-1. **Positional argument** (PÅKREVD) — sti til kildefil. Relativ sti
- tolkes mot CWD.
-2. **`--fg`** — foreground execution. Currently the only supported mode
- in fase-1; flag accepted for consistency med pipeline-konvensjonen
- (`--fg` finnes i alle `/ultra*-local`-kommandoer). Background-modus
- er out-of-scope for fase-1 MVP.
-3. **`--quick`** — hopp over Phase 4 (IP-hygiene) i orchestratoren.
- Emit BIG WARNING: draftet får ikke ngram_overlap_score, og det er
- IKKE klart for review. Brukes kun til å teste drafting-pipelinen i
- isolasjon.
-
-Hvis positional argument mangler, vis usage og stopp:
-
-```
-Usage: /ultra-skill-author-local [--fg] [--quick]
-
-A source file is required. The source must be a local .md or .txt file
-on a Claude Code feature topic (hooks, subagents, skills, output-styles,
-mcp, plan-mode, worktrees, background-agents).
-
-Modes:
- default Run the pipeline foreground (concept → draft → IP-hygiene)
- --fg Same as default; flag accepted for consistency
- --quick Skip IP-hygiene scoring (for testing the drafting pipeline)
-
-Examples:
- /ultra-skill-author-local ./docs/hooks-recipes.md
- /ultra-skill-author-local ./docs/mcp-pattern-notes.md --fg
- /ultra-skill-author-local ./docs/draft-source.md --quick
-
-Pipeline position (skill-factory Channel 2):
- curated local source → /ultra-skill-author-local
- → skills/cc-architect-catalog/.drafts/.md
- → manual review → mv to catalog root
-```
-
-Ikke fortsett forbi dette steget hvis kildefil mangler.
-
-## Phase 2 — Validate source
-
-Bash:
-
-```bash
-test -f "" && echo "OK"
-```
-
-Hvis filen ikke finnes: stopp med tydelig feilmelding.
-
-Sjekk extension:
-
-```bash
-case "" in
- *.md|*.txt) ;;
- *) echo "Error: source must be .md or .txt"; exit 1 ;;
-esac
-```
-
-Sjekk størrelse:
-
-```bash
-size=$(wc -c < "")
-if [ "$size" -gt 204800 ]; then
- echo "Error: source > 200 KB (got $size bytes) — too large for fase-1 MVP"
- exit 1
-fi
-```
-
-200 KB-grensen kommer fra brief §Non-Goals (ingen multi-fil eller
-mega-source-håndtering i fase 1).
-
-Hvis quick-modus: emit BIG WARNING:
-
-```
-WARNING: --quick mode active.
-The draft will NOT be scored against the source.
-ngram_overlap_score will remain null.
-DO NOT promote this draft to the catalog root without re-running
-without --quick or scoring it manually.
-```
-
-## Phase 3 — Launch the orchestrator
-
-Launch `skill-author-orchestrator` (model: opus) via the `Agent` tool
-med denne prompten:
-
-```
-Source file:
-Catalog root: ${CLAUDE_PLUGIN_ROOT}/skills/cc-architect-catalog/
-Plugin root: ${CLAUDE_PLUGIN_ROOT}
-Mode:
-
-Run the full skill-author pipeline:
-1. Validate source (you re-validate; trust nothing).
-2. Launch concept-extractor (sonnet) with the source path. Parse JSON.
-3. If out_of_scope: report and stop.
-4. Launch skill-drafter (sonnet) with concept JSON + source path.
-5. If too-technical-to-paraphrase: report and stop.
-6. If mode != quick: launch ip-hygiene-checker (sonnet) with draft + source.
-7. Emit completion summary with verdict, draft path, score, next-step.
-```
-
-Foreground execution (no `run_in_background`). Wait for the
-orchestrator to complete before continuing.
-
-## Phase 4 — Present summary to user
-
-Når orchestratoren returnerer, presenter et kompakt sammendrag:
-
-```
-## Skill-Author Complete
-
-Source:
-Verdict:
-Draft: <.drafts/.md | deleted | not-written>
-Score:
-Longest:
-
-### Next step
-
-```
-
-Next-step-tekstene matcher orchestratorens guidance:
-
-- **accepted** →
- ```
- Review the draft body. If you're happy:
- mv skills/cc-architect-catalog/.drafts/.md \
- skills/cc-architect-catalog/.md
- ```
-- **needs-review** →
- ```
- Score is in the gray zone (between accepted and rejected). Open the
- draft, compare against the source, decide whether the overlap is
- unavoidable (technical contract) or fixable (rephrase further).
- ```
-- **rejected** →
- ```
- Draft was deleted (containment too high or longest verbatim run too
- long). Either rephrase the source by hand and re-run, or pick a
- different source.
- ```
-- **out-of-scope** →
- ```
- Source did not map to a fase-1 supported cc_feature/layer combo.
- Reason:
- Pick a source that explains how a CC feature works (reference layer)
- or when to reach for it (pattern layer).
- ```
-- **skipped (--quick)** →
- ```
- Re-run WITHOUT --quick to score the draft before promotion.
- ```
-- **error** →
- ```
- See error above. Common causes: source unreadable, source too large,
- drafter aborted on too-technical-to-paraphrase.
- ```
-
-## Phase 5 — Stats
-
-Append én linje til
-`${CLAUDE_PLUGIN_DATA}/ultra-skill-author-local-stats.jsonl`:
-
-```json
-{
- "ts": "",
- "source": "",
- "source_size_bytes": ,
- "mode": "",
- "verdict": "",
- "cc_feature": "",
- "layer": "",
- "slug": "",
- "draft_path": "<.drafts/.md | null>",
- "ngram_overlap_score": ,
- "longest_run": ,
- "deleted":
-}
-```
-
-Hvis `${CLAUDE_PLUGIN_DATA}` ikke er satt eller ikke skrivbar, skip
-stats silently.
-
-## Hard rules
-
-- **One source per invocation.** Brukeren passer én sti. Pipelinen
- produserer én draft (eller null på out-of-scope/rejected/error).
-- **No automation.** Ingen watcher, ingen batch, ingen retry. Brief
- §Non-Goals er eksplisitt.
-- **No catalog-root writes.** Drafts lever i `.drafts/` only.
- Promotion er manuell `mv` av brukeren.
-- **No source edits.** Kilden er read-only input.
-- **No URL or remote input.** Kun lokale filstier i fase-1 MVP.
-- **Foreground only in fase-1.** `--fg` aksepteres som no-op for
- konvensjon; background-modus kommer i fase 2+.
-- **Sonnet for sub-agents.** Opus kun for denne kommandoen og
- orchestratoren.
-- **Privacy.** Aldri logg kilde-innhold i stats eller summaries.
- Verdikt, scorer og stier er nok.
-- **Honesty.** Hvis pipelinen feiler, rapporter eksakt fase og grunn.
- Ikke later som om det gikk bra.
-- **--quick warning is mandatory.** Hopper du over IP-hygiene må
- brukeren vite det tydelig — draftet er IKKE klart for promotion.
diff --git a/commands/ultraplan-local.md b/commands/ultraplan-local.md
index c7ed18a..6bc6e5e 100644
--- a/commands/ultraplan-local.md
+++ b/commands/ultraplan-local.md
@@ -64,8 +64,8 @@ Parse `$ARGUMENTS` for mode flags. Order of precedence:
- Set **has_research_brief = true** if `{dir}/research/*.md` matches ≥ 1 file.
- Set **has_architecture_note = true** if `{dir}/architecture/overview.md` exists.
If set, **architecture_note_path = {dir}/architecture/overview.md**. Produced by
- the optional `/ultra-cc-architect-local` command. Missing file is fine — this is
- additive discovery, not a requirement.
+ the optional `/ultra-cc-architect-local` command from the separate `ultra-cc-architect`
+ plugin. Missing file is fine — this is additive discovery, not a requirement.
4. **`--brief `** — extract the brief path. If the file does not exist:
```
diff --git a/scripts/ngram-overlap.mjs b/scripts/ngram-overlap.mjs
deleted file mode 100644
index f2bb340..0000000
--- a/scripts/ngram-overlap.mjs
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/usr/bin/env node
-// ngram-overlap.mjs — IP-hygiene check for skill-factory drafts.
-//
-// Computes word-n-gram containment similarity between a draft and source,
-// plus a longest-consecutive-shingle-run signal. Verdict drives whether the
-// draft passes IP-hygiene (`accepted`), warrants human review
-// (`needs-review`), or must be rejected as too-close-to-source (`rejected`).
-//
-// Algorithm (research brief 01 §Recommendation):
-// - Word 5-gram containment: |shingles(draft) ∩ shingles(source)| / |shingles(draft)|
-// - Longest-run secondary signal: max consecutive draft shingles also in source
-// - Verdict thresholds:
-// containment <0.15 AND longestRun <8 → accepted
-// containment ≥0.35 OR longestRun ≥15 → rejected
-// otherwise → needs-review
-// - Short-text fallback: shingles n=4 when min(words) <500; verdict
-// `needs-review` with `reason: too-short-to-score` when min(words) <300.
-//
-// Pure Node stdlib. No npm dependencies.
-//
-// CLI:
-// node scripts/ngram-overlap.mjs
-// node scripts/ngram-overlap.mjs --help
-
-import { readFile } from 'node:fs/promises';
-import { argv, exit, stdout, stderr } from 'node:process';
-
-// === Constants (research-backed defaults; see research brief 01 §Open Questions) ===
-export const SHINGLE_N_DEFAULT = 5;
-export const SHINGLE_N_FALLBACK = 4;
-export const SHORT_FALLBACK_THRESHOLD = 500;
-export const TOO_SHORT_THRESHOLD = 300;
-export const ACCEPT_CONTAINMENT_MAX = 0.15;
-export const REJECT_CONTAINMENT_MIN = 0.35;
-export const ACCEPT_RUN_MAX = 8;
-export const REJECT_RUN_MIN = 15;
-
-const USAGE = `Usage: node scripts/ngram-overlap.mjs
-
-Computes word-n-gram containment overlap of draft against source.
-Outputs JSON to stdout. Exit 0 on success, non-zero only on I/O error.
-
-Verdict bands:
- accepted containment <${ACCEPT_CONTAINMENT_MAX} AND longestRun <${ACCEPT_RUN_MAX}
- needs-review between bands, or min words <${TOO_SHORT_THRESHOLD}
- rejected containment >=${REJECT_CONTAINMENT_MIN} OR longestRun >=${REJECT_RUN_MIN}
-`;
-
-// === Markdown stripping (research brief 01 §step 2) ===
-// Strict order: frontmatter, fenced code, inline code, block quotes, links,
-// images, emphasis, headings, hr, table pipes.
-export function stripMarkdown(text) {
- let t = text;
- // YAML frontmatter (only at file start)
- t = t.replace(/^---\n[\s\S]*?\n---\n?/, '');
- // Fenced code blocks ```lang ... ```
- t = t.replace(/```[\s\S]*?```/g, ' ');
- // Inline code `...`
- t = t.replace(/`[^`\n]*`/g, ' ');
- // Block quotes (line-leading >)
- t = t.replace(/^>\s?/gm, '');
- // Markdown links [text](url) → text
- t = t.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1');
- // Images  → alt (handled before link strip if alt present;
- // but link strip already removed; so handle remaining bang-prefix)
- t = t.replace(/!\[([^\]]*)\]/g, '$1');
- // Emphasis: ** _ * ~~ (anchored by char, non-greedy)
- t = t.replace(/\*\*([^*]+)\*\*/g, '$1');
- t = t.replace(/__([^_]+)__/g, '$1');
- t = t.replace(/\*([^*\n]+)\*/g, '$1');
- t = t.replace(/_([^_\n]+)_/g, '$1');
- t = t.replace(/~~([^~]+)~~/g, '$1');
- // Heading markers (line-leading #+)
- t = t.replace(/^#{1,6}\s+/gm, '');
- // Horizontal rules
- t = t.replace(/^[-*_]{3,}\s*$/gm, ' ');
- // Table pipes
- t = t.replace(/\|/g, ' ');
- return t;
-}
-
-// === Tokenization ===
-// NFKC normalize, lowercase, split on Unicode letter/number runs.
-export function tokenize(text) {
- const stripped = stripMarkdown(text);
- const normalized = stripped.normalize('NFKC').toLowerCase();
- // Match runs of letters/numbers (Unicode-aware via /u flag)
- const matches = normalized.match(/[\p{L}\p{N}]+/gu);
- return matches || [];
-}
-
-// === Shingles (n-grams of words) ===
-export function shingles(tokens, n) {
- if (tokens.length < n) return [];
- const out = [];
- for (let i = 0; i <= tokens.length - n; i++) {
- out.push(tokens.slice(i, i + n).join(' '));
- }
- return out;
-}
-
-// === Overlap metrics ===
-//
-// Returns {containment, longestRun, draftShingleCount, sharedCount}.
-// Containment = |draft ∩ source| / |draft| (asymmetric: how much of draft
-// is reused from source). Longest-run = max consecutive draft shingles also
-// in source.
-export function overlap(draftTokens, sourceTokens, n) {
- const draftShingles = shingles(draftTokens, n);
- const sourceShingles = shingles(sourceTokens, n);
- if (draftShingles.length === 0) {
- return { containment: 0, longestRun: 0, draftShingleCount: 0, sharedCount: 0 };
- }
- const sourceSet = new Set(sourceShingles);
- let shared = 0;
- let longest = 0;
- let current = 0;
- for (const sh of draftShingles) {
- if (sourceSet.has(sh)) {
- shared += 1;
- current += 1;
- if (current > longest) longest = current;
- } else {
- current = 0;
- }
- }
- const containment = shared / draftShingles.length;
- return {
- containment,
- longestRun: longest,
- draftShingleCount: draftShingles.length,
- sharedCount: shared,
- };
-}
-
-// === Verdict dispatch ===
-export function verdict(metrics, opts = {}) {
- const {
- acceptContainmentMax = ACCEPT_CONTAINMENT_MAX,
- rejectContainmentMin = REJECT_CONTAINMENT_MIN,
- acceptRunMax = ACCEPT_RUN_MAX,
- rejectRunMin = REJECT_RUN_MIN,
- } = opts;
- const { containment, longestRun } = metrics;
- if (containment >= rejectContainmentMin || longestRun >= rejectRunMin) {
- const reasons = [];
- if (containment >= rejectContainmentMin) {
- reasons.push(`containment ${containment.toFixed(3)} >= ${rejectContainmentMin}`);
- }
- if (longestRun >= rejectRunMin) {
- reasons.push(`longestRun ${longestRun} >= ${rejectRunMin}`);
- }
- return { verdict: 'rejected', reasons };
- }
- if (containment < acceptContainmentMax && longestRun < acceptRunMax) {
- return { verdict: 'accepted', reasons: [] };
- }
- const reasons = [];
- if (containment >= acceptContainmentMax) {
- reasons.push(`containment ${containment.toFixed(3)} in [${acceptContainmentMax}, ${rejectContainmentMin})`);
- }
- if (longestRun >= acceptRunMax) {
- reasons.push(`longestRun ${longestRun} in [${acceptRunMax}, ${rejectRunMin})`);
- }
- return { verdict: 'needs-review', reasons };
-}
-
-// === Top-level analysis ===
-export function analyze(draftText, sourceText) {
- const draftTokens = tokenize(draftText);
- const sourceTokens = tokenize(sourceText);
- const minWords = Math.min(draftTokens.length, sourceTokens.length);
- const n = minWords < SHORT_FALLBACK_THRESHOLD ? SHINGLE_N_FALLBACK : SHINGLE_N_DEFAULT;
-
- if (minWords < TOO_SHORT_THRESHOLD) {
- return {
- verdict: 'needs-review',
- reasons: [`min word count ${minWords} < ${TOO_SHORT_THRESHOLD}`],
- reason: 'too-short-to-score',
- containment: 0,
- longestRun: 0,
- thresholds: {
- accept: ACCEPT_CONTAINMENT_MAX,
- reject: REJECT_CONTAINMENT_MIN,
- minRun: REJECT_RUN_MIN,
- },
- shingleSize: n,
- draftWords: draftTokens.length,
- sourceWords: sourceTokens.length,
- draftShingles: 0,
- sharedShingles: 0,
- };
- }
-
- const metrics = overlap(draftTokens, sourceTokens, n);
- const v = verdict(metrics);
-
- return {
- verdict: v.verdict,
- reasons: v.reasons,
- containment: metrics.containment,
- longestRun: metrics.longestRun,
- thresholds: {
- accept: ACCEPT_CONTAINMENT_MAX,
- reject: REJECT_CONTAINMENT_MIN,
- minRun: REJECT_RUN_MIN,
- },
- shingleSize: n,
- draftWords: draftTokens.length,
- sourceWords: sourceTokens.length,
- draftShingles: metrics.draftShingleCount,
- sharedShingles: metrics.sharedCount,
- };
-}
-
-// === CLI entry ===
-async function main() {
- const args = argv.slice(2);
- if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
- stdout.write(USAGE);
- exit(0);
- }
- if (args.length !== 2) {
- stderr.write(`Error: expected 2 arguments (draft-path, source-path), got ${args.length}\n`);
- stderr.write(USAGE);
- exit(2);
- }
- const [draftPath, sourcePath] = args;
- let draftText, sourceText;
- try {
- draftText = await readFile(draftPath, 'utf8');
- } catch (err) {
- stderr.write(`Error reading draft ${draftPath}: ${err.message}\n`);
- exit(1);
- }
- try {
- sourceText = await readFile(sourcePath, 'utf8');
- } catch (err) {
- stderr.write(`Error reading source ${sourcePath}: ${err.message}\n`);
- exit(1);
- }
- const result = analyze(draftText, sourceText);
- stdout.write(JSON.stringify(result, null, 2) + '\n');
- exit(0);
-}
-
-// Only run main when invoked as CLI (not when imported)
-const invokedAsScript = import.meta.url === `file://${process.argv[1]}`;
-if (invokedAsScript) {
- main();
-}
diff --git a/scripts/ngram-overlap.test.mjs b/scripts/ngram-overlap.test.mjs
deleted file mode 100644
index b4bf37a..0000000
--- a/scripts/ngram-overlap.test.mjs
+++ /dev/null
@@ -1,281 +0,0 @@
-// node:test suite for scripts/ngram-overlap.mjs
-//
-// Run: node --test scripts/ngram-overlap.test.mjs
-//
-// Covers: identical text, disjoint text, partial overlap bands,
-// longest-run override, fenced-code stripping, short-source fallback,
-// markdown-emphasis stripping, fixture integration.
-
-import { test } from 'node:test';
-import assert from 'node:assert/strict';
-import { execFileSync } from 'node:child_process';
-import { existsSync } from 'node:fs';
-import { analyze, tokenize, shingles, overlap, verdict, stripMarkdown } from './ngram-overlap.mjs';
-
-// === Fixtures (inline prose to control word counts and overlap) ===
-
-// 600+ word source on a generic technical topic (Claude Code hooks).
-// Reused across multiple tests with different drafts.
-const SOURCE_LONG = (() => {
- const sentences = [
- 'Hooks in Claude Code allow you to intercept events emitted by the agent runtime',
- 'These events fire at specific lifecycle points such as before a tool call runs',
- 'or after the agent completes a turn or when a session starts up for the first time',
- 'A hook is configured by adding an entry to the settings file under the hooks key',
- 'Each hook entry binds a matcher pattern to a shell command that the runtime executes',
- 'The matcher uses simple glob syntax to select which tool calls trigger the hook',
- 'When a tool call matches the pattern the hook runs synchronously before the call proceeds',
- 'A non-zero exit code from a hook script blocks the underlying tool call entirely',
- 'This blocking behavior makes hooks useful for security policy enforcement and audit logging',
- 'For example a pre-bash-executor hook can scan command strings against a denylist',
- 'Hooks receive structured JSON input on standard input describing the event payload',
- 'The schema includes the tool name the parameters and the working directory among other fields',
- 'Hooks can emit JSON output on standard output to add additional context for the model',
- 'Output is appended to the conversation as a system message before the next turn begins',
- 'Plugin hooks live inside the plugin directory and apply only when the plugin is enabled',
- 'User hooks live in the home directory under dot claude and apply across every project',
- 'Project hooks live in the project root and apply only when working in that project',
- 'Conflicts between hook layers resolve in a documented precedence order favoring user settings',
- 'Hooks are written as plain executable scripts in any language that the system can run',
- 'Common languages include shell python and node although any executable will work fine',
- 'Best practice is to keep hooks fast and deterministic so they do not slow down the agent',
- 'Slow hooks add latency to every tool call which compounds across long agent turns',
- 'Hook scripts should also avoid making destructive changes during their execution',
- 'Read-only checks fail safely while write operations from hooks are very hard to debug',
- 'Testing hooks is straightforward by invoking them directly with the same input json',
- 'Capture the output and exit code and verify they match the expected values',
- 'Document hook behavior in the project readme so other contributors understand the constraints',
- 'Hook misconfigurations often manifest as mysterious blocked tool calls during normal use',
- 'Always include a clear error message in stderr when a hook intentionally blocks a call',
- 'This makes debugging easier when the user wonders why their command did not run',
- 'When designing a hook you should think first about what event you actually need to intercept',
- 'Pre-tool-use events fire before any tool runs and can block dangerous operations early',
- 'Post-tool-use events fire after a tool returns and can log results or trigger follow-up actions',
- 'Session-start events fire when the agent begins a new conversation in a fresh context window',
- 'Session-end events fire when the user closes the session and are useful for cleanup tasks',
- 'Stop events fire whenever the agent finishes generating a response and yields back to the user',
- 'Compaction events fire when the conversation history grows too large and must be summarized',
- 'Each event type passes a different payload shape so you must read the schema documentation carefully',
- 'A common pattern is to write a small dispatcher hook that routes events to language-specific handlers',
- 'The dispatcher pattern keeps individual handlers simple and lets you add new ones without rewriting glue code',
- 'Avoid putting business logic directly in the dispatcher because it becomes a bottleneck for testing',
- 'Instead keep the dispatcher pure and delegate all real work to small focused single-purpose handler scripts',
- 'Hook timeouts matter because slow handlers block the agent indefinitely until they return or error out',
- 'Set a strict timeout in your handler implementation rather than relying on the runtime to kill it',
- 'Use exit code two for hard errors and exit code zero for normal pass-through with no policy violation',
- 'Reserve exit code one for soft warnings that should appear in the conversation but not block execution',
- ];
- return sentences.join('. ') + '.';
-})();
-
-const wordCount = (s) => (s.match(/[\p{L}\p{N}]+/gu) || []).length;
-
-// === Unit tests on pure functions ===
-
-test('tokenize: lowercases and splits on word boundaries', () => {
- const tokens = tokenize('Hello, World! Foo-bar.');
- assert.deepEqual(tokens, ['hello', 'world', 'foo', 'bar']);
-});
-
-test('tokenize: NFKC normalizes', () => {
- // Full-width digits normalize to ASCII
- const tokens = tokenize('café 123');
- assert.deepEqual(tokens, ['café', '123']);
-});
-
-test('shingles: returns empty when input shorter than n', () => {
- assert.deepEqual(shingles(['a', 'b', 'c'], 5), []);
-});
-
-test('shingles: returns sliding window of size n', () => {
- const result = shingles(['a', 'b', 'c', 'd', 'e'], 3);
- assert.deepEqual(result, ['a b c', 'b c d', 'c d e']);
-});
-
-test('stripMarkdown: removes fenced code blocks', () => {
- const input = 'Before\n```js\nconst x = 1;\n```\nAfter';
- const stripped = stripMarkdown(input);
- assert.ok(!stripped.includes('const x'));
- assert.ok(stripped.includes('Before'));
- assert.ok(stripped.includes('After'));
-});
-
-test('stripMarkdown: removes inline code', () => {
- const stripped = stripMarkdown('Use `npm install` to set up.');
- assert.ok(!stripped.includes('npm install'));
-});
-
-test('stripMarkdown: removes heading markers but keeps text', () => {
- const stripped = stripMarkdown('# Title\nBody');
- assert.ok(!stripped.includes('#'));
- assert.ok(stripped.includes('Title'));
-});
-
-test('stripMarkdown: removes emphasis markers', () => {
- const stripped = stripMarkdown('This **is bold** and *italic* and ~~strike~~');
- assert.ok(!stripped.includes('**'));
- assert.ok(!stripped.includes('~~'));
- assert.ok(stripped.includes('is bold'));
- assert.ok(stripped.includes('italic'));
-});
-
-test('stripMarkdown: links keep text only', () => {
- const stripped = stripMarkdown('See [docs](https://example.com) for info.');
- assert.ok(!stripped.includes('https'));
- assert.ok(stripped.includes('docs'));
-});
-
-test('stripMarkdown: removes YAML frontmatter at start', () => {
- const input = '---\nname: foo\n---\nBody text here';
- const stripped = stripMarkdown(input);
- assert.ok(!stripped.includes('name: foo'));
- assert.ok(stripped.includes('Body text here'));
-});
-
-// === Overlap behavior ===
-
-test('overlap: identical token streams give containment 1.0', () => {
- const tokens = tokenize(SOURCE_LONG);
- const m = overlap(tokens, tokens, 5);
- assert.equal(m.containment, 1);
- assert.ok(m.longestRun > 15);
-});
-
-test('overlap: completely disjoint streams give containment 0', () => {
- const a = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa'];
- const b = ['xray', 'yankee', 'zulu', 'whiskey', 'victor', 'uniform', 'tango', 'sierra', 'romeo', 'quebec'];
- const m = overlap(a, b, 5);
- assert.equal(m.containment, 0);
- assert.equal(m.longestRun, 0);
-});
-
-// === Verdict bands ===
-
-test('verdict 1: identical text → rejected (containment 1.0)', () => {
- const result = analyze(SOURCE_LONG, SOURCE_LONG);
- assert.equal(result.verdict, 'rejected');
- assert.equal(result.containment, 1);
-});
-
-test('verdict 2: completely disjoint text → accepted (low containment, low run)', () => {
- // Build a draft of unrelated words ≥300 to skip too-short fallback
- const draftWords = [];
- for (let i = 0; i < 350; i++) {
- draftWords.push(`uniqueword${i}`);
- }
- const draft = draftWords.join(' ');
- const result = analyze(draft, SOURCE_LONG);
- assert.equal(result.verdict, 'accepted');
- assert.equal(result.containment, 0);
- assert.equal(result.longestRun, 0);
-});
-
-test('verdict 3: partial overlap (mid-band) → needs-review', () => {
- // Construct draft where ~25% of 5-grams match source but no run is long.
- // Strategy: alternate 6-token source chunks with 2-token padding. Each
- // chunk yields exactly 2 source 5-grams (longestRun = 2). Need both
- // draft and source ≥500 tokens to keep shingleSize=5 (no fallback).
- // 65 chunks × 8 = 520 draft tokens; SOURCE_LONG is ~600 tokens.
- const sourceTokens = tokenize(SOURCE_LONG);
- const draftWords = [];
- let pad = 0;
- for (let i = 0; i < 65; i++) {
- draftWords.push(...sourceTokens.slice(i * 6, i * 6 + 6));
- draftWords.push(`padword${pad++}`, `padword${pad++}`);
- }
- const draft = draftWords.join(' ');
- const result = analyze(draft, SOURCE_LONG);
- assert.equal(result.shingleSize, 5,
- `precondition: expected shingleSize=5 (no fallback), got ${result.shingleSize}`);
- assert.equal(result.verdict, 'needs-review',
- `expected needs-review, got ${result.verdict} (containment=${result.containment.toFixed(3)}, longestRun=${result.longestRun})`);
-});
-
-test('verdict 4: high overlap → rejected (containment ≥0.35)', () => {
- // Draft is 60% source + 40% padding
- const sourceTokens = tokenize(SOURCE_LONG);
- const sourcePart = sourceTokens.slice(0, 200);
- const padding = [];
- for (let i = 0; i < 130; i++) padding.push(`pad${i}`);
- const draft = sourcePart.concat(padding).join(' ');
- const result = analyze(draft, SOURCE_LONG);
- assert.equal(result.verdict, 'rejected',
- `expected rejected, got ${result.verdict} (containment=${result.containment.toFixed(3)}, longestRun=${result.longestRun})`);
-});
-
-test('verdict 5: long verbatim run triggers rejection even with low containment', () => {
- // Mostly unique words (low containment) but one 25-word verbatim sentence
- // from source — longestRun ≥15 should reject.
- const verbatim = tokenize(SOURCE_LONG).slice(50, 75).join(' ');
- const padding = [];
- for (let i = 0; i < 500; i++) padding.push(`unique${i}`);
- const draft = padding.slice(0, 250).join(' ') + ' ' + verbatim + ' ' + padding.slice(250).join(' ');
- const result = analyze(draft, SOURCE_LONG);
- assert.equal(result.verdict, 'rejected',
- `expected rejected, got ${result.verdict} (containment=${result.containment.toFixed(3)}, longestRun=${result.longestRun})`);
- assert.ok(result.longestRun >= 15, `longestRun ${result.longestRun} should be ≥15`);
-});
-
-test('verdict 6: fenced code block in source → stripped → not counted as match', () => {
- const draftBody = [];
- for (let i = 0; i < 350; i++) draftBody.push(`uniq${i}`);
- const draft = draftBody.join(' ');
- // Source with a fenced code block containing some of the draft's words
- const sourceWithCode = SOURCE_LONG + '\n```\n' + draftBody.slice(0, 100).join(' ') + '\n```\n';
- const result = analyze(draft, sourceWithCode);
- // The code-block words should be stripped from source, so the draft remains disjoint
- assert.equal(result.containment, 0,
- `code-block words should be stripped (got containment ${result.containment})`);
-});
-
-test('verdict 7: short draft (<300 words) → needs-review with too-short reason', () => {
- const draft = 'This is a short note. It has fewer than three hundred words. Just a quick sketch.';
- const result = analyze(draft, SOURCE_LONG);
- assert.equal(result.verdict, 'needs-review');
- assert.equal(result.reason, 'too-short-to-score');
-});
-
-test('verdict 8: markdown emphasis is stripped before tokenization', () => {
- // Build a draft of unique tokens then wrap parts in **bold** and *italic*
- const baseWords = [];
- for (let i = 0; i < 350; i++) baseWords.push(`tok${i}`);
- const plain = baseWords.join(' ');
- const wrapped = baseWords
- .map((w, i) => (i % 5 === 0 ? `**${w}**` : i % 7 === 0 ? `*${w}*` : w))
- .join(' ');
- const plainResult = analyze(plain, SOURCE_LONG);
- const wrappedResult = analyze(wrapped, SOURCE_LONG);
- // After stripping, both should yield the same containment / longestRun
- assert.equal(plainResult.containment, wrappedResult.containment,
- 'markdown emphasis should not change containment after stripping');
- assert.equal(plainResult.longestRun, wrappedResult.longestRun,
- 'markdown emphasis should not change longestRun after stripping');
-});
-
-// === Integration: fixtures (Step 5 will create these; skip if missing) ===
-
-const FIXTURE_DIR = 'tests/fixtures/skill-factory';
-const SCRIPT = 'scripts/ngram-overlap.mjs';
-
-function runCli(draft, source) {
- const out = execFileSync('node', [SCRIPT, draft, source], { encoding: 'utf8' });
- return JSON.parse(out);
-}
-
-test('integration: accepted fixture pair → verdict accepted', { skip: !existsSync(`${FIXTURE_DIR}/draft-accepted.md`) }, () => {
- const result = runCli(`${FIXTURE_DIR}/draft-accepted.md`, `${FIXTURE_DIR}/source-accepted.md`);
- assert.equal(result.verdict, 'accepted',
- `expected accepted, got ${result.verdict} (containment=${result.containment.toFixed(3)}, longestRun=${result.longestRun})`);
-});
-
-test('integration: needs-review fixture pair → verdict needs-review', { skip: !existsSync(`${FIXTURE_DIR}/draft-needs-review.md`) }, () => {
- const result = runCli(`${FIXTURE_DIR}/draft-needs-review.md`, `${FIXTURE_DIR}/source-needs-review.md`);
- assert.equal(result.verdict, 'needs-review',
- `expected needs-review, got ${result.verdict} (containment=${result.containment.toFixed(3)}, longestRun=${result.longestRun})`);
-});
-
-test('integration: rejected fixture pair → verdict rejected', { skip: !existsSync(`${FIXTURE_DIR}/draft-rejected.md`) }, () => {
- const result = runCli(`${FIXTURE_DIR}/draft-rejected.md`, `${FIXTURE_DIR}/source-rejected.md`);
- assert.equal(result.verdict, 'rejected',
- `expected rejected, got ${result.verdict} (containment=${result.containment.toFixed(3)}, longestRun=${result.longestRun})`);
-});
diff --git a/skills/cc-architect-catalog/.drafts/.gitkeep b/skills/cc-architect-catalog/.drafts/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/skills/cc-architect-catalog/SKILL.md b/skills/cc-architect-catalog/SKILL.md
deleted file mode 100644
index ba4948b..0000000
--- a/skills/cc-architect-catalog/SKILL.md
+++ /dev/null
@@ -1,193 +0,0 @@
----
-name: cc-architect-catalog
-description: Internal catalog for ultra-cc-architect-local — not invoked directly. Indexes CC-feature reference and pattern skills.
-layer: manifest
-cc_feature: meta
-source: https://docs.claude.com/en/docs/claude-code
-concept: catalog-index
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# CC Architect Catalog — Manifest
-
-This file is the catalog index consumed by the `feature-matcher` and
-`gap-identifier` agents inside `/ultra-cc-architect-local`. It is NOT
-intended to be auto-invoked by Claude Code's skill system — the
-description above exists only so the skill loader has something to
-display if it indexes this directory.
-
-## Purpose
-
-The catalog enumerates which Claude Code features the architect command
-can reason about, and at which layer of abstraction. Each feature gets
-one or more skill files in this directory. A skill is a self-contained
-note about *one* feature at *one* layer.
-
-## Layers (frontmatter `layer` field)
-
-| Layer | Purpose | Kilde |
-|-------|---------|-------|
-| `reference` | Facts, API, syntax. What the feature *is*. | CC changelog, official docs |
-| `pattern` | When and how to use it. Typical shapes, pitfalls. | Synthesized from practice |
-| `decision` | Operational decision tree across features. | Synthesized. (No seeds yet.) |
-
-Lag representeres som frontmatter-felt, ikke mappestruktur. Rationale:
-one feature can have skills at multiple layers without relocation, and
-future skill-factory output can target a specific layer without moving
-files.
-
-## Frontmatter contract (per skill file)
-
-Every skill file in this directory MUST have this frontmatter. The
-fields are load-bearing for the architect command.
-
-```yaml
----
-name: # unique, kebab-case
-description: # used by feature-matcher
-layer: reference | pattern | decision
-cc_feature: # see table below
-source: # canonical upstream source
-concept: # 3–6 word concept handle
-last_verified: # when a human last checked against upstream
-ngram_overlap_score: null # reserved for skill-factory IP-hygiene
-review_status: approved | pending | auto-merged
----
-```
-
-`ngram_overlap_score` is reserved. This command respects it (will flag
-non-null values > threshold) but does not compute it. Skill-factory (a
-separate later process) populates that field.
-
-`review_status: approved` is the default for seeds (approved by
-construction — handwritten, no third-party text copied). Future
-skill-factory output will start as `pending` (channel 2) or
-`auto-merged` (channel 1).
-
-## Canonical `cc_feature` values
-
-| Value | Coverage |
-|-------|----------|
-| `hooks` | Event hooks (UserPromptSubmit, PreToolUse, PostToolUse, Stop, Notification, SessionStart, etc.) |
-| `subagents` | Task-tool sub-agents, delegation patterns |
-| `skills` | Claude Code skill system (not Agent SDK skills) |
-| `output-styles` | Output style configuration |
-| `mcp` | Model Context Protocol servers and tools |
-| `plan-mode` | Built-in plan mode |
-| `worktrees` | Git worktree integration |
-| `background-agents` | `run_in_background`, Monitor, long-running agents |
-| `meta` | This manifest only — not a real feature |
-
-If a future skill covers a feature not in this list, add the row above
-and surface the extension in the relevant CHANGELOG entry.
-
-## Slug convention
-
-Skill filenames follow this pattern:
-
-```
-[-]-.md
-```
-
-- **Unqualified slug** (`-.md`) — the baseline/canonical
- entry for that (feature, layer) pair. One per pair. Example:
- `hooks-pattern.md` = generic hook shapes and pitfalls.
-- **Qualified slug** (`--.md`) — a
- specialized variant covering one specific sub-pattern or use-case.
- Zero-or-more per pair. Example: `hooks-observability-pattern.md` =
- progressive-alert observability pattern specifically.
-
-Qualifiers exist because one CC feature can support multiple
-non-overlapping patterns at different abstraction levels. Forcing
-everything into a single `-.md` either bloats the
-canonical entry or loses useful specialization. Qualified slugs let the
-catalog grow with concrete, named patterns without displacing the
-baseline.
-
-`feature-matcher` treats all skills with the same `cc_feature` + `layer`
-as candidates and picks the most relevant to the brief (or proposes
-several if they cover different aspects). See "How `feature-matcher`
-uses this file" below.
-
-## Current seed coverage (v2.3.0 — see .drafts/ for skill-factory output)
-
-| Feature | reference | pattern | qualified patterns | decision |
-|---------|-----------|---------|--------------------|----------|
-| hooks | hooks-reference | hooks-pattern | hooks-observability-pattern | — |
-| subagents | subagents-reference | subagents-pattern | — | — |
-| skills | skills-reference | — | — | — |
-| output-styles | output-styles-reference | — | — | — |
-| mcp | mcp-reference | — | — | — |
-| plan-mode | plan-mode-reference | — | — | — |
-| worktrees | worktrees-reference | — | — | — |
-| background-agents | background-agents-reference | — | — | — |
-
-Total: 11 seed skills, 8 features, 2 layers. Decision-layer is
-intentionally empty — decisions cross features and require broader
-synthesis than a single seed pass can provide. Skill-factory populates
-decision-layer later.
-
-## How `feature-matcher` uses this file
-
-1. Read this file to learn the `cc_feature` taxonomy and slug convention.
-2. Glob the directory for `*.md` files (excluding SKILL.md).
-3. Parse each skill's frontmatter.
-4. For each feature mentioned in the brief or research, match against
- `cc_feature` field. Build the candidate set per feature, grouped by
- layer. Selection rules:
- - **Layer preference:** prefer `pattern` over `reference` when both
- exist (pattern is richer).
- - **Multiple patterns per feature:** when two or more pattern-layer
- skills share the same `cc_feature`, read each `description` and
- pick the one(s) most relevant to the brief. If two cover
- non-overlapping aspects that both apply, propose both with clear
- rationale. Prefer the unqualified baseline (`-pattern.md`)
- when the brief does not specifically justify a qualified variant.
- - **Be explicit:** name the chosen skill in `supporting_skill` so
- `architecture-critic` can verify the match.
-5. When no skill exists for a mentioned feature, fall back to the
- hardcoded minimum-list inside the `feature-matcher` prompt and mark
- the gap in stats (`fallback_used: true`).
-
-## How `gap-identifier` uses this file
-
-1. Collect every feature referenced in `feature-matcher`'s output.
-2. For each feature, check whether the catalog has at least one skill at
- each expected layer (reference always; pattern when complexity
- warrants; decision for cross-feature choices).
-3. Emit a gap entry for every missing (feature × layer) pair.
-4. Label with `skill-layer:` and `cc-feature:`.
-
-## Non-goals for this file
-
-- No skill-factory logic. That is a separate later process.
-- No auto-discovery of new CC features.
-- No n-gram computation.
-- No triggering Claude Code auto-invocation (description deliberately
- says "not invoked directly").
-
-## Modification rules
-
-- **Adding a canonical skill:** create `-.md` with the
- frontmatter contract above. Bump the coverage table in this file.
-- **Adding a qualified pattern skill:** create
- `--.md` when the new pattern covers a
- distinct sub-case that does not belong in the unqualified baseline.
- The qualifier MUST be kebab-case and descriptive (e.g.,
- `observability`, `migration`, `multi-tenant`). Add it to the
- "qualified patterns" column in the coverage table.
-- **Choosing qualified vs. canonical:** if no unqualified skill exists
- yet for a `(feature, layer)` pair, the new skill SHOULD be the
- unqualified baseline — don't ship a qualified skill without a
- canonical one, because `feature-matcher` prefers baseline when the
- brief has no specific justification for a variant.
-- **Renaming `cc_feature` values:** update both this file AND every
- skill using the old value in the same commit.
-- **Removing a skill:** document in CHANGELOG under the version that
- drops it.
-- **Slug collision:** two skills with the same slug are a hard error.
- Skill-factory (`/ultra-skill-author-local`) must refuse to promote a
- draft that would overwrite an approved skill. Collision is resolved
- either by qualifying the new slug or by revising the baseline.
diff --git a/skills/cc-architect-catalog/background-agents-reference.md b/skills/cc-architect-catalog/background-agents-reference.md
deleted file mode 100644
index 2afd54a..0000000
--- a/skills/cc-architect-catalog/background-agents-reference.md
+++ /dev/null
@@ -1,127 +0,0 @@
----
-name: background-agents-reference
-description: CC background agents — long-running subagents with run_in_background and Monitor for progress streaming.
-layer: reference
-cc_feature: background-agents
-source: https://docs.claude.com/en/docs/claude-code/background-agents
-concept: async-agents-and-monitoring
-last_verified: 2026-04-19
-ngram_overlap_score: null
-review_status: approved
----
-
-# Background Agents — Reference
-
-A background agent is a subagent launched with `run_in_background:
-true`. The parent does not block on its return; instead, the harness
-notifies the parent when the agent completes. Useful for long-running
-exploration, orchestration, and work that overlaps with user activity.
-
-> **Hard constraint (verified 2026-04-19):** The Claude Code harness does
-> NOT expose the `Agent` tool to sub-agents — foreground OR background.
-> A sub-agent cannot spawn further sub-agents. "Nested orchestration"
-> patterns silently degrade: the inner orchestrator loses its planned
-> swarm and falls back to single-context reasoning. Source:
-> github.com/anthropics/claude-code/issues/19077. Only the main session
-> can spawn agents. Plan shapes that require a swarm below a background
-> agent do not work — keep the orchestration in the main command context
-> instead. See Pitfalls and Composition below.
-
-## Launching
-
-```
-Agent({
- description: "...",
- subagent_type: "...",
- prompt: "...",
- run_in_background: true
-})
-```
-
-The Agent tool returns a handle (agent ID / name). The parent
-continues its turn; no wait.
-
-## Monitoring
-
-Two complementary tools work with background agents:
-
-- **Monitor** — streams updates from a named background process. Each
- event line arrives as a notification. Used for long-running Bash
- processes (and, in newer builds, some agent streaming paths).
-- **Completion notifications** — the harness posts a message to the
- parent when the background agent finishes. The parent sees it as a
- system-reminder / notification on its next turn.
-
-## When background is worth it
-
-- **Overlapping work** — orchestrator runs 30+ minutes of research
- while the user continues coding. Without background, the user is
- blocked the whole time.
-- **Parallel waves** — wave N of sessions running concurrently; the
- parent collects results as they arrive.
-- **Long-running processes** — an agent waiting on a build, test run,
- or deployment.
-
-## When background hurts
-
-- **Short tasks** — agent returns in 10 seconds; making it async adds
- overhead for no gain.
-- **Tight coupling** — if the parent needs the result before doing
- anything else, background is just foreground with extra steps.
-- **Unbounded token spend** — a background agent with no budget
- signaling can run until it hits limits. Cap explicitly.
-
-## Common shapes
-
-### Shape A: Orchestrator handoff (AVOID — see warning above)
-
-Pattern: parent interviews user, writes a spec, launches a background
-orchestrator that re-spawns a swarm of workers. **This does not work
-as documented.** The background orchestrator never gets the Agent
-tool, so the swarm never materializes and the inner orchestrator
-degrades to single-context reasoning.
-
-Anti-pattern confirmed in ultraplan-local v1.0–v2.3.2. Removed in
-v2.4.0 — the command markdown itself is now the orchestrator in main
-context.
-
-### Shape B: Parallel waves (single-file execution only)
-
-Parent decomposes work into N independent sessions, launches them
-all in parallel with `run_in_background: true`, then synthesizes
-returns as they arrive. **Each session must be self-contained and
-avoid spawning further agents** — they can use Bash, Read, Grep,
-Edit, Write, but not Agent.
-
-Valid use: `ultraplan-local --decompose` execution where each session
-implements concrete code changes without further orchestration.
-
-### Shape C: Watcher
-
-A background agent polls a process (build, test, deploy) and reports
-status changes. Uses Monitor for streaming. Watchers need Bash/Read
-only — no Agent tool needed, so the harness limitation does not
-apply.
-
-## Pitfalls
-
-- **Lost context** — if the parent conversation ends before the
- background agent completes, the result may be orphaned. Persist to
- disk, not memory.
-- **Notification fatigue** — too many background agents = too many
- reminders interrupting the parent's flow.
-- **Debugging** — background agents run out of the user's view; their
- failures can be silent. Log to files, not just return messages.
-
-## Composition
-
-- Background + worktrees: the canonical pattern for parallel
- implementation — each background agent in its own worktree, no
- clashes. Each session performs concrete file changes, not nested
- orchestration.
-- Background + subagents: **NOT SUPPORTED.** A sub-agent, whether
- foreground or background, does not have the Agent tool. Only the
- main session can spawn agents. See the warning at the top of this
- file.
-- Background + hooks: hooks fire inside the background agent's tool
- calls, same as foreground.
diff --git a/skills/cc-architect-catalog/hooks-observability-pattern.md b/skills/cc-architect-catalog/hooks-observability-pattern.md
deleted file mode 100644
index 6f2ce04..0000000
--- a/skills/cc-architect-catalog/hooks-observability-pattern.md
+++ /dev/null
@@ -1,50 +0,0 @@
----
-name: hooks-observability-pattern
-description: Observe user-interaction patterns across session lifecycle hooks and emit cooldown-gated nudges
-layer: pattern
-cc_feature: hooks
-source: ../../../../ai-psychosis/README.md
-concept: progressive alerts via lifecycle hooks
-last_verified: 2026-04-18
-ngram_overlap_score: 0.01
-review_status: approved
----
-
-# Hooks — Progressive-Alert Observability Pattern
-
-## Use this when
-
-- Measure behaviour the model itself cannot see: cadence, duration, repetition, time-of-day.
-- Surface soft nudges rather than hard blocks — the operator keeps the final call.
-- Separate "what happened" (metrics) from "what was said" (prompt text) so no conversation content touches disk.
-
-## Shape
-
-- Wire four lifecycle events: a start handler for baseline counters, a prompt handler for language-category flags, a tool handler for cadence and burst detection, and an end handler for totals and state cleanup.
-- Keep per-session counters in a tiny JSON file under the plugin data dir; keep aggregate events in an append-only JSONL log for later reporting.
-- Gate every nudge behind two things: a threshold (hard or soft) and a cooldown window, so repeat alerts do not spam the transcript.
-- Deliver alerts as `additionalContext` injection, never as a tool block — the goal is awareness, not control.
-
-## Forces
-
-- **Privacy vs. signal.** Richer signal wants more content logged; the user wants none. Resolve by computing boolean flags in-memory and discarding the raw text before the handler returns.
-- **Latency budget.** Handlers fire on every prompt and every tool call. Stay well under 100 ms per invocation; append-only JSONL is sub-millisecond and safe.
-- **Portability.** Hooks that assume a shell, `jq`, or npm dependencies break on half the operator fleet. Stick to Node stdlib so the same script runs on macOS, Linux, and Windows.
-- **Instruction layer alone is not enough.** Behavioural rules in a skill file shape tone but cannot measure duration or frequency. Layer the hook observability on top of the skill — each compensates for the other.
-
-## Gotchas
-
-- A handler that crashes blocks the turn. Catch everything, log, and exit zero by default.
-- Cooldowns must be per-category, not global, or the most-triggered alert silences the rarer, more informative ones.
-- Late-night and rapid-fire thresholds are legitimate signals but also easy to over-tune; start with generous bands and tighten only with data.
-- `additionalContext` from an end-of-session handler is discarded — inject alerts on start, prompt, or tool events where the model will actually see them.
-
-## Anti-patterns
-
-- Storing prompt text or tool arguments "just for debugging" — once it is on disk, the privacy guarantee is gone.
-- Treating every elevated metric as an intervention. If the hook starts blocking, the operator works around it and loses the awareness benefit.
-- Hardcoding thresholds into the handler. Pull them from a single config so future tuning does not require a rewrite of four scripts.
-
-## Decision quick-check
-
-Reach for this pattern when you need visibility into *how* the user is interacting, not *what* they are saying, and when the response should be a gentle nudge rather than a gate. Otherwise use a PreToolUse denylist (hard limit) or a skill-only instruction layer (style, not cadence).
diff --git a/skills/cc-architect-catalog/hooks-pattern.md b/skills/cc-architect-catalog/hooks-pattern.md
deleted file mode 100644
index 2a19e99..0000000
--- a/skills/cc-architect-catalog/hooks-pattern.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-name: hooks-pattern
-description: When to choose hooks over prompts or subagents, and common hook shapes that work.
-layer: pattern
-cc_feature: hooks
-source: https://docs.claude.com/en/docs/claude-code/hooks
-concept: hooks-decision-and-shapes
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# Hooks — Pattern
-
-## When to reach for a hook
-
-Use hooks when the behavior must hold even if Claude is prompt-injected,
-distracted, or adversarial. Hooks are outside the model's control loop —
-Claude cannot talk its way past them.
-
-Good fits:
-
-- **Hard prohibitions** — "never run `rm -rf /`", "never push to main
- without a commit signature", "never read files outside this repo".
-- **Deterministic context injection** — always show git status at
- session start; always inject the current sprint's tasks.
-- **Audit trails** — log every Bash call, every file write, outside the
- conversation context so it survives `/clear`.
-- **Compliance boundaries** — redact secrets from transcripts; block
- tool calls that would leak PII.
-
-Bad fits:
-
-- Behavior that requires judgment ("should this test run?") — that's a
- subagent call.
-- Heuristics that drift ("mostly block, sometimes allow") — a hook that
- frequently second-guesses itself is a sign the rule belongs in a
- prompt or skill.
-- Anything that needs to read lots of conversation history — hooks see
- a payload, not the full context.
-
-## Common shapes
-
-### Shape A: PreToolUse deny
-
-A small script that reads `tool_input`, matches a pattern, and exits
-with a `block` decision. Latency: a few ms. Used for command denylists,
-path guards, secrets scanners.
-
-### Shape B: UserPromptSubmit context injection
-
-A script that reads the prompt, computes context (e.g., recent git log,
-active TODO list), and emits JSON with an `additionalContext` field.
-The harness adds that context to the prompt before Claude sees it.
-
-### Shape C: Stop hook with reminder
-
-A script that runs when Claude finishes a turn. Checks for uncommitted
-work, surfaces it as a notification. Non-blocking.
-
-### Shape D: SessionStart status
-
-Runs once per session. Prints repo metadata (branch, open PRs, recent
-commits) so every new session starts with shared context.
-
-## Pitfalls
-
-- **Slow hooks compound.** A 500 ms PreToolUse hook run 50 times per
- session adds 25 seconds of latency.
-- **Hooks without error handling crash the turn.** A hook that exits
- non-zero on an edge case blocks real work. Default to exit 0 with a
- logged warning.
-- **Shell-injection in hook scripts.** A hook that interpolates
- `tool_input.command` into `bash -c` is itself a security hole. Parse
- inputs; never interpolate unescaped.
-- **Hooks can leak secrets into transcripts** if their output mentions
- env-var values. Scrub before emitting.
-- **Cross-platform scripts.** A hook that assumes bash 4 or GNU sed
- breaks on macOS. Prefer Node.js, Python, or POSIX sh.
-
-## Composition with other features
-
-- Hooks + subagents: a hook can delegate the "should this be blocked"
- question to a subagent when the decision needs judgment. Cost: a full
- model call per hook invocation — use sparingly.
-- Hooks + MCP: a hook can call out to an MCP-exposed tool for policy
- lookup. Latency depends on transport.
-- Hooks + plan mode: hooks fire during plan mode too. Useful for
- enforcing "no writes while planning".
diff --git a/skills/cc-architect-catalog/hooks-reference.md b/skills/cc-architect-catalog/hooks-reference.md
deleted file mode 100644
index 0681142..0000000
--- a/skills/cc-architect-catalog/hooks-reference.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-name: hooks-reference
-description: CC hooks API — event types, payload shapes, exit codes, and where hooks run.
-layer: reference
-cc_feature: hooks
-source: https://docs.claude.com/en/docs/claude-code/hooks
-concept: hooks-api-surface
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# Hooks — Reference
-
-Hooks are shell commands or scripts that the Claude Code harness runs
-in response to events. They give the harness — not Claude — the final
-say on whether a tool call, prompt, or session action proceeds. Claude
-cannot bypass a hook by prompting itself; the hook runs outside the
-model's control loop.
-
-## Event types
-
-- **UserPromptSubmit** — fires when the user sends a prompt. Runs before
- Claude processes it. Common use: inject extra context, reject
- disallowed prompts.
-- **PreToolUse** — fires before a tool call. Can deny the call. Common
- use: block destructive commands, require confirmation.
-- **PostToolUse** — fires after a tool call completes. Sees the result.
- Common use: log side effects, redact output, trigger follow-up work.
-- **Stop** — fires when the agent finishes a turn. Common use: commit
- reminders, session summaries.
-- **Notification** — fires when Claude wants to show the user a
- notification (e.g., long-running task).
-- **SessionStart** — fires when a session begins. Common use: print
- repo state, inject context.
-
-## Payload shape
-
-Hooks receive a JSON payload on stdin. Common fields:
-
-- `session_id` — the current session identifier.
-- `transcript_path` — path to the conversation transcript.
-- `cwd` — current working directory.
-- `tool_name` (PreToolUse, PostToolUse) — which tool is running.
-- `tool_input` (PreToolUse) — the arguments to the tool.
-- `tool_response` (PostToolUse) — the tool's result.
-- `prompt` (UserPromptSubmit) — the submitted text.
-
-Exact field availability depends on event type. Read the payload JSON
-rather than assuming a schema.
-
-## Exit codes and control
-
-Hooks communicate back via exit code and stdout JSON:
-
-- Exit 0, no stdout → proceed normally.
-- Exit 0, stdout JSON with `decision` field → harness honors the
- decision (e.g., `{"decision": "block", "reason": "..."}`).
-- Exit non-zero → harness treats as a denial or error, depending on
- event and hook type.
-
-Some hook types support structured output beyond deny/allow (e.g.,
-adding context to the prompt). Details differ per event.
-
-## Where hooks live
-
-- Project hooks: `.claude/settings.json` `hooks` field, paths relative
- to project.
-- User hooks: `~/.claude/settings.json` (global).
-- Plugin hooks: packaged with a plugin, activated when the plugin is
- enabled.
-
-Hooks run in the harness process's shell, not in Claude's tool-use
-sandbox. They can spawn subprocesses, read environment variables,
-and touch the filesystem.
-
-## Implications for architecture
-
-- Hooks are the mechanism for **deterministic policy** (things that
- must always or never happen, regardless of what Claude decides).
-- Hooks are load-bearing for security: prompt-injection-resistant
- defenses live here, not in prompts.
-- Hooks add latency to every tool call they gate — keep them fast.
-- Hook output is part of the context window; verbose hooks burn
- tokens quickly.
diff --git a/skills/cc-architect-catalog/mcp-reference.md b/skills/cc-architect-catalog/mcp-reference.md
deleted file mode 100644
index 539ce0f..0000000
--- a/skills/cc-architect-catalog/mcp-reference.md
+++ /dev/null
@@ -1,72 +0,0 @@
----
-name: mcp-reference
-description: Model Context Protocol — external tools and resources exposed to Claude via MCP servers.
-layer: reference
-cc_feature: mcp
-source: https://docs.claude.com/en/docs/claude-code/mcp
-concept: mcp-tool-protocol
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# MCP — Reference
-
-Model Context Protocol (MCP) is the protocol Claude Code uses to talk
-to external tool servers. An MCP server advertises *tools* and
-*resources*; Claude Code surfaces them to Claude as callable tools.
-
-## Architecture
-
-- **MCP server** — a process (local or remote) that implements the
- protocol. Can be written in any language. Communicates over stdio,
- HTTP, or WebSocket.
-- **Transport** — stdio (local subprocess), SSE/HTTP (remote), or
- WebSocket. Stdio is the default for local servers.
-- **Tools** — callable functions the server exposes. Each has a name,
- description, and JSON schema for inputs.
-- **Resources** — readable entities the server exposes (files,
- database rows, API responses). Addressed by URI.
-- **Prompts** — optional; MCP can expose templated prompts.
-
-## Configuration
-
-MCP servers are declared in:
-
-- `.mcp.json` — project-level MCP config.
-- `~/.claude.json` or equivalent — user-level.
-- Plugin-bundled — a plugin can ship its own MCP server.
-
-Each entry specifies command, args, transport, and optional auth.
-
-## Tool naming
-
-Tools from MCP servers appear to Claude with a namespaced name:
-`mcp____`. This keeps names collision-free
-across servers.
-
-## Permissions
-
-- `allowed-tools` in settings or plugin frontmatter can include MCP
- tools by full name.
-- Some MCP servers require OAuth or API keys; those are configured in
- the server's own config, not Claude's.
-
-## Common uses
-
-- Exposing internal APIs to Claude without hand-wrapping them (one
- generic MCP server → many tools).
-- Cross-language tool servers (Python tool called from Claude Code
- running in Node).
-- Sandboxed access to external services with explicit scoping.
-
-## Failure modes
-
-- Server not running → tool calls fail; Claude sees an error string.
-- Server misbehaves → tool returns wrong schema; Claude may retry or
- hallucinate.
-- Authentication drift → 401s look like transient errors; diagnose by
- checking the server directly.
-- Security: an MCP server runs with the permissions of its own
- process. A malicious server is a supply-chain risk; audit before
- enabling.
diff --git a/skills/cc-architect-catalog/output-styles-reference.md b/skills/cc-architect-catalog/output-styles-reference.md
deleted file mode 100644
index abe34fa..0000000
--- a/skills/cc-architect-catalog/output-styles-reference.md
+++ /dev/null
@@ -1,58 +0,0 @@
----
-name: output-styles-reference
-description: CC output styles — configurable response shape, tone, length, and formatting baselines.
-layer: reference
-cc_feature: output-styles
-source: https://docs.claude.com/en/docs/claude-code/output-styles
-concept: output-style-config
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# Output Styles — Reference
-
-Output styles let a user or plugin shape how Claude Code responds:
-length defaults, formatting preferences, tone, verbosity. They apply
-across the session rather than needing to be re-stated per prompt.
-
-## Where they live
-
-- **Built-in styles** — shipped with the CLI.
-- **Custom styles** — directory with a manifest describing the style.
-- **Selection** — the user sets an active style via settings or a
- `/style` command. The style is injected into Claude's system context.
-
-## What a style can control
-
-- Default response length baseline ("keep responses ≤ 100 words
- unless detail is required").
-- Formatting rules (markdown vs plain, code-block conventions).
-- Tone ("terse", "pedagogical", "adversarial").
-- Domain voice (Norwegian for dialog, English for code — a project
- convention encoded as a style).
-
-## What a style cannot control
-
-- Tool permissions (that is `allowed-tools` / `settings.json`).
-- Hooks (those are harness-level).
-- Agent system prompts (those come from agent definitions).
-
-## When to use a custom style
-
-- The project has a persistent communication convention that should
- hold across every session (e.g., "never use emojis").
-- Multiple users share the project and want consistent output.
-- A skill's prompts would otherwise have to restate formatting rules
- each time.
-
-## When not to
-
-- For per-task formatting needs — use the prompt instead.
-- For rules that must hold against prompt injection — use hooks.
-
-## Practical shape
-
-A minimal custom style is a markdown or plain-text block listing the
-conventions. Claude treats it as top-of-system guidance. Keep it
-short: long styles crowd out the task.
diff --git a/skills/cc-architect-catalog/plan-mode-reference.md b/skills/cc-architect-catalog/plan-mode-reference.md
deleted file mode 100644
index 72874bf..0000000
--- a/skills/cc-architect-catalog/plan-mode-reference.md
+++ /dev/null
@@ -1,65 +0,0 @@
----
-name: plan-mode-reference
-description: CC plan mode — read-only planning phase before implementation, with explicit user approval gate.
-layer: reference
-cc_feature: plan-mode
-source: https://docs.claude.com/en/docs/claude-code/plan-mode
-concept: planning-before-execution
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# Plan Mode — Reference
-
-Plan mode is a built-in state where Claude operates read-only and
-produces an implementation plan instead of executing it. The user
-reviews the plan, then either approves it to transition to
-implementation or iterates.
-
-## State machine
-
-1. **Plan mode entered** — user triggers it (Shift+Tab twice, `/plan`,
- or harness-initiated) or Claude calls `EnterPlanMode`.
-2. **Read-only operation** — Claude can read files, search, run
- analysis. Writes, edits, and commits are blocked by the harness.
-3. **Plan produced** — Claude presents a plan via `ExitPlanMode` or
- equivalent.
-4. **User reviews** — accepts, rejects, or iterates.
-5. **Exit** — on acceptance, mode returns to normal (edits allowed).
-
-## What plan mode guarantees
-
-- No writes during the plan phase. Even if Claude tries, the harness
- denies write tools.
-- A structured handoff: the plan is a message the user sees before
- anything happens.
-
-## What plan mode does not guarantee
-
-- Plan quality. Plan mode is a *gate*, not a *reviewer*. A bad plan
- still passes if the user approves it.
-- Scope locking. After exit, Claude can do whatever the new prompts
- ask — plan mode is a phase, not a contract.
-
-## When to opt into plan mode
-
-- Tasks touching multiple files or modules where the order and file
- list matter.
-- Refactors where the first wrong edit is expensive to undo.
-- Unfamiliar codebases where planning surfaces missing context.
-
-## When to skip plan mode
-
-- Single-file trivial changes.
-- Tasks already specified by a detailed plan from another tool
- (e.g., an `ultraplan-local` plan.md) — planning twice is waste.
-
-## Relationship to /ultra* planning
-
-- `/ultraplan-local` produces a *plan artifact* that outlives the
- session. Plan mode produces an *in-conversation plan* that does not
- survive `/clear`.
-- They compose: use plan mode to sketch at session start, then run
- `/ultraplan-local` to get the durable, reviewable, machine-readable
- plan with manifests.
diff --git a/skills/cc-architect-catalog/skills-reference.md b/skills/cc-architect-catalog/skills-reference.md
deleted file mode 100644
index 1481131..0000000
--- a/skills/cc-architect-catalog/skills-reference.md
+++ /dev/null
@@ -1,83 +0,0 @@
----
-name: skills-reference
-description: CC skills — auto-invoked domain modules with SKILL.md, frontmatter triggers, and file-hierarchy discovery.
-layer: reference
-cc_feature: skills
-source: https://docs.claude.com/en/docs/claude-code/skills
-concept: skills-system
-last_verified: 2026-04-18
-ngram_overlap_score: null
-review_status: approved
----
-
-# Skills — Reference
-
-Claude Code's skill system is a way to package domain knowledge,
-workflows, and supporting files so Claude can load them on demand. A
-skill is a directory with a `SKILL.md` manifest and any auxiliary
-files (scripts, templates, references).
-
-## Anatomy
-
-- **`SKILL.md`** — the entry point. Markdown file with YAML
- frontmatter and a body. The frontmatter declares when the skill
- triggers; the body is instructions Claude follows after loading.
-- **Auxiliary files** — any files in the skill directory. Loaded on
- demand (typically by Claude reading them when the body references
- them). Common: `scripts/`, `templates/`, `references/`.
-
-## Frontmatter
-
-```yaml
----
-name:
-description: