@rune-kit/rune 2.12.3 → 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 (49) hide show
  1. package/README.md +41 -7
  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 +31 -0
  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/compiler/adapters/openclaw.js +43 -3
  11. package/package.json +2 -2
  12. package/skills/adversary/SKILL.md +1 -1
  13. package/skills/audit/SKILL.md +1 -0
  14. package/skills/autopsy/SKILL.md +1 -1
  15. package/skills/ba/SKILL.md +241 -82
  16. package/skills/ba/references/context-md-format.md +136 -0
  17. package/skills/ba/references/explore-first.md +107 -0
  18. package/skills/ba/references/out-of-scope-format.md +152 -0
  19. package/skills/brainstorm/SKILL.md +77 -1
  20. package/skills/brainstorm/references/design-it-twice.md +155 -0
  21. package/skills/context-pack/SKILL.md +69 -26
  22. package/skills/context-pack/evals.md +122 -0
  23. package/skills/context-pack/references/brief-template.md +121 -0
  24. package/skills/context-pack/references/durability-rules.md +109 -0
  25. package/skills/cook/SKILL.md +4 -4
  26. package/skills/debug/SKILL.md +2 -1
  27. package/skills/fix/SKILL.md +2 -1
  28. package/skills/graft/SKILL.md +1 -1
  29. package/skills/improve-architecture/SKILL.md +275 -0
  30. package/skills/improve-architecture/evals.md +145 -0
  31. package/skills/improve-architecture/references/deepening.md +87 -0
  32. package/skills/improve-architecture/references/interface-design.md +68 -0
  33. package/skills/improve-architecture/references/language.md +81 -0
  34. package/skills/improve-architecture/references/scoring.md +122 -0
  35. package/skills/journal/SKILL.md +34 -7
  36. package/skills/journal/references/adr-criteria.md +109 -0
  37. package/skills/marketing/SKILL.md +2 -1
  38. package/skills/review/SKILL.md +1 -0
  39. package/skills/review-intake/SKILL.md +25 -2
  40. package/skills/safeguard/SKILL.md +1 -1
  41. package/skills/scout/SKILL.md +33 -1
  42. package/skills/sentinel-env/SKILL.md +24 -13
  43. package/skills/skill-forge/SKILL.md +108 -1
  44. package/skills/surgeon/SKILL.md +17 -2
  45. package/skills/test/SKILL.md +48 -1
  46. package/skills/test/evals.md +137 -0
  47. package/skills/test/references/mocking-policy.md +121 -0
  48. package/skills/test/references/test-quality.md +124 -0
  49. package/skills/test/references/vertical-tdd.md +110 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Zoom-out output validation — scout v0.4 zoom-out mode produces a 3-layer Mermaid map.
