@rune-kit/rune 2.13.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +23 -12
  2. package/compiler/__tests__/adr-scoring.test.js +91 -0
  3. package/compiler/__tests__/context-md-format.test.js +180 -0
  4. package/compiler/__tests__/context-pack-smell-tests.test.js +215 -0
  5. package/compiler/__tests__/diversity-score.test.js +117 -0
  6. package/compiler/__tests__/improve-architecture.test.js +171 -0
  7. package/compiler/__tests__/openclaw-adapter.test.js +11 -6
  8. package/compiler/__tests__/out-of-scope-format.test.js +303 -0
  9. package/compiler/__tests__/zoom-out-output.test.js +112 -0
  10. package/package.json +2 -2
  11. package/skills/audit/SKILL.md +1 -0
  12. package/skills/ba/SKILL.md +241 -82
  13. package/skills/ba/references/context-md-format.md +136 -0
  14. package/skills/ba/references/explore-first.md +107 -0
  15. package/skills/ba/references/out-of-scope-format.md +152 -0
  16. package/skills/brainstorm/SKILL.md +77 -1
  17. package/skills/brainstorm/references/design-it-twice.md +155 -0
  18. package/skills/context-pack/SKILL.md +68 -25
  19. package/skills/context-pack/evals.md +122 -0
  20. package/skills/context-pack/references/brief-template.md +121 -0
  21. package/skills/context-pack/references/durability-rules.md +109 -0
  22. package/skills/cook/SKILL.md +4 -4
  23. package/skills/debug/SKILL.md +2 -1
  24. package/skills/fix/SKILL.md +2 -1
  25. package/skills/improve-architecture/SKILL.md +275 -0
  26. package/skills/improve-architecture/evals.md +145 -0
  27. package/skills/improve-architecture/references/deepening.md +87 -0
  28. package/skills/improve-architecture/references/interface-design.md +68 -0
  29. package/skills/improve-architecture/references/language.md +81 -0
  30. package/skills/improve-architecture/references/scoring.md +122 -0
  31. package/skills/journal/SKILL.md +33 -6
  32. package/skills/journal/references/adr-criteria.md +109 -0
  33. package/skills/review/SKILL.md +1 -0
  34. package/skills/review-intake/SKILL.md +25 -2
  35. package/skills/scout/SKILL.md +33 -1
  36. package/skills/surgeon/SKILL.md +16 -1
  37. package/skills/test/SKILL.md +48 -1
  38. package/skills/test/evals.md +137 -0
  39. package/skills/test/references/mocking-policy.md +121 -0
  40. package/skills/test/references/test-quality.md +124 -0
  41. package/skills/test/references/vertical-tdd.md +110 -0
