diff --git a/skills/compose-solution/SKILL.md b/skills/compose-solution/SKILL.md new file mode 100644 index 0000000..2595e0a --- /dev/null +++ b/skills/compose-solution/SKILL.md @@ -0,0 +1,121 @@ +--- +name: compose-solution +description: Meta-orchestrator — converts a free-text task description into the right artefact(s) (agent, skill, hook, rule, or block) by composing existing KeiSeiKit primitives. Pure-click decision chain except the single intake field. Enriches `_blocks/` over time via Phase 6 block-augmentation — the kit gets smarter with every invocation. +argument-hint: +--- + +# Compose-Solution — Meta-Orchestrator (index) + +You are converting an arbitrary user task ("I want to solve X") into the +right durable KeiSeiKit artefact — an agent manifest, a skill, a hook, a +rule, or a new behavioural block. You decompose, grep prior art, +gap-analyse, compose, and assemble. Every decision is a click; only the +intake description (and an optional free-text edit in Phase 6) is typed. + +This skill is the **meta-creator**: it does not itself write production +code. It routes to `new-agent` (agent branch), to `escalate-recurrence` +(hook/rule branch), or composes a new skill/block in-place. + +This `SKILL.md` is the INDEX. Each phase lives in its own file and is +executed in order. Never skip a phase. Never re-order phases. + +--- + +## Pipeline overview (7 phases + final report) + +| Phase | File | Purpose | Free-text? | AskUserQuestion | +|---|---|---|---|---| +| 1 | [phase-1-intake.md](phase-1-intake.md) | Intake + target-type click | 1 line (`DESC`) | 1× AskUserQuestion | +| 2 | [phase-2-decompose.md](phase-2-decompose.md) | Wave-based decomposition | no | 1× AskUserQuestion | +| 3 | [phase-3-prior-art.md](phase-3-prior-art.md) | Prior-art grep sweep | no | 0 | +| 4 | [phase-4-gap-analysis.md](phase-4-gap-analysis.md) | Gap analysis (multi-select) | no | 1× AskUserQuestion | +| 5 | [phase-5-architecture.md](phase-5-architecture.md) | Architecture (math-first) | no | 1× AskUserQuestion | +| 6 | [phase-6-block-augment.md](phase-6-block-augment.md) | Block augmentation | optional per-block | 1× AskUserQuestion per new block | +| 7 | [phase-7-assemble.md](phase-7-assemble.md) | Recipe assembly (branches on `T`) | no | 1× AskUserQuestion | + +Minimum AskUserQuestion count across a full session: **6** — one each in +Phases 1, 2, 4, 5, at least one in Phase 6 (if any gaps selected), and one +in Phase 7. This is the pure-click contract: only intake is free-text. + +--- + +## Variables the pipeline produces + +| Name | Set in | Meaning | +|---|---|---| +| `DESC` | Phase 1a | The user's one-paragraph task description | +| `T` | Phase 1b | Target artefact type — Agent / Skill / Hook / Rule / Block / Auto-detect | +| `COMPONENTS` | Phase 2 | 2-5 orthogonal components, each with 3-5 grep keywords | +| `CLASSIFICATION` | Phase 3 | Per-component: REUSE / ADAPT / CREATE / EXTERNAL + evidence grade | +| `GAPS` | Phase 4 | User-selected subset of components that need Phase-6 augmentation | +| `ARCHITECTURE` | Phase 5 | Math-first composition expression + block list + Constructor-Pattern check | +| `BLOCKS_WRITTEN` | Phase 6 | Names of newly persisted `_blocks/*.md` files (possibly empty) | +| `FINAL_NAME` | Phase 7 | Path of the assembled artefact (or handoff target) | + +--- + +## Final report (emit after Phase 7) + +``` +=== COMPOSE-SOLUTION REPORT === +Intake: ... +Target type: +Decomposition: +Prior-art: +Blocks written: (kit: ) +Assembled: "> +Next action: + +Future invocations benefit from the K new blocks — kit is now smarter by K blocks. +``` + +--- + +## Rules (apply throughout — enforced at every phase) + +- **Pure-click contract.** Only `DESC` (Phase 1a) and optional per-block + edits (Phase 6b "Edit") are typed. Every other decision is an + `AskUserQuestion` call. Count them in the final report. +- **NO DOWNGRADE.** Any phase that fails returns 2-3 constructive paths, + never "can't be done". +- **NO HALLUCINATION (RULE 0.4).** Every block / skill / agent / bridge + name referenced in the session MUST exist on disk. Phase 3 greps, Phase 5 + architecture listing, and Phase 7 handoffs all verify before citing. If + grep returns nothing — the component class is CREATE, report it, never + invent a phantom match. +- **Plan Mode First (RULE 0.5).** This skill IS the plan; each phase file + has its own verify-criterion. No Edit/Write before the corresponding + phase's confirm click. +- **Constructor Pattern (RULE ZERO).** Every new block is single-concern, + 20-40 LOC, hard-capped at 60 LOC → split. Every new skill phase is < 30 + LOC of imperative prose. This `SKILL.md` index file itself must stay + < 200 LOC; phase files each < 150 LOC. +- **Surgical Changes.** Compose-solution writes only to: + - `_blocks/.md` (Phase 6, user-approved) + - `skills//SKILL.md` (Phase 7c, user-approved) + - Hands off to `new-agent` (Phase 7b) or `escalate-recurrence` + (Phase 7d/e) — no direct writes to `_manifests/`, `~/.claude/rules/`, + or `~/.claude/hooks/`. +- **Kit-enrichment feedback loop.** Phase 6 is the virtuous cycle: every + missing block becomes a new permanent block, so the next invocation of + compose-solution (or `new-agent`) finds more prior art in Phase 3. + Report the before/after block count in every session that touched Phase + 6 — this makes the loop visible. + +--- + +## References + +- [phase-1-intake.md](phase-1-intake.md) · [phase-2-decompose.md](phase-2-decompose.md) · [phase-3-prior-art.md](phase-3-prior-art.md) · [phase-4-gap-analysis.md](phase-4-gap-analysis.md) · [phase-5-architecture.md](phase-5-architecture.md) · [phase-6-block-augment.md](phase-6-block-augment.md) · [phase-7-assemble.md](phase-7-assemble.md) +- `skills/research/SKILL.md` — Variant C "Deep decomposition" wave pattern + (Phase 2 delegation target for heavy tasks) +- `skills/new-agent/SKILL.md` — 8-phase wizard (Phase 7b handoff target) +- `~/.claude/skills/escalate-recurrence/SKILL.md` — hook + rule + wiki + pipeline (Phase 7d/e handoff target) +- `~/.claude/skills/architecture/SKILL.md` — optional, for heavy + architectural decomposition if `research` is overkill +- `_blocks/baseline.md`, `_blocks/rule-math-first.md` — block templates + (Phase 6a shape references) +- `_manifests/kei-*.toml` — 14 kit agents (Phase 7b handoff references) +- `_bridges/*.tmpl` — 11 tool bridges (architecture Phase 5 may reference + them for agent-creation flows) diff --git a/skills/compose-solution/phase-1-intake.md b/skills/compose-solution/phase-1-intake.md new file mode 100644 index 0000000..1ccc257 --- /dev/null +++ b/skills/compose-solution/phase-1-intake.md @@ -0,0 +1,46 @@ +# Phase 1 — Intake + +One free-text line + one click batch. This is the only typed input required +by the whole skill (Phase 6 may add optional per-block edit prose). + +## 1a — Ask for the task description + +Emit a regular message (NOT AskUserQuestion): + +> Describe the task in one paragraph: what do you want to solve, for which +> project or concern, and what's the expected surface (something that runs, +> something that blocks a mistake, something that documents a pattern)? +> Reply in one message. + +Store the user's reply verbatim as `DESC`. + +## 1b — Target-type click (AskUserQuestion, ONE call) + +```json +{ + "questions": [ + { + "question": "Target artefact type?", + "header": "Type", + "multiSelect": false, + "options": [ + {"label": "Auto-detect", "description": "Orchestrator infers from intake — recommended when unsure"}, + {"label": "Agent (specialist)", "description": "New kit-agent manifest — specialist for a project or concern"}, + {"label": "Skill (user-invoked)", "description": "A /slash skill in ~/.claude/skills/ or KeiSeiKit/skills/"}, + {"label": "Hook (enforcement)", "description": "Shell hook registered in settings.json (block / enforce / warn / remind)"}, + {"label": "Rule (documentation)", "description": "Rule file in ~/.claude/rules/ with optional hook partner"}, + {"label": "Block (reusable)", "description": "Behavioural block in _blocks/ — composable via manifests"} + ] + } + ] +} +``` + +Store the choice as `T`. If `T == "Auto-detect"`, leave resolution until +Phase 7 (after architecture is known). + +## Verify-criterion + +- `DESC` is non-empty. +- `T` is exactly one of the six labels above. +- If either fails — re-ask the failing input; do not fall through. diff --git a/skills/compose-solution/phase-2-decompose.md b/skills/compose-solution/phase-2-decompose.md new file mode 100644 index 0000000..1ebecaf --- /dev/null +++ b/skills/compose-solution/phase-2-decompose.md @@ -0,0 +1,49 @@ +# Phase 2 — Wave-based decomposition + +Goal: break `DESC` into 2-5 orthogonal components that can each be +independently researched and composed. + +## 2a — Choose path (heavy vs lightweight) + +For heavy / patent-scale / unfamiliar-domain tasks, delegate to the +`research` skill (`skills/research/SKILL.md`, Variant C "Deep decomposition" +is the pattern — Wave 0 decomposition, then Wave 1 per-component +exploration). Invoke via the Agent tool with `subagent_type: kei-researcher` +(or `researcher` if that agent is present in the user's global fleet). Pass +`DESC` as the research question with the constraint: + +> Decompose into 2-5 orthogonal components, each with a 1-line description +> and 3-5 distinctive keywords suitable for grep prior-art search. + +For lighter tasks (single-feature, obvious stack), do **inline lightweight +decomposition**: emit 3-5 components as a plain markdown bullet list in +chat — one line each — with 3-5 grep keywords per component in parentheses. + +## 2b — Confirm decomposition (AskUserQuestion) + +```json +{ + "questions": [ + { + "question": "Decomposition OK?", + "header": "Decomposition", + "multiSelect": false, + "options": [ + {"label": "Confirm", "description": "Proceed to Phase 3 prior-art sweep with this decomposition"}, + {"label": "Merge / split", "description": "You want to merge two components or split one — reply with one free-text line"}, + {"label": "Add component", "description": "A necessary component is missing — reply with one free-text line"}, + {"label": "Abort", "description": "Stop — nothing gets written"} + ] + } + ] +} +``` + +On `Merge / split` or `Add component` → single free-text prompt, regenerate, +re-ask. Do NOT silently adjust. + +## Verify-criterion + +- User clicked `Confirm`. +- Each component has ≥ 3 grep keywords (for Phase 3 search). +- Components are orthogonal (no circular dependency between two components). diff --git a/skills/compose-solution/phase-3-prior-art.md b/skills/compose-solution/phase-3-prior-art.md new file mode 100644 index 0000000..c417d45 --- /dev/null +++ b/skills/compose-solution/phase-3-prior-art.md @@ -0,0 +1,52 @@ +# Phase 3 — Prior-art grep sweep (parallel) + +For EACH component from Phase 2, run three independent searches in parallel +(single message, multiple Bash tool calls). + +## 3a — KeiSeiKit reuse + +```bash +# Replace with the component's 3-5 distinctive keywords as an +# ERE alternation like (foo|bar|baz). +grep -rinlE '' _blocks/ _manifests/ skills/ _bridges/ hooks/ 2>/dev/null +``` + +## 3b — Personal bundle reuse (conditional, skip on missing) + +```bash +if [ -d ~/Projects/KeiSeiBundle ]; then + grep -rinlE '' ~/Projects/KeiSeiBundle/ 2>/dev/null | head -20 +else + echo "KeiSeiBundle: absent — skipping layer B" +fi +``` + +Document absence in the report — do NOT fabricate a hit. + +## 3c — External docs (delegate) + +For any component that involves an external API, framework, or third-party +library, delegate a tiny research task to a `kei-researcher` subagent: one +WebSearch call, one WebFetch of the top hit, one-paragraph summary. Skip if +the component is entirely internal. + +## 3d — Classify + evidence-grade + +For each component produce ONE row: + +``` +Component N: + Keywords: (foo|bar|baz) + 3a reuse: , or NONE + 3b reuse: (bundle) or ABSENT / NONE + 3c ext: or INTERNAL + Class: [REUSE | ADAPT | CREATE | EXTERNAL] + Evidence: [E1-E6] +``` + +## Verify-criterion + +- Every component has a classification. +- Every cited file path exists on disk (RULE 0.4 — no fabricated paths). +- If grep returns nothing, class is CREATE and the report says so — no + phantom matches. diff --git a/skills/compose-solution/phase-4-gap-analysis.md b/skills/compose-solution/phase-4-gap-analysis.md new file mode 100644 index 0000000..bf5ee03 --- /dev/null +++ b/skills/compose-solution/phase-4-gap-analysis.md @@ -0,0 +1,38 @@ +# Phase 4 — Gap analysis (AskUserQuestion multi-select) + +Present the classification matrix from Phase 3 as a code block (markdown +list) in chat, then emit: + +```json +{ + "questions": [ + { + "question": "Which gaps to close this session?", + "header": "Gaps", + "multiSelect": true, + "options": [ + {"label": "Component N — CREATE new block", "description": "No prior art found — draft a new _blocks/ entry in Phase 6"}, + {"label": "Component M — ADAPT existing block", "description": "Prior art found but needs edits — copy + modify in Phase 6"}, + {"label": "Component K — wire external API", "description": "External dep — reference api-*.md block or add a new one"}, + {"label": "Skip — components K, L reuse as-is", "description": "No action needed, they're already covered"} + ] + } + ] +} +``` + +Options are GENERATED dynamically — one per component from Phase 3 whose +class ∈ {ADAPT, CREATE, EXTERNAL}. User clicks zero or more. Empty +multi-select is valid: means "reuse only, skip Phase 6". + +Substitute the literal component descriptions in the option labels (not the +placeholders shown above — those are the shape). For example, if +Component 2 is "cost guard for fal.ai calls" and its class is CREATE, the +option label becomes `"Component 2: cost guard for fal.ai calls — CREATE new block"`. + +## Verify-criterion + +- Selected gap list stored as `GAPS` (a list of component-indices with + their chosen action: CREATE / ADAPT / EXTERNAL). +- Empty list is allowed and means Phase 6 is skipped entirely. +- No component has two contradicting actions (e.g. REUSE + CREATE). diff --git a/skills/compose-solution/phase-5-architecture.md b/skills/compose-solution/phase-5-architecture.md new file mode 100644 index 0000000..947cdac --- /dev/null +++ b/skills/compose-solution/phase-5-architecture.md @@ -0,0 +1,70 @@ +# Phase 5 — Architecture proposal (math-first) + +Compose the architecture by following `_blocks/rule-math-first.md`. + +## 5a — Expression first + +One to three lines describing which primitives combine, in which order, +with which invariants. Use this shape: + +``` +artefact = compose(block_A, block_B, ..., block_N) +where block_* ∈ {_blocks/, newly drafted, skills/, _manifests/} +invariant: +``` + +## 5b — What is UNNECESSARY? + +For each block listed, justify why it's in. If a block can be removed +without losing the user's goal — remove it. Derive-first: explicit claim +"this is the minimal decomposition, nothing removable". Follow the checklist +from `_blocks/rule-math-first.md`: + +- Learned parameters / free knobs? WHY? Determined by input? +- Separate blocks for similar concerns? WHY? Can a single block cover both? +- Gate / wrapper layers? WHY? Is a direct reference enough? + +## 5c — Constructor Pattern check + +Each output cube must be single-concern, file < 200 LOC, function < 30 LOC. +If the proposed assembly violates this, split before proceeding. + +## 5d — Count + +Show the numbers explicitly in the preview: +- New files: N +- Edits to existing files: M +- Total lines of markdown to be written: L + +## 5e — Preview + confirm + +Preview as plain text in chat, then: + +```json +{ + "questions": [ + { + "question": "Architecture OK?", + "header": "Architecture", + "multiSelect": false, + "options": [ + {"label": "Confirm", "description": "Proceed to Phase 6 block augmentation (if any gaps) then Phase 7 assembly"}, + {"label": "Revise component N", "description": "One component's decomposition or reuse choice is wrong — reply with one free-text line"}, + {"label": "Remove something", "description": "You see a block that's not strictly necessary — reply which one"}, + {"label": "Abort", "description": "Stop — nothing gets written"} + ] + } + ] +} +``` + +On `Revise` / `Remove` → ONE free-text prompt, regenerate the architecture, +re-preview. + +## Verify-criterion + +- User clicked Confirm. +- The expression (5a) is present and < 3 lines. +- The "what is unnecessary" pass (5b) has been applied and is visible in the + preview. +- Constructor Pattern check (5c) passed. diff --git a/skills/compose-solution/phase-6-block-augment.md b/skills/compose-solution/phase-6-block-augment.md new file mode 100644 index 0000000..e23f9a1 --- /dev/null +++ b/skills/compose-solution/phase-6-block-augment.md @@ -0,0 +1,94 @@ +# Phase 6 — Block augmentation (conditional) + +Only runs if `GAPS` from Phase 4 is non-empty. For EACH `CREATE` or `ADAPT` +entry in `GAPS`, run this sub-phase in sequence (NOT in parallel — user must +approve each before the next). + +## 6a — Draft the block + +Template (follow the shape of `_blocks/baseline.md` or +`_blocks/rule-math-first.md` — short, single-concern, imperative voice): + +```markdown +# + + + +## When to include + +<1-3 bullets describing which manifests should list this block in +their `blocks = [...]` array.> + +## What it declares + +<3-8 imperative bullets. Constructor Pattern: one concern only.> + +## References + +- +- +``` + +Target length: 20-40 LOC markdown. Hard ceiling: 60 LOC — above that, SPLIT +into two blocks before continuing. + +Slug: kebab-case, 2-4 words. Must not collide with existing `_blocks/*.md`. +Verify via: + +```bash +ls _blocks/.md 2>/dev/null && echo "COLLISION" || echo "free" +``` + +If collision: append a disambiguator (`-v2`, or a domain suffix like +`-patent`). + +## 6b — Preview + per-block click (AskUserQuestion) + +Emit the draft inline in chat, then: + +```json +{ + "questions": [ + { + "question": "Write this block?", + "header": "Block", + "multiSelect": false, + "options": [ + {"label": "Write to _blocks/.md", "description": "Save permanently — enriches the kit for all future sessions"}, + {"label": "Edit (free-text)", "description": "Reply with one free-text message describing changes; I regenerate"}, + {"label": "Skip this block", "description": "Don't save this one; proceed to next gap"}, + {"label": "Abort session", "description": "Stop the whole skill; nothing else gets written"} + ] + } + ] +} +``` + +Resolution: + +- **Write** → use Write tool to create `_blocks/.md` under the repo + root (`~/Projects/KeiSeiKit/_blocks/` when running against the kit repo; + or wherever `$PWD`'s `_blocks/` lives when invoked from another KeiSeiKit + fork). +- **Edit** → single free-text prompt, regenerate, re-preview. +- **Skip** → move to next gap. +- **Abort** → stop; no writes Phase 6 onward. + +## 6c — After all gaps processed + +Report the block-count delta: + +```bash +ls _blocks/ | wc -l +``` + +Show `before → after` count so the user sees the kit got N blocks smarter +this session. This is the feedback-loop signal — make it visible in every +session that touched Phase 6. + +## Verify-criterion + +Every block written passes two sanity checks: +- File exists on disk after Write. +- No `{{placeholder}}` literals remain (the assembler's `validator.rs` + rejects those; same hygiene applies here). diff --git a/skills/compose-solution/phase-7-assemble.md b/skills/compose-solution/phase-7-assemble.md new file mode 100644 index 0000000..d1b64c4 --- /dev/null +++ b/skills/compose-solution/phase-7-assemble.md @@ -0,0 +1,156 @@ +# Phase 7 — Recipe assembly (branches on `T`) + +Before branching, resolve auto-detect if `T == "Auto-detect"`. + +## 7a — Resolve auto-detect (conditional) + +Infer target type from architecture (Phase 5): + +- Expression mentions a project's CLAUDE.md + stack block + deploy block → + **Agent**. +- Expression is a 3-phase flow with AskUserQuestion calls → **Skill**. +- Expression is a trigger + enforcement pair, pattern-matched on tool input + → **Hook** (and, usually, companion **Rule**). +- Expression is documentation + wiki indexing, no automation → **Rule**. +- Expression is a single reusable 20-40 LOC markdown — already handled in + Phase 6 → **Block**. + +Present the inferred type: + +```json +{ + "questions": [ + { + "question": "Detected target: . Proceed?", + "header": "Auto-detect", + "multiSelect": false, + "options": [ + {"label": "Yes — proceed with ", "description": "Run the branch below"}, + {"label": "Change to Agent", "description": "Override the inference — go to 7b"}, + {"label": "Change to Skill", "description": "Override — go to 7c"}, + {"label": "Change to Hook", "description": "Override — go to 7d"}, + {"label": "Change to Rule", "description": "Override — go to 7e"}, + {"label": "Block only (no assembly)", "description": "Already handled in Phase 6 — skip to final report"} + ] + } + ] +} +``` + +Substitute `` with the literal inferred label. + +## 7b — Agent branch + +Hand off to the `new-agent` skill — it already codifies the 8-phase wizard +(`skills/new-agent/SKILL.md`). Two handoff methods: + +1. **Invoke via Agent tool** with `subagent_type: kei-code-implementer` (or + equivalent), prompt: "Run the `new-agent` skill wizard. Use these + already-decided fields from compose-solution: stack, deploy, paid-APIs, + ML, patent-IP, secrets, scrapers. Slug, description, path, gotchas are + derived from DESC. Blocks list preference (from Phase 5 architecture): + ." +2. **Instruct user** to run `/new-agent` in a fresh turn if Agent + delegation is unavailable; paste the Phase-5 architecture into that + session. + +Compose-solution steps back here — `new-agent` owns the rest. + +## 7c — Skill branch + +Compose a new `skills//SKILL.md` inline: + +```markdown +--- +name: +description: +argument-hint: "> +--- + +# + +<2-3 sentences: what the skill does, when to invoke, who owns the output.> + +## Phase 1 — Intake () + + + +## Phase 2 — + + + +## Phase 3 — Report + + + +## Rules + + +``` + +Minimum three phases (intake / action / report). AskUserQuestion pattern +follows `escalate-recurrence` (see +`~/.claude/skills/escalate-recurrence/SKILL.md` globally, or +`skills/new-agent/SKILL.md` Phase-1b style locally). + +Preview + final confirm: + +```json +{ + "questions": [ + { + "question": "Write this skill?", + "header": "Skill", + "multiSelect": false, + "options": [ + {"label": "Write to skills//SKILL.md", "description": "Save permanently; user can invoke as /"}, + {"label": "Edit (free-text)", "description": "Reply with one message describing changes"}, + {"label": "Abort", "description": "Stop — nothing gets written"} + ] + } + ] +} +``` + +On `Write` → `mkdir -p skills// && Write skills//SKILL.md`. + +## 7d — Hook branch + +Delegate to the `escalate-recurrence` skill +(`~/.claude/skills/escalate-recurrence/SKILL.md`). That skill already owns +hook scaffolding at 4 severities (block / enforce / warn / remind) + 5 +event types (PreToolUse:Bash, PreToolUse:Edit|Write, PostToolUse:*, +UserPromptSubmit, Stop) and registers via the `update-config` skill. + +Instruct the user: + +> Run `/escalate-recurrence` in a fresh turn. Use these already-decided +> fields from compose-solution: +> - Pattern name: `` +> - Two+ concrete trigger instances: +> - Suggested severity: — based on +> +> - Suggested event: + +Or invoke via Agent tool if delegation is permitted. + +Compose-solution steps back — `escalate-recurrence` owns writes. + +## 7e — Rule branch + +Same handoff as 7d — `escalate-recurrence` owns the rule + wiki pipeline +(it writes `~/.claude/rules/.md`, updates `RULES.md`, `MEMORY.md`, and +optionally `CLAUDE.md` Rules Index). Instruct the user to run +`/escalate-recurrence` with Phase-1 choice "No hook" if the user wants +documentation-only. + +## 7f — Block only + +Already handled in Phase 6. Skip to final report. + +## Verify-criterion + +- Exactly one branch ran (7b / 7c / 7d / 7e / 7f). +- The resulting artefact path is captured for the final report.