3
+ *
4
+ * Validates:
5
+ * - Output is parseable Mermaid (graph LR ... or graph TB)
6
+ * - L0 (target) node is present and styled as "stuck"
7
+ * - L1 cap: max 8 sibling files
8
+ * - L2 cap: max 8 caller modules
9
+ * - Total nodes never exceed L0 + 16
10
+ * - Edge collapse note appears when caps hit
11
+ */
12
+
13
+ import assert from 'node:assert';
14
+ import { describe, test } from 'node:test';
15
+
16
+ function parseMermaid(text) {
17
+ // Minimal validator — just need to confirm structure
18
+ const lines = text
19
+ .split('\n')
20
+ .map((l) => l.trim())
21
+ .filter(Boolean);
22
+ const directive = lines.find((l) => /^graph (LR|TB|RL|BT)/.test(l));
23
+ if (!directive) return { valid: false, error: 'missing graph directive' };
24
+
25
+ const nodes = new Set();
26
+ const edges = [];
27
+ for (const line of lines) {
28
+ if (line.startsWith('graph ') || line.startsWith('classDef ') || line.startsWith('%%')) continue;
29
+ // Extract node names from edges like "A --> B" or "A -.text.- B"
30
+ const edgeMatch = line.match(/^(\S+?)(?:\[[^\]]*\])?\s*(?:-->|-\.[^.]*\.-)\s*(\S+?)(?:\[[^\]]*\])?$/);
31
+ if (edgeMatch) {
32
+ nodes.add(edgeMatch[1]);
33
+ nodes.add(edgeMatch[2]);
34
+ edges.push({ from: edgeMatch[1], to: edgeMatch[2] });
35
+ }
36
+ }
37
+ return { valid: true, nodes: [...nodes], edges };
38
+ }
39
+
40
+ function buildZoomOutFixture({ targetName, l1Files, l2Modules, edgeCollapseNote = false }) {
41
+ const lines = ['graph LR', ` ${targetName}[src/auth/login.ts]:::stuck`];
42
+ for (let i = 0; i < l1Files; i++) {
43
+ lines.push(` sibling${i}[siblingFile${i}] -.same-dir.- ${targetName}`);
44
+ }
45
+ for (let i = 0; i < l2Modules; i++) {
46
+ lines.push(` caller${i}[callerModule${i}] --> ${targetName}`);
47
+ }
48
+ if (edgeCollapseNote) {
49
+ lines.push(' %% showing top 8 by import-frequency (>8 collapsed)');
50
+ }
51
+ lines.push(' classDef stuck fill:#ff6b6b');
52
+ return lines.join('\n');
53
+ }
54
+
55
+ describe('zoom-out Mermaid output', () => {
56
+ test('valid output parses', () => {
57
+ const fixture = buildZoomOutFixture({ targetName: 'target', l1Files: 3, l2Modules: 4 });
58
+ const parsed = parseMermaid(fixture);
59
+ assert.strictEqual(parsed.valid, true);
60
+ assert.ok(parsed.nodes.includes('target'));
61
+ });
62
+
63
+ test('target has classDef stuck', () => {
64
+ const fixture = buildZoomOutFixture({ targetName: 'target', l1Files: 1, l2Modules: 1 });
65
+ assert.ok(fixture.includes(':::stuck'));
66
+ assert.ok(fixture.includes('classDef stuck'));
67
+ });
68
+
69
+ test('respects L1 cap (8 max)', () => {
70
+ const fixture = buildZoomOutFixture({ targetName: 'target', l1Files: 8, l2Modules: 0 });
71
+ const parsed = parseMermaid(fixture);
72
+ const siblingCount = parsed.nodes.filter((n) => n.startsWith('sibling')).length;
73
+ assert.ok(siblingCount <= 8, `expected <=8 siblings, got ${siblingCount}`);
74
+ });
75
+
76
+ test('respects L2 cap (8 max)', () => {
77
+ const fixture = buildZoomOutFixture({ targetName: 'target', l1Files: 0, l2Modules: 8 });
78
+ const parsed = parseMermaid(fixture);
79
+ const callerCount = parsed.nodes.filter((n) => n.startsWith('caller')).length;
80
+ assert.ok(callerCount <= 8, `expected <=8 callers, got ${callerCount}`);
81
+ });
82
+
83
+ test('total node cap: target + L1 (8) + L2 (8) = 17 max', () => {
84
+ const fixture = buildZoomOutFixture({ targetName: 'target', l1Files: 8, l2Modules: 8 });
85
+ const parsed = parseMermaid(fixture);
86
+ assert.ok(parsed.nodes.length <= 17, `expected <=17 nodes, got ${parsed.nodes.length}`);
87
+ });
88
+
89
+ test('edge-collapse note included when caps hit', () => {
90
+ const fixture = buildZoomOutFixture({
91
+ targetName: 'target',
92
+ l1Files: 8,
93
+ l2Modules: 8,
94
+ edgeCollapseNote: true,
95
+ });
96
+ assert.ok(fixture.includes('showing top 8'));
97
+ });
98
+
99
+ test('rejects output without graph directive', () => {
100
+ const fixture = `target[src/auth/login.ts]
101
+ caller --> target`;
102
+ const parsed = parseMermaid(fixture);
103
+ assert.strictEqual(parsed.valid, false);
104
+ });
105
+ });
106
+
107
+ describe('agent.stuck signal name validity', () => {
108
+ test('agent.stuck conforms to signal naming pattern', () => {
109
+ const SIGNAL_PATTERN = /^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)+$/;
110
+ assert.ok(SIGNAL_PATTERN.test('agent.stuck'));
111
+ });
112
+ });
@@ -7,6 +7,25 @@
7
7
  * .openclaw/rune/skills/*.md (transformed skill files)
8
8
  *
9
9
  * Follows the NeuralMemory OpenClaw plugin pattern.
10
+ *
11
+ * ARTIFACT CONVENTION (v2.13+):
12
+ * OpenClaw skills that produce file artifacts (images, reports, data) should
13
+ * resolve output directory in this fallback order — honored by the Rune script
14
+ * output contract (see skills/skill-forge Phase 5.25):
15
+ *
16
+ * 1. --out-dir <path> (explicit caller intent)
17
+ * 2. <SKILL>_OUT_DIR (skill-specific env var)
18
+ * 3. OPENCLAW_OUTPUT_DIR (platform-wide override)
19
+ * 4. OPENCLAW_AGENT_DIR/artifacts/<skill> (per-agent scoped default)
20
+ * 5. OPENCLAW_STATE_DIR/artifacts/<skill> (state-scoped fallback)
21
+ * 6. ./.rune/<skill>/ (project-local default)
22
+ *
23
+ * Reference implementations in @rune-pro/media/scripts/:
24
+ * - codex_imagen_bridge.mjs (full resolution + 9-tier binary detection)
25
+ * - image_optimizer.py (Python equivalent)
26
+ *
27
+ * Reference codex-imagen repo (darkamenosa/codex-imagen) documents the
28
+ * de-facto in-the-wild convention this adapter formalizes.
10
29
  */
11
30
 
12
31
  import { BRANDING_FOOTER } from '../transforms/branding.js';
