@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.
- package/README.md +23 -12
- package/compiler/__tests__/adr-scoring.test.js +91 -0
- package/compiler/__tests__/context-md-format.test.js +180 -0
- package/compiler/__tests__/context-pack-smell-tests.test.js +215 -0
- package/compiler/__tests__/diversity-score.test.js +117 -0
- package/compiler/__tests__/improve-architecture.test.js +171 -0
- package/compiler/__tests__/openclaw-adapter.test.js +11 -6
- package/compiler/__tests__/out-of-scope-format.test.js +303 -0
- package/compiler/__tests__/zoom-out-output.test.js +112 -0
- package/package.json +2 -2
- package/skills/audit/SKILL.md +1 -0
- package/skills/ba/SKILL.md +241 -82
- package/skills/ba/references/context-md-format.md +136 -0
- package/skills/ba/references/explore-first.md +107 -0
- package/skills/ba/references/out-of-scope-format.md +152 -0
- package/skills/brainstorm/SKILL.md +77 -1
- package/skills/brainstorm/references/design-it-twice.md +155 -0
- package/skills/context-pack/SKILL.md +68 -25
- package/skills/context-pack/evals.md +122 -0
- package/skills/context-pack/references/brief-template.md +121 -0
- package/skills/context-pack/references/durability-rules.md +109 -0
- package/skills/cook/SKILL.md +4 -4
- package/skills/debug/SKILL.md +2 -1
- package/skills/fix/SKILL.md +2 -1
- package/skills/improve-architecture/SKILL.md +275 -0
- package/skills/improve-architecture/evals.md +145 -0
- package/skills/improve-architecture/references/deepening.md +87 -0
- package/skills/improve-architecture/references/interface-design.md +68 -0
- package/skills/improve-architecture/references/language.md +81 -0
- package/skills/improve-architecture/references/scoring.md +122 -0
- package/skills/journal/SKILL.md +33 -6
- package/skills/journal/references/adr-criteria.md +109 -0
- package/skills/review/SKILL.md +1 -0
- package/skills/review-intake/SKILL.md +25 -2
- package/skills/scout/SKILL.md +33 -1
- package/skills/surgeon/SKILL.md +16 -1
- package/skills/test/SKILL.md +48 -1
- package/skills/test/evals.md +137 -0
- package/skills/test/references/mocking-policy.md +121 -0
- package/skills/test/references/test-quality.md +124 -0
- 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
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rune-kit/rune",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
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"
|
package/skills/audit/SKILL.md
CHANGED
|
@@ -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
|
package/skills/ba/SKILL.md
CHANGED
|
@@ -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.
|
|
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 —
|
|
452
|
+
### Step 7 — Artifact Triad
|
|
334
453
|
|
|
335
|
-
Produce structured
|
|
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
|
-
|
|
372
|
-
|
|
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
|
|
501
|
+
→ Hand off to rune:plan (consumes all 3 artifacts)
|
|
388
502
|
```
|
|
389
503
|
|
|
390
|
-
|
|
504
|
+
#### Artifact 2: requirements.mermaid
|
|
391
505
|
|
|
392
|
-
|
|
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
|
-
|
|
399
|
-
[Problem statement — 2-3 sentences]
|
|
521
|
+
**State machine** (only if any User Story implies state):
|
|
400
522
|
|
|
401
|
-
|
|
402
|
-
-
|
|
403
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
425
|
-
|
|
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
|
-
|
|
428
|
-
-
|
|
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
|
-
|
|
572
|
+
#### Handoff
|
|
431
573
|
|
|
432
|
-
|
|
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
|
-
|
|
576
|
+
### Step 7.5 — Glossary Sharpen (CONTEXT.md update)
|
|
439
577
|
|
|
440
|
-
|
|
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
|
-
|
|
444
|
-
-
|
|
445
|
-
-
|
|
446
|
-
-
|
|
447
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
462
|
-
|
|
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
|
-
|
|
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
|
-
|
|
|
486
|
-
|
|
|
487
|
-
|
|
|
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
|
-
-
|
|
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
|