@@ -0,0 +1,136 @@
1
+ # CONTEXT.md — Project Glossary Format
2
+
3
+ Persistent vocabulary for the project's domain — what nouns mean, how concepts relate, which words are aliases of which. Lives at the repo root (or per-bounded-context root in multi-context repos).
4
+
5
+ ## Where it lives
6
+
7
+ ```
8
+ <repo-root>/
9
+ ├── CONTEXT.md ← single-context repo
10
+ └── src/
11
+
12
+ # OR for multi-context repos:
13
+ <repo-root>/
14
+ ├── CONTEXT-MAP.md ← lists each context + relationships
15
+ └── src/
16
+ ├── ordering/CONTEXT.md
17
+ └── billing/CONTEXT.md
18
+ ```
19
+
20
+ If `CONTEXT-MAP.md` exists at root, the repo has multiple contexts; otherwise it's single-context.
21
+
22
+ ## Lazy creation
23
+
24
+ CONTEXT.md is created **only when there's a non-trivial term to record**. Empty file = bad signal. Absent file = silent OK.
25
+
26
+ `ba` checks via Glob; absence is **not** flagged as a project gap. Don't suggest "you should create one." Wait until a term needs sharpening.
27
+
28
+ ## Format
29
+
30
+ ```markdown
31
+ # Project Glossary
32
+
33
+ One-line description of what this project is and why this glossary exists.
34
+
35
+ ## Language
36
+
37
+ | Term | Definition | Aliases to avoid | Status |
38
+ |------|------------|-------------------|--------|
39
+ | **Order** | A customer's request to purchase items | Purchase, transaction | canonical |
40
+ | **Invoice** | A request for payment sent after delivery | Bill, payment request | canonical |
41
+ | **Customer** | A person or organization that places orders | Client, buyer, account | canonical |
42
+ | **User** | An authentication identity in the system | Login, account | canonical |
43
+
44
+ ## Relationships
45
+
46
+ - An **Order** produces one or more **Invoices**
47
+ - An **Invoice** belongs to exactly one **Customer**
48
+ - A **Customer** may or may not be a **User** (guests can place orders)
49
+
50
+ ## Example dialogue
51
+
52
+ > **Dev:** "When a **Customer** places an **Order**, do we create the **Invoice** immediately?"
53
+ > **Domain expert:** "No — an **Invoice** is generated once a **Fulfillment** is confirmed. A single **Order** can produce multiple **Invoices** if items ship in separate **Shipments**."
54
+
55
+ ## Flagged ambiguities
56
+
57
+ - "account" was used for both **Customer** and **User** — resolved: distinct concepts. **Customer** places orders; **User** is an authentication identity.
58
+ - "transaction" sometimes meant **Order** and sometimes **Payment** — resolved: avoid the word entirely.
59
+ ```
60
+
61
+ ## Term schema
62
+
63
+ Each row in the **Language** table:
64
+
65
+ | Column | Required | Description |
66
+ |--------|----------|-------------|
67
+ | Term | ✅ | Bold, kebab-case-friendly singular noun (or short phrase) |
68
+ | Definition | ✅ | One sentence. Defines what it IS, not what it does. |
69
+ | Aliases to avoid | optional | Other words the team has used; agents and humans must avoid them in code, comments, and conversation |
70
+ | Status | ✅ | `canonical` (settled) \| `pending` (waiting on domain-expert confirmation) \| `conflicted` (active disagreement, needs resolution) |
71
+
72
+ ## Update protocol
73
+
74
+ ### Inline sharpen (during a BA session)
75
+
76
+ When the user uses a term whose meaning is ambiguous, propose a precise canonical version. When confirmed, update CONTEXT.md right there. Don't batch.
77
+
78
+ > "You used 'account' twice — once meaning **Customer** (the person ordering), once meaning **User** (the login). I'll record these as distinct in CONTEXT.md."
79
+
80
+ ### Cross-reference (HARD-GATE)
81
+
82
+ When the user asserts behavior — "the system cancels Orders when X" — `ba` MUST grep the codebase to verify before recording in CONTEXT.md. If grep contradicts the user, surface the conflict and ask which is canonical.
83
+
84
+ > User: "Yes, partial cancellation is supported."
85
+ > Agent (after grepping `src/orders/cancel.ts`): "The code path I see only handles full cancellation (`cancel(orderId)` returns `Order` with status `cancelled`, no partial-quantity argument). Either the code is incomplete, or partial cancellation isn't implemented yet. Which is the canonical behavior?"
86
+
87
+ This gate stops AI agents from silently recording user-asserted behavior that contradicts the code — a frequent source of "the docs say X but the code does Y" drift.
88
+
89
+ ### Conflict gate
90
+
91
+ When a new term has ≥0.7 token overlap with an existing one, force a user choice:
92
+
93
+ | Choice | Action |
94
+ |--------|--------|
95
+ | Merge | Combine the new term's aliases into the existing entry |
96
+ | Rename | Pick a distinct slug for the new term |
97
+ | Keep distinct | Confirm the overlap is coincidental; record both |
98
+
99
+ Agents must NOT silently re-define existing terms.
100
+
101
+ ## Single vs multi-context
102
+
103
+ **Single context (most repos)**: one `CONTEXT.md` at the repo root.
104
+
105
+ **Multiple contexts**: a `CONTEXT-MAP.md` at the root lists where each context lives:
106
+
107
+ ```markdown
108
+ # Context Map
109
+
110
+ ## Contexts
111
+
112
+ - [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders
113
+ - [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments
114
+
115
+ ## Relationships
116
+
117
+ - **Ordering → Billing**: Ordering emits `OrderPlaced` events; Billing consumes them
118
+ - **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`
119
+ ```
120
+
121
+ `ba` infers structure:
122
+ - If `CONTEXT-MAP.md` exists → multi-context; read it to find the right CONTEXT.md
123
+ - If only root `CONTEXT.md` exists → single-context
124
+ - If neither exists → silent skip; create root CONTEXT.md lazily on first term resolution
125
+
126
+ ## What does NOT belong in CONTEXT.md
127
+
128
+ - Generic programming concepts (timeouts, error types, function signatures) — these aren't domain terms.
129
+ - Module / class names — they belong in code, not glossary, unless they have meaning to a domain expert.
130
+ - Implementation details — CONTEXT.md is the *what* (concept), not the *how* (data shape).
131
+
132
+ Before adding a term, ask: would a non-engineer domain expert recognize this and care? If no, don't add it.
133
+
134
+ ## Relationship to CLAUDE.md
135
+
136
+ CLAUDE.md describes *how to work in this repo* — conventions, danger zones, deploy commands. CONTEXT.md describes *what these words mean* — the domain glossary. The scopes are mutually exclusive; never duplicate.
@@ -0,0 +1,107 @@
1
+ # Explore-First Gate
2
+
3
+ The explore-first rule: **never ask the user a question whose answer is in the codebase, the user's message, or the project metadata.** Every question burns user attention; an inferable question burns it for nothing.
4
+
5
+ This is enforced as a HARD-GATE at Step 2.0 of `ba`, before any of the 5 elicitation questions are emitted.
6
+
7
+ ## The 4-item pre-check
8
+
9
+ For each question the agent intends to ask, walk through this checklist:
10
+
11
+ 1. **Is the answer in `package.json` / `pyproject.toml` / `Cargo.toml` / `go.mod` / `pom.xml`?**
12
+ - Stack, framework, language version, dependencies, scripts → all live here.
13
+ 2. **Is the answer in `README.md` or `CLAUDE.md` or `docs/`?**
14
+ - Project description, target audience, conventions, deploy process.
15
+ 3. **Is it inferable from file extensions, directory structure, or config files?**
16
+ - `.tsx` files → React frontend. `Dockerfile` → containerized deploy. `.github/workflows/*` → CI exists.
17
+ 4. **Has the user answered it earlier in this conversation?**
18
+ - Read back through the conversation; cached answers are reusable.
19
+
20
+ If ANY of the 4 checks would yield the answer, the question is inferable. **Don't ask it.** Read the source, infer, and proceed.
21
+
22
+ ## Tool-call evidence requirement (HARD-GATE)
23
+
24
+ For every question Q the agent emits, there MUST be prior tool-call evidence in the same session:
25
+
26
+ - At least 1 `Read`, `Glob`, or `Grep` related to Q's domain, OR
27
+ - An explicit declaration: *"Q cannot be answered from project artifacts because [specific reason]."*
28
+
29
+ Without one of these, Q is BLOCKED. The receiving validator (preflight, completion-gate) checks the tool-call log for evidence before allowing the question to count toward the 5-question budget.
30
+
31
+ This prevents lazy questioning. The gate is "tried to infer" — not "must succeed in inferring." If the file simply doesn't have the answer, that's fine; the attempt is the gate.
32
+
33
+ ## Worked examples
34
+
35
+ ### ❌ Wrong — skips inference
36
+
37
+ User: "I want to add a payment integration."
38
+
39
+ Agent: "What language and framework are you using?"
40
+
41
+ Failure: `package.json` (or equivalent) answers this. No grep needed.
42
+
43
+ ### ✅ Right — infers first
44
+
45
+ User: "I want to add a payment integration."
46
+
47
+ Agent: *(reads `package.json` — sees `"react": "^18"`, `"next": "^14"`)*
48
+ Agent: "I see you're on Next.js 14 with React 18. For the payment integration, are you targeting Stripe, PayPal, or something else?"
49
+
50
+ The first question is now non-trivial — it's the question only the user can answer.
51
+
52
+ ### ❌ Wrong — re-asks cached answer
53
+
54
+ Earlier in the session: User said "the deadline is end of Q2."
55
+
56
+ Agent (later): "What's the timeline for this?"
57
+
58
+ Failure: cached answer exists. Re-asking is redundant.
59
+
60
+ ### ✅ Right — uses cached answer
61
+
62
+ Agent: "Given the Q2 deadline you mentioned, [follow-up question that builds on it]."
63
+
64
+ ### ❌ Wrong — asks shape questions for inferable values
65
+
66
+ User: "Build me a CLI tool that..."
67
+
68
+ Agent: "Are you using TypeScript or JavaScript?"
69
+
70
+ Failure: check `tsconfig.json` and `package.json`'s `type: "module"`. Or check existing files' extensions.
71
+
72
+ ### ✅ Right — narrow to genuine unknowns
73
+
74
+ Agent: *(checks tsconfig + sample file)*
75
+ Agent: "I see you're on TypeScript with strict mode. For the CLI tool, are you targeting Node 20+ or do we need to support older runtimes?"
76
+
77
+ ## What questions ARE worth asking
78
+
79
+ Questions that survive the explore-first filter typically:
80
+
81
+ - **Reveal user intent** that's not in the code ("what's the success metric for this feature?")
82
+ - **Choose between credible alternatives** the code doesn't disambiguate ("auth: JWT vs session cookies?")
83
+ - **Set scope** that the user hasn't yet bounded ("should this also handle anonymous users?")
84
+ - **Capture domain expertise** the codebase doesn't encode ("when an Order is cancelled, do we refund automatically or wait for review?")
85
+
86
+ These are the high-leverage questions. Aim for 5 of them, not 5 of "what stack are you using?"
87
+
88
+ ## Caching results
89
+
90
+ When explore-first finds an inferable answer, record it in the requirements doc as a cached fact:
91
+
92
+ ```
93
+ **Inferred from package.json**: TypeScript 5.4, Next.js 14.2, React 18.3
94
+ **Inferred from .github/workflows/**: CI runs on PRs targeting main
95
+ **Inferred from CLAUDE.md**: Strict TypeScript, no `any`, semantic commits
96
+ ```
97
+
98
+ Future BA sessions reuse these without re-running grep.
99
+
100
+ ## When the rule relaxes
101
+
102
+ Two narrow exceptions:
103
+
104
+ 1. **Stack/conventions are not yet in the repo** (greenfield, brand-new project) — explore-first finds nothing, so questions are necessary. Note "no project metadata available" in the question rationale.
105
+ 2. **User explicitly asked a redundant question themselves** — sometimes the user wants confirmation. "Yes, you're on TypeScript — the `tsconfig.json` confirms it. Anything else to verify?"
106
+
107
+ Otherwise, the rule applies. Burn no user attention on questions agents can answer alone.
@@ -0,0 +1,152 @@
1
+ # `.out-of-scope/` Knowledge Base — Format & Matching
2
+
3
+ A persistent record of rejected feature requests so AI agents stop re-litigating the same decision across sessions. Project-scoped, version-controlled, durable.
4
+
5
+ ## Where it lives
6
+
7
+ ```
8
+ <repo-root>/
9
+ ├── .out-of-scope/
10
+ │ ├── dark-mode.md
11
+ │ ├── plugin-system.md
12
+ │ └── graphql-api.md
13
+ ```
14
+
15
+ One file per **concept**, not per issue. Multiple incoming requests for the same thing are appended to a single concept file's `prior_requests` list.
16
+
17
+ ## File format
18
+
19
+ YAML frontmatter (for machine parsing) + Markdown body (for humans).
20
+
21
+ ```markdown
22
+ ---
23
+ concept: dark-mode
24
+ aliases: [night-theme, dark-theme, theme-switcher]
25
+ decision: rejected
26
+ rejected_at: 2026-04-27
27
+ rejected_by: review-intake
28
+ priority_to_revisit: low # low | medium | high
29
+ prior_requests:
30
+ - id: gh-issue-42
31
+ summary: Add dark mode support
32
+ closed_at: 2025-08-01
33
+ - id: discord-thread-2026-02-14
34
+ summary: Night theme for accessibility
35
+ closed_at: 2026-02-15
36
+ conflicts_with: [] # paths to ADRs that this rejection contradicts
37
+ revisit_if:
38
+ - "team adds front-end engineer"
39
+ - "user count crosses 50k"
40
+ ---
41
+
42
+ # Dark Mode
43
+
44
+ This project does not support runtime dark mode.
45
+
46
+ ## Why out of scope
47
+
48
+ [Substantive reasoning — references project scope, technical constraints, or strategic decisions. NOT temporary circumstances ("we're busy now" — that's a deferral, not a rejection).]
49
+
50
+ The rendering pipeline assumes a single color palette resolved at build time. Adding runtime theming would require:
51
+
52
+ - A theme context provider wrapping every render
53
+ - Per-component theme-aware style resolution
54
+ - A persistence layer for user theme preferences
55
+
56
+ This is a significant architectural change that conflicts with the project's focus on author-time content and downstream-consumer flexibility.
57
+
58
+ ## What would change our mind
59
+
60
+ - A user paying for theme switcher specifically (revenue signal)
61
+ - A team member with deep expertise on theme-aware CSS pipelines
62
+ - A platform requirement (e.g., partner integration mandates dark mode)
63
+ ```
64
+
65
+ ## Frontmatter fields
66
+
67
+ | Field | Type | Required | Description |
68
+ |-------|------|----------|-------------|
69
+ | `concept` | string | ✅ | kebab-case slug; matches filename without `.md` |
70
+ | `aliases` | string[] | ✅ | Other phrasings of the same concept; used by similarity matcher |
71
+ | `decision` | enum | ✅ | `rejected` (only — deferrals do not belong here) |
72
+ | `rejected_at` | ISO date | ✅ | When the decision was made |
73
+ | `rejected_by` | enum | ✅ | `ba` \| `review-intake` \| `incident` \| `cook` |
74
+ | `priority_to_revisit` | enum | optional | `low` \| `medium` \| `high`; default `low` |
75
+ | `prior_requests` | object[] | ✅ | At least one entry; appended on every re-request |
76
+ | `conflicts_with` | string[] | optional | Paths to ADRs this contradicts (rare, surface for review) |
77
+ | `revisit_if` | string[] | optional | Concrete signals that should trigger re-evaluation |
78
+
79
+ ## Slug rules
80
+
81
+ - kebab-case, lowercase
82
+ - max 40 chars
83
+ - recognizable without opening the file (`dark-mode` good; `feature-x-v2` bad)
84
+ - distinct from existing concepts — if a new slug has ≥0.7 alias overlap with an existing one, the writer MUST prompt: merge or pick distinct slug.
85
+
86
+ ## Concept-similarity matching
87
+
88
+ When `ba` Step 1.5 runs intake on a new request, it builds a hash-keyed map:
89
+
90
+ ```
91
+ Map<lowercased_token, [concept_slugs]>
92
+ ```
93
+
94
+ For each `.out-of-scope/*.md` file, it indexes:
95
+ - `concept` field tokens (split on `-`)
96
+ - `aliases` field tokens
97
+ - 1–3-word phrases from the body's title and first paragraph
98
+
99
+ For incoming request, it tokenizes the same way, computes overlap with each indexed concept, and returns:
100
+
101
+ | Confidence | Range | Action |
102
+ |------------|-------|--------|
103
+ | Exact match | ≥0.8 | Surface immediately: "This matches a prior rejection (`<slug>`). Do you still feel the same way?" |
104
+ | Similar | 0.5–0.79 | Mention as similar prior decision, offer to read the file together |
105
+ | Weak / no match | <0.5 | Ignore (don't pollute conversation with low-confidence matches) |
106
+
107
+ The matcher is purely lexical — agents do NOT call out to a model to compute similarity. Lexical is fast (~1ms per file), deterministic, and good enough for the ≥0.8 threshold. Domain-specific concept clustering is a future enrichment.
108
+
109
+ ## When to write a new file
110
+
111
+ Only when:
112
+ 1. An **enhancement** (not a bug) is rejected as `wontfix` / `out of scope`
113
+ 2. The reasoning is **durable** (project-scope, technical constraint, strategic decision) — NOT a temporary deferral
114
+ 3. A future similar request would benefit from finding this record
115
+
116
+ If the rejection reason is "we're busy this quarter" → that's a deferral, route to a backlog issue, not `.out-of-scope/`.
117
+
118
+ ## When to append to an existing file
119
+
120
+ When the matcher finds an exact concept match, append to `prior_requests`:
121
+
122
+ ```yaml
123
+ prior_requests:
124
+ - id: gh-issue-42
125
+ summary: Add dark mode support
126
+ closed_at: 2025-08-01
127
+ - id: gh-issue-87 # <-- new
128
+ summary: Night theme for accessibility
129
+ closed_at: 2026-02-15 # <-- new
130
+ ```
131
+
132
+ Do NOT create a duplicate file. Update the existing one.
133
+
134
+ ## When to delete a file
135
+
136
+ When the maintainer decides to actually build the rejected feature. The file gets deleted in the same commit that opens the new tracking issue. Historical issues (in `prior_requests`) are not reopened — they're snapshots.
137
+
138
+ ## Conflicts with ADRs
139
+
140
+ If a rejection contradicts an existing ADR (e.g., ADR says "we use REST" but a request asks for GraphQL and the rejection cites different reasons), populate `conflicts_with: [docs/adr/0007-rest-only.md]`. `audit` later flags this for cross-reference.
141
+
142
+ ## Validation (compiler test)
143
+
144
+ `compiler/__tests__/out-of-scope-format.test.js` validates:
145
+ - Frontmatter parses as YAML
146
+ - Required fields present
147
+ - `decision == "rejected"`
148
+ - `concept` matches filename
149
+ - `prior_requests` has ≥1 entry
150
+ - Slug rules pass
151
+
152
+ Failures here block the merge that introduced the broken file.
@@ -3,7 +3,7 @@ name: brainstorm
3
3
  description: Creative ideation and solution exploration. Generates multiple approaches with trade-offs, uses structured frameworks (SCAMPER, First Principles), and hands off to plan for structuring.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.5.0"
6
+ version: "0.6.0"
7
7
  layer: L2
8
8
  model: opus
9
9
  group: creation
@@ -43,6 +43,23 @@ Activated for product-level rethinks — not "how to implement X" but "should we
43
43
  3. MUST apply the "10-star experience" lens: what would a 1-star, 5-star, and 10-star version look like?
44
44
  4. MUST challenge assumptions: "why does this need to be a page?" "why does the user need to do this at all?"
45
45
 
46
+ ### Design-It-Twice Mode
47
+ Activated when exploring alternative *interface shapes* for a deepening candidate. Spawns N=3-4 parallel subagents, each pinned to a radically different design constraint (minimize / maximize-flexibility / optimize-common-case / ports-and-adapters), computes a diversity score over feature vectors, and presents sequentially with an opinionated recommendation. Used by `improve-architecture` when a deepened module's interface is non-obvious.
48
+
49
+ **Design-It-Twice triggers:**
50
+ - `improve-architecture` (Step 7 hand-off) when the picked candidate has multiple credible interface shapes
51
+ - User says "design it twice", "explore interfaces", "what are the API options"
52
+ - Manual: `/rune brainstorm design-it-twice <module>`
53
+
54
+ **Design-It-Twice constraints:**
55
+ 1. MUST spawn N=3 (minimum) or N=4 (when dependency category is remote-owned or true-external) parallel subagents
56
+ 2. Each subagent pinned to exactly ONE of the 4 standard constraints — enforced via prompt template
57
+ 3. Diversity score MUST be >= 0.4 before presenting (re-spawn once if below)
58
+ 4. Recommendation MUST be opinionated with a concrete hedge condition — "it depends" is BLOCKED
59
+ 5. Hybrid synthesis (Step 4.5) is opt-in when 2 designs have complementary strengths
60
+
61
+ Full doctrine: [references/design-it-twice.md](references/design-it-twice.md).
62
+
46
63
  ### Rescue Mode
47
64
  Activated when an approach has been tried and **fundamentally failed** — not a bug, but a wrong approach. Rescue mode forces **category-diverse** alternatives instead of variants of the failed approach.
48
65
 
@@ -102,6 +119,7 @@ Direct API call ≠ Wrapper/middleware layer ≠ Reverse engineering ≠ Browser
102
119
  - User: `/rune brainstorm <topic>` direct invocation (Discovery Mode)
103
120
  - User: `/rune brainstorm rescue <context>` manual rescue (Rescue Mode)
104
121
  - `ba` (L2): when multiple requirement approaches exist
122
+ - `improve-architecture` (L2): when a deepened module's interface needs Design-It-Twice exploration
105
123
 
106
124
  ## Cross-Hub Connections
107
125
 
@@ -143,6 +161,7 @@ CRAZY 8s — 8 ideas in 8 minutes (rapid ideation)
143
161
  ### Step 0 — Detect Mode
144
162
 
145
163
  Check the invocation context:
164
+ - If `mode="design-it-twice"` is set, or caller is `improve-architecture` Step 7, or user says "design it twice / explore interfaces" → **Design-It-Twice Mode** (jump to Step 2.5 directly)
146
165
  - If `mode="vision"` is set, or user says "rethink/reimagine/step back" → **Vision Mode**
147
166
  - If `mode="rescue"` is set, or caller is Approach Pivot Gate / 3-Fix Escalation → **Rescue Mode**
148
167
  - Otherwise → **Discovery Mode**
@@ -209,6 +228,7 @@ When Step 1 or Step 1.5 reveals gaps, ask structured clarifying questions using
209
228
 
210
229
  **Discovery Mode**: Produce exactly 2–3 distinct approaches.
211
230
  **Rescue Mode**: Produce exactly 3–5 approaches, each a **different category** from the failed approach.
231
+ **Design-It-Twice Mode**: skip to Step 2.5.
212
232
 
213
233
  Each approach must be meaningfully different — not just variations of the same idea. For each approach provide:
214
234
  - **Name**: short memorable label
@@ -220,6 +240,21 @@ Each approach must be meaningfully different — not just variations of the same
220
240
 
221
241
  If the domain is unfamiliar or data is needed, invoke `rune:research` before generating options. For product/market context, invoke `rune:trend-scout`.
222
242
 
243
+ ### Step 2.5 — Constraint Matrix Spawn (Design-It-Twice Mode only)
244
+
245
+ Spawn N=3 parallel subagents (or N=4 if dependency category is `remote-owned` / `true-external`). Each is pinned to exactly one constraint via Task tool spawn:
246
+
247
+ | Constraint ID | Pinning |
248
+ |---------------|---------|
249
+ | C1 | "Minimize the interface — aim for 1–3 entry points. Maximize leverage per entry point." |
250
+ | C2 | "Maximize flexibility — support many use cases, extension surface." |
251
+ | C3 | "Optimize for the most common caller — make the default case trivial. Rare cases pay cost." |
252
+ | C4 | "Design around ports and adapters for cross-seam dependencies." (only when applicable) |
253
+
254
+ Use the spawn prompt template from [references/design-it-twice.md](references/design-it-twice.md). Include CONTEXT.md domain terms in the prompt so each design names things consistently with project domain language.
255
+
256
+ Each subagent returns a YAML block: interface, usage example, what's hidden, dependency strategy/adapters, tradeoffs.
257
+
223
258
  ### Step 3 — Evaluate
224
259
 
225
260
  **Discovery Mode** — Apply the most relevant framework:
@@ -243,6 +278,26 @@ Additionally in Rescue Mode:
243
278
 
244
279
  For approaches with many interacting variables, invoke `rune:sequential-thinking` to reason through trade-offs systematically.
245
280
 
281
+ ### Step 3.5 — Diversity Gate (Design-It-Twice Mode only)
282
+
283
+ After subagents return, compute the diversity score:
284
+
285
+ ```
286
+ feature_vector(design) = [
287
+ count(methods), count(return_types), count(adapter_kinds),
288
+ count(dependencies), paradigm_tag, has_async, has_streaming
289
+ ]
290
+ diversity = 1 - mean(pairwise_jaccard(feature_vectors))
291
+ ```
292
+
293
+ | Diversity | Action |
294
+ |-----------|--------|
295
+ | ≥ 0.6 | Proceed to Step 4 |
296
+ | 0.4 – 0.59 | Surface to user: "designs are similar in [shared trait] — re-spawn with different constraints?" |
297
+ | < 0.4 | Re-spawn once with rotated constraints; if still <0.4, give up and present what's there with a diversity-low warning |
298
+
299
+ Emit `diversity_score` in chain_metadata.
300
+
246
301
  ### Step 4 — Recommend
247
302
 
248
303
  Select ONE approach as the recommendation. State:
@@ -288,6 +343,20 @@ For product-level brainstorming (Vision Mode or when approaches have strategic i
288
343
  - Skip this step for pure technical brainstorming (no product/strategy dimension)
289
344
  - If all tiers look equally expensive → approach may be too complex for Quick Win
290
345
 
346
+ ### Step 4.5 — Hybrid Synthesis (Design-It-Twice Mode, optional)
347
+
348
+ If two designs have complementary strengths (e.g., C1's leverage + C4's seam discipline), propose a 4th option that combines them. Skip this step when no two designs have clear complementary strengths.
349
+
350
+ ```
351
+ Option D (Hybrid C1 + C4):
352
+ - Interface: 3 methods (from C1's minimization)
353
+ - Adapters: HttpAdapter + InMemoryAdapter (from C4's port discipline)
354
+ - Pros: small surface AND testable across the seam
355
+ - Cons: more upfront design work; locks the port early
356
+ ```
357
+
358
+ The hybrid is the recommended default in many cases. Be opinionated.
359
+
291
360
  ### Step 5 — Return to Plan
292
361
  Pass the recommended approach back to `rune:plan` for structuring into an executable implementation plan. Include:
293
362
  - The chosen option name
@@ -306,6 +375,9 @@ If the user rejects the recommendation, return to Step 2 with adjusted constrain
306
375
  6. [Rescue Mode] MUST NOT generate variants of the failed approach — each approach must be a different CATEGORY
307
376
  7. [Rescue Mode] MUST use Collision-Zone or Inversion framework — conventional thinking already failed
308
377
  8. [Rescue Mode] MUST include at least 1 unconventional/hacky approach — sometimes the "dirty" solution is the only one that works
378
+ 9. [Design-It-Twice Mode] MUST spawn parallel subagents with one constraint pinned per agent — fake diversity (one agent producing N options) is BLOCKED
379
+ 10. [Design-It-Twice Mode] MUST emit `diversity_score` and re-spawn (once) if below 0.4 floor
380
+ 11. [Design-It-Twice Mode] MUST NOT produce "it depends" recommendations — pick one design with a concrete hedge condition
309
381
 
310
382
  ## Output Format
311
383
 
@@ -363,6 +435,10 @@ Known failure modes for this skill. Check these before declaring done.
363
435
  | [Rescue] All approaches are "clean/proper" — no hacky option | MEDIUM | At least 1 must be unconventional — wrappers, reverse-engineering, debug mode abuse, proxy layers |
364
436
  | Calling plan directly instead of presenting options first | CRITICAL | Steps 2-3 are mandatory — present options, get approval, THEN call plan |
365
437
  | "Creative" options that ignore stated constraints | MEDIUM | Every option must satisfy the constraints declared in Step 1 |
438
+ | [Design-It-Twice] Single agent producing N options instead of N parallel subagents | HIGH | Step 2.5 — constraint pinning happens at spawn, not in a loop. Each constraint = one Task call |
439
+ | [Design-It-Twice] Diversity score below 0.4 ignored | HIGH | Step 3.5 gate — re-spawn once; if still low, present with explicit "low-diversity" warning |
440
+ | [Design-It-Twice] "It depends" recommendation | HIGH | Step 4 — must pick one with a hedge; if genuinely tied, propose hybrid (Step 4.5) and recommend that |
441
+ | [Design-It-Twice] Forgetting to include CONTEXT.md domain terms in subagent prompt | MEDIUM | Step 2.5 spawn template requires domain glossary be passed through |
366
442
 
367
443
  ## Done When
368
444