@@ -67,15 +86,36 @@ export default {
67
86
  * @param {object} pluginJson - Rune's .claude-plugin/plugin.json
68
87
  * @returns {object} manifest object
69
88
  */
70
- generateManifest(_skills, pluginJson) {
89
+ generateManifest(skills, pluginJson) {
71
90
  return {
72
91
  id: 'rune',
73
92
  name: 'Rune',
74
93
  kind: 'skills',
75
- description:
76
- '62-skill mesh for AI coding assistants. Routes all code tasks through specialized skills. 215+ connections, 14 extension packs.',
94
+ description: `${skills.length}-skill mesh for AI coding assistants. Routes all code tasks through specialized skills. 215+ connections, 14 extension packs.`,
77
95
  version: pluginJson.version || '0.0.0',
78
96
  skills: ['./skills'],
97
+ artifactConvention: {
98
+ outputDirPriority: [
99
+ '--out-dir <path>',
100
+ '<SKILL>_OUT_DIR',
101
+ 'OPENCLAW_OUTPUT_DIR',
102
+ 'OPENCLAW_AGENT_DIR/artifacts/<skill>',
103
+ 'OPENCLAW_STATE_DIR/artifacts/<skill>',
104
+ './.rune/<skill>/',
105
+ ],
106
+ outputContract: {
107
+ stdout: 'one artifact path per line (default) or JSON (--json mode)',
108
+ stderr: 'diagnostics + warnings',
109
+ exitCodes: {
110
+ 0: 'success',
111
+ 1: 'execution failed (retryable)',
112
+ 2: 'usage error (bug)',
113
+ 3: 'data-integrity error (halt)',
114
+ 4: 'timeout with partial results (accept)',
115
+ 124: 'timeout with zero results (retry or abort)',
116
+ },
117
+ },
118
+ },
79
119
  configSchema: {
80
120
  jsonSchema: {
81
121
  type: 'object',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rune-kit/rune",
3
- "version": "2.12.3",
4
- "description": "62-skill mesh for AI coding assistants — runtime auto-discipline via native hooks (Claude/Cursor/Windsurf/Antigravity), 5-layer architecture, 215+ connections, multi-platform compiler.",
3
+ "version": "2.14.0",
4
+ "description": "63-skill mesh for AI coding assistants — runtime auto-discipline via native hooks (Claude/Cursor/Windsurf/Antigravity), 5-layer architecture, 215+ connections, multi-platform compiler.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "rune": "./compiler/bin/rune.js"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: adversary
3
- description: Pre-implementation red-team analysis. Challenges plans before code is written — finds edge cases, security holes, scalability bottlenecks, error propagation risks, and integration conflicts. Catches flaws at plan time (10x cheaper than post-implementation).
3
+ description: "Pre-implementation red-team analysis. Use when a plan is high-risk, critical path, or expensive to reverse. Challenges plans before code is written — finds edge cases, security holes, scalability bottlenecks, error propagation risks, and integration conflicts. Catches flaws at plan time (10x cheaper than post-implementation)."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.1.0"
@@ -30,6 +30,7 @@ Comprehensive project health audit across 8 dimensions (7 project + 1 mesh analy
30
30
  - `dependency-doctor` (L3): Phase 1 — vulnerability scan and outdated dependency check
31
31
  - `sentinel` (L2): Phase 2 — security audit (OWASP Top 10, secrets, config)
32
32
  - `autopsy` (L2): Phase 3 — code quality and complexity assessment
33
+ - `improve-architecture` (L2): Phase 3.5 — architecture sub-score (depth / leverage / locality across top modules)
33
34
  - `perf` (L2): Phase 4 — performance regression check
34
35
  - `db` (L2): Phase 5 — database health dimension (schema, migrations, indexes)
35
36
  - `journal` (L3): record audit date, overall score, and verdict
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: autopsy
3
- description: Full codebase health assessment. Analyzes complexity, dependencies, dead code, tech debt, and git hotspots. Produces a health score and rescue plan.
3
+ description: Full codebase health assessment. Use when diagnosing project health or starting a rescue workflow on legacy code. Analyzes complexity, dependencies, dead code, tech debt, and git hotspots. Produces a health score and rescue plan.
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.4.0"
@@ -3,11 +3,12 @@ name: ba
3
3
  description: Business Analyst agent. Deeply understands user requirements before any planning or coding begins. Asks probing questions, identifies hidden requirements, maps stakeholders, defines scope boundaries, and produces a structured Requirements Document that plan and cook consume.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.7.0"
6
+ version: "0.11.0"
7
7
  layer: L2
8
8
  model: opus
9
9
  group: creation
10
10
  tools: "Read, Glob, Grep"
11
+ emit: outofscope.match
11
12
  ---
12
13
 
13
14
  # ba
@@ -16,6 +17,8 @@ metadata:
16
17
 
17
18
  Business Analyst agent — the ROOT FIX for "Claude works a lot but produces nothing." BA forces deep understanding of WHAT to build before any code is written. It asks probing questions, identifies hidden requirements, maps stakeholders, defines scope boundaries, and produces a structured Requirements Document.
18
19
 
20
+ > Wrong requirements shipped correctly is the most expensive bug. BA's job is to prevent it — measure clarity (Step 2.5), measure completeness (Step 3.5), and measure cross-dimension consistency (Step 3.6) before handoff.
21
+
19
22
  <HARD-GATE>
20
23
  BA produces WHAT, not HOW. Never write code. Never plan implementation.
21
24
  Output is a Requirements Document → hand off to rune:plan for implementation planning.
@@ -70,6 +73,58 @@ If Refactor → light version (Step 1 + Step 4 only). Skip Steps 2, 2.5, 3, 5, 6
70
73
 
71
74
  If existing codebase → invoke `rune:scout` for context before proceeding.
72
75
 
76
+ ### Step 1.5 — Out-of-Scope Match Check
77
+
78
+ Before any elicitation, check whether the request matches a concept previously rejected.
79
+
80
+ 1. `Glob` `.out-of-scope/*.md` — if directory absent, skip silently.
81
+ 2. For each file, parse YAML frontmatter (`concept`, `aliases`).
82
+ 3. Build a token map (lowercased, split on `-` and whitespace).
83
+ 4. Tokenize the user's request the same way.
84
+ 5. Compute lexical overlap per concept; keep the top match's `confidence` (0.0–1.0).
85
+
86
+ **Action by confidence**:
87
+
88
+ | Confidence | Verdict | Action |
89
+ |------------|---------|--------|
90
+ | ≥ 0.8 | exact-match | Surface to user: *"This matches a prior rejection (`.out-of-scope/<slug>.md`) — closed because [body's "Why out of scope" first sentence]. Do you still feel the same way?"* Pause for user response before continuing. |
91
+ | 0.5 – 0.79 | similar | Mention inline: *"This is similar to a prior rejection (`<slug>`). Would you like to review it before we proceed?"* Continue regardless of answer. |
92
+ | < 0.5 | no-match | Continue silently, no user-facing mention. |
93
+
94
+ Emit `outofscope.match` signal with `{concept, confidence, verdict}` so downstream skills (cook, plan) inherit the context.
95
+
96
+ If verdict is exact-match AND user says "yes I still want it" → record their override reason in the Requirements Document `## Risks` section AND mark `priority_to_revisit: high` in the existing `.out-of-scope/<slug>.md` (do NOT delete the file). The override forces the candidate up the revisit ladder; it doesn't erase the prior decision.
97
+
98
+ If verdict is exact-match AND user accepts the prior rejection → end the BA session with a one-line summary referencing the file. No further questions.
99
+
100
+ Format reference: [references/out-of-scope-format.md](references/out-of-scope-format.md).
101
+
102
+ ### Step 2.0 — Explore-First Pre-Check (HARD-GATE)
103
+
104
+ Before emitting ANY of the 5 elicitation questions, run the 4-item pre-check on each intended question:
105
+
106
+ 1. Is the answer in `package.json` / `pyproject.toml` / `Cargo.toml` / `go.mod` / `pom.xml`?
107
+ 2. Is the answer in `README.md` / `CLAUDE.md` / `docs/`?
108
+ 3. Is it inferable from file extensions, directory structure, or config files?
109
+ 4. Has the user answered it earlier in this conversation?
110
+
111
+ <HARD-GATE>
112
+ For every question Q the agent intends to ask, there MUST be prior tool-call evidence in the same session:
113
+ - At least 1 Read / Glob / Grep related to Q's domain, OR
114
+ - Explicit declaration: "Q cannot be answered from project artifacts because [specific reason]."
115
+ Without one of these, Q is BLOCKED — re-route to inference.
116
+ </HARD-GATE>
117
+
118
+ The gate is "tried to infer" — not "must succeed in inferring." If the file genuinely doesn't have the answer, the attempt itself is the gate.
119
+
120
+ Cache inferred answers in the requirements doc:
121
+ ```
122
+ **Inferred from package.json**: TypeScript 5.4, Next.js 14.2, React 18.3
123
+ **Inferred from .github/workflows/**: CI runs on PRs targeting main
124
+ ```
125
+
126
+ Worked examples + edge cases: [references/explore-first.md](references/explore-first.md).
127
+
73
128
  ### Step 2 — Requirement Elicitation (the "5 Questions")
74
129
 
75
130
  Ask exactly 5 probing questions, ONE AT A TIME (not all at once):
@@ -195,6 +250,23 @@ Clarity Score: [100 - ambiguity]%
195
250
  Status: ACCEPTABLE (ambiguity 23%) — proceeding with noted gaps
196
251
  ```
197
252
 
253
+ ### Step 2.6 — CONTEXT.md Cross-Reference Gate
254
+
255
+ After elicitation, before hidden-requirement discovery, scan the user's answers for assertions about *current behavior* — phrasings like "the system X", "the code does X", "we already X", "right now it X".
256
+
257
+ For each such assertion:
258
+
259
+ 1. `Grep` the codebase for evidence (function names, route handlers, schema definitions matching the asserted behavior).
260
+ 2. Compare grep results to the user's claim.
261
+
262
+ | Outcome | Action |
263
+ |---------|--------|
264
+ | Grep confirms claim | Proceed; record term in CONTEXT.md if domain-relevant |
265
+ | Grep contradicts claim | <HARD-GATE>Surface the conflict immediately. *"You said the system does X, but the code path I see does Y. Which is canonical?"* Pause until resolved.</HARD-GATE> |
266
+ | Grep returns nothing | Note as unverified; ask user for the file/function name; do not record in CONTEXT.md until verified |
267
+
268
+ This gate prevents the agent from silently transcribing user-asserted behavior that contradicts code — a common source of "the docs say X but the code does Y" drift.
269
+
198
270
  ### Step 3 — Hidden Requirement Discovery
199
271
 
200
272
  After the 5 questions, analyze for requirements the user DIDN'T mention:
@@ -243,6 +315,53 @@ When presenting options, alternatives, or scope decisions to the user, rate each
243
315
  **Anti-pattern**: "Choose B — it covers 90% of the value with less code." → If A is only 70 lines more, choose A. The last 10% is where production bugs hide.
244
316
 
245
317
 
318
+ ### Step 3.6 — Logic Consistency Check
319
+
320
+ After ambiguity + completeness pass, scan for **cross-dimension contradictions**. Ambiguity measures CLARITY of each dimension in isolation; this step measures CONSISTENCY across dimensions. A perfectly clear requirement can still contradict itself.
321
+
322
+ #### Checks
323
+
324
+ Run each, label verdict 🟢 pass / 🟡 warn / 🔴 fail:
325
+
326
+ | # | Check | 🔴 Fail | 🟢 Pass |
327
+ |---|-------|---------|---------|
328
+ | 1 | Every Acceptance Criterion traces to a User Story | AC orphaned | 1:N mapping clear |
329
+ | 2 | Every Business Rule (Q5) is enforced in an AC or Exception Flow | Rule has no enforcement path | Rule → specific AC or exception |
330
+ | 3 | Scope IN ∩ Scope OUT = ∅ | Direct overlap in phrasing | Sets disjoint |
331
+ | 4 | Every user-story flow has a terminal state | State loop without exit condition | Terminal state explicit |
332
+ | 5 | Dependencies (Step 4) ⊂ Constraints acknowledged (Q5) | Dependency never mentioned in constraints | All deps covered |
333
+ | 6 | NFRs measurable against at least one AC | NFR has no test hook | Every NFR → testable AC |
334
+ | 7 | Hidden requirements (Step 3) resolved in/out | Silent inclusion | User confirmed inclusion or exclusion |
335
+ | 0 | Prior rejection check (Step 1.5) — exact-match resolved with explicit override or session ended | Silent re-litigation of rejected concept | User chose: override (priority bumped) OR accept prior decision (session ends) |
336
+
337
+ #### Output Format
338
+
339
+ ```
340
+ Logic Consistency Report:
341
+ 1. AC → User Story: 🟢 all AC trace to US-1 or US-2
342
+ 2. Business rule → AC: 🟡 "no duplicate emails" cited — exception flow missing
343
+ 3. Scope disjoint: 🟢
344
+ 4. Terminal states: 🟢
345
+ 5. Deps in constraints: 🔴 "PostgreSQL 15" missing from Q5 answer
346
+ 6. NFR measurable: 🟢
347
+ 7. Hidden reqs resolved: 🟢
348
+
349
+ Verdict: 1 🔴, 1 🟡, 5 🟢 → BLOCK handoff until 🔴 fixed
350
+ ```
351
+
352
+ #### Gate Rule
353
+
354
+ | Result | Action |
355
+ |--------|--------|
356
+ | 0 🔴 | Proceed to Step 4 — 🟡 warnings become "Risks" in Requirements Doc |
357
+ | 1-2 🔴 | BLOCK — ask targeted question or re-scope to resolve each 🔴 |
358
+ | 3+ 🔴 | Scrap Steps 2-3 and restart — requirements structurally incoherent |
359
+
360
+ <HARD-GATE>
361
+ NEVER hand off to plan with unresolved 🔴. Ambiguity ≤ 40% does not imply consistency — they are orthogonal gates.
362
+ If user pushes "just build it" with 🔴 present, respond: "Contradiction in [dimension]: [specific conflict]. One clarification fixes this: [targeted question]"
363
+ </HARD-GATE>
364
+
246
365
  ### Step 4 — Scope Definition
247
366
 
248
367
  Based on all gathered information, produce:
@@ -330,9 +449,19 @@ For product-oriented requirements (Feature Request, Integration, Greenfield), ge
330
449
  - Every tier includes "Risk if skipped" — makes trade-offs explicit
331
450
  - Skip this step for Bug Fix and Refactor types (no strategic dimension)
332
451
 
333
- ### Step 7 — Requirements Document
452
+ ### Step 7 — Artifact Triad
334
453
 
335
- Produce structured output and hand off to `plan`:
454
+ Produce three structured artifacts not one prose doc. Plan consumes all three; each answers a different question.
455
+
456
+ | Artifact | Question Answered | Consumer |
457
+ |----------|-------------------|----------|
458
+ | `requirements.md` | WHAT to build and WHY | plan, cook |
459
+ | `requirements.mermaid` | WHAT does the flow look like visually | plan, design, review |
460
+ | `tasks.md` | WHAT work layers exist | plan (as task backbone, not from scratch) |
461
+
462
+ #### Artifact 1: requirements.md
463
+
464
+ Structured document combining Steps 1-6.5. Save to `.rune/features/<feature-name>/requirements.md`:
336
465
 
337
466
  ```markdown
338
467
  # Requirements Document: [Feature Name]
@@ -350,11 +479,8 @@ Created: [date] | BA Session: [summary]
350
479
 
351
480
  ## Scope
352
481
  ### In Scope
353
- [from Step 4]
354
482
  ### Out of Scope
355
- [from Step 4]
356
483
  ### Assumptions
357
- [from Step 4]
358
484
 
359
485
  ## Non-Functional Requirements
360
486
  [from Step 6]
@@ -368,101 +494,119 @@ Created: [date] | BA Session: [summary]
368
494
  ## Strategic Recommendations
369
495
  [from Step 6.5 — skip for Bug Fix/Refactor]
370
496
 
371
- ### Quick Win (0-30 days)
372
- - **Action**: [specific deliverable]
373
- - **Resources**: [effort estimate]
374
- - **Expected Impact**: [measurable outcome]
375
-
376
- ### Differentiation (1-3 months)
377
- - **Action**: [...]
378
- - **Resources**: [...]
379
- - **Expected Impact**: [...]
380
-
381
- ### Long-term Moat (6-12 months)
382
- - **Action**: [...]
383
- - **Resources**: [...]
384
- - **Expected Impact**: [...]
497
+ ## Logic Consistency Report
498
+ [from Step 3.6 — verbatim, for audit trail]
385
499
 
386
500
  ## Next Step
387
- → Hand off to rune:plan for implementation planning
501
+ → Hand off to rune:plan (consumes all 3 artifacts)
388
502
  ```
389
503
 
390
- Save to `.rune/features/<feature-name>/requirements.md`
504
+ #### Artifact 2: requirements.mermaid
391
505
 
392
- ## Output Format
506
+ Auto-generate from User Stories. Save to `.rune/features/<feature-name>/requirements.mermaid`.
507
+
508
+ **Sequence diagram** (primary happy path from US-1):
393
509
 
510
+ ```mermaid
511
+ sequenceDiagram
512
+ actor User
513
+ participant System
514
+ participant Database
515
+ User->>System: [action from US-1]
516
+ System->>Database: [read/write from AC-1.1]
517
+ Database-->>System: [response]
518
+ System-->>User: [result from AC-1.1]
394
519
  ```
395
- # Requirements Document: [Feature Name]
396
- Created: [date] | BA Session: [summary]
397
520
 
398
- ## Context
399
- [Problem statement — 2-3 sentences]
521
+ **State machine** (only if any User Story implies state):
400
522
 
401
- ## Stakeholders
402
- - Primary user: [who, technical level, workflow context]
403
- - Affected systems: [existing services, databases, APIs]
523
+ ```mermaid
524
+ stateDiagram-v2
525
+ [*] --> initial
526
+ initial --> processing: [trigger from AC]
527
+ processing --> success: [happy path AC]
528
+ processing --> failed: [error AC]
529
+ success --> [*]
530
+ failed --> initial: retry
531
+ ```
404
532
 
405
- ## User Stories
406
- US-1: As a [persona], I want to [action] so that [benefit]
407
- AC-1.1: GIVEN [context] WHEN [action] THEN [result]
408
- AC-1.2: GIVEN [error case] WHEN [action] THEN [error handling]
533
+ Skip state machine if feature is stateless (simple CRUD with no lifecycle). Sequence is always produced.
409
534
 
410
- ## Scope
411
- ### In Scope
412
- - [feature/behavior 1]
413
- - [feature/behavior 2]
414
- ### Out of Scope
415
- - [explicitly excluded 1]
416
- ### Assumptions
417
- - [assumption — risk if wrong]
535
+ #### Artifact 3: tasks.md
418
536
 
419
- ## Non-Functional Requirements
420
- | NFR | Requirement | Measurement |
421
- |-----|-------------|-------------|
422
- | [Performance/Security/etc.] | [specific target] | [how to verify] |
537
+ Pre-broken implementation tasks by layer. Plan refines this backbone, does not create from scratch. Save to `.rune/features/<feature-name>/tasks.md`:
423
538
 
424
- ## Dependencies
425
- - [API/service/library]: [status — available/needs setup]
539
+ ```markdown
540
+ # Implementation Tasks: [Feature Name]
541
+
542
+ ## Data Layer
543
+ - [ ] Schema — [tables/models from AC]
544
+ - [ ] Migration up + down
545
+ - [ ] Seed/fixtures if tests need them
546
+
547
+ ## Logic Layer
548
+ - [ ] [each Q5 Business Rule → one task]
549
+ - [ ] Validation for [each AC error case]
550
+ - [ ] State transitions from requirements.mermaid (if present)
551
+
552
+ ## Interface Layer (API / UI)
553
+ - [ ] [each User Story → one endpoint or UI component]
554
+ - [ ] Contract schema from AC (request/response)
555
+ - [ ] Error handling for [each AC error]
556
+
557
+ ## Test Layer
558
+ - [ ] Unit: [each business rule → one test]
559
+ - [ ] Integration: [each AC happy path]
560
+ - [ ] Regression: [each AC error case]
561
+
562
+ ## NFR Verification
563
+ - [ ] [each NFR from Step 6 → one measurement task]
564
+ ```
426
565
 
427
- ## Risks
428
- - [risk]: [mitigation strategy]
566
+ Derivation rules:
567
+ - 1 User Story → ≥1 Interface task
568
+ - 1 Business Rule → 1 Logic task + 1 Unit test task
569
+ - 1 AC → ≥1 Test task (happy path + error)
570
+ - 1 NFR → 1 NFR Verification task
429
571
 
430
- ## Decision Classification
572
+ #### Handoff
431
573
 
432
- | Category | Meaning | Example |
433
- |----------|---------|---------|
434
- | **Decisions** (locked) | User confirmed — agent MUST follow | "Use PostgreSQL, not MongoDB" |
435
- | **Discretion** (agent decides) | User trusts agent judgment | "Pick the best validation library" |
436
- | **Deferred** (out of scope) | Explicitly NOT this task | "Mobile app — future phase" |
574
+ Emit signal to `plan` with paths to all three artifacts. Plan MUST read all three before producing phase files — the triad is the contract.
437
575
 
438
- Plan gates on Decision compliance Discretion items don't need approval.
576
+ ### Step 7.5Glossary Sharpen (CONTEXT.md update)
439
577
 
440
- ## Strategic Recommendations
441
- [Skip for Bug Fix/Refactor]
578
+ After the artifact triad is saved, append/update the project glossary `CONTEXT.md` with any domain terms that were sharpened during this session.
442
579
 
443
- ### Quick Win (0-30 days)
444
- - **Action**: [immediate deliverable]
445
- - **Resources**: [effort + dependencies]
446
- - **Expected Impact**: [measurable KPI]
447
- - **Risk if skipped**: [consequence]
580
+ 1. Determine glossary location:
581
+ - If `CONTEXT-MAP.md` exists at root → multi-context; pick the right per-context CONTEXT.md
582
+ - Else if root `CONTEXT.md` exists → use it
583
+ - Else if any term needs recording → create root `CONTEXT.md` lazily
584
+ - Else skip silently (no-op when no terms emerged)
585
+ 2. For each new term, add a row to the **Language** table (term, definition, aliases-to-avoid, status).
586
+ 3. For each user-asserted relationship, add to the **Relationships** section.
587
+ 4. For each ambiguity surfaced during elicitation, add to **Flagged ambiguities**.
448
588
 
449
- ### Differentiation (1-3 months)
450
- - **Action**: [competitive advantage work]
451
- - **Resources**: [...]
452
- - **Expected Impact**: [...]
453
- - **Risk if skipped**: [...]
589
+ **Conflict gate** — if a new term has ≥0.7 token overlap with an existing one, surface to user (merge / rename / keep distinct). NEVER silently re-define an existing term.
454
590
 
455
- ### Long-term Moat (6-12 months)
456
- - **Action**: [defensible position work]
457
- - **Resources**: [...]
458
- - **Expected Impact**: [...]
459
- - **Risk if skipped**: [...]
591
+ Format reference: [references/context-md-format.md](references/context-md-format.md).
460
592
 
461
- ## Next Step
462
- → Hand off to rune:plan for implementation planning
463
- ```
593
+ ## Output Format
594
+
595
+ Triad of artifacts under `.rune/features/<feature-name>/`:
596
+
597
+ | File | Template Reference |
598
+ |------|-------------------|
599
+ | `requirements.md` | Step 7 Artifact 1 |
600
+ | `requirements.mermaid` | Step 7 Artifact 2 (sequence + optional state machine) |
601
+ | `tasks.md` | Step 7 Artifact 3 (Data / Logic / Interface / Test / NFR layers) |
464
602
 
465
- Saved to `.rune/features/<feature-name>/requirements.md`
603
+ Inside `requirements.md` the **Decision Classification** table MUST appear verbatim — plan gates on Decision compliance, Discretion items skip approval:
604
+
605
+ | Category | Meaning | Example |
606
+ |----------|---------|---------|
607
+ | **Decisions** (locked) | User confirmed — agent MUST follow | "Use PostgreSQL, not MongoDB" |
608
+ | **Discretion** (agent decides) | User trusts agent judgment | "Pick the best validation library" |
609
+ | **Deferred** (out of scope) | Explicitly NOT this task | "Mobile app — future phase" |
466
610
 
467
611
  ## Constraints
468
612
 
@@ -482,9 +626,10 @@ Saved to `.rune/features/<feature-name>/requirements.md`
482
626
  | Artifact | Format | Location |
483
627
  |----------|--------|----------|
484
628
  | Requirements document | Markdown | `.rune/features/<feature-name>/requirements.md` |
485
- | User stories with acceptance criteria | Markdown (GIVEN/WHEN/THEN) | inline + requirements.md |
486
- | Scope definition (in/out/assumptions) | Markdown sections | requirements.md |
487
- | Non-functional requirements table | Markdown table | requirements.md |
629
+ | Visual model | Mermaid (sequence + optional state machine) | `.rune/features/<feature-name>/requirements.mermaid` |
630
+ | Implementation task backbone | Markdown checklist by layer | `.rune/features/<feature-name>/tasks.md` |
631
+ | Logic Consistency Report | Markdown section | Embedded in requirements.md |
632
+ | Ambiguity + Completeness scores | Markdown display blocks | Embedded in requirements.md |
488
633
 
489
634
  ## Sharp Edges
490
635
 
@@ -508,6 +653,18 @@ Known failure modes for this skill. Check these before declaring done.
508
653
  | Skipping ambiguity scoring because "user seems clear" | HIGH | Always compute the score — perceived clarity ≠ measured clarity. The formula catches gaps humans miss |
509
654
  | Tiered recommendations too vague ("improve things") | MEDIUM | Each tier needs specific Action + measurable Expected Impact. "Build better UX" → "Reduce checkout steps from 5 to 3, targeting 15% conversion lift" |
510
655
  | All three tiers have same resources/effort | MEDIUM | Quick Win should be low-effort. If all tiers need "2 engineers, 3 months" → re-scope Quick Win to something achievable in 1 sprint |
656
+ | Skipping Logic Consistency check because ambiguity is low | CRITICAL | Step 3.6 HARD-GATE: clarity ≠ consistency. A 90% clarity spec can still contain pairwise contradictions (scope IN/OUT overlap, rules with no enforcement, orphan ACs) |
657
+ | Handing off to plan with unresolved 🔴 consistency fails | CRITICAL | Step 3.6 gate: 1+ 🔴 = BLOCK. 🟡 allowed only when logged as Risk in requirements.md |
658
+ | Producing only requirements.md, skipping mermaid and tasks.md | HIGH | Step 7 is a triad — plan's contract expects all 3. Sequence diagram is always produced; state machine only if stateful; tasks.md always produced |
659
+ | Mermaid diagram unrelated to actual user stories (decorative only) | MEDIUM | Sequence must trace AC-1.1 of US-1; state machine nodes must map to state-bearing ACs. Auditable by pattern-match |
660
+ | tasks.md as flat list instead of layered | MEDIUM | Derivation rules enforce 1 US → Interface task, 1 rule → Logic + Unit test, 1 AC → Test task, 1 NFR → verification. Skipping layers loses plan's backbone structure |
661
+ | Re-litigating a previously rejected concept without surfacing it | HIGH | Step 1.5 HARD-GATE: scan `.out-of-scope/` first; exact match (≥0.8) MUST be surfaced before elicitation begins |
662
+ | Skipping Step 1.5 because `.out-of-scope/` directory looks empty | MEDIUM | Empty directory is silent-skip OK; directory absent entirely is silent-skip OK; never skip due to "I don't think this matches anything" — let the matcher decide |
663
+ | User asserts behavior; agent records user's version without grep verification | HIGH | Step 2.6 HARD-GATE: every "the system does X" assertion gets grep'd; conflicts surface to user before recording |
664
+ | Silently re-defining an existing CONTEXT.md term | HIGH | Step 7.5 conflict gate: ≥0.7 overlap → user chooses merge/rename/keep-distinct |
665
+ | Auto-creating an empty CONTEXT.md when no terms emerged | LOW | Lazy creation rule: only write when there's a non-trivial term to record |
666
+ | Asking inferable questions ("what stack are you using?") without first checking package.json | HIGH | Step 2.0 HARD-GATE — every question requires prior tool-call evidence (Read/Glob/Grep) or explicit unavailability declaration |
667
+ | Re-asking a question already answered earlier in the conversation | MEDIUM | Step 2.0 check 4 — cache and reuse, never re-ask |
511
668
 
512
669
  ## Done When
513
670
 
@@ -518,8 +675,10 @@ Known failure modes for this skill. Check these before declaring done.
518
675
  - Scope defined (in/out/assumptions/dependencies)
519
676
  - User stories with testable acceptance criteria produced
520
677
  - Non-functional requirements assessed (relevant ones only)
678
+ - Logic Consistency Report produced — 0 🔴 before handoff (🟡 logged as Risks)
521
679
  - Tiered recommendations generated (Quick Win / Differentiation / Moat) — skip for Bug Fix/Refactor
522
- - Requirements Document saved to `.rune/features/<name>/requirements.md`
680
+ - Artifact triad saved: `requirements.md` + `requirements.mermaid` + `tasks.md`
681
+ - Out-of-scope match check completed (verdict logged: no-match | similar | exact-match-overridden | exact-match-accepted)
523
682
  - Handed off to `plan` for implementation planning
524
683
 
525
684
  ## Cost Profile