chore(marketplace): remove ultra-cc-architect plugin
Moved to a separate marketplace. Drops the plugin directory, the manifest entry, and the README/CLAUDE.md sections describing it. ultraplan-local references to the optional architecture/overview.md contract are kept (filesystem-level discovery, drift-WARN), but marketplace-name pointers in ultraplan-local docs may follow.
This commit is contained in:
parent
e6503adae8
commit
a09c2e0382
43 changed files with 3 additions and 4774 deletions
|
|
@ -25,11 +25,6 @@
|
||||||
"source": "./plugins/ultraplan-local",
|
"source": "./plugins/ultraplan-local",
|
||||||
"description": "Four-command context-engineering pipeline (brief → research → plan → execute) with specialized agent swarms, external research triangulation, adversarial review, session decomposition, and headless execution"
|
"description": "Four-command context-engineering pipeline (brief → research → plan → execute) with specialized agent swarms, external research triangulation, adversarial review, session decomposition, and headless execution"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "ultra-cc-architect",
|
|
||||||
"source": "./plugins/ultra-cc-architect",
|
|
||||||
"description": "Match a task brief and research against available Claude Code features (Hooks, Subagents, Skills, MCP, Plan Mode, Worktrees, Background Agents) with brief-anchored rationale and explicit coverage gaps. Includes the skill-factory authoring command. Pre-release (v0.1.0)."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "linkedin-thought-leadership",
|
"name": "linkedin-thought-leadership",
|
||||||
"source": "./plugins/linkedin-thought-leadership",
|
"source": "./plugins/linkedin-thought-leadership",
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ plugins/
|
||||||
ms-ai-architect/ v1.8.0 — Microsoft AI architecture (Cosmo Skyberg persona)
|
ms-ai-architect/ v1.8.0 — Microsoft AI architecture (Cosmo Skyberg persona)
|
||||||
okr/ v1.0.0 — OKR guidance for Norwegian public sector
|
okr/ v1.0.0 — OKR guidance for Norwegian public sector
|
||||||
ultraplan-local/ v3.3.0 — Brief, research, plan, execute, review, continue (six-command universal pipeline + multi-session resumption)
|
ultraplan-local/ v3.3.0 — Brief, research, plan, execute, review, continue (six-command universal pipeline + multi-session resumption)
|
||||||
ultra-cc-architect/ v0.1.0 — Claude-Code-specific architecture matching + skill-factory (extracted from ultraplan-local in v3.0.0)
|
|
||||||
|
|
||||||
shared/
|
shared/
|
||||||
playground-design-system/ v0.1 — Aksel/Digdir-aligned CSS design system + JSON schemas + self-hosted Inter/JetBrains Mono/Source Serif 4 fonts (Tier 1+2+3 wave 1+wave 2 = 20 Tier 3 components total). Consumed by ms-ai-architect, okr, llm-security, ultraplan-local, config-audit
|
playground-design-system/ v0.1 — Aksel/Digdir-aligned CSS design system + JSON schemas + self-hosted Inter/JetBrains Mono/Source Serif 4 fonts (Tier 1+2+3 wave 1+wave 2 = 20 Tier 3 components total). Consumed by ms-ai-architect, okr, llm-security, ultraplan-local, config-audit
|
||||||
|
|
|
||||||
27
README.md
27
README.md
|
|
@ -81,7 +81,7 @@ Six commands, one pipeline with clear division of labor:
|
||||||
|
|
||||||
- **`/ultrabrief-local`** — Capture intent. Dynamic, quality-gated interview: a section-driven completeness loop (Phase 3) followed by a `brief-reviewer` stop-gate (Phase 4, max 3 review iterations). Required sections must reach an initial-signal gate AND pass review across completeness, consistency, testability, scope clarity, and research-plan validity before `brief.md` is written. Identifies research topics with copy-paste-ready `/ultraresearch-local` commands. Optional auto-orchestration runs research + planning in foreground. Always interactive.
|
- **`/ultrabrief-local`** — Capture intent. Dynamic, quality-gated interview: a section-driven completeness loop (Phase 3) followed by a `brief-reviewer` stop-gate (Phase 4, max 3 review iterations). Required sections must reach an initial-signal gate AND pass review across completeness, consistency, testability, scope clarity, and research-plan validity before `brief.md` is written. Identifies research topics with copy-paste-ready `/ultraresearch-local` commands. Optional auto-orchestration runs research + planning in foreground. Always interactive.
|
||||||
- **`/ultraresearch-local`** — Gather context. Deep multi-source research with triangulation: 5 local agents + 4 external agents + Gemini bridge, producing structured briefs with confidence ratings. Makes no build decisions.
|
- **`/ultraresearch-local`** — Gather context. Deep multi-source research with triangulation: 5 local agents + 4 external agents + Gemini bridge, producing structured briefs with confidence ratings. Makes no build decisions.
|
||||||
- **`/ultraplan-local`** — Transform intent into an executable contract. Per-step YAML manifests (`expected_paths`, `commit_message_pattern`, `bash_syntax_check`). Plan-critic is a hard gate on manifest quality. Requires a task brief as input (`--brief` or `--project`). Auto-discovers `architecture/overview.md` when the optional `ultra-cc-architect` plugin is installed and cross-references its `cc_features_proposed` against exploration findings.
|
- **`/ultraplan-local`** — Transform intent into an executable contract. Per-step YAML manifests (`expected_paths`, `commit_message_pattern`, `bash_syntax_check`). Plan-critic is a hard gate on manifest quality. Requires a task brief as input (`--brief` or `--project`). Auto-discovers `architecture/overview.md` when produced upstream and cross-references its `cc_features_proposed` against exploration findings.
|
||||||
- **`/ultraexecute-local`** — Execute the contract disciplined. Manifest-based verification, independent Phase 7.5 audit from git log + filesystem (ignores agent bookkeeping), Phase 7.6 bounded recovery dispatch for missing steps. Step 0 pre-flight catches sandbox push-denial before any work. `--validate` mode offers a fast schema-only sanity-check between planning and execution.
|
- **`/ultraexecute-local`** — Execute the contract disciplined. Manifest-based verification, independent Phase 7.5 audit from git log + filesystem (ignores agent bookkeeping), Phase 7.6 bounded recovery dispatch for missing steps. Step 0 pre-flight catches sandbox push-denial before any work. `--validate` mode offers a fast schema-only sanity-check between planning and execution.
|
||||||
- **`/ultrareview-local`** — Close the iteration loop. Independent post-hoc reviewer reads `brief.md` from scratch and evaluates the diff produced by execute. Two parallel reviewers (brief-conformance + code-correctness) plus a Judge Agent (review-coordinator) for dedup and reasonableness filtering. Severity-tagged findings (Critical/High/Medium/Low/Info) with stable 40-char hex IDs feed back into planning via Handover 6 (`/ultraplan-local --brief review.md` → remediation plan with `source_findings:` audit trail).
|
- **`/ultrareview-local`** — Close the iteration loop. Independent post-hoc reviewer reads `brief.md` from scratch and evaluates the diff produced by execute. Two parallel reviewers (brief-conformance + code-correctness) plus a Judge Agent (review-coordinator) for dedup and reasonableness filtering. Severity-tagged findings (Critical/High/Medium/Low/Info) with stable 40-char hex IDs feed back into planning via Handover 6 (`/ultraplan-local --brief review.md` → remediation plan with `source_findings:` audit trail).
|
||||||
- **`/ultracontinue-local`** — Zero-friction multi-session resumption. In a fresh chat, type `/ultracontinue` — reads `.session-state.local.json` (Handover 7), prints a 3-line summary, and immediately begins executing the next session. Any session-end mechanism may write the state file (`/ultraexecute-local` Phase 8/2.55/4 do so automatically; `/ultraplan-end-session-local` helper writes it for informal flows). Forward-compat schema (unknown top-level keys ignored) so future producers can extend additively.
|
- **`/ultracontinue-local`** — Zero-friction multi-session resumption. In a fresh chat, type `/ultracontinue` — reads `.session-state.local.json` (Handover 7), prints a 3-line summary, and immediately begins executing the next session. Any session-end mechanism may write the state file (`/ultraexecute-local` Phase 8/2.55/4 do so automatically; `/ultraplan-end-session-local` helper writes it for informal flows). Forward-compat schema (unknown top-level keys ignored) so future producers can extend additively.
|
||||||
|
|
@ -92,7 +92,7 @@ v3.3.0 (non-breaking) adds `/ultracontinue-local` as the sixth command and the c
|
||||||
|
|
||||||
v3.2.0 (non-breaking) adds `/ultrareview-local` as the fifth command and the contracted **Handover 6 (review → plan)** feedback loop. New artifact type `type: ultrareview` validated by `lib/validators/review-validator.mjs`, stable 40-char SHA1 finding-IDs from `lib/parsers/finding-id.mjs`, Jaccard similarity for determinism testing (`lib/parsers/jaccard.mjs`), and a 12-key version-pinned rule catalogue (`lib/review/rule-catalogue.mjs`). Four new agents (review-orchestrator, brief-conformance-reviewer, code-correctness-reviewer, review-coordinator) implementing the Judge-Agent dedup pattern. `/ultraplan-local` now consumes `--brief review.md` (BLOCKER + MAJOR findings become plan goals) and writes `source_findings: [<id>, ...]` audit trail. `brief-validator` accepts both `type: ultrabrief` and `type: ultrareview`.
|
v3.2.0 (non-breaking) adds `/ultrareview-local` as the fifth command and the contracted **Handover 6 (review → plan)** feedback loop. New artifact type `type: ultrareview` validated by `lib/validators/review-validator.mjs`, stable 40-char SHA1 finding-IDs from `lib/parsers/finding-id.mjs`, Jaccard similarity for determinism testing (`lib/parsers/jaccard.mjs`), and a 12-key version-pinned rule catalogue (`lib/review/rule-catalogue.mjs`). Four new agents (review-orchestrator, brief-conformance-reviewer, code-correctness-reviewer, review-coordinator) implementing the Judge-Agent dedup pattern. `/ultraplan-local` now consumes `--brief review.md` (BLOCKER + MAJOR findings become plan goals) and writes `source_findings: [<id>, ...]` audit trail. `brief-validator` accepts both `type: ultrabrief` and `type: ultrareview`.
|
||||||
|
|
||||||
v3.0.0 extracts the Claude-Code-specific architecture phase to a separate plugin (`ultra-cc-architect`, see below). The planning pipeline now stays technology-agnostic; CC-feature matching becomes opt-in. The plan command still auto-discovers `architecture/overview.md` if the new plugin is installed — the contract is filesystem-level, not code-level. Non-breaking for users of brief/research/plan/execute. See `plugins/ultraplan-local/CHANGELOG.md` for migration steps.
|
v3.0.0 extracts the Claude-Code-specific architecture phase to a separate plugin. The planning pipeline now stays technology-agnostic; CC-feature matching becomes opt-in. The plan command still auto-discovers `architecture/overview.md` if produced upstream — the contract is filesystem-level, not code-level. Non-breaking for users of brief/research/plan/execute. See `plugins/ultraplan-local/CHANGELOG.md` for migration steps.
|
||||||
|
|
||||||
v2.4.0 (breaking, default behavior) removes background mode. The commands now run foreground in the main context because the harness does not expose the Agent tool to sub-agents — background orchestrators silently degraded the swarm to inline reasoning without external research tools. The `--fg` flag is preserved as a no-op alias for backward compatibility. Source: github.com/anthropics/claude-code/issues/19077.
|
v2.4.0 (breaking, default behavior) removes background mode. The commands now run foreground in the main context because the harness does not expose the Agent tool to sub-agents — background orchestrators silently degraded the swarm to inline reasoning without external research tools. The `--fg` flag is preserved as a no-op alias for backward compatibility. Source: github.com/anthropics/claude-code/issues/19077.
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ v2.1 (non-breaking) replaced the hardcoded Q1–Q8 interview with a dynamic, qua
|
||||||
|
|
||||||
v1.7 self-verifying chain (preserved): a step may not be marked `completed` unless its manifest verifies. v1.8 Opus 4.7 literalism fixes (preserved): literal Step+Manifest template, forbidden narrative headers, schema self-check.
|
v1.7 self-verifying chain (preserved): a step may not be marked `completed` unless its manifest verifies. v1.8 Opus 4.7 literalism fixes (preserved): literal Step+Manifest template, forbidden narrative headers, schema self-check.
|
||||||
|
|
||||||
v3.1.0 (in progress) adds a `lib/`-tree of zero-dep validators (`brief-validator`, `research-validator`, `plan-validator`, `progress-validator`, `architecture-discovery`) wired into the four commands as CLI shims, plus 109 `node:test` cases and a doc-consistency invariant test. The Phase 5.5 schema self-check now runs as `node lib/validators/plan-validator.mjs --strict` instead of three `grep -cE` calls — same checks, single source of truth, machine-readable error codes. Architecture discovery treats the `ultra-cc-architect` contract as drift-WARN, never drift-FAIL. Forking the plugin? `npm test` is the readiness gate.
|
v3.1.0 (in progress) adds a `lib/`-tree of zero-dep validators (`brief-validator`, `research-validator`, `plan-validator`, `progress-validator`, `architecture-discovery`) wired into the four commands as CLI shims, plus 109 `node:test` cases and a doc-consistency invariant test. The Phase 5.5 schema self-check now runs as `node lib/validators/plan-validator.mjs --strict` instead of three `grep -cE` calls — same checks, single source of truth, machine-readable error codes. Architecture discovery treats the upstream `architecture/overview.md` contract as drift-WARN, never drift-FAIL. Forking the plugin? `npm test` is the readiness gate.
|
||||||
|
|
||||||
v3.1.0 also adds: `docs/HANDOVER-CONTRACTS.md` as the single source of truth for the 5 pipeline handovers (extended to 6 in v3.2.0, then to 7 in v3.3.0); PreCompact-hook (`pre-compact-flush.mjs`, CC v2.1.105+) that fixes the documented progress.json drift bug — `--resume` now works after long conversations; UserPromptSubmit-hook that sets session titles `ultra:<command>:<slug>` for headless multiplexing (CC v2.1.94+); PostToolUse-hook that captures Bash `duration_ms` per call (CC v2.1.97+); semantic plan-critic rubric that catches paraphrased deferred decisions ("implement as needed", "wire it up") instead of just exact-string blacklist; `examples/01-add-verbose-flag/` showing a calibrated end-to-end pipeline run; `SECURITY.md` boilerplate; `docs/architect-bridge-test.md` smoke checklist.
|
v3.1.0 also adds: `docs/HANDOVER-CONTRACTS.md` as the single source of truth for the 5 pipeline handovers (extended to 6 in v3.2.0, then to 7 in v3.3.0); PreCompact-hook (`pre-compact-flush.mjs`, CC v2.1.105+) that fixes the documented progress.json drift bug — `--resume` now works after long conversations; UserPromptSubmit-hook that sets session titles `ultra:<command>:<slug>` for headless multiplexing (CC v2.1.94+); PostToolUse-hook that captures Bash `duration_ms` per call (CC v2.1.97+); semantic plan-critic rubric that catches paraphrased deferred decisions ("implement as needed", "wire it up") instead of just exact-string blacklist; `examples/01-add-verbose-flag/` showing a calibrated end-to-end pipeline run; `SECURITY.md` boilerplate; `docs/architect-bridge-test.md` smoke checklist.
|
||||||
|
|
||||||
|
|
@ -114,27 +114,6 @@ Modes: default, brief-driven, project-scoped, research-enriched, foreground, qui
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### [Ultra CC Architect](plugins/ultra-cc-architect/) `v0.1.0` `🚧 pre-release`
|
|
||||||
|
|
||||||
Match a task brief and research against available Claude Code features, with brief-anchored rationale and explicit coverage gaps. Extracted from `ultraplan-local` v2.4.0 in 2026-04-30.
|
|
||||||
|
|
||||||
Two commands, both Claude-Code-specific:
|
|
||||||
|
|
||||||
- **`/ultra-cc-architect-local`** — Reads `brief.md` + `research/*.md` (typically produced by `ultraplan-local`), consults the seeded `cc-architect-catalog` skill (hooks, subagents, skills, output styles, MCP, plan mode, worktrees, background agents), and produces `architecture/overview.md` with brief-anchored rationale plus `architecture/gaps.md` with issue-ready drafts for missing catalog entries. Hallucination gate (enforced by `architecture-critic`) blocks proposals for features not covered by the catalog.
|
|
||||||
- **`/ultra-skill-author-local`** *(skill-factory Fase 1)* — Generates one `cc-architect-catalog` draft skill from a curated local source file with IP-hygiene enforcement. Sequential pipeline: `concept-extractor` → `skill-drafter` → `ip-hygiene-checker`. Drafts land in `skills/cc-architect-catalog/.drafts/` for manual review and `mv` promotion. Pure-Node n-gram containment scorer (`scripts/ngram-overlap.mjs`) enforces verdict bands; rejected drafts are deleted.
|
|
||||||
|
|
||||||
The plugin sits between `/ultraresearch-local` and `/ultraplan-local` in the typical workflow. `ultraplan-local` v3.0.0+ auto-discovers `architecture/overview.md` when present — install both plugins to keep the full pipeline (brief → research → architect → plan → execute) working.
|
|
||||||
|
|
||||||
**Pre-release because:** catalog is thin (11 seed skills across 8 features), decision-layer is intentionally empty, skill-factory has only Fase 1 (Fase 2/3 unbuilt), and `feature-matcher` falls back to a hardcoded list when the catalog is sparse. v1.0 ships when the catalog is dense enough that the fallback list can be removed.
|
|
||||||
|
|
||||||
Slug convention: `<cc_feature>[-<qualifier>]-<layer>.md`. Unqualified slugs are the canonical baseline per `(feature, layer)` pair; qualified slugs cover specific sub-patterns. `feature-matcher` prefers the unqualified baseline unless the brief justifies a variant. Slug collisions with approved skills are a hard error. `skill-drafter` warns before overwrite.
|
|
||||||
|
|
||||||
8 specialized agents · 2 commands · 1 skill (CC-feature catalog, 11 seeds) · 1 IP-hygiene script
|
|
||||||
|
|
||||||
→ [Full documentation](plugins/ultra-cc-architect/README.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### [AI Psychosis](plugins/ai-psychosis/) `v1.2.0`
|
### [AI Psychosis](plugins/ai-psychosis/) `v1.2.0`
|
||||||
|
|
||||||
Meta-awareness tools that counteract sycophancy, reinforcement loops, and compulsive AI interaction patterns.
|
Meta-awareness tools that counteract sycophancy, reinforcement loops, and compulsive AI interaction patterns.
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ultra-cc-architect",
|
|
||||||
"description": "Match a task brief and research against available Claude Code features (Hooks, Subagents, Skills, MCP, Plan Mode, Worktrees, Background Agents) with brief-anchored rationale and explicit coverage gaps. Includes the skill-factory authoring command for catalog growth. Pre-release — catalog is thin, expect breaking changes before v1.0.",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"author": {
|
|
||||||
"name": "Kjell Tore Guttormsen"
|
|
||||||
},
|
|
||||||
"homepage": "https://git.fromaitochitta.com/open/ktg-plugin-marketplace",
|
|
||||||
"repository": "https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git",
|
|
||||||
"license": "MIT",
|
|
||||||
"keywords": ["claude-code", "architecture", "feature-matching", "skills", "hooks", "subagents", "catalog", "ip-hygiene", "context-engineering"]
|
|
||||||
}
|
|
||||||
21
plugins/ultra-cc-architect/.gitignore
vendored
21
plugins/ultra-cc-architect/.gitignore
vendored
|
|
@ -1,21 +0,0 @@
|
||||||
# OS files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Editor files
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
*~
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# Local configuration / session files (gitignored across the marketplace)
|
|
||||||
*.local.md
|
|
||||||
REMEMBER.md
|
|
||||||
TODO.md
|
|
||||||
ROADMAP.md
|
|
||||||
|
|
||||||
# Skill-factory drafts (Fase 1 — manual promotion via mv)
|
|
||||||
skills/cc-architect-catalog/.drafts/*.md
|
|
||||||
!skills/cc-architect-catalog/.drafts/.gitkeep
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to `ultra-cc-architect` are documented here.
|
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
||||||
|
|
||||||
## [0.1.0] — 2026-04-30
|
|
||||||
|
|
||||||
### Initial release — extracted from `ultraplan-local` v2.4.0
|
|
||||||
|
|
||||||
`ultra-cc-architect` is the CC-specific architecture phase pulled out of the `ultraplan-local` plugin. The split decouples the universal planning pipeline (brief → research → plan → execute) from the Claude-Code-specific feature-matching logic, so users can adopt the planning pipeline without inheriting an unfinished CC-feature catalog and skill-factory.
|
|
||||||
|
|
||||||
**Why pre-release (0.1.0):**
|
|
||||||
- Catalog is thin: 11 seed skills across 8 features, decision-layer intentionally empty.
|
|
||||||
- Skill-factory has only Fase 1 (one source → one draft, manual promotion). Fase 2 (CC-changelog watcher) and Fase 3 (cross-feature decision skills) are unbuilt.
|
|
||||||
- `feature-matcher` falls back to a hardcoded list when the catalog is sparse — this fallback should disappear before v1.0.
|
|
||||||
- Slug convention is stable but catalog-growth tooling (batch authoring, automated taxonomy updates) is not.
|
|
||||||
|
|
||||||
### Inherited from ultraplan-local v2.4.0
|
|
||||||
|
|
||||||
**Commands (2):**
|
|
||||||
- `/ultra-cc-architect-local` — feature matching with brief-anchored rationale and explicit coverage gaps. Modes: `--project` (required), `--quick` (skip critic), `--no-gaps`, `--fg` (no-op alias).
|
|
||||||
- `/ultra-skill-author-local` — skill-factory Fase 1 manual authoring. Modes: default, `--quick` (skip IP-hygiene), `--fg` (no-op alias).
|
|
||||||
|
|
||||||
**Agents (8):**
|
|
||||||
- `architect-orchestrator` (opus) — inline reference for the architect workflow
|
|
||||||
- `feature-matcher` (sonnet) — match brief+research to CC features with brief-anchored rationale
|
|
||||||
- `gap-identifier` (sonnet) — surface catalog/pattern/decision/outside-CC-scope gaps
|
|
||||||
- `architecture-critic` (sonnet) — adversarial review with hallucination gate (BLOCKER)
|
|
||||||
- `skill-author-orchestrator` (opus) — inline reference for the 3-stage authoring pipeline
|
|
||||||
- `concept-extractor` (sonnet) — read source, output concept JSON with cc_feature/layer/slug
|
|
||||||
- `skill-drafter` (sonnet) — write `.drafts/<slug>.md` with 9-field frontmatter
|
|
||||||
- `ip-hygiene-checker` (sonnet) — run `ngram-overlap.mjs`, stamp verdict or delete
|
|
||||||
|
|
||||||
**Skill catalog:** `skills/cc-architect-catalog/` (13 files: SKILL.md manifest + 11 seeds + `.drafts/.gitkeep`)
|
|
||||||
|
|
||||||
**Scripts:** `scripts/ngram-overlap.mjs` + `scripts/ngram-overlap.test.mjs` (zero-dependency Node)
|
|
||||||
|
|
||||||
**Test fixtures:** `tests/fixtures/skill-factory/` (calibration prose for verdict bands) + `tests/fixtures/skill-drafter/slug-collision-expected.md`
|
|
||||||
|
|
||||||
### Slug-convention version
|
|
||||||
|
|
||||||
Inherits the v2.3.1 slug convention from ultraplan-local: `<cc_feature>[-<qualifier>]-<layer>.md`. Unqualified slug = canonical baseline per (feature, layer); qualified slugs cover specific sub-patterns. Slug-collision hint in `skill-drafter` (v2.3.2) preserved.
|
|
||||||
|
|
||||||
### Breaking changes
|
|
||||||
|
|
||||||
None at the command level — `/ultra-cc-architect-local` and `/ultra-skill-author-local` keep their names and flag surfaces. Users who installed `ultraplan-local` v2.4.0 must additionally install `ultra-cc-architect` v0.1.0+ to keep using these commands. See `ultraplan-local` v3.0.0 CHANGELOG for migration steps.
|
|
||||||
|
|
||||||
### Filesystem contract
|
|
||||||
|
|
||||||
Both plugins write into `.claude/projects/{YYYY-MM-DD}-{slug}/`. The directory contract is owned by `ultraplan-local`; this plugin opt-in writes to the `architecture/` subdirectory. No code-level dependency between plugins — the contract is filesystem-level documentation only.
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
# ultra-cc-architect
|
|
||||||
|
|
||||||
Claude-Code-specific architecture matching and skill-factory authoring. Extracted from `ultraplan-local` v2.4.0 in v0.1.0 (2026-04-30).
|
|
||||||
|
|
||||||
**Status: pre-release (v0.1.0).** Catalog is thin (~11 seed skills across 8 features), Fase 2/3 of the skill-factory remain unbuilt, decision-layer skills are intentionally empty. Expect breaking changes before v1.0.
|
|
||||||
|
|
||||||
**Design principle: Context Engineering** — match a task brief and research against available CC features, propose a feature set with brief-anchored rationale, surface honest coverage gaps. The plugin consumes upstream artifacts (typically from `ultraplan-local`) and produces an architecture note that downstream `ultraplan-local` can auto-discover as priors.
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
| Command | Description | Model |
|
|
||||||
|---------|-------------|-------|
|
|
||||||
| `/ultra-cc-architect-local` | Architect — match brief+research against Claude Code features; produce architecture note with explicit gaps. Requires `--project` | opus |
|
|
||||||
| `/ultra-skill-author-local` | Authoring (skill-factory Fase 1) — generate one cc-architect-catalog draft from a local source with IP-hygiene | opus |
|
|
||||||
|
|
||||||
### /ultra-cc-architect-local modes
|
|
||||||
|
|
||||||
| Flag | Behavior |
|
|
||||||
|------|----------|
|
|
||||||
| `--project <dir>` | **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) |
|
|
||||||
| `--quick` | Skip adversarial review (architecture-critic) |
|
|
||||||
| `--no-gaps` | Skip gap-identifier; overview.md only |
|
|
||||||
|
|
||||||
Architect sits between `/ultraresearch-local` and `/ultraplan-local` in the typical pipeline. It matches the task brief + research against available Claude Code features (Hooks, Subagents, Skills, Output Styles, MCP, Plan Mode, Worktrees, Background Agents) using the seeded `cc-architect-catalog` skill, and produces a proposed feature set with brief-anchored rationale plus explicit gaps (missing reference, pattern, decision, or outside-CC-scope).
|
|
||||||
|
|
||||||
### /ultra-skill-author-local modes
|
|
||||||
|
|
||||||
| Flag | Behavior |
|
|
||||||
|------|----------|
|
|
||||||
| _(default)_ | Run the pipeline (concept → draft → IP-hygiene) foreground |
|
|
||||||
| `--fg` | Same as default; flag accepted for pipeline-convention consistency |
|
|
||||||
| `--quick` | Skip IP-hygiene with BIG WARNING (drafting-pipeline test only) |
|
|
||||||
|
|
||||||
Manual one-skill-at-a-time generator for the `cc-architect-catalog`. 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).
|
|
||||||
|
|
||||||
## Agents
|
|
||||||
|
|
||||||
| Agent | Model | Role |
|
|
||||||
|-------|-------|------|
|
|
||||||
| 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) |
|
|
||||||
| skill-author-orchestrator | opus | Inline reference for the `/ultra-skill-author-local` 3-stage pipeline |
|
|
||||||
| concept-extractor | sonnet | Read one local source file and extract a structured concept JSON (cc_feature, layer, slug) |
|
|
||||||
| skill-drafter | sonnet | Consume concept JSON + source; produce draft SKILL.md with 9-field frontmatter |
|
|
||||||
| ip-hygiene-checker | sonnet | Score draft against source via ngram-overlap.mjs; stamp verdict or delete draft |
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
**Architect:** Foreground workflow: 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. Writes to `{dir}/architecture/overview.md` and `{dir}/architecture/gaps.md`. Additive — downstream `/ultraplan-local` auto-discovers the note if present.
|
|
||||||
|
|
||||||
**Skill-factory Fase 1 (`/ultra-skill-author-local`):** Sequential 3-stage pipeline, no parallelism, no retry. Source file → `concept-extractor` (JSON: cc_feature/layer/slug) → `skill-drafter` (writes `.drafts/<slug>.md`, 9-field frontmatter, 150–600 word body in user voice) → `ip-hygiene-checker` (runs `scripts/ngram-overlap.mjs`; `accepted`/`needs-review` stamps `ngram_overlap_score` into frontmatter, `rejected` deletes the draft).
|
|
||||||
|
|
||||||
## CC-feature catalog
|
|
||||||
|
|
||||||
The `cc-architect-catalog` skill at `skills/cc-architect-catalog/` indexes Claude Code primitives across three layers:
|
|
||||||
- **`reference`** — how a feature works
|
|
||||||
- **`pattern`** — when to reach for it
|
|
||||||
- **`decision`** — adoption heuristics (intentionally empty in v0.1.0; pending skill-factory Fase 2)
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
**Slug convention:** catalog files follow `<cc_feature>[-<qualifier>]-<layer>.md`.
|
|
||||||
|
|
||||||
- **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:** `skill-drafter` reads `{catalog_root}/<slug>.md` before writing, and prepends a warning block to its confirmation output when an existing skill would be overwritten during manual `mv` promotion. The draft is still written to `.drafts/<slug>.md` — the check is a hint, not a block.
|
|
||||||
|
|
||||||
Seeds (v0.1.0, inherited from ultraplan-local 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.
|
|
||||||
|
|
||||||
## Project-directory contract (consumed)
|
|
||||||
|
|
||||||
The plugin participates in the `ultraplan-local` project-directory contract. It is not strictly required to use `ultraplan-local`, but the typical workflow assumes those upstream artifacts exist:
|
|
||||||
|
|
||||||
```
|
|
||||||
.claude/projects/{YYYY-MM-DD}-{slug}/
|
|
||||||
brief.md ← consumed (typically produced by /ultrabrief-local)
|
|
||||||
research/*.md ← consumed (typically produced by /ultraresearch-local)
|
|
||||||
architecture/ ← produced by this plugin
|
|
||||||
overview.md
|
|
||||||
gaps.md
|
|
||||||
plan.md ← downstream consumer is /ultraplan-local (it auto-discovers overview.md)
|
|
||||||
```
|
|
||||||
|
|
||||||
Path discipline: the plugin only reads from `brief.md` + `research/*.md`, only writes to `architecture/overview.md` + `architecture/gaps.md`. No code dependency on `ultraplan-local` — the contract is filesystem-level only.
|
|
||||||
|
|
||||||
## Stats
|
|
||||||
|
|
||||||
- Architect stats: `${CLAUDE_PLUGIN_DATA}/ultra-cc-architect-stats.jsonl`
|
|
||||||
- Skill-author stats: `${CLAUDE_PLUGIN_DATA}/ultra-skill-author-local-stats.jsonl`
|
|
||||||
|
|
||||||
## Roadmap to v1.0
|
|
||||||
|
|
||||||
Pre-release because:
|
|
||||||
- Catalog is thin (11 seed skills; gaps in pattern + decision layers across most features)
|
|
||||||
- Decision-layer skills are intentionally empty — Fase 2 of skill-factory not yet built
|
|
||||||
- Skill-factory has only Fase 1 (manual one-source one-draft); Fase 2/3 (CC-changelog watcher, batch processing, cross-feature decision skills) remain
|
|
||||||
- `feature-matcher` falls back to a hardcoded list when catalog is sparse — fragile until catalog grows
|
|
||||||
|
|
||||||
See `ROADMAP.md` (gitignored) for current milestone tracking.
|
|
||||||
|
|
||||||
## Terminology
|
|
||||||
|
|
||||||
- **Architecture note** — the artifact produced by `/ultra-cc-architect-local`: `overview.md` + `gaps.md`. Proposes which Claude Code features fit the task with brief-anchored rationale and explicit gaps.
|
|
||||||
- **Catalog skill** — a single file in `skills/cc-architect-catalog/<slug>.md`. Indexes one (feature, layer) pair, possibly with a qualifier.
|
|
||||||
- **Draft** — output of `skill-drafter`, written to `skills/cc-architect-catalog/.drafts/<slug>.md`. Promoted to the catalog by manual `mv` after review.
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
# Governance
|
|
||||||
|
|
||||||
How this marketplace is maintained, what you can expect from upstream, and how it's meant to be used.
|
|
||||||
|
|
||||||
## TL;DR
|
|
||||||
|
|
||||||
- Solo-maintained, AI-assisted development, MIT licensed.
|
|
||||||
- **Fork-and-own is the default model.** Upstream is a starting point, not a vendor.
|
|
||||||
- Issues welcome as signals. Pull requests are not accepted — see [Why no PRs](#pull-requests--no).
|
|
||||||
- No SLA. Best-effort bug fixes and security advisories. Breaking changes happen and are noted in each plugin's CHANGELOG.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Can I trust this?
|
|
||||||
|
|
||||||
Be honest with yourself about what you're adopting:
|
|
||||||
|
|
||||||
- **One maintainer.** If I get hit by a bus, the bus wins. The repos stay up under MIT, but no one owes you a fix.
|
|
||||||
- **AI-generated code with human review.** Every plugin is built through dialog-driven development with Claude Code. I read, test, and judge the output before it ships, but I'm not auditing every line the way a security firm would. Treat it accordingly.
|
|
||||||
- **No commercial interests.** I'm not selling a SaaS, not steering you toward a paid tier, not collecting telemetry. The plugins run locally in your Claude Code installation.
|
|
||||||
- **MIT licensed.** Fork it, modify it, ship it under your own name.
|
|
||||||
|
|
||||||
If you work somewhere that needs vendor accountability, support contracts, or signed assurances — **this isn't that.** Use it as a reference implementation, fork it into your own organization, and own the result.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## How this is meant to be used
|
|
||||||
|
|
||||||
### Fork-and-own
|
|
||||||
|
|
||||||
The intended workflow:
|
|
||||||
|
|
||||||
1. **Fork** the marketplace (or a single plugin) into your own organization or namespace.
|
|
||||||
2. **Tailor** it to your context — terminology, integrations, cycle lengths, regulatory framing, whatever doesn't fit out of the box.
|
|
||||||
3. **Maintain it yourself.** Treat your fork as the canonical version for your team.
|
|
||||||
4. **Watch upstream selectively.** Cherry-pick changes that help, ignore changes that don't. There's no obligation to stay in sync.
|
|
||||||
|
|
||||||
This isn't a workaround for not accepting PRs. It's the actual recommended adoption pattern, especially for plugins like `okr` and `ms-ai-architect` where every Norwegian public sector organization will need its own tildelingsbrev mappings, terminology, and integrations. A central "one true plugin" would be wrong for everyone.
|
|
||||||
|
|
||||||
### What to change first when you fork
|
|
||||||
|
|
||||||
Each plugin differs, but the common edits are:
|
|
||||||
|
|
||||||
- **Identity** — rename the plugin, replace authorship, update README.
|
|
||||||
- **External integrations** — issue trackers, knowledge bases, dashboards, observability backends. The plugins ship as starting points, not pre-wired. Every organization must configure its own integrations.
|
|
||||||
- **Norwegian-specific framing** — relevant for `okr` and `ms-ai-architect`. Other plugins are jurisdiction-neutral. Rewrite for your jurisdiction if you're outside Norway.
|
|
||||||
- **Reference docs** — the knowledge base in each plugin reflects my reading. Replace with your organization's authoritative sources.
|
|
||||||
- **Hooks and policies** — security thresholds, blocked commands, and audit gates are tuned to my taste. Tune them to yours.
|
|
||||||
|
|
||||||
### Staying current with upstream
|
|
||||||
|
|
||||||
If you want to pull in upstream changes later:
|
|
||||||
|
|
||||||
- **Cherry-pick, don't merge.** Each plugin moves independently and breaking changes land without ceremony.
|
|
||||||
- **Read the CHANGELOG first.** Every plugin has one.
|
|
||||||
- **Keep your customizations in clearly-named files.** The harder upstream is to merge cleanly, the more painful staying current becomes. A `local/` directory or `*.local.md` convention helps.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## What upstream provides
|
|
||||||
|
|
||||||
| | What I do | What I don't |
|
|
||||||
|---|---|---|
|
|
||||||
| **Bug fixes** | Best-effort when I notice or get a clear report | No SLA, no triage commitment |
|
|
||||||
| **Security issues** | Investigate within reasonable time, document in CHANGELOG | No CVE process, no embargo coordination |
|
|
||||||
| **New features** | When they fit my own usage | Not on request |
|
|
||||||
| **Norwegian public sector context** | Kept current as long as the project lives | If I lose interest or change jobs, the framing freezes |
|
|
||||||
| **Breaking changes** | Documented in CHANGELOG | They happen — version pin if you need stability |
|
|
||||||
| **Compatibility** | Tracked against current Claude Code releases | No long-term support branches |
|
|
||||||
|
|
||||||
If any of this is a dealbreaker — fork now, version-pin, and stop reading upstream.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## How to contribute
|
|
||||||
|
|
||||||
### Issues — yes, please
|
|
||||||
|
|
||||||
Issues are the most valuable thing you can send me:
|
|
||||||
|
|
||||||
- **Bug reports** with reproduction steps. Even a screenshot helps.
|
|
||||||
- **Use-case feedback.** "I tried to use this in my organization and X didn't fit" is genuinely useful, even if I can't fix it for you.
|
|
||||||
- **Pointers to better sources.** If you know a DFØ veileder, an NSM guideline, or an academic paper that contradicts what's in a knowledge base, tell me.
|
|
||||||
- **Security findings.** See each plugin's `SECURITY.md` for disclosure preference where one exists; otherwise email rather than open a public issue.
|
|
||||||
|
|
||||||
### Pull requests — no
|
|
||||||
|
|
||||||
This is deliberate, not laziness:
|
|
||||||
|
|
||||||
- **Solo review is a bottleneck.** Honest PR review takes me longer than rewriting from scratch. The math doesn't work.
|
|
||||||
- **Forks are where the value is.** The fork-and-own model means upstream consolidation isn't the point. Your organization's adaptations belong in your fork, not mine.
|
|
||||||
- **AI-generated code complicates provenance.** Every line here is produced through dialog with Claude Code, with me as the judge. Mixing in PRs from contributors with different processes and licensing assumptions creates a mess I'd rather not untangle.
|
|
||||||
|
|
||||||
If you've built something useful on top of a fork, **publish it under your own name and link back.** I'll happily list notable forks here once they exist.
|
|
||||||
|
|
||||||
### Notable forks
|
|
||||||
|
|
||||||
*(To be populated as forks emerge. If you've forked one of these plugins for production use, open an issue and I'll add a link.)*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Relationship between plugins
|
|
||||||
|
|
||||||
These plugins are **independent**. Install one without the others, fork one without the others. They share conventions (slash command naming, hook patterns, AI-generated disclosure) but no runtime dependencies.
|
|
||||||
|
|
||||||
The marketplace is a **catalog**, not a suite. Don't fork the whole repo unless you actually want to maintain everything.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Versioning and stability
|
|
||||||
|
|
||||||
- **Semantic versioning per plugin.** Each plugin has its own `CHANGELOG.md` and version number.
|
|
||||||
- **Breaking changes happen.** I bump the major version when they do, but I don't run an LTS branch.
|
|
||||||
- **Pin your version.** If stability matters more than features, install a specific version and stay there until you choose to upgrade.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Public sector adoption notes
|
|
||||||
|
|
||||||
For Norwegian etater specifically:
|
|
||||||
|
|
||||||
- **DPIA-relevant data flows are documented in the relevant plugin README where applicable.** Read them before installation.
|
|
||||||
- **No data leaves your machine** beyond what Claude Code itself sends to Anthropic. The plugins themselves do not call external services unless you configure an integration.
|
|
||||||
- **Drøftingsplikt and ledelsesansvar** are not replaced by these tools. The `okr` plugin coaches; it does not decide. The `ms-ai-architect` plugin advises; it does not approve.
|
|
||||||
- **Choose your Claude deployment carefully.** claude.ai vs. API direct vs. Bedrock in EU region have different data residency profiles. The plugins don't choose for you.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT for all plugins in this marketplace. See each plugin's `LICENSE` file.
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2026 Kjell Tore Guttormsen
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
@ -1,193 +0,0 @@
|
||||||
# ultra-cc-architect — Match tasks to Claude Code features
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
> **Solo-maintained, fork-and-own.** This plugin is a starting point, not a vendor product. Issues are welcome as signals; pull requests are not accepted. See [GOVERNANCE.md](GOVERNANCE.md) for the full model and what upstream provides.
|
|
||||||
|
|
||||||
*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 that matches a task brief and 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 plus explicit coverage gaps.
|
|
||||||
|
|
||||||
> **Pre-release (v0.1.0).** Extracted from `ultraplan-local` v2.4.0 on 2026-04-30. The catalog is thin (11 seed skills) and the skill-factory has only Fase 1. Expect breaking changes before v1.0. See [Roadmap to v1.0](#roadmap-to-v10).
|
|
||||||
|
|
||||||
| Command | What it does |
|
|
||||||
|---------|--------------|
|
|
||||||
| **`/ultra-cc-architect-local`** | Match brief+research against CC features; produce architecture note with explicit gaps |
|
|
||||||
| **`/ultra-skill-author-local`** | Skill-factory Fase 1 — generate one cc-architect-catalog draft from a local source with IP-hygiene |
|
|
||||||
|
|
||||||
## Why a separate plugin
|
|
||||||
|
|
||||||
`ultraplan-local` provides a universal planning pipeline (brief → research → plan → execute) that is technology-agnostic. `ultra-cc-architect` is the Claude-Code-specific layer on top: it only makes sense if you're building features for Claude Code itself. Splitting them out:
|
|
||||||
|
|
||||||
- Lets you adopt the planning pipeline without inheriting an unfinished CC-feature catalog
|
|
||||||
- Lets the catalog and feature-matching logic version independently from the planning flow
|
|
||||||
- Makes it explicit when a workflow takes a CC-specific turn
|
|
||||||
|
|
||||||
## Typical workflow
|
|
||||||
|
|
||||||
`ultra-cc-architect` consumes the same project-directory contract as `ultraplan-local`. The full pipeline:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Capture intent (ultraplan-local plugin)
|
|
||||||
/ultrabrief-local Add a custom prompt-injection hook to all our plugins
|
|
||||||
# → .claude/projects/2026-04-30-prompt-injection-hook/brief.md
|
|
||||||
|
|
||||||
# 2. Research (ultraplan-local plugin)
|
|
||||||
/ultraresearch-local --project .claude/projects/2026-04-30-prompt-injection-hook --external "How do PreToolUse hooks compose with prompt-level rules?"
|
|
||||||
# → .claude/projects/2026-04-30-prompt-injection-hook/research/01-*.md
|
|
||||||
|
|
||||||
# 3. Match to CC features (THIS plugin)
|
|
||||||
/ultra-cc-architect-local --project .claude/projects/2026-04-30-prompt-injection-hook
|
|
||||||
# → architecture/overview.md + architecture/gaps.md
|
|
||||||
|
|
||||||
# 4. Plan (ultraplan-local plugin — auto-discovers architecture/overview.md)
|
|
||||||
/ultraplan-local --project .claude/projects/2026-04-30-prompt-injection-hook
|
|
||||||
|
|
||||||
# 5. Execute (ultraplan-local plugin)
|
|
||||||
/ultraexecute-local --project .claude/projects/2026-04-30-prompt-injection-hook
|
|
||||||
```
|
|
||||||
|
|
||||||
You don't have to use `ultraplan-local` — the plugin reads `brief.md` + `research/*.md` from any directory matching the contract. But the natural upstream is `/ultrabrief-local` + `/ultraresearch-local`, and the natural downstream is `/ultraplan-local`.
|
|
||||||
|
|
||||||
## `/ultra-cc-architect-local` — Architect
|
|
||||||
|
|
||||||
Reads the task brief and any research, then matches against available Claude Code features and produces an architecture note with brief-anchored rationale per feature and an explicit coverage-gap section.
|
|
||||||
|
|
||||||
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` (unless `--quick`) — hallucination gate is BLOCKER
|
|
||||||
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 <dir>` | **Required.** Read `{dir}/brief.md` + `{dir}/research/*.md`; write to `{dir}/architecture/`. |
|
|
||||||
| `--fg` | No-op alias (foreground is default). |
|
|
||||||
| `--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** — table with rationale (brief-anchored), supporting skill, 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
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
## `/ultra-skill-author-local` — Skill-factory Fase 1
|
|
||||||
|
|
||||||
Manual one-skill-at-a-time generator for the `cc-architect-catalog`. 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 11 seed skills covering 8 features, the matcher falls back to a hardcoded list more often than it should. 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 <source>
|
|
||||||
→ concept-extractor (sonnet) → JSON: cc_feature, layer, slug
|
|
||||||
→ skill-drafter (sonnet) → .drafts/<slug>.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 <source>` | Run the pipeline foreground |
|
|
||||||
| **`--fg`** | `/ultra-skill-author-local <source> --fg` | Same as default; flag accepted for pipeline-convention consistency |
|
|
||||||
| **`--quick`** | `/ultra-skill-author-local <source> --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
|
|
||||||
|
|
||||||
## CC-feature catalog
|
|
||||||
|
|
||||||
The catalog at `skills/cc-architect-catalog/` indexes Claude Code primitives across three layers (`reference`, `pattern`, `decision`). v0.1.0 inherits the v2.3.1 seeds from `ultraplan-local`: 11 skills covering 8 features, with one qualified pattern (`hooks-observability-pattern.md`).
|
|
||||||
|
|
||||||
**Slug convention:** `<cc_feature>[-<qualifier>]-<layer>.md`. Unqualified slugs are the canonical baseline per `(feature, layer)` pair; qualified slugs cover specific sub-patterns. `feature-matcher` prefers the unqualified baseline when the brief does not specifically justify a qualified variant. Slug collisions with approved skills are a hard error.
|
|
||||||
|
|
||||||
The catalog is designed for expansion via `/ultra-skill-author-local`. Gaps surfaced by `/ultra-cc-architect-local` are the backlog for catalog growth.
|
|
||||||
|
|
||||||
## Roadmap to v1.0
|
|
||||||
|
|
||||||
Pre-release because:
|
|
||||||
- Catalog is thin (11 seed skills; gaps in pattern + decision layers across most features)
|
|
||||||
- Decision-layer skills are intentionally empty — Fase 2 of skill-factory not yet built
|
|
||||||
- Skill-factory has only Fase 1 (manual one-source one-draft); Fase 2/3 (CC-changelog watcher, batch processing, cross-feature decision skills) remain
|
|
||||||
- `feature-matcher` falls back to a hardcoded list when catalog is sparse — fragile until catalog grows
|
|
||||||
|
|
||||||
v1.0 ships when the catalog is dense enough that the fallback list can be removed and decision-layer skills exist for the most common adoption-question patterns.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Add the marketplace and enable both plugins:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git
|
|
||||||
```
|
|
||||||
|
|
||||||
Then in `~/.claude/settings.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"enabledPlugins": {
|
|
||||||
"ultraplan-local@ktg-plugin-marketplace": true,
|
|
||||||
"ultra-cc-architect@ktg-plugin-marketplace": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can install `ultra-cc-architect` without `ultraplan-local`, but the typical workflow assumes brief + research artifacts produced upstream.
|
|
||||||
|
|
||||||
## Cost profile
|
|
||||||
|
|
||||||
- **Architect**: 1 Opus orchestration + 2-3 Sonnet agents (feature-matcher + gap-identifier in parallel; architecture-critic if not `--quick`)
|
|
||||||
- **Skill-author**: 3 Sonnet agents sequential (concept-extractor + skill-drafter + ip-hygiene-checker)
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (CLI, desktop app, or web app)
|
|
||||||
- Claude subscription with Opus access (Max plan recommended)
|
|
||||||
- For typical pipeline use: `ultraplan-local` plugin (provides upstream `/ultrabrief-local` + `/ultraresearch-local` and downstream `/ultraplan-local`)
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[MIT](LICENSE)
|
|
||||||
|
|
@ -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"]
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- Phase mapping: orchestrator → command
|
|
||||||
Orchestrator Phase 1 = Command Phase 3 (Read inputs)
|
|
||||||
Orchestrator Phase 2 = Command Phase 4 (Feature matching)
|
|
||||||
Orchestrator Phase 3 = Command Phase 5 (Synthesis — write overview.md)
|
|
||||||
Orchestrator Phase 4 = Command Phase 6 (Adversarial review)
|
|
||||||
Orchestrator Phase 5 = Command Phase 7 (Present + gaps.md + stats)
|
|
||||||
As of v2.4.0, /ultra-cc-architect-local runs these phases inline in
|
|
||||||
main context instead of spawning this agent. Keep this file as the
|
|
||||||
canonical reference for what those phases do. -->
|
|
||||||
|
|
||||||
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: <from brief frontmatter>
|
|
||||||
slug: <from brief frontmatter>
|
|
||||||
created: <ISO date>
|
|
||||||
source_brief: <relative path from overview.md to brief.md>
|
|
||||||
source_research: [<list of relative paths>]
|
|
||||||
skills_consulted: [<list of skill `name` values from catalog>]
|
|
||||||
cc_features_proposed: [<list of feature_id values>]
|
|
||||||
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 — <task>
|
|
||||||
|
|
||||||
These are issue-ready drafts. Copy to the project's git host manually
|
|
||||||
when you decide a gap warrants tracking. No auto-creation.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<gap 1>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<gap 2>
|
|
||||||
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
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": "<ISO-8601>",
|
|
||||||
"task": "<brief task, first 100 chars>",
|
|
||||||
"mode": "<default|quick|no-gaps>",
|
|
||||||
"slug": "<from brief>",
|
|
||||||
"project_dir": "<project_dir>",
|
|
||||||
"architecture_path": "<architecture_dir>/overview.md",
|
|
||||||
"gaps_path": "<architecture_dir>/gaps.md | null>",
|
|
||||||
"skills_catalog_size": <N>,
|
|
||||||
"skills_consulted": <N>,
|
|
||||||
"features_proposed": <N>,
|
|
||||||
"gaps_identified": <N>,
|
|
||||||
"critic_verdict": "<PASS|REVISE|BLOCK|SKIPPED>",
|
|
||||||
"guardian_verdict": "<ALIGNED|CREEP|GAP|MIXED|SKIPPED>",
|
|
||||||
"fallback_used": <true|false>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
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:** <task>
|
|
||||||
**Project:** <project_dir>
|
|
||||||
**Architecture note:** <overview.md path>
|
|
||||||
**Gaps draft:** <gaps.md path or "skipped (--no-gaps)">
|
|
||||||
**Features proposed:** N (primary: N, secondary: N, fallback: N)
|
|
||||||
**Gaps identified:** N
|
|
||||||
**Review:** <critic_verdict> / <guardian_verdict>
|
|
||||||
|
|
||||||
### Primary features
|
|
||||||
- <feature 1>: <one-line rationale>
|
|
||||||
- <feature 2>: ...
|
|
||||||
|
|
||||||
### Top gaps (if any)
|
|
||||||
- <gap 1>
|
|
||||||
- <gap 2>
|
|
||||||
|
|
||||||
Next step: /ultraplan-local --project <project_dir>
|
|
||||||
(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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
<example>
|
|
||||||
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."
|
|
||||||
<commentary>
|
|
||||||
architect-orchestrator spawns this agent alongside scope-guardian.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
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
|
|
||||||
`<feature>[-<qualifier>]-<layer>.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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
<example>
|
|
||||||
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."
|
|
||||||
<commentary>
|
|
||||||
skill-author-orchestrator spawns this agent first; its JSON output drives
|
|
||||||
the rest of the pipeline.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
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": "<one of 8 canonical values, or null when out_of_scope>",
|
|
||||||
"layer": "<reference | pattern, or null when out_of_scope>",
|
|
||||||
"concept": "<3–6 word handle, or null when out_of_scope>",
|
|
||||||
"description": "<one-line matcher hint, or null when out_of_scope>",
|
|
||||||
"source_path": "<absolute path to input>",
|
|
||||||
"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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
<example>
|
|
||||||
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."
|
|
||||||
<commentary>
|
|
||||||
architect-orchestrator spawns this agent in parallel with gap-identifier.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
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 (`<feature>[-<qualifier>]-<layer>.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 (`<feature>-pattern.md`) plus
|
|
||||||
zero-or-more qualified patterns (`<feature>-<qualifier>-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 `<feature>-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. **<feature_id>** (confidence: <high|med|low>)
|
|
||||||
- Brief anchor: "<verbatim quote from brief section X>"
|
|
||||||
- Supporting skill: <skill_name, or [skill_a, skill_b] for multi, or "none — fallback hint">
|
|
||||||
- Integration: <one sentence>
|
|
||||||
|
|
||||||
2. ...
|
|
||||||
|
|
||||||
### Secondary features
|
|
||||||
...
|
|
||||||
|
|
||||||
### Fallback features
|
|
||||||
...
|
|
||||||
|
|
||||||
### Feature composition notes
|
|
||||||
- <point 1>
|
|
||||||
- <point 2>
|
|
||||||
|
|
||||||
### Catalog metadata
|
|
||||||
- Skills consulted: N
|
|
||||||
- Fallback used: <true|false>
|
|
||||||
- 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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
<example>
|
|
||||||
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."
|
|
||||||
<commentary>
|
|
||||||
architect-orchestrator spawns this agent alongside feature-matcher.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
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
|
|
||||||
(`<feature>[-<qualifier>]-<layer>.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:<feature_id>` (use the taxonomy from SKILL.md)
|
|
||||||
- Layer: `skill-layer:<reference|pattern|decision>`
|
|
||||||
- Urgency: `priority:<low|med|high>` (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 — <feature> / <layer>
|
|
||||||
- **Title**: <imperative title>
|
|
||||||
- **Class**: A | B | C | D
|
|
||||||
- **Priority**: low | med | high
|
|
||||||
- **Description**: <2–4 sentences>
|
|
||||||
- **Labels**: gap, origin:brief-trigger, cc-feature:<x>, skill-layer:<y>, priority:<z>
|
|
||||||
- **Brief context**:
|
|
||||||
> <quote block from brief>
|
|
||||||
- **Proposed resolution**: <one sentence>
|
|
||||||
|
|
||||||
#### Gap 2 — ...
|
|
||||||
|
|
||||||
### Out-of-scope requirements
|
|
||||||
- <requirement>: 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.
|
|
||||||
|
|
@ -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).
|
|
||||||
|
|
||||||
<example>
|
|
||||||
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."
|
|
||||||
<commentary>
|
|
||||||
skill-author-orchestrator spawns this agent after skill-drafter writes a
|
|
||||||
draft. Verdict drives whether the draft survives or gets removed.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
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/<slug>.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 <draft-path> <source-path>
|
|
||||||
```
|
|
||||||
|
|
||||||
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: <value>`.
|
|
||||||
|
|
||||||
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: <value>` 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 <draft-path>
|
|
||||||
```
|
|
||||||
|
|
||||||
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": "<verbatim error message>",
|
|
||||||
"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: <value>` 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 <path-inside-.drafts/>`. 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 <draft-path> <source-path>
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
@ -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).
|
|
||||||
|
|
||||||
<example>
|
|
||||||
Context: /ultra-skill-author-local default mode
|
|
||||||
user: "/ultra-skill-author-local ./docs/hooks-recipes.md --fg"
|
|
||||||
assistant: "Source validated. Launching skill-author-orchestrator."
|
|
||||||
<commentary>
|
|
||||||
Phase 3 of /ultra-skill-author-local spawns this agent with the source
|
|
||||||
path; the orchestrator runs the 3-stage pipeline sequentially.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
model: opus
|
|
||||||
color: cyan
|
|
||||||
tools: ["Agent", "Read", "Bash"]
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- Phase mapping: orchestrator → command
|
|
||||||
Orchestrator Phase 1 = Command Phase 2 (Validate source)
|
|
||||||
Orchestrator Phase 2 = Concept extraction
|
|
||||||
Orchestrator Phase 3 = Drafting
|
|
||||||
Orchestrator Phase 4 = IP-hygiene scoring
|
|
||||||
Orchestrator Phase 5 = Completion summary
|
|
||||||
This agent runs sequentially — each phase consumes the previous output. -->
|
|
||||||
|
|
||||||
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 `<cc_feature>-<layer>` (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/<slug>.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: <value>` 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: <source path>
|
|
||||||
Verdict: <accepted | needs-review | rejected | out-of-scope | skipped (--quick) | error>
|
|
||||||
Draft: <.drafts/<slug>.md | deleted | not-written>
|
|
||||||
Score: <containment | n/a>
|
|
||||||
Longest: <longestRun | n/a>
|
|
||||||
Reasons: <reasons array from checker, joined with "; ">
|
|
||||||
Next: <see below>
|
|
||||||
```
|
|
||||||
|
|
||||||
`Next` field guidance:
|
|
||||||
|
|
||||||
- **accepted:** `mv {catalog_root}/.drafts/<slug>.md {catalog_root}/<slug>.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.
|
|
||||||
|
|
@ -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/<slug>.md with the 9-field frontmatter contract and a
|
|
||||||
150–600 word body in user's own words.
|
|
||||||
|
|
||||||
<example>
|
|
||||||
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."
|
|
||||||
<commentary>
|
|
||||||
skill-author-orchestrator spawns this agent after concept-extractor returns
|
|
||||||
a non-out-of-scope JSON.
|
|
||||||
</commentary>
|
|
||||||
</example>
|
|
||||||
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 `<cc_feature>-<layer>` (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/<slug>.md`.
|
|
||||||
|
|
||||||
### 2. Check for slug collision at the catalog root
|
|
||||||
|
|
||||||
Before proceeding, attempt to `Read` `{catalog_root}/<slug>.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/<slug>.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
|
|
||||||
`<cc_feature>-<qualifier>-<layer>.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: <slug> # = cc_feature-layer
|
|
||||||
description: <one-line matcher hint> # from concept-extractor
|
|
||||||
layer: <reference | pattern> # from concept-extractor
|
|
||||||
cc_feature: <one of 8 canonical values> # from concept-extractor
|
|
||||||
source: <relative path back to source> # e.g., ./docs/hooks-recipes.md
|
|
||||||
concept: <3–6 word concept handle> # from concept-extractor
|
|
||||||
last_verified: <YYYY-MM-DD> # 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/<slug>.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: <full path to .drafts/<slug>.md>
|
|
||||||
Word count: <body word count>
|
|
||||||
Frontmatter: 9 fields, review_status=pending, ngram_overlap_score=null
|
|
||||||
Collision: <none | approved | pending | auto-merged | soft>
|
|
||||||
Next: ip-hygiene-checker for IP scoring
|
|
||||||
```
|
|
||||||
|
|
||||||
If Step 2 detected a collision at `{catalog_root}/<slug>.md`, prepend
|
|
||||||
a warning block to the confirmation:
|
|
||||||
|
|
||||||
```
|
|
||||||
⚠️ Slug collision at catalog root
|
|
||||||
Existing: {catalog_root}/<slug>.md (review_status=<status>)
|
|
||||||
Draft: {catalog_root}/.drafts/<slug>.md (this run)
|
|
||||||
Risk: manual `mv` during promotion will silently overwrite the existing file.
|
|
||||||
Suggested qualified slug: <cc_feature>-<qualifier>-<layer>.md
|
|
||||||
Reason for qualifier: <one short sentence citing the concept handle>
|
|
||||||
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: <source_path>
|
|
||||||
Reason: <one sentence on what made paraphrasing impossible>
|
|
||||||
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: <today>`.** 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}/<slug>.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.
|
|
||||||
|
|
@ -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 <dir> [--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 <dir>`** (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 <dir> [--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: <from brief>
|
|
||||||
slug: <from brief>
|
|
||||||
created: <ISO date>
|
|
||||||
source_brief: <relative path to brief.md>
|
|
||||||
source_research: [<list of relative research paths>]
|
|
||||||
skills_consulted: [<list of skill `name` values>]
|
|
||||||
cc_features_proposed: [<list of feature_id values>]
|
|
||||||
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 — <task>
|
|
||||||
|
|
||||||
These are issue-ready drafts. Copy to the project's git host manually
|
|
||||||
when you decide a gap warrants tracking. No auto-creation.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<gap 1 full draft>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<gap 2>
|
|
||||||
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
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": "<ISO-8601>",
|
|
||||||
"task": "<brief task, first 100 chars>",
|
|
||||||
"mode": "<default|quick|no-gaps|quick+no-gaps|foreground|foreground+quick|...>",
|
|
||||||
"slug": "<from brief>",
|
|
||||||
"project_dir": "<project_dir>",
|
|
||||||
"architecture_path": "<architecture_dir>/overview.md",
|
|
||||||
"gaps_path": "<architecture_dir>/gaps.md | null>",
|
|
||||||
"skills_catalog_size": <N>,
|
|
||||||
"skills_consulted": <N>,
|
|
||||||
"features_proposed": <N>,
|
|
||||||
"gaps_identified": <N>,
|
|
||||||
"critic_verdict": "<PASS|REVISE|BLOCK|SKIPPED>",
|
|
||||||
"guardian_verdict": "<ALIGNED|CREEP|GAP|MIXED|SKIPPED>",
|
|
||||||
"fallback_used": <true|false>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Hvis `${CLAUDE_PLUGIN_DATA}` ikke er satt eller ikke skrivbar, skip
|
|
||||||
stats silently.
|
|
||||||
|
|
||||||
**Summary til brukeren:**
|
|
||||||
|
|
||||||
```
|
|
||||||
## Ultra-CC-Architect Complete
|
|
||||||
|
|
||||||
**Task:** <task>
|
|
||||||
**Project:** <project_dir>
|
|
||||||
**Architecture note:** <architecture_dir>/overview.md
|
|
||||||
**Gaps draft:** <architecture_dir>/gaps.md | skipped (--no-gaps)
|
|
||||||
**Features proposed:** N (primary: N, secondary: N, fallback: N)
|
|
||||||
**Gaps identified:** N
|
|
||||||
**Review:** <critic_verdict> / <guardian_verdict>
|
|
||||||
|
|
||||||
### Primary features
|
|
||||||
- <feature 1>: <one-line rationale>
|
|
||||||
- <feature 2>: ...
|
|
||||||
|
|
||||||
### Top gaps (if any)
|
|
||||||
- <gap 1>
|
|
||||||
- <gap 2>
|
|
||||||
|
|
||||||
Next step: /ultraplan-local --project <project_dir>
|
|
||||||
(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.
|
|
||||||
|
|
@ -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: "<source-file> [--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 <source> → review .drafts/<slug>.md
|
|
||||||
→ if happy: mv .drafts/<slug>.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 <source-file> [--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/<slug>.md
|
|
||||||
→ manual review → mv to catalog root
|
|
||||||
```
|
|
||||||
|
|
||||||
Ikke fortsett forbi dette steget hvis kildefil mangler.
|
|
||||||
|
|
||||||
## Phase 2 — Validate source
|
|
||||||
|
|
||||||
Bash:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
test -f "<source>" && echo "OK"
|
|
||||||
```
|
|
||||||
|
|
||||||
Hvis filen ikke finnes: stopp med tydelig feilmelding.
|
|
||||||
|
|
||||||
Sjekk extension:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
case "<source>" in
|
|
||||||
*.md|*.txt) ;;
|
|
||||||
*) echo "Error: source must be .md or .txt"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
```
|
|
||||||
|
|
||||||
Sjekk størrelse:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
size=$(wc -c < "<source>")
|
|
||||||
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: <absolute path to source>
|
|
||||||
Catalog root: ${CLAUDE_PLUGIN_ROOT}/skills/cc-architect-catalog/
|
|
||||||
Plugin root: ${CLAUDE_PLUGIN_ROOT}
|
|
||||||
Mode: <default | quick>
|
|
||||||
|
|
||||||
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: <source path>
|
|
||||||
Verdict: <accepted | needs-review | rejected | out-of-scope | skipped (--quick) | error>
|
|
||||||
Draft: <.drafts/<slug>.md | deleted | not-written>
|
|
||||||
Score: <ngram_overlap_score | n/a>
|
|
||||||
Longest: <longestRun shingle | n/a>
|
|
||||||
|
|
||||||
### Next step
|
|
||||||
<context-specific next step>
|
|
||||||
```
|
|
||||||
|
|
||||||
Next-step-tekstene matcher orchestratorens guidance:
|
|
||||||
|
|
||||||
- **accepted** →
|
|
||||||
```
|
|
||||||
Review the draft body. If you're happy:
|
|
||||||
mv skills/cc-architect-catalog/.drafts/<slug>.md \
|
|
||||||
skills/cc-architect-catalog/<slug>.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: <reason from concept-extractor>
|
|
||||||
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": "<ISO-8601>",
|
|
||||||
"source": "<source path>",
|
|
||||||
"source_size_bytes": <N>,
|
|
||||||
"mode": "<default|quick>",
|
|
||||||
"verdict": "<accepted|needs-review|rejected|out-of-scope|skipped|error>",
|
|
||||||
"cc_feature": "<from concept-extractor or null>",
|
|
||||||
"layer": "<reference|pattern|null>",
|
|
||||||
"slug": "<computed slug or null>",
|
|
||||||
"draft_path": "<.drafts/<slug>.md | null>",
|
|
||||||
"ngram_overlap_score": <float | null>,
|
|
||||||
"longest_run": <int | null>,
|
|
||||||
"deleted": <true|false>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
@ -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 <draft-path> <source-path>
|
|
||||||
// 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 <draft-path> <source-path>
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
@ -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})`);
|
|
||||||
});
|
|
||||||
|
|
@ -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: <skill-id> # unique, kebab-case
|
|
||||||
description: <one-line matcher hint> # used by feature-matcher
|
|
||||||
layer: reference | pattern | decision
|
|
||||||
cc_feature: <feature-id> # see table below
|
|
||||||
source: <URL> # canonical upstream source
|
|
||||||
concept: <short phrase> # 3–6 word concept handle
|
|
||||||
last_verified: <YYYY-MM-DD> # 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:
|
|
||||||
|
|
||||||
```
|
|
||||||
<cc_feature>[-<qualifier>]-<layer>.md
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Unqualified slug** (`<feature>-<layer>.md`) — the baseline/canonical
|
|
||||||
entry for that (feature, layer) pair. One per pair. Example:
|
|
||||||
`hooks-pattern.md` = generic hook shapes and pitfalls.
|
|
||||||
- **Qualified slug** (`<feature>-<qualifier>-<layer>.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 `<feature>-<layer>.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 (`<feature>-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:<layer>` and `cc-feature:<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 `<feature>-<layer>.md` with the
|
|
||||||
frontmatter contract above. Bump the coverage table in this file.
|
|
||||||
- **Adding a qualified pattern skill:** create
|
|
||||||
`<feature>-<qualifier>-<layer>.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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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).
|
|
||||||
|
|
@ -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".
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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__<server-name>__<tool-name>`. 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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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: <skill-name>
|
|
||||||
description: <one-line trigger hint>
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
The `description` is what Claude sees when deciding whether to invoke.
|
|
||||||
It should describe *when* to use the skill, not *what* it does.
|
|
||||||
|
|
||||||
## Invocation
|
|
||||||
|
|
||||||
- **Auto-invocation** — Claude loads the skill when the user's prompt
|
|
||||||
matches the description's triggers. The trigger model is implicit
|
|
||||||
(natural-language match), not regex.
|
|
||||||
- **Manual invocation** — the user types `/<skill-name>` and Claude
|
|
||||||
calls the Skill tool.
|
|
||||||
- **Never auto-invoked** — if the description explicitly says so
|
|
||||||
("Internal catalog for X — not invoked directly"), Claude typically
|
|
||||||
respects the hint.
|
|
||||||
|
|
||||||
## Discovery
|
|
||||||
|
|
||||||
Skills are discovered from:
|
|
||||||
|
|
||||||
- **Built-in skills** — shipped with the CLI.
|
|
||||||
- **Plugin skills** — packaged inside a plugin's `skills/` directory.
|
|
||||||
- **User skills** — `~/.claude/skills/`.
|
|
||||||
- **Project skills** — `.claude/skills/` inside the repo.
|
|
||||||
|
|
||||||
The CLI surfaces available skills via `--allowedTools` and in the
|
|
||||||
system prompt.
|
|
||||||
|
|
||||||
## Progressive disclosure
|
|
||||||
|
|
||||||
Skills use progressive disclosure:
|
|
||||||
|
|
||||||
1. Claude sees only the name + description at session start.
|
|
||||||
2. When a skill triggers, the body loads into context.
|
|
||||||
3. Files referenced by the body load only when Claude reads them.
|
|
||||||
|
|
||||||
This keeps the baseline context small; depth is paid for on demand.
|
|
||||||
|
|
||||||
## Relationship to other features
|
|
||||||
|
|
||||||
- **Skills vs subagents** — a skill lives in the parent's context when
|
|
||||||
loaded. A subagent runs in its own context. Choose skill when the
|
|
||||||
context flows through; subagent when it should not.
|
|
||||||
- **Skills vs hooks** — hooks are deterministic harness-level rules.
|
|
||||||
Skills are context that Claude interprets. A skill cannot enforce;
|
|
||||||
only guide.
|
|
||||||
- **Skills vs MCP** — MCP exposes *tools*. Skills are *knowledge*. An
|
|
||||||
MCP tool + a skill that explains when to use it is a common pairing.
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
---
|
|
||||||
name: subagents-pattern
|
|
||||||
description: When subagents earn their cost and how to compose them — swarm, pipeline, and guard patterns.
|
|
||||||
layer: pattern
|
|
||||||
cc_feature: subagents
|
|
||||||
source: https://docs.claude.com/en/docs/claude-code/sub-agents
|
|
||||||
concept: subagent-composition
|
|
||||||
last_verified: 2026-04-18
|
|
||||||
ngram_overlap_score: null
|
|
||||||
review_status: approved
|
|
||||||
---
|
|
||||||
|
|
||||||
# Subagents — Pattern
|
|
||||||
|
|
||||||
## When to delegate
|
|
||||||
|
|
||||||
Delegation earns its cost when at least one of these holds:
|
|
||||||
|
|
||||||
- **Context isolation** — the subtask needs to read 50+ files or run
|
|
||||||
many greps, and the parent conversation does not need the raw
|
|
||||||
results. Summaries survive; raw output stays in the subagent.
|
|
||||||
- **Parallelism** — multiple independent subtasks can run at once,
|
|
||||||
compressing wall-clock time.
|
|
||||||
- **Specialization** — the subagent has a tailored system prompt that
|
|
||||||
changes its behavior meaningfully (e.g., adversarial reviewer).
|
|
||||||
- **Tool scoping** — the subtask should run with fewer tools than the
|
|
||||||
parent (principle of least privilege).
|
|
||||||
|
|
||||||
If none of these apply, inline the work. A subagent call costs a full
|
|
||||||
model turn; do not pay it for routine reads.
|
|
||||||
|
|
||||||
## Common patterns
|
|
||||||
|
|
||||||
### Pattern A: Exploration swarm
|
|
||||||
|
|
||||||
Parent launches 4-8 specialized subagents in parallel, each with a
|
|
||||||
narrow brief (architecture, dependencies, risks, tests, ...). Each
|
|
||||||
returns a summary. Parent synthesizes.
|
|
||||||
|
|
||||||
Used by: `ultraplan-local` Phase 2 exploration.
|
|
||||||
|
|
||||||
Cost shape: N × Sonnet call, wall-clock ≈ slowest subagent.
|
|
||||||
|
|
||||||
### Pattern B: Adversarial review
|
|
||||||
|
|
||||||
Parent writes an artifact (plan, design note). Launches a reviewer
|
|
||||||
subagent with a system prompt that demands problems, never praise.
|
|
||||||
Reviewer returns findings. Parent revises.
|
|
||||||
|
|
||||||
Used by: `plan-critic`, `scope-guardian`, `architecture-critic`.
|
|
||||||
|
|
||||||
Cost shape: 1 × Sonnet call per review pass.
|
|
||||||
|
|
||||||
### Pattern C: Background orchestrator
|
|
||||||
|
|
||||||
Parent kicks off a long-running orchestrator subagent with
|
|
||||||
`run_in_background: true`, then continues. Orchestrator runs its own
|
|
||||||
subagents, synthesizes, writes output to disk. Parent is notified on
|
|
||||||
completion.
|
|
||||||
|
|
||||||
Used by: `planning-orchestrator`, `research-orchestrator`.
|
|
||||||
|
|
||||||
Cost shape: 1 × Opus orchestrator + N × Sonnet workers. Overlaps with
|
|
||||||
other user work.
|
|
||||||
|
|
||||||
### Pattern D: Guard subagent
|
|
||||||
|
|
||||||
A hook delegates an "is this safe?" question to a subagent when the
|
|
||||||
answer needs judgment. The subagent returns a verdict; the hook
|
|
||||||
enforces it.
|
|
||||||
|
|
||||||
Cost shape: 1 × Sonnet call per hook invocation. Use sparingly —
|
|
||||||
adds seconds of latency per tool call.
|
|
||||||
|
|
||||||
## Pitfalls
|
|
||||||
|
|
||||||
- **Delegate-understanding anti-pattern** — do not write "based on your
|
|
||||||
findings, fix the bug" to a subagent. The subagent is not inside your
|
|
||||||
head; it cannot see what you synthesized. Pass concrete context.
|
|
||||||
- **Prompt-on-top-of-prompt drift** — if the parent's prompt to a
|
|
||||||
subagent contradicts the subagent's own system prompt, the subagent
|
|
||||||
follows its system prompt. Do not try to re-style a reviewer into a
|
|
||||||
cheerleader by prompting harder.
|
|
||||||
- **Silent failure** — a subagent that returns "done" without evidence
|
|
||||||
may have done nothing. Trust but verify: check for the concrete
|
|
||||||
artifacts the subagent was asked to produce.
|
|
||||||
- **Orchestration explosion** — a three-level-deep subagent tree costs
|
|
||||||
exponentially. Flatten wherever the inner levels don't need their own
|
|
||||||
context isolation.
|
|
||||||
- **Token budget fights** — parent and all active subagents share the
|
|
||||||
harness's overall budget. Cap subagent output length ("report in
|
|
||||||
under 200 words") when the summary is what matters.
|
|
||||||
|
|
||||||
## Composition with other features
|
|
||||||
|
|
||||||
- Subagents + hooks: hooks fire during subagent tool calls too. A
|
|
||||||
subagent with only `Read` tools is already constrained; hooks add
|
|
||||||
defense in depth.
|
|
||||||
- Subagents + worktrees: an `isolation: "worktree"` subagent works in
|
|
||||||
an isolated copy of the repo, so its writes never clash with the
|
|
||||||
parent's writes.
|
|
||||||
- Subagents + background: run heavy exploration in background while the
|
|
||||||
user continues other work.
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
---
|
|
||||||
name: subagents-reference
|
|
||||||
description: CC subagents — how the Task tool spawns isolated agent instances with scoped tools and context.
|
|
||||||
layer: reference
|
|
||||||
cc_feature: subagents
|
|
||||||
source: https://docs.claude.com/en/docs/claude-code/sub-agents
|
|
||||||
concept: task-tool-delegation
|
|
||||||
last_verified: 2026-04-18
|
|
||||||
ngram_overlap_score: null
|
|
||||||
review_status: approved
|
|
||||||
---
|
|
||||||
|
|
||||||
# Subagents — Reference
|
|
||||||
|
|
||||||
Subagents are fresh Claude instances spawned via the Task tool. Each
|
|
||||||
receives a task prompt, a tool subset, and no memory of the parent
|
|
||||||
conversation except what the parent explicitly passes. They return a
|
|
||||||
single final message to the parent.
|
|
||||||
|
|
||||||
## Anatomy
|
|
||||||
|
|
||||||
A subagent has:
|
|
||||||
|
|
||||||
- **A name** — either a built-in type (`general-purpose`, `Explore`,
|
|
||||||
`Plan`) or a plugin-defined type (`code-reviewer`, `test-runner`,
|
|
||||||
...).
|
|
||||||
- **A system prompt** — defined by the agent type. The parent cannot
|
|
||||||
override it.
|
|
||||||
- **A tool set** — subset of the parent's tools, as declared in the
|
|
||||||
agent definition's frontmatter `tools:` field.
|
|
||||||
- **A task prompt** — what the parent asks it to do. Self-contained;
|
|
||||||
the subagent has no access to prior messages.
|
|
||||||
- **A model** — either explicit in the agent definition (`model: opus |
|
|
||||||
sonnet | haiku`) or inherited from the parent.
|
|
||||||
|
|
||||||
## How to define a subagent
|
|
||||||
|
|
||||||
A plugin agent is a markdown file in `agents/` with frontmatter:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
name: code-reviewer
|
|
||||||
description: <when to invoke, include examples>
|
|
||||||
model: sonnet
|
|
||||||
tools: ["Read", "Grep", "Glob"]
|
|
||||||
---
|
|
||||||
|
|
||||||
<system prompt content>
|
|
||||||
```
|
|
||||||
|
|
||||||
The `description` field is how Claude decides when to spawn this
|
|
||||||
subagent. Include concrete trigger examples.
|
|
||||||
|
|
||||||
## How to invoke
|
|
||||||
|
|
||||||
Parent calls the `Task` / `Agent` tool with:
|
|
||||||
|
|
||||||
- `subagent_type` — the agent's name
|
|
||||||
- `description` — short label for logs
|
|
||||||
- `prompt` — the self-contained task
|
|
||||||
|
|
||||||
Optional:
|
|
||||||
|
|
||||||
- `run_in_background: true` — agent runs in the background; parent
|
|
||||||
is notified on completion.
|
|
||||||
- `isolation: "worktree"` — agent runs in a temporary git worktree
|
|
||||||
(isolated copy of the repo).
|
|
||||||
|
|
||||||
## Return protocol
|
|
||||||
|
|
||||||
- Foreground agent: parent blocks until the agent returns. Return value
|
|
||||||
is a single text message.
|
|
||||||
- Background agent: parent continues. On completion, the harness
|
|
||||||
injects a notification into the parent's next turn.
|
|
||||||
|
|
||||||
## Isolation guarantees
|
|
||||||
|
|
||||||
- No conversation history sharing. Each subagent starts cold.
|
|
||||||
- Separate context window. A subagent can read large files without
|
|
||||||
polluting the parent's context.
|
|
||||||
- Separate tool permissions. A subagent with only `Read` tools cannot
|
|
||||||
write files, even if the parent can.
|
|
||||||
|
|
||||||
## Cost and latency
|
|
||||||
|
|
||||||
- Every subagent call is a full model call with its own token budget.
|
|
||||||
- Model choice matters: Sonnet is ~5× cheaper than Opus; Haiku is
|
|
||||||
cheaper still but cannot be used (per project policy).
|
|
||||||
- Parallel subagents: the parent can launch multiple in one message;
|
|
||||||
the harness runs them concurrently. Total latency ≈ slowest agent.
|
|
||||||
|
|
||||||
## Failure modes
|
|
||||||
|
|
||||||
- Subagent hits context limit → partial or missing return.
|
|
||||||
- Subagent runs in background and the parent conversation ends → result
|
|
||||||
may be orphaned.
|
|
||||||
- Subagent's return message hallucinates file paths → caller must
|
|
||||||
verify.
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
---
|
|
||||||
name: worktrees-reference
|
|
||||||
description: CC git worktree integration — isolated repo copies per agent for parallel or destructive work.
|
|
||||||
layer: reference
|
|
||||||
cc_feature: worktrees
|
|
||||||
source: https://docs.claude.com/en/docs/claude-code/worktrees
|
|
||||||
concept: git-worktree-isolation
|
|
||||||
last_verified: 2026-04-18
|
|
||||||
ngram_overlap_score: null
|
|
||||||
review_status: approved
|
|
||||||
---
|
|
||||||
|
|
||||||
# Worktrees — Reference
|
|
||||||
|
|
||||||
Git worktrees let a repo check out multiple branches simultaneously in
|
|
||||||
separate directories. Claude Code integrates with worktrees to give
|
|
||||||
agents isolated filesystem scopes — one agent's edits cannot clash
|
|
||||||
with another's.
|
|
||||||
|
|
||||||
## How it surfaces in CC
|
|
||||||
|
|
||||||
- **`isolation: "worktree"` on a subagent call** — the harness creates
|
|
||||||
a temporary worktree for the subagent. The subagent runs with its
|
|
||||||
cwd set to the worktree. Changes stay there until merged or
|
|
||||||
discarded.
|
|
||||||
- **`/worktree` skill / command** — interactive tooling for creating,
|
|
||||||
listing, and merging worktrees during a session.
|
|
||||||
- **Auto-cleanup** — worktrees created by subagents are removed if the
|
|
||||||
subagent made no changes. Otherwise the path is returned in the
|
|
||||||
result for the caller to review.
|
|
||||||
|
|
||||||
## Branch semantics
|
|
||||||
|
|
||||||
- Each worktree checks out a named branch. Two worktrees cannot check
|
|
||||||
out the same branch (git's rule).
|
|
||||||
- Creating a worktree creates a branch if one does not exist.
|
|
||||||
- Deleting a worktree does not delete the branch; use `git branch -d`
|
|
||||||
separately if desired.
|
|
||||||
|
|
||||||
## Use cases
|
|
||||||
|
|
||||||
- **Parallel exploration** — three subagents trying three approaches,
|
|
||||||
each in its own worktree. The parent compares diffs.
|
|
||||||
- **Destructive experiments** — upgrade a dependency, run the full
|
|
||||||
test suite, measure breakage. Discard the worktree if results are
|
|
||||||
bad.
|
|
||||||
- **Long-running session without blocking main** — execute a refactor
|
|
||||||
in a worktree while continuing other work in the main checkout.
|
|
||||||
|
|
||||||
## Pitfalls
|
|
||||||
|
|
||||||
- **Shared state leaks** — node_modules, .env, build artifacts are
|
|
||||||
per-worktree but may be symlinked in ways that defeat isolation.
|
|
||||||
Verify.
|
|
||||||
- **Disk use** — each worktree is a full checkout of the tree. For
|
|
||||||
large repos, disk pressure adds up.
|
|
||||||
- **Branch proliferation** — agents that create worktrees without
|
|
||||||
cleanup leave orphan branches. Prune periodically.
|
|
||||||
- **Not a sandbox** — a worktree isolates files, not network or
|
|
||||||
processes. A subagent in a worktree can still call the outside
|
|
||||||
world.
|
|
||||||
|
|
||||||
## Composition
|
|
||||||
|
|
||||||
- Worktrees + background agents: a background agent in a worktree can
|
|
||||||
work on a long task while the user continues in the main checkout.
|
|
||||||
- Worktrees + subagents + hooks: hooks fire inside the worktree cwd,
|
|
||||||
so path-based hooks naturally scope to the isolated work.
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
# Skill-drafter slug-collision — expected output fixture
|
|
||||||
|
|
||||||
This fixture documents the expected confirmation-message shape from
|
|
||||||
`skill-drafter` when it detects a slug collision at the catalog root.
|
|
||||||
It is a reference fixture — not an auto-executed test — used to
|
|
||||||
verify the agent by running a synthetic scenario by hand and
|
|
||||||
comparing output against the shapes below.
|
|
||||||
|
|
||||||
## Scenario A — no collision (baseline)
|
|
||||||
|
|
||||||
### Synthetic input
|
|
||||||
|
|
||||||
- **Catalog root:** `skills/cc-architect-catalog/`
|
|
||||||
- **Concept JSON (from concept-extractor):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"cc_feature": "worktrees",
|
|
||||||
"layer": "pattern",
|
|
||||||
"concept": "parallel feature isolation",
|
|
||||||
"description": "Isolate concurrent feature work in per-task worktrees to avoid git race conditions.",
|
|
||||||
"source_path": "/tmp/worktrees-notes.md",
|
|
||||||
"out_of_scope": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- **Catalog state at time of run:** no `worktrees-pattern.md` present
|
|
||||||
at catalog root (only `worktrees-reference.md`).
|
|
||||||
|
|
||||||
### Expected confirmation output
|
|
||||||
|
|
||||||
```
|
|
||||||
Drafted: /Users/…/skills/cc-architect-catalog/.drafts/worktrees-pattern.md
|
|
||||||
Word count: 312
|
|
||||||
Frontmatter: 9 fields, review_status=pending, ngram_overlap_score=null
|
|
||||||
Collision: none
|
|
||||||
Next: ip-hygiene-checker for IP scoring
|
|
||||||
```
|
|
||||||
|
|
||||||
No warning block. `Collision: none`.
|
|
||||||
|
|
||||||
## Scenario B — approved collision (primary case)
|
|
||||||
|
|
||||||
### Synthetic input
|
|
||||||
|
|
||||||
- **Catalog root:** `skills/cc-architect-catalog/`
|
|
||||||
- **Concept JSON:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"cc_feature": "hooks",
|
|
||||||
"layer": "pattern",
|
|
||||||
"concept": "observability progressive alerts",
|
|
||||||
"description": "Progressive-alert observability pattern for hook-driven telemetry.",
|
|
||||||
"source_path": "/tmp/hooks-telemetry-notes.md",
|
|
||||||
"out_of_scope": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- **Catalog state:** `hooks-pattern.md` exists with
|
|
||||||
`review_status: approved` (the v2.3.0 seed).
|
|
||||||
|
|
||||||
### Expected confirmation output
|
|
||||||
|
|
||||||
```
|
|
||||||
⚠️ Slug collision at catalog root
|
|
||||||
Existing: skills/cc-architect-catalog/hooks-pattern.md (review_status=approved)
|
|
||||||
Draft: skills/cc-architect-catalog/.drafts/hooks-pattern.md (this run)
|
|
||||||
Risk: manual `mv` during promotion will silently overwrite the existing file.
|
|
||||||
Suggested qualified slug: hooks-observability-pattern.md
|
|
||||||
Reason for qualifier: concept handle names "observability" as the named sub-pattern.
|
|
||||||
Action: rename the draft before `mv`, or revise the existing baseline.
|
|
||||||
|
|
||||||
Drafted: /Users/…/skills/cc-architect-catalog/.drafts/hooks-pattern.md
|
|
||||||
Word count: 287
|
|
||||||
Frontmatter: 9 fields, review_status=pending, ngram_overlap_score=null
|
|
||||||
Collision: approved
|
|
||||||
Next: ip-hygiene-checker for IP scoring
|
|
||||||
```
|
|
||||||
|
|
||||||
The warning is prepended. The draft is still written — the collision
|
|
||||||
check is a hint, not a block. `Collision: approved` appears in the
|
|
||||||
confirmation for downstream-log parsers.
|
|
||||||
|
|
||||||
## Scenario C — soft collision (pending existing)
|
|
||||||
|
|
||||||
### Synthetic input
|
|
||||||
|
|
||||||
- **Catalog state:** `subagents-pattern.md` exists with
|
|
||||||
`review_status: pending` (a prior draft that was `mv`-ed up without
|
|
||||||
the status being flipped, or a skill-factory auto-merged entry).
|
|
||||||
|
|
||||||
### Expected confirmation output
|
|
||||||
|
|
||||||
```
|
|
||||||
⚠️ Slug collision at catalog root
|
|
||||||
Existing: skills/cc-architect-catalog/subagents-pattern.md (review_status=pending)
|
|
||||||
Draft: skills/cc-architect-catalog/.drafts/subagents-pattern.md (this run)
|
|
||||||
Risk: manual `mv` during promotion will silently overwrite the existing file.
|
|
||||||
Suggested qualified slug: subagents-delegation-pattern.md
|
|
||||||
Reason for qualifier: concept handle centers on "delegation chains".
|
|
||||||
Action: rename the draft before `mv`, or revise the existing baseline.
|
|
||||||
|
|
||||||
Drafted: /Users/…/skills/cc-architect-catalog/.drafts/subagents-pattern.md
|
|
||||||
Word count: 256
|
|
||||||
Frontmatter: 9 fields, review_status=pending, ngram_overlap_score=null
|
|
||||||
Collision: pending
|
|
||||||
Next: ip-hygiene-checker for IP scoring
|
|
||||||
```
|
|
||||||
|
|
||||||
`Collision: pending` signals a soft collision — the existing file is
|
|
||||||
not necessarily a guaranteed baseline. Reviewer decides.
|
|
||||||
|
|
||||||
## Scenario D — collision but no good qualifier
|
|
||||||
|
|
||||||
### Synthetic input
|
|
||||||
|
|
||||||
- **Concept handle:** `generic feature note` (no specific noun)
|
|
||||||
- **Catalog state:** `skills-reference.md` exists (approved).
|
|
||||||
|
|
||||||
### Expected confirmation output
|
|
||||||
|
|
||||||
```
|
|
||||||
⚠️ Slug collision at catalog root
|
|
||||||
Existing: skills/cc-architect-catalog/skills-reference.md (review_status=approved)
|
|
||||||
Draft: skills/cc-architect-catalog/.drafts/skills-reference.md (this run)
|
|
||||||
Risk: manual `mv` during promotion will silently overwrite the existing file.
|
|
||||||
Suggested qualified slug: none — reviewer must pick one manually.
|
|
||||||
Action: rename the draft before `mv`, or revise the existing baseline.
|
|
||||||
|
|
||||||
Drafted: /Users/…/skills/cc-architect-catalog/.drafts/skills-reference.md
|
|
||||||
Word count: 198
|
|
||||||
Frontmatter: 9 fields, review_status=pending, ngram_overlap_score=null
|
|
||||||
Collision: approved
|
|
||||||
Next: ip-hygiene-checker for IP scoring
|
|
||||||
```
|
|
||||||
|
|
||||||
The fallback line replaces the "Suggested qualified slug" value.
|
|
||||||
`Reason for qualifier` is omitted.
|
|
||||||
|
|
||||||
## How to verify against this fixture
|
|
||||||
|
|
||||||
This is not an auto-run test. To verify:
|
|
||||||
|
|
||||||
1. Stage a synthetic concept JSON matching one of the scenarios above.
|
|
||||||
2. Invoke `skill-drafter` via the `Agent` tool with the concept JSON,
|
|
||||||
source path, and catalog root.
|
|
||||||
3. Capture the confirmation output.
|
|
||||||
4. Compare structurally against the corresponding scenario. The exact
|
|
||||||
word counts and paths will differ; the warning block, collision
|
|
||||||
field, and suggested-slug line are the load-bearing shapes.
|
|
||||||
|
|
||||||
If a future change alters the confirmation format, update this file
|
|
||||||
alongside the agent prompt so the two remain in lockstep.
|
|
||||||
|
|
||||||
## Why a reference fixture and not a unit test
|
|
||||||
|
|
||||||
`skill-drafter` is a prompt-driven Sonnet agent. There is no in-repo
|
|
||||||
harness that executes prompts deterministically, so a unit test is
|
|
||||||
not practical. The reference fixture is the next-best anchor — it
|
|
||||||
documents the expected shape for human verification and for
|
|
||||||
downstream agents that parse the confirmation (e.g., the
|
|
||||||
skill-author-orchestrator's summary phase).
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# Skill-factory calibration fixtures
|
|
||||||
|
|
||||||
These fixtures calibrate the IP-hygiene thresholds used by `scripts/ngram-overlap.mjs`. Each
|
|
||||||
pair (`source-*`, `draft-*`) is hand-tuned so that the n-gram containment verdict lands in a
|
|
||||||
specific band, anchoring the empirical thresholds against representative prose.
|
|
||||||
|
|
||||||
## Pairs
|
|
||||||
|
|
||||||
| Pair | Target verdict | Containment | Longest run | Notes |
|
|
||||||
|------|----------------|-------------|-------------|-------|
|
|
||||||
| `source-accepted.md` ↔ `draft-accepted.md` | **accepted** | 0.014 | 3 | Heavy paraphrase; concept-equivalent without phrase reuse |
|
|
||||||
| `source-needs-review.md` ↔ `draft-needs-review.md` | **needs-review** | 0.211 | 12 | Mixed: paraphrased frame, retained domain phrasing |
|
|
||||||
| `source-rejected.md` ↔ `draft-rejected.md` | **rejected** | 0.676 | 74 | Light edit on top of source; verbatim runs survive |
|
|
||||||
|
|
||||||
## Verdict bands
|
|
||||||
|
|
||||||
The verdict bands match the constants in `scripts/ngram-overlap.mjs`:
|
|
||||||
|
|
||||||
- **accepted** — containment < 0.15 AND longestRun < 8
|
|
||||||
- **needs-review** — between accepted and rejected
|
|
||||||
- **rejected** — containment ≥ 0.35 OR longestRun ≥ 15
|
|
||||||
|
|
||||||
If you change the thresholds in `ngram-overlap.mjs`, re-verify each fixture pair to confirm
|
|
||||||
the calibration still holds. The fixtures are content-stable; the thresholds are the variable.
|
|
||||||
|
|
||||||
## Why these topics
|
|
||||||
|
|
||||||
The fixtures use Claude Code reference prose (session-start hooks, subagent delegation, output
|
|
||||||
styles) so they live near the kind of source material the skill-factory will actually paraphrase
|
|
||||||
in production. Drift between fixture domain and production domain would weaken the calibration
|
|
||||||
signal.
|
|
||||||
|
|
||||||
## Regeneration
|
|
||||||
|
|
||||||
These files are committed to the repo as ground-truth fixtures. Do not regenerate them ad-hoc —
|
|
||||||
edit deliberately, re-run the verification commands listed in `plan.md` Step 5, and commit
|
|
||||||
intentionally.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
node scripts/ngram-overlap.mjs tests/fixtures/skill-factory/draft-accepted.md \
|
|
||||||
tests/fixtures/skill-factory/source-accepted.md
|
|
||||||
```
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
---
|
|
||||||
name: session-startup-hook-pattern
|
|
||||||
description: Pattern for warming up agent context at conversation boot
|
|
||||||
layer: pattern
|
|
||||||
cc_feature: hooks
|
|
||||||
source: ./source-accepted.md
|
|
||||||
concept: warm-start briefing via boot hook
|
|
||||||
last_verified: 2026-04-18
|
|
||||||
ngram_overlap_score: null
|
|
||||||
review_status: pending
|
|
||||||
---
|
|
||||||
|
|
||||||
## Use this when
|
|
||||||
|
|
||||||
You want each new conversation to begin with the agent already aware of project status — pending tasks, recent commits, key file paths — instead of burning early turns on orientation.
|
|
||||||
|
|
||||||
## Shape
|
|
||||||
|
|
||||||
Bind one script to the boot lifecycle event. Inside, gather whatever situational data justifies opening a fresh chat with: git log summary, todo file digest, branch identity, env snapshot. Format as terse markdown headings. Emit on stdout. The runtime grafts whatever you print into the model's opening context window.
|
|
||||||
|
|
||||||
## Forces
|
|
||||||
|
|
||||||
Cold turns cost real seconds. Anything you compute inside this script delays the first user prompt visibly. Therefore: prefer cached lookups, avoid synchronous calls to remote services, and timebox expensive operations. If a piece of data takes longer than roughly 200 ms to fetch, demote it from the briefing or front-load a cache refresh asynchronously elsewhere.
|
|
||||||
|
|
||||||
Multiple installation layers can each register their own boot script. They run in this order: marketplace-supplied first, your personal home-level second, and project-rooted third. Outputs concatenate without merging. Two scripts both reporting the branch name will both show up. There is no built-in dedupe.
|
|
||||||
|
|
||||||
Crash semantics are partial-write friendly: anything you streamed to stdout before exiting non-zero still reaches the agent. The fix is to assemble the full briefing in a buffer and only flush on the success path. That way a midpoint failure leaves an empty intro rather than a torn one.
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- No native simulator. Test by piping a hand-crafted payload directly into the script and reading the stdout it returns. Keep one canonical payload checked in.
|
|
||||||
- No selective firing — boot scripts cannot be scoped to subdirectories or file patterns. Workaround: branch inside the script body and short-circuit early when the heuristic does not match.
|
|
||||||
- Privileges are unfiltered: these scripts run with full operator credentials before any agent sandbox spins up. Audit third-party scripts before enabling them, and pin their versions to defeat silent updates.
|
|
||||||
- Telemetry is your problem: the runtime does not emit structured execution logs. If you want metrics, append to a local jsonl yourself from inside the script.
|
|
||||||
|
|
||||||
## Anti-patterns
|
|
||||||
|
|
||||||
- Doing remote network calls on the hot path without caching.
|
|
||||||
- Skipping output buffering and streaming partial briefings.
|
|
||||||
- Allowing two layers to print conflicting information without coordinating.
|
|
||||||
- Trusting installed marketplace scripts implicitly.
|
|
||||||
|
|
||||||
## Decision quick-check
|
|
||||||
|
|
||||||
Pick this approach when:
|
|
||||||
|
|
||||||
- Pending state across sessions is non-trivial enough to merit the boot delay.
|
|
||||||
- You can keep the script under a 250 ms wall-clock budget.
|
|
||||||
- The information surfaced changes meaningfully between sessions.
|
|
||||||
|
|
||||||
Skip it when:
|
|
||||||
|
|
||||||
- Project state rarely shifts; static instructions in CLAUDE.md serve the same purpose at zero startup cost.
|
|
||||||
- The data you would print is sensitive and could leak into copies of the conversation transcript.
|
|
||||||
- You are still iterating on what should appear; build the briefing as a plain script the operator runs manually before nailing it down as a boot binding.
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
---
|
|
||||||
name: subagent-delegation-pattern
|
|
||||||
description: Pattern for spawning isolated worker contexts to handle bounded sub-tasks
|
|
||||||
layer: pattern
|
|
||||||
cc_feature: subagents
|
|
||||||
source: ./source-needs-review.md
|
|
||||||
concept: context-isolated worker delegation
|
|
||||||
last_verified: 2026-04-18
|
|
||||||
ngram_overlap_score: null
|
|
||||||
review_status: pending
|
|
||||||
---
|
|
||||||
|
|
||||||
## Use this when
|
|
||||||
|
|
||||||
A chunk of work is logically self-contained, would otherwise drown the main thread in noise, or could profitably run in parallel with other branches of investigation. Reach for delegation whenever the orchestrator's transcript would be polluted by intermediate steps that nobody upstream cares about.
|
|
||||||
|
|
||||||
## Shape
|
|
||||||
|
|
||||||
The orchestrator constructs a complete prompt at spawn time and hands it off to a worker. That worker operates in its own conversation, with its own context window, and answers with one structured response when finished. The parent treats that response as a tool result and proceeds. Whatever the worker reads, generates, or discards never appears in the orchestrator's transcript — only the final return value crosses the boundary. That bound is precious in long sessions where every token of orchestrator context counts.
|
|
||||||
|
|
||||||
For parallel decomposition, the parent kicks off several workers in a single turn and waits for them all to complete. The runtime executes them concurrently, so a research task that would otherwise be three sequential delegations finishes in roughly the time of the slowest single one. For workflows that legitimately decompose into independent investigations, the speedup is substantial.
|
|
||||||
|
|
||||||
## Forces
|
|
||||||
|
|
||||||
Each spawn carries a startup tax. The runtime loads a fresh system prompt and the relevant tool schemas — several thousand tokens before the worker has done anything useful. Spawning ten workers to do work that one careful Grep would have handled is wasteful. Heuristic: do not delegate anything you could finish in two or three direct tool calls in the main thread.
|
|
||||||
|
|
||||||
Tool scoping cuts both noise and overhead. A search worker has no need for write or edit. A summarizer has no business running shell commands. Tightening the toolset reduces the chance of off-task behavior and shrinks the system prompt overhead. The default open-tool-set is appropriate only for general-purpose subagents that genuinely need flexibility.
|
|
||||||
|
|
||||||
Briefing is the second discipline. The worker has no view into the parent's broader conversation. Anything implicit upstream — user intent, file paths already in play, active constraints — has to be restated explicitly inside the spawn payload. Skip that step and the worker drifts into plausible-looking tangents that have nothing to do with what the parent was actually trying to accomplish.
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- Trust failure is the largest pitfall. The parent only sees the worker's final structured response. If the worker hallucinates that it wrote a file, the orchestrator has no easy way to verify. Best practice: independently confirm every claim that matters — read the file, check the test result, inspect the diff.
|
|
||||||
- Failure handling is on you. The runtime does not auto-retry. When a worker crashes, decide deliberately whether to retry, fall back to in-line execution, or surface the failure to the user. Cap retries at two or three to prevent loops, and log enough to iterate on the prompt later.
|
|
||||||
- Cost compounds quickly. Workers bill against the same account as the orchestrator. A workflow that spawns five workers per orchestrator turn can multiply token spend by an order of magnitude. Watch the burn rate and treat hitting cost ceilings as a signal that something is over-delegated.
|
|
||||||
- Deep hierarchies seldom pay off. Workers can spawn further workers, producing a tree, but in practice the overhead compounds at every layer and trust verification becomes intractable. One orchestrator, one layer of workers — that is the default.
|
|
||||||
|
|
||||||
## Anti-patterns
|
|
||||||
|
|
||||||
- Delegating work that two or three direct tool calls would have covered.
|
|
||||||
- Granting the open default toolset when a narrow scope would suffice.
|
|
||||||
- Trusting a worker's self-report without separate verification.
|
|
||||||
- Building deep hierarchies where every additional layer compounds overhead and weakens the trust chain.
|
|
||||||
|
|
||||||
## Decision quick-check
|
|
||||||
|
|
||||||
Pick this approach when:
|
|
||||||
|
|
||||||
- The sub-task is bounded and produces an output you can structure ahead of time.
|
|
||||||
- You can brief it adequately in a single spawn prompt without dragging in the whole transcript.
|
|
||||||
- The context savings or parallelism gain pay back the spawn tax.
|
|
||||||
|
|
||||||
Skip it when:
|
|
||||||
|
|
||||||
- The work fits in two or three direct tool calls from the main thread.
|
|
||||||
- The brief required would essentially recapitulate the orchestrator's whole conversation anyway.
|
|
||||||
- The result is hard for you to verify and the cost of a fabricated success would be material.
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
---
|
|
||||||
name: output-styles-pattern
|
|
||||||
description: Pattern for reshaping how the agent presents responses
|
|
||||||
layer: pattern
|
|
||||||
cc_feature: output-styles
|
|
||||||
source: ./source-rejected.md
|
|
||||||
concept: presentation-only voice and format directives
|
|
||||||
last_verified: 2026-04-18
|
|
||||||
ngram_overlap_score: null
|
|
||||||
review_status: pending
|
|
||||||
---
|
|
||||||
|
|
||||||
## Use this when
|
|
||||||
|
|
||||||
You want to change the voice, format, or rendering of agent output without changing what the agent actually does. Output styles let operators reshape how Claude Code presents its responses without changing the underlying behavior of the agent. They live as small markdown files in a known directory and bind by name. When a style is active, the runtime injects its directives into the system prompt area before the agent generates each turn.
|
|
||||||
|
|
||||||
## Shape
|
|
||||||
|
|
||||||
A style file is a short markdown document. A handful of bullets describing the desired tone, target reading level, and any structural conventions like always using level-three headings or always wrapping commands in fenced code blocks.
|
|
||||||
|
|
||||||
The runtime does not enforce any of these directives mechanically. It is the agent itself that reads the style file at turn time and chooses to comply. This means style enforcement is best-effort and degrades when the agent's primary task pulls strongly in a different direction.
|
|
||||||
|
|
||||||
## Forces
|
|
||||||
|
|
||||||
Layering matters. Styles can be defined at the user level, the project level, or supplied by an installed plugin. When more than one style is active simultaneously, the runtime concatenates them in a documented order. There is no merging or conflict resolution. If two styles disagree about whether to use markdown tables, both directives are presented to the agent, which then has to pick one. Practitioners learn to keep styles narrow and orthogonal so that conflicts are rare.
|
|
||||||
|
|
||||||
Performance is rarely an issue with styles. They add a small fixed cost to each turn for prompt assembly and that is essentially all. Unlike session-start hooks, they do not block first-turn rendering. Unlike subagent spawns, they do not introduce additional billable workers. The cost is purely the marginal tokens of the style body itself, multiplied by the number of turns in the session.
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- A pitfall worth flagging is the temptation to encode behavior in styles when a hook or a skill would be more appropriate. Styles change presentation, not capability. If you find yourself writing imperative instructions like "always run the linter before reporting success," that belongs in a hook, not a style.
|
|
||||||
- Testing styles is awkward because their effect is on free-form output. The standard approach is to keep a small set of canonical prompts and run them once with the style and once without, then eyeball the diff.
|
|
||||||
- Security boundaries are minimal because styles only inject text into the prompt area. They cannot run code, cannot read files, and cannot make network calls. The risk surface is therefore mostly social.
|
|
||||||
- Observability is essentially DIY. The runtime does not log which style was active for which turn or whether the agent obeyed the style's directives.
|
|
||||||
|
|
||||||
## Anti-patterns
|
|
||||||
|
|
||||||
- Encoding procedural behavior in a style instead of a hook.
|
|
||||||
- Stacking many overlapping styles whose directives conflict.
|
|
||||||
- Trusting a third-party plugin's style without reading its body.
|
|
||||||
- Treating style enforcement as a hard guarantee rather than best-effort guidance.
|
|
||||||
|
|
||||||
## Decision quick-check
|
|
||||||
|
|
||||||
Pick this approach when:
|
|
||||||
|
|
||||||
- You have multiple distinct audiences and consistent voice matters across sessions.
|
|
||||||
- The directive is purely about format, voice, or rendering — not capability.
|
|
||||||
- You can keep the style narrow enough to compose with others without conflict.
|
|
||||||
|
|
||||||
Skip it when:
|
|
||||||
|
|
||||||
- The behavior you want is procedural and would belong in a hook or skill.
|
|
||||||
- The team has only one audience and the default voice is already adequate.
|
|
||||||
- You need hard enforcement guarantees rather than best-effort agent compliance.
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Session-Start Hooks Reference
|
|
||||||
|
|
||||||
Session-start hooks fire when a Claude Code conversation begins. Their job is to inject opening context into the agent's working memory before the user has typed anything. Practitioners reach for them when a project carries cross-cutting state that must be surfaced on every session entry: open todo items, recent commit history, current branch, the location of relevant config files, and so on.
|
|
||||||
|
|
||||||
The runtime invokes these hooks once per session. Each hook receives a JSON payload describing the session id, the working directory at startup, the launch flags, and a few environment hints. Output written to stdout is appended verbatim into the system prompt area before the agent reads its first user message. A non-zero exit code blocks the session from progressing. Implementations should treat that path with care — a misbehaving session-start hook can soft-brick the project for the operator until they remember to disable the binding.
|
|
||||||
|
|
||||||
A typical pattern is the briefing script. The hook reads a TODO file, summarizes recent activity in git, and emits a short markdown block with three or four headings. The agent then begins its first turn already aware of where the user left off. This collapses the warm-up phase that would otherwise consume several tool calls every time someone opens the project.
|
|
||||||
|
|
||||||
Performance discipline matters. Session-start hooks add latency to every cold start. Operators have reported sessions that take eight or ten seconds just to render the first prompt because a chain of synchronous network calls runs at session start. Cache where possible. Keep the hot path local. If you genuinely need a remote lookup, make it asynchronous and wrap the result so a slow upstream cannot stall the entire session.
|
|
||||||
|
|
||||||
Conflict handling shows up when multiple layers register a session-start hook. Plugin hooks land first, then user-level hooks, then project-level hooks. Each layer's stdout output is concatenated in that order. There is no merging or deduplication. A plugin and the user might both decide to print the current branch name, and the agent will see both. The runtime makes no attempt to resolve such collisions; the operator must coordinate.
|
|
||||||
|
|
||||||
Failure recovery deserves explicit thought. If a session-start hook crashes mid-way, partial stdout that was already emitted may still reach the agent. This can produce a confusing initial state where the briefing was truncated and the agent reasons over a half-written summary. Defensive implementations buffer their entire output and emit it as a single write at the very end, after all I/O has succeeded. That way a crash leaves a clean empty briefing rather than a partial one.
|
|
||||||
|
|
||||||
Testing these hooks is awkward because there is no native simulation harness. The standard workaround is to invoke the hook script directly with a synthesized JSON payload on stdin, then inspect the resulting stdout. Operators with tight feedback loops keep a small fixture file containing the canonical payload and run the hook through it after every change. This catches the most common failure modes — JSON parse errors, missing keys, broken pipes — without needing to spin up a real session.
|
|
||||||
|
|
||||||
Security boundaries deserve a second look. Session-start hooks run with the operator's full filesystem privileges, before any sandbox is established for the agent itself. A compromised hook can read any path the operator can read. Plugin marketplaces distribute hooks as plain shell or node scripts, often without strong signing. The mitigation is review discipline: read the hook source before installing a plugin, and pin plugin versions so an upstream rug-pull does not silently swap the script.
|
|
||||||
|
|
||||||
Observability is mostly DIY. The runtime does not log hook execution to any structured channel. If you want telemetry — how often each hook ran, how long it took, whether it succeeded — you must wire it yourself, typically by appending to a local jsonl file from inside the hook script. A few teams have built lightweight aggregators that scrape these jsonl files into a dashboard, but no shared community tool exists for this yet.
|
|
||||||
|
|
||||||
The flag landscape is small. There is no built-in flag to skip session-start hooks for a particular run. Operators sometimes work around this by toggling a sentinel environment variable that their own hook checks at the top, exiting fast when present. This is purely a convention; the runtime will not interpret it.
|
|
||||||
|
|
||||||
Looking ahead, the most-requested feature on community boards is selective firing — the ability to bind a session-start hook only when the session opens in a particular subdirectory, or only when a particular file pattern matches. The current matcher syntax is too coarse for this, and operators end up writing internal switch logic inside the hook to bail out early when the heuristic does not apply. A future runtime release may address this, but as of the current shipping version it remains an open gap that operators must paper over themselves.
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Subagent Delegation Reference
|
|
||||||
|
|
||||||
Subagents are isolated worker contexts that the primary agent can spawn to handle bounded sub-tasks. Each subagent runs in its own conversation, with its own context window, and returns a single structured response when finished. The orchestrating agent treats this response as a tool result and continues from there. The pattern shines when a piece of work is independent enough that running it in the main thread would either pollute the context or block other concurrent work.
|
|
||||||
|
|
||||||
The headline benefit is context isolation. The primary thread can stay focused on the user's intent while a subagent burns its own context on noisy intermediate steps — searching the codebase, reading large files, summarizing transcripts. Whatever the subagent reads or generates does not appear in the orchestrator's transcript. Only the final return value crosses the boundary. This bound is precious in long sessions where every token of orchestrator context counts.
|
|
||||||
|
|
||||||
The second benefit is parallelism. The orchestrator can launch several subagents in a single turn and wait for them all to finish. The runtime executes them concurrently. A research task that would have taken three sequential subagent calls finishes in roughly the time of the slowest single call. For workflows that legitimately decompose into independent investigations, the speedup is substantial.
|
|
||||||
|
|
||||||
There are real costs. Each subagent loads a fresh system prompt and any allow-listed tool schemas. That startup cost is several thousand tokens per subagent. Spawning ten subagents to do work that one careful Grep would have handled is wasteful. The break-even threshold depends on subagent complexity and on how much orchestrator context you save by not inlining the work, but the heuristic is: do not spawn a subagent for anything you could complete in two or three direct tool calls in the main thread.
|
|
||||||
|
|
||||||
The biggest pitfall is trust failure. The orchestrator only sees the subagent's final structured response. If the subagent hallucinates that it wrote a file, the orchestrator has no easy way to verify. Best practice is to have the orchestrator independently confirm every claim that matters: read the file, check the test result, inspect the diff. Treat the subagent's self-report as input to verification, not as ground truth.
|
|
||||||
|
|
||||||
Subagent prompts are the second pitfall. The subagent does not see the orchestrator's full conversation; it only receives the prompt the orchestrator constructs at spawn time. Anything the orchestrator implicitly knew about the user's intent, the file paths discussed, or the constraints in play must be re-stated in the spawn prompt. Otherwise the subagent will go off on tangents that look plausible in isolation but miss the point of the parent task. Briefing matters.
|
|
||||||
|
|
||||||
Tool scoping is the third dimension. The orchestrator can restrict the tool set the subagent receives. A code-search subagent does not need Write or Edit. A summarizer subagent does not need Bash. Tighter scopes reduce both the chance of off-task behavior and the system prompt overhead. Most workflows benefit from this discipline. The default open-tool-set is appropriate only for general-purpose subagents that genuinely need flexibility.
|
|
||||||
|
|
||||||
Failure modes deserve explicit thought. If a subagent crashes or returns an error, the orchestrator receives that as a tool error and must decide whether to retry, fall back to in-line execution, or propagate the failure to the user. The runtime does not auto-retry. Build the retry policy into the orchestrator's logic. Limit retries to two or three to prevent loops. Log the failure mode so the operator can iterate on the prompt.
|
|
||||||
|
|
||||||
Cost accounting matters. Subagents bill against the same account as the orchestrator. A workflow that spawns five subagents per orchestrator turn can multiply token spend by an order of magnitude. Watch the burn rate. If your workflow is hitting cost ceilings, the first place to look is whether subagents are being used for problems that did not warrant the overhead.
|
|
||||||
|
|
||||||
Composability deserves a final note. Subagents can themselves spawn further subagents, producing a tree. In practice this rarely pays off; the overhead compounds at every layer and trust verification becomes intractable. Keep the tree shallow — one orchestrator, one layer of workers — unless the problem genuinely requires deeper hierarchy.
|
|
||||||
|
|
||||||
Looking forward, community discussions show steady demand for richer return-value schemas, persistent subagent state across calls, and cleaner cancellation semantics. None of these are shipping today. Operators must work within the constraints of single-shot stateless workers with the result schema they define themselves at spawn time.
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
# Output Styles Reference
|
|
||||||
|
|
||||||
Output styles let operators reshape how Claude Code presents its responses without changing the underlying behavior of the agent. They live as small markdown files in a known directory and bind by name. When a style is active, the runtime injects its directives into the system prompt area before the agent generates each turn. The agent treats those directives as binding instructions about format, voice, and rendering, and adapts its output accordingly.
|
|
||||||
|
|
||||||
The simplest style files are short. A handful of bullets describing the desired tone, target reading level, and any structural conventions like always using level-three headings or always wrapping commands in fenced code blocks. The runtime does not enforce any of these directives mechanically. It is the agent itself that reads the style file at turn time and chooses to comply. This means style enforcement is best-effort and degrades when the agent's primary task pulls strongly in a different direction.
|
|
||||||
|
|
||||||
A common pattern is the audience-specific style. A team might keep one style tuned for non-technical stakeholders, with longer prose, fewer code blocks, and a polite explanatory tone, alongside another style tuned for engineers, with terse responses, dense code, and minimal hedging. Operators switch styles per session depending on who is asking. The style file itself stays in version control so the conventions are reviewable and shareable.
|
|
||||||
|
|
||||||
Layering matters. Styles can be defined at the user level, the project level, or supplied by an installed plugin. When more than one style is active simultaneously, the runtime concatenates them in a documented order. There is no merging or conflict resolution. If two styles disagree about whether to use markdown tables, both directives are presented to the agent, which then has to pick one. Practitioners learn to keep styles narrow and orthogonal so that conflicts are rare.
|
|
||||||
|
|
||||||
A pitfall worth flagging is the temptation to encode behavior in styles when a hook or a skill would be more appropriate. Styles change presentation, not capability. If you find yourself writing imperative instructions like "always run the linter before reporting success," that belongs in a hook, not a style. Styles whose body looks like a procedure are usually mis-scoped and will not be followed reliably because the agent reads them as voice guidance rather than as obligations.
|
|
||||||
|
|
||||||
Performance is rarely an issue with styles. They add a small fixed cost to each turn for prompt assembly and that is essentially all. Unlike session-start hooks, they do not block first-turn rendering. Unlike subagent spawns, they do not introduce additional billable workers. The cost is purely the marginal tokens of the style body itself, multiplied by the number of turns in the session.
|
|
||||||
|
|
||||||
Testing styles is awkward because their effect is on free-form output. The standard approach is to keep a small set of canonical prompts and run them once with the style and once without, then eyeball the diff. Some teams have built lightweight golden-file harnesses for this, but no shared community tool exists. Most operators rely on quick manual checks during style development and trust the style to keep working in normal use.
|
|
||||||
|
|
||||||
Security boundaries are minimal because styles only inject text into the prompt area. They cannot run code, cannot read files, and cannot make network calls. The risk surface is therefore mostly social: a malicious style could try to coax the agent into ignoring safety instructions or revealing prompt-internal information. The mitigation is review discipline. Read the style body before installing a third-party plugin that ships one, the same way you would read any prompt-injecting artifact.
|
|
||||||
|
|
||||||
Observability is essentially DIY. The runtime does not log which style was active for which turn or whether the agent obeyed the style's directives. If you want to track style adherence, you will need to build it yourself, typically by sampling sessions and comparing the output to the style spec. A few teams have wired this into their prompt evaluation suites.
|
|
||||||
|
|
||||||
The flag landscape is mostly per-session. There is no global way to disable styles for a particular run, but operators can switch to a no-op style or remove the binding before launching. Some setups bind styles to environment variables so that a single export controls which voice the session uses, but this is a convention, not a runtime feature.
|
|
||||||
|
|
||||||
Looking ahead, the most-requested feature is conditional style activation: the ability to bind a style only when certain conditions are met, like when the working directory matches a pattern or when a specific user is operating the session. Currently this kind of selectivity has to be handled by manually swapping styles between sessions, which is friction operators would gladly trade for declarative bindings. A future runtime release may address this.
|
|
||||||
|
|
||||||
The takeaway is that styles are a low-risk, low-cost lever for tuning how the agent talks, and they pay off most when teams have multiple distinct audiences or when consistent voice across sessions matters for the brand or the team's external communication. Used within those constraints, they earn their keep without surprising anyone.
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue