@rune-kit/rune 2.18.1 → 2.21.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 +31 -12
- package/compiler/__tests__/comprehension.test.js +916 -0
- package/compiler/__tests__/governance-collector.test.js +376 -0
- package/compiler/__tests__/setup.test.js +5 -0
- package/compiler/analytics.js +5 -0
- package/compiler/bin/rune.js +165 -1
- package/compiler/comprehension-client.js +2348 -0
- package/compiler/comprehension.js +1254 -0
- package/compiler/governance-collector.js +382 -0
- package/compiler/schemas/comprehension.schema.json +87 -0
- package/compiler/schemas/governance.schema.json +78 -0
- package/compiler/transforms/branding.js +1 -1
- package/hooks/context-watch/index.cjs +24 -13
- package/hooks/hooks.json +2 -2
- package/hooks/lib/context-key.cjs +37 -0
- package/hooks/metrics-collector/index.cjs +37 -8
- package/hooks/pre-tool-guard/index.cjs +44 -0
- package/hooks/session-start/index.cjs +4 -10
- package/package.json +1 -1
- package/skills/adversary/SKILL.md +36 -3
- package/skills/adversary/references/cross-model-escalation.md +85 -0
- package/skills/adversary/references/reasoning-modes.md +95 -0
- package/skills/autopsy/SKILL.md +41 -0
- package/skills/ba/SKILL.md +106 -27
- package/skills/ba/references/ears-format.md +91 -0
- package/skills/brainstorm/SKILL.md +32 -7
- package/skills/completion-gate/SKILL.md +21 -10
- package/skills/converge/SKILL.md +178 -0
- package/skills/converge/references/eval-fixtures.md +59 -0
- package/skills/cook/SKILL.md +41 -6
- package/skills/debug/SKILL.md +4 -2
- package/skills/deploy/SKILL.md +23 -2
- package/skills/deploy/references/observability.md +146 -0
- package/skills/design/SKILL.md +15 -1
- package/skills/graft/SKILL.md +24 -8
- package/skills/onboard/SKILL.md +45 -0
- package/skills/perf/SKILL.md +4 -1
- package/skills/plan/SKILL.md +70 -7
- package/skills/plan/references/boundary-artifacts.md +127 -0
- package/skills/plan/references/plan-templates.md +28 -9
- package/skills/plan/references/vertical-slice.md +8 -6
- package/skills/preflight/SKILL.md +9 -3
- package/skills/review/SKILL.md +4 -2
- package/skills/skill-router/SKILL.md +2 -0
- package/skills/test/SKILL.md +15 -8
- package/skills/verification/SKILL.md +39 -7
package/skills/ba/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: ba
|
|
|
3
3
|
description: "Business Analyst agent. Use when starting a new feature requiring requirements elicitation BEFORE plan or cook. 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: "1.
|
|
6
|
+
version: "1.2.0"
|
|
7
7
|
layer: L2
|
|
8
8
|
model: opus
|
|
9
9
|
group: creation
|
|
@@ -44,6 +44,7 @@ Output is a Requirements Document → hand off to rune:plan for implementation p
|
|
|
44
44
|
- `cook` (L1): before Phase 2 PLAN, when task is non-trivial
|
|
45
45
|
- `scaffold` (L1): Phase 1, before any project generation
|
|
46
46
|
- `plan` (L2): when plan receives vague requirements
|
|
47
|
+
- `brainstorm` (L2): standalone ideation that picked an approach for a new feature with no spec — hands the chosen approach to `ba` for requirements before `plan`
|
|
47
48
|
- `mcp-builder` (L2): requirements elicitation before MCP server design
|
|
48
49
|
- User: `/rune ba` direct invocation
|
|
49
50
|
|
|
@@ -389,6 +390,7 @@ Run each, label verdict 🟢 pass / 🟡 warn / 🔴 fail:
|
|
|
389
390
|
| # | Check | 🔴 Fail | 🟢 Pass |
|
|
390
391
|
|---|-------|---------|---------|
|
|
391
392
|
| 1 | Every Acceptance Criterion traces to a User Story | AC orphaned | 1:N mapping clear |
|
|
393
|
+
| 1b | Every EARS `FR-n` (Step 4.5) traces up to a User Story AND down to an AC | FR has no AC (untested promise) or no story (orphan behavior) | FR → story + AC both present |
|
|
392
394
|
| 2 | Every Business Rule (Q5) is enforced in an AC or Exception Flow | Rule has no enforcement path | Rule → specific AC or exception |
|
|
393
395
|
| 3 | Scope IN ∩ Scope OUT = ∅ | Direct overlap in phrasing | Sets disjoint |
|
|
394
396
|
| 4 | Every user-story flow has a terminal state | State loop without exit condition | Terminal state explicit |
|
|
@@ -402,6 +404,7 @@ Run each, label verdict 🟢 pass / 🟡 warn / 🔴 fail:
|
|
|
402
404
|
```
|
|
403
405
|
Logic Consistency Report:
|
|
404
406
|
1. AC → User Story: 🟢 all AC trace to US-1 or US-2
|
|
407
|
+
1b. EARS FR → story+AC: 🟢 FR-1..FR-5 each map to a story and an AC
|
|
405
408
|
2. Business rule → AC: 🟡 "no duplicate emails" cited — exception flow missing
|
|
406
409
|
3. Scope disjoint: 🟢
|
|
407
410
|
4. Terminal states: 🟢
|
|
@@ -441,12 +444,44 @@ Based on all gathered information, produce:
|
|
|
441
444
|
**Dependencies** (things that must exist before we can build):
|
|
442
445
|
- [APIs, services, libraries, access, existing code]
|
|
443
446
|
|
|
447
|
+
### Step 4.5 — Functional Requirements (EARS)
|
|
448
|
+
<MUST-READ path="references/ears-format.md" trigger="when writing the functional-requirements section for a Feature/Integration/Greenfield requirement"/>
|
|
449
|
+
|
|
450
|
+
Translate each in-scope item (Step 4) into atomic, testable **functional requirements** using EARS (Easy Approach to Requirements Syntax). EARS sits between user stories (WHY) and acceptance criteria (HOW we prove it) — it names exactly WHAT the system shall do, with an explicit trigger or condition.
|
|
451
|
+
|
|
452
|
+
Pick the simplest EARS template that fits each behavior; give each a stable ID (`FR-1`, `FR-2`, …):
|
|
453
|
+
|
|
454
|
+
| Type | Template |
|
|
455
|
+
|------|----------|
|
|
456
|
+
| Ubiquitous | The `<system>` shall `<response>`. |
|
|
457
|
+
| Event-driven | When `<trigger>`, the `<system>` shall `<response>`. |
|
|
458
|
+
| State-driven | While `<state>`, the `<system>` shall `<response>`. |
|
|
459
|
+
| Optional | Where `<feature is included>`, the `<system>` shall `<response>`. |
|
|
460
|
+
| Unwanted | If `<unwanted condition>`, then the `<system>` shall `<response>`. |
|
|
461
|
+
| Complex | While `<state>`, when `<trigger>`, the `<system>` shall `<response>`. |
|
|
462
|
+
|
|
463
|
+
```
|
|
464
|
+
FR-1 The API shall return responses in JSON.
|
|
465
|
+
FR-2 When a request omits a valid auth token, the API shall respond with HTTP 401.
|
|
466
|
+
FR-3 If the payment provider times out, then the system shall mark the order pending and queue a retry.
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Rules (full guidance in [references/ears-format.md](references/ears-format.md)):
|
|
470
|
+
- **One `shall` per requirement** — compound "shall do A and B" splits into two `FR-n`.
|
|
471
|
+
- **Named subject, testable response** — never "it shall handle gracefully". Move measurable limits into the response; pure performance targets stay in NFRs (Step 6).
|
|
472
|
+
- **Don't smuggle HOW** — observable behavior only; leave implementation to `plan`.
|
|
473
|
+
- Every `FR-n` traces up to a User Story and down to an Acceptance Criterion (checked in Step 3.6).
|
|
474
|
+
|
|
475
|
+
**Skip EARS** for Bug Fix and Refactor types (no new behavior to specify). For plumbing/integration, a few event-driven + unwanted-behavior lines suffice — don't pad with ubiquitous filler. EARS is a format recommendation, not a gate.
|
|
476
|
+
|
|
444
477
|
### Step 5 — User Stories & Acceptance Criteria
|
|
445
478
|
|
|
446
479
|
For each in-scope feature, generate:
|
|
447
480
|
|
|
448
481
|
```
|
|
449
|
-
US-1: As a [persona], I want to [action] so that [benefit]
|
|
482
|
+
US-1 [P1]: As a [persona], I want to [action] so that [benefit]
|
|
483
|
+
Independent Test: [specific action proving this story works end-to-end on its own —
|
|
484
|
+
e.g., "submit the form with valid data and see the saved record listed"]
|
|
450
485
|
AC-1.1: GIVEN [context] WHEN [action] THEN [result]
|
|
451
486
|
AC-1.2: GIVEN [error case] WHEN [action] THEN [error handling]
|
|
452
487
|
AC-1.3: GIVEN [edge case] WHEN [action] THEN [graceful behavior]
|
|
@@ -454,8 +489,28 @@ US-1: As a [persona], I want to [action] so that [benefit]
|
|
|
454
489
|
|
|
455
490
|
Rules:
|
|
456
491
|
- Primary user story first, then edge cases
|
|
492
|
+
- **Every story carries a priority**: `P1` = MVP-critical (the P1 set alone must be a viable, demoable product), `P2` = important, `P3` = nice-to-have. Implementing ONLY the P1 stories must still yield a working feature
|
|
493
|
+
- **Every story carries an Independent Test** — one concrete user action that proves the story end-to-end (through UI, logic, AND data if the story touches them). If no single action can prove it, the story is sliced wrong — split or merge until it can. This field is what downstream verification gates (plan's Coverage Gate, `converge`'s gap scan, completion-gate's evidence trail) trace against
|
|
457
494
|
- Every user story has at least 2 acceptance criteria (happy path + error)
|
|
458
495
|
- Acceptance criteria are TESTABLE — they become test cases in Phase 3
|
|
496
|
+
- Each AC proves a specific `FR-n` from Step 4.5 — cite it (`AC-1.2 → FR-3`). Every unwanted-behavior `FR` (the `If …` lines) needs an error-path AC; that's where EARS earns its keep
|
|
497
|
+
- An AC whose THEN clause stops at the UI ("THEN the button shows a spinner") for a story that persists or fetches data is INCOMPLETE — the THEN must name the observable outcome ("THEN the order appears in the list / the record is persisted")
|
|
498
|
+
|
|
499
|
+
### Step 5.5 — Key Entities (mandatory if feature involves data)
|
|
500
|
+
|
|
501
|
+
If ANY user story creates, reads, updates, or deletes data, list the key entities — WHAT the data is, not HOW it's stored (no table names, no column types, no ORM detail):
|
|
502
|
+
|
|
503
|
+
```
|
|
504
|
+
## Key Entities
|
|
505
|
+
- **Order**: what a customer submits — items, quantities, status (draft → submitted → fulfilled). One User has many Orders.
|
|
506
|
+
- **User**: the person placing orders — identity, contact. Referenced by Order.
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Rules:
|
|
510
|
+
- One line per entity: name, what it represents, key attributes (plain language), relationships
|
|
511
|
+
- State-bearing entities name their lifecycle states — these become the state machine in requirements.mermaid
|
|
512
|
+
- This section SEEDS `plan`'s data-model.md — a story that touches data but has no entity here is a spec gap (plan will bounce it back)
|
|
513
|
+
- Skip entirely for stateless features (pure computation, styling, config)
|
|
459
514
|
|
|
460
515
|
### Step 6 — Non-Functional Requirements (NFRs)
|
|
461
516
|
|
|
@@ -538,7 +593,13 @@ Created: [date] | BA Session: [summary]
|
|
|
538
593
|
- Affected systems: [what]
|
|
539
594
|
|
|
540
595
|
## User Stories
|
|
541
|
-
[from Step 5]
|
|
596
|
+
[from Step 5 — each with [P1|P2|P3] priority and Independent Test]
|
|
597
|
+
|
|
598
|
+
## Functional Requirements
|
|
599
|
+
[from Step 4.5 — EARS-format FR-n list; skip for Bug Fix/Refactor]
|
|
600
|
+
|
|
601
|
+
## Key Entities
|
|
602
|
+
[from Step 5.5 — mandatory if feature involves data; omit section for stateless features]
|
|
542
603
|
|
|
543
604
|
## Scope
|
|
544
605
|
### In Scope
|
|
@@ -597,40 +658,42 @@ Skip state machine if feature is stateless (simple CRUD with no lifecycle). Sequ
|
|
|
597
658
|
|
|
598
659
|
#### Artifact 3: tasks.md
|
|
599
660
|
|
|
600
|
-
Pre-broken implementation tasks by layer. Plan refines this backbone, does not create from scratch. Save to `.rune/features/<feature-name>/tasks.md`:
|
|
661
|
+
Pre-broken implementation tasks **grouped by user story** (vertical slices), NOT by layer. Plan refines this backbone, does not create from scratch. Save to `.rune/features/<feature-name>/tasks.md`:
|
|
601
662
|
|
|
602
663
|
```markdown
|
|
603
664
|
# Implementation Tasks: [Feature Name]
|
|
604
665
|
|
|
605
|
-
##
|
|
606
|
-
|
|
607
|
-
- [ ]
|
|
608
|
-
- [ ]
|
|
666
|
+
## Foundational (blocking prerequisites)
|
|
667
|
+
> Shared infrastructure NO story can start without. Keep minimal.
|
|
668
|
+
- [ ] Schema/migrations for Key Entities shared by 2+ stories
|
|
669
|
+
- [ ] Auth/routing/middleware skeleton (only if 2+ stories need it)
|
|
609
670
|
|
|
610
|
-
##
|
|
611
|
-
|
|
612
|
-
- [ ]
|
|
613
|
-
- [ ]
|
|
671
|
+
## US-1 [P1]: [story title]
|
|
672
|
+
> Layer order WITHIN the story: Data → Logic → Endpoint → UI → Test. UI never first.
|
|
673
|
+
- [ ] Data: [entity/migration this story owns, if not Foundational]
|
|
674
|
+
- [ ] Logic: [each Business Rule this story enforces → one task]
|
|
675
|
+
- [ ] Endpoint: [handler/service/API this story calls — skip only if story is pure-UI]
|
|
676
|
+
- [ ] UI: [component/surface — calls the Endpoint task above; a UI element and the
|
|
677
|
+
endpoint it calls are ONE story's tasks, never split across stories]
|
|
678
|
+
- [ ] Test: [each AC of this story → one test; happy path + error]
|
|
679
|
+
- **Checkpoint**: US-1 independently functional — run its Independent Test
|
|
614
680
|
|
|
615
|
-
##
|
|
616
|
-
- [ ]
|
|
617
|
-
- [ ] Contract schema from AC (request/response)
|
|
618
|
-
- [ ] Error handling for [each AC error]
|
|
619
|
-
|
|
620
|
-
## Test Layer
|
|
621
|
-
- [ ] Unit: [each business rule → one test]
|
|
622
|
-
- [ ] Integration: [each AC happy path]
|
|
623
|
-
- [ ] Regression: [each AC error case]
|
|
681
|
+
## US-2 [P2]: [story title]
|
|
682
|
+
- [ ] ... (same internal structure)
|
|
624
683
|
|
|
625
684
|
## NFR Verification
|
|
626
685
|
- [ ] [each NFR from Step 6 → one measurement task]
|
|
627
686
|
```
|
|
628
687
|
|
|
629
688
|
Derivation rules:
|
|
630
|
-
- 1 User Story →
|
|
631
|
-
- 1 Business Rule → 1 Logic task + 1
|
|
632
|
-
- 1 AC → ≥1 Test task (happy path + error)
|
|
689
|
+
- 1 User Story → 1 `## US-n` section containing ALL its layers (data through test) — a story section with only UI/Endpoint tasks and no Logic/Data/Test is a broken slice; a UI task with no Endpoint task above it (and no pure-UI justification) is a dead button in waiting
|
|
690
|
+
- 1 Business Rule → 1 Logic task + 1 test task, inside the story that enforces it
|
|
691
|
+
- 1 AC → ≥1 Test task inside its story (happy path + error)
|
|
633
692
|
- 1 NFR → 1 NFR Verification task
|
|
693
|
+
- Foundational holds ONLY what 2+ stories share — story-specific work stays in the story
|
|
694
|
+
- P1 sections first; completing all P1 sections + Foundational = viable MVP
|
|
695
|
+
|
|
696
|
+
**Why story-grouped**: layer-grouped backbones ("all Data → all Logic → all Interface") invite the executor to finish the Interface layer and stop — shipping UI with no wiring. Story-grouped means every completed section is a demoable end-to-end slice.
|
|
634
697
|
|
|
635
698
|
#### Handoff
|
|
636
699
|
|
|
@@ -683,6 +746,10 @@ Inside `requirements.md` the **Decision Classification** table MUST appear verba
|
|
|
683
746
|
8. MUST NOT write code or plan implementation — BA produces WHAT, plan produces HOW
|
|
684
747
|
9. MUST ask ONE question at a time by default; bundle yes/no batches only after user shows concise replies
|
|
685
748
|
10. MUST NOT skip BA for non-trivial tasks — "just build it" gets redirected to Question 1
|
|
749
|
+
11. MUST assign [P1|P2|P3] priority to every user story — the P1 set alone must be a viable, demoable product
|
|
750
|
+
12. MUST give every user story an Independent Test — one concrete action proving it end-to-end
|
|
751
|
+
13. MUST list Key Entities when any story touches data (Step 5.5) — a data-touching story with no entity is a spec gap
|
|
752
|
+
14. MUST group tasks.md by user story (vertical slices), never by layer
|
|
686
753
|
|
|
687
754
|
## Returns
|
|
688
755
|
|
|
@@ -690,7 +757,7 @@ Inside `requirements.md` the **Decision Classification** table MUST appear verba
|
|
|
690
757
|
|----------|--------|----------|
|
|
691
758
|
| Requirements document | Markdown | `.rune/features/<feature-name>/requirements.md` |
|
|
692
759
|
| Visual model | Mermaid (sequence + optional state machine) | `.rune/features/<feature-name>/requirements.mermaid` |
|
|
693
|
-
| Implementation task backbone | Markdown checklist by
|
|
760
|
+
| Implementation task backbone | Markdown checklist by user story (vertical slices — Data→Logic→Endpoint→UI→Test per US-n) | `.rune/features/<feature-name>/tasks.md` |
|
|
694
761
|
| Logic Consistency Report | Markdown section | Embedded in requirements.md |
|
|
695
762
|
| Ambiguity + Completeness scores | Markdown display blocks | Embedded in requirements.md |
|
|
696
763
|
|
|
@@ -718,9 +785,17 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
718
785
|
| 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 |
|
|
719
786
|
| 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) |
|
|
720
787
|
| Handing off to plan with unresolved 🔴 consistency fails | CRITICAL | Step 3.6 gate: 1+ 🔴 = BLOCK. 🟡 allowed only when logged as Risk in requirements.md |
|
|
788
|
+
| Vague functional requirements ("system shall be fast/user-friendly") instead of EARS | MEDIUM | Step 4.5: every FR uses an EARS template with a named subject + testable response; vague targets move to NFRs (Step 6) |
|
|
789
|
+
| Compound EARS requirement ("shall do A and B and C") hiding untested behavior | MEDIUM | Step 4.5: one `shall` per `FR-n` — split compounds so each behavior gets its own AC |
|
|
790
|
+
| EARS `FR-n` with no acceptance criterion (untested promise) | MEDIUM | Step 3.6 check 1b: every FR traces down to an AC and up to a User Story |
|
|
791
|
+
| Manufacturing EARS requirements for a bug fix or refactor | LOW | Step 4.5: skip EARS when there's no new behavior to specify — format recommendation, not ceremony |
|
|
721
792
|
| 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 |
|
|
722
793
|
| 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 |
|
|
723
|
-
| tasks.md
|
|
794
|
+
| tasks.md grouped by layer instead of by story | HIGH | Story-grouped derivation: 1 US → 1 section with ALL its layers (Data→Logic→Interface→Test). Layer-grouped backbones invite "finish the UI layer and stop" — the dead-button root cause |
|
|
795
|
+
| Story with UI tasks but no Logic/Data/Test tasks (broken slice) | HIGH | Step 7 Artifact 3 rule: a `## US-n` section containing only UI/Endpoint tasks is invalid — the UI element and the endpoint it calls belong to the SAME story |
|
|
796
|
+
| Story without an Independent Test (unprovable slice) | HIGH | Step 5 rule: every story names one concrete action proving it end-to-end. Can't name one → story is sliced wrong |
|
|
797
|
+
| AC whose THEN stops at the UI for a data-touching story | HIGH | Step 5 rule: THEN must name the observable outcome (record persisted / data returned), not just the widget state |
|
|
798
|
+
| Data-touching story with no Key Entity listed | MEDIUM | Step 5.5: plan bounces specs where a story touches data absent from Key Entities |
|
|
724
799
|
| 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 |
|
|
725
800
|
| 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 |
|
|
726
801
|
| 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 |
|
|
@@ -741,7 +816,11 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
741
816
|
- Ambiguity Score computed and displayed — must be ≤ 40% before proceeding (≤ 25% preferred)
|
|
742
817
|
- Hidden requirements discovered and confirmed with user
|
|
743
818
|
- Scope defined (in/out/assumptions/dependencies)
|
|
744
|
-
-
|
|
819
|
+
- Functional requirements written in EARS format (FR-n) — skip for Bug Fix/Refactor
|
|
820
|
+
- User stories with testable acceptance criteria produced, each AC citing the `FR-n` it proves
|
|
821
|
+
- Every story has a [P1|P2|P3] priority and an Independent Test; P1 set alone = viable MVP
|
|
822
|
+
- Key Entities listed (if feature involves data) — seeds plan's data-model.md
|
|
823
|
+
- tasks.md grouped by user story (vertical slices), Foundational section minimal
|
|
745
824
|
- Non-functional requirements assessed (relevant ones only)
|
|
746
825
|
- Logic Consistency Report produced — 0 🔴 before handoff (🟡 logged as Risks)
|
|
747
826
|
- Tiered recommendations generated (Quick Win / Differentiation / Moat) — skip for Bug Fix/Refactor
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# EARS — Easy Approach to Requirements Syntax
|
|
2
|
+
|
|
3
|
+
EARS (Mavin et al., Rolls-Royce) constrains a functional requirement to one of a
|
|
4
|
+
few sentence templates. The constraint is the value: every requirement becomes a
|
|
5
|
+
single, atomic, testable "shall" statement with an explicit trigger or condition —
|
|
6
|
+
which kills the two classic requirement defects, **ambiguity** and **compound scope**.
|
|
7
|
+
|
|
8
|
+
EARS sits **between** user stories and acceptance criteria:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
User Story (WHY) → EARS Functional Requirement (WHAT the system shall do) → Acceptance Criterion (HOW we prove it)
|
|
12
|
+
As a user, I want… → When X, the system shall Y. → GIVEN … WHEN … THEN …
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
A user story is intent. An AC is a test. EARS is the contract in between — the
|
|
16
|
+
precise behavior the test verifies. Skipping it lets vague stories ("make login
|
|
17
|
+
smooth") flow straight into vague tests.
|
|
18
|
+
|
|
19
|
+
## The 5 Templates (+ 1 combined)
|
|
20
|
+
|
|
21
|
+
Give each requirement a stable ID (`FR-1`, `FR-2`, …). Pick the **simplest**
|
|
22
|
+
template that fits — escalate only when the behavior genuinely needs it.
|
|
23
|
+
|
|
24
|
+
| # | Type | Template | Use when |
|
|
25
|
+
|---|------|----------|----------|
|
|
26
|
+
| 1 | **Ubiquitous** | The `<system>` shall `<response>`. | Always-active behavior, no trigger or precondition. |
|
|
27
|
+
| 2 | **Event-driven** | When `<trigger>`, the `<system>` shall `<response>`. | A discrete event/input causes the behavior. |
|
|
28
|
+
| 3 | **State-driven** | While `<state>`, the `<system>` shall `<response>`. | Behavior holds for the duration of a state. |
|
|
29
|
+
| 4 | **Optional** | Where `<feature is included>`, the `<system>` shall `<response>`. | Behavior exists only when an optional feature/config is present. |
|
|
30
|
+
| 5 | **Unwanted** | If `<unwanted condition>`, then the `<system>` shall `<response>`. | Error handling, failure modes, abuse, invalid input. |
|
|
31
|
+
| 6 | **Complex** | While `<state>`, when `<trigger>`, the `<system>` shall `<response>`. | A trigger handled differently depending on state. |
|
|
32
|
+
|
|
33
|
+
### Examples (good)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
FR-1 (ubiquitous) The API shall return responses in JSON.
|
|
37
|
+
FR-2 (event-driven) When a request omits a valid auth token, the API shall respond with HTTP 401.
|
|
38
|
+
FR-3 (state-driven) While the account is in maintenance mode, the system shall reject all write operations.
|
|
39
|
+
FR-4 (optional) Where rate limiting is enabled, the API shall reject the 101st request per minute with HTTP 429.
|
|
40
|
+
FR-5 (unwanted) If the payment provider times out, then the system shall mark the order pending and queue a retry.
|
|
41
|
+
FR-6 (complex) While a checkout is in progress, when the cart total changes, the system shall recompute tax before payment.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Rules for a well-formed EARS requirement
|
|
45
|
+
|
|
46
|
+
1. **Named subject, never "it".** The `<system>` is a concrete component ("the
|
|
47
|
+
API", "the scheduler", "the login form") — not a pronoun.
|
|
48
|
+
2. **One shall per requirement.** Two behaviors → two `FR-n`. Compound "shall do A
|
|
49
|
+
and B" hides one of them from testing.
|
|
50
|
+
3. **Testable response.** "shall respond with HTTP 401" is testable; "shall handle
|
|
51
|
+
it gracefully" / "shall be fast" is not. Move measurable limits into the response
|
|
52
|
+
("within 200 ms", "with HTTP 429"). Pure performance targets stay in NFRs (Step 6).
|
|
53
|
+
4. **Trigger/condition is observable.** "When the user clicks Submit" — yes. "When
|
|
54
|
+
appropriate" — no.
|
|
55
|
+
5. **Active voice.** "the system shall reject…" not "requests are rejected".
|
|
56
|
+
6. **Don't smuggle HOW.** EARS captures observable behavior, not implementation
|
|
57
|
+
("…shall store the token in Redis" → leave Redis to plan; say "…shall persist the
|
|
58
|
+
session token").
|
|
59
|
+
|
|
60
|
+
## Anti-patterns
|
|
61
|
+
|
|
62
|
+
| Smell | Why it fails | Fix |
|
|
63
|
+
|-------|--------------|-----|
|
|
64
|
+
| "The system shall be user-friendly." | Not testable, no trigger. | Reframe as a concrete event/response, or move to NFR/UX. |
|
|
65
|
+
| "When X, the system shall do A and B and C." | Compound — partial passes hide. | Split into 3 EARS requirements. |
|
|
66
|
+
| "It shall validate input." | "It" is ambiguous; "validate" is vague. | "If a field fails validation, then the form shall display the field-level error." |
|
|
67
|
+
| Every requirement is Ubiquitous. | Triggers/states were dropped → context lost. | Most real requirements are event- or unwanted-behavior. Look for the trigger. |
|
|
68
|
+
| EARS restates the user story verbatim. | No added precision. | The story is WHY; the EARS line is the specific observable behavior. |
|
|
69
|
+
|
|
70
|
+
## Traceability (feeds Step 3.6 Logic Consistency)
|
|
71
|
+
|
|
72
|
+
EARS is only worth the ceremony if it chains:
|
|
73
|
+
|
|
74
|
+
- Every `FR-n` traces **up** to at least one User Story (it exists for a reason).
|
|
75
|
+
- Every `FR-n` traces **down** to at least one Acceptance Criterion (it gets proven).
|
|
76
|
+
- Every **unwanted-behavior** requirement (`If …`) should map to an error-path AC —
|
|
77
|
+
this is where EARS earns its keep, by forcing failure modes to be named, not assumed.
|
|
78
|
+
|
|
79
|
+
An `FR-n` with no AC is an untested promise. An AC with no `FR-n` is a test for a
|
|
80
|
+
behavior nobody specified. Both are consistency failures.
|
|
81
|
+
|
|
82
|
+
## When to keep it light
|
|
83
|
+
|
|
84
|
+
- **Bug fix / Refactor** → skip EARS entirely (no new behavior to specify).
|
|
85
|
+
- **Plumbing / Integration** → a handful of event-driven + unwanted-behavior lines is
|
|
86
|
+
usually enough; don't manufacture ubiquitous requirements to pad the list.
|
|
87
|
+
- **Small feature** → 3–7 requirements is typical. If you have 30, the feature is an
|
|
88
|
+
epic — hand the split to `plan`.
|
|
89
|
+
|
|
90
|
+
EARS is a **format recommendation**, not a gate. The goal is precision per
|
|
91
|
+
requirement, not requirement count.
|
|
@@ -103,7 +103,8 @@ Direct API call ≠ Wrapper/middleware layer ≠ Reverse engineering ≠ Browser
|
|
|
103
103
|
|
|
104
104
|
## Calls (outbound)
|
|
105
105
|
|
|
106
|
-
- `
|
|
106
|
+
- `ba` (L2): when no requirements spec exists yet AND brainstorm is a standalone entry point — hand off for requirement elicitation BEFORE plan (never when `ba` is the caller — would loop)
|
|
107
|
+
- `plan` (L2): when idea is selected and needs structuring into actionable steps (spec already exists, or task is a refactor/config change with no new behavior)
|
|
107
108
|
- `design` (L2): when selected approach has UI/UX implications — hand off visual decisions
|
|
108
109
|
- `research` (L3): gather data for informed brainstorming (existing solutions, benchmarks)
|
|
109
110
|
- `trend-scout` (L3): market context and trends for product-oriented brainstorming
|
|
@@ -124,6 +125,7 @@ Direct API call ≠ Wrapper/middleware layer ≠ Reverse engineering ≠ Browser
|
|
|
124
125
|
## Cross-Hub Connections
|
|
125
126
|
|
|
126
127
|
- `brainstorm` ↔ `plan` — bidirectional: brainstorm generates options → plan structures the chosen one, plan needs exploration → brainstorm ideates
|
|
128
|
+
- `brainstorm` → `ba` — a standalone brainstorm that picks an approach for a NEW feature with no requirements spec routes to `ba` first (WHAT before HOW). Suppressed when `ba` is the caller — that direction is `ba` → `brainstorm` and re-invoking would loop.
|
|
127
129
|
|
|
128
130
|
## Reasoning Frameworks
|
|
129
131
|
|
|
@@ -374,12 +376,33 @@ For each rejected option, state:
|
|
|
374
376
|
|
|
375
377
|
The "Revisit if" clause is critical — it turns a rejection into a future trigger, not a permanent dismissal.
|
|
376
378
|
|
|
377
|
-
### Step 5 —
|
|
378
|
-
|
|
379
|
+
### Step 5 — Hand Off (Spec Gate → BA if missing, then Plan)
|
|
380
|
+
|
|
381
|
+
Before structuring the chosen approach, check whether a requirements spec exists. Choosing an approach answers **HOW** — it does NOT answer **WHAT** (requirements, acceptance criteria, scope boundaries, hidden requirements). Handing a bare approach straight to `plan` produces a plan with no spec behind it — the "plan without spec" gap that turns into vibe-coding.
|
|
382
|
+
|
|
383
|
+
**Spec-presence gate:**
|
|
384
|
+
|
|
385
|
+
1. `Glob` `.rune/features/*/requirements.md`.
|
|
386
|
+
2. **Route to `rune:plan` directly** if ANY of:
|
|
387
|
+
- A requirements doc already exists (BA ran earlier this session, or a continuation).
|
|
388
|
+
- Brainstorm was invoked BY `ba` or `cook` (mode/caller from Step 0) — the spec step is already in the chain; re-invoking `ba` would loop.
|
|
389
|
+
- The chosen approach implies NO new user-facing behavior (pure refactor, config change, infra swap, dependency choice).
|
|
390
|
+
3. **Route to `rune:ba` FIRST** (then `ba` hands to `plan`) if ALL of:
|
|
391
|
+
- No requirements doc exists, AND
|
|
392
|
+
- Brainstorm is a standalone entry point (user ran `/rune brainstorm …` directly), AND
|
|
393
|
+
- The chosen approach implies new feature behavior (a new capability, workflow, or product surface).
|
|
394
|
+
|
|
395
|
+
<HARD-GATE>
|
|
396
|
+
Do NOT skip `ba` on the way to `plan` for a NEW feature just because an approach was already chosen.
|
|
397
|
+
Approach ≠ requirements. A plan built on a chosen approach but no acceptance criteria is a plan without a spec.
|
|
398
|
+
Loop guard: if `ba` was the caller, hand back to `plan` normally — NEVER re-invoke `ba`.
|
|
399
|
+
</HARD-GATE>
|
|
400
|
+
|
|
401
|
+
Pass to the next skill (`ba` or `plan`):
|
|
379
402
|
- The chosen option name
|
|
380
|
-
- Key constraints to honor
|
|
381
|
-
- Any risks identified that
|
|
382
|
-
- The Not Doing list (so
|
|
403
|
+
- Key constraints to honor
|
|
404
|
+
- Any risks identified that must be mitigated
|
|
405
|
+
- The Not Doing list (so the next skill knows what's explicitly out of scope)
|
|
383
406
|
|
|
384
407
|
If the user rejects the recommendation, return to Step 2 with adjusted constraints and regenerate.
|
|
385
408
|
|
|
@@ -456,6 +479,7 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
456
479
|
| [Rescue] Skipping Collision-Zone/Inversion frameworks | HIGH | Conventional thinking already failed — MUST use at least one breakthrough framework |
|
|
457
480
|
| [Rescue] All approaches are "clean/proper" — no hacky option | MEDIUM | At least 1 must be unconventional — wrappers, reverse-engineering, debug mode abuse, proxy layers |
|
|
458
481
|
| Calling plan directly instead of presenting options first | CRITICAL | Steps 2-3 are mandatory — present options, get approval, THEN call plan |
|
|
482
|
+
| Handing a chosen approach straight to `plan` for a new feature with no requirements spec | CRITICAL | Step 5 spec-presence gate: standalone brainstorm + no `requirements.md` + new behavior → route to `ba` FIRST. Approach (HOW) is not a spec (WHAT). Skipping `ba` here is the "plan without spec" vibe-coding gap |
|
|
459
483
|
| "Creative" options that ignore stated constraints | MEDIUM | Every option must satisfy the constraints declared in Step 1 |
|
|
460
484
|
| Missing "Not Doing" list — rejected options not documented | MEDIUM | Step 4.75 is MANDATORY — every rejected option needs trade-off rationale + "Revisit if" condition |
|
|
461
485
|
| [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 |
|
|
@@ -470,7 +494,8 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
470
494
|
- User has explicitly approved an approach (not implied or assumed)
|
|
471
495
|
- Selected option documented with rationale
|
|
472
496
|
- Constraints for plan phase listed explicitly
|
|
473
|
-
- `
|
|
497
|
+
- Step 5 spec-presence gate evaluated — routed to `ba` (new feature, no spec, standalone) or `plan` (spec exists, or ba/cook was the caller, or no new behavior)
|
|
498
|
+
- Next skill (`ba` or `plan`) called with the approved approach and constraints
|
|
474
499
|
|
|
475
500
|
## Cost Profile
|
|
476
501
|
|
|
@@ -4,7 +4,7 @@ description: "Validates agent claims against evidence trail. Use when verifying
|
|
|
4
4
|
user-invocable: false
|
|
5
5
|
metadata:
|
|
6
6
|
author: runedev
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.9.0"
|
|
8
8
|
layer: L3
|
|
9
9
|
model: haiku
|
|
10
10
|
group: validation
|
|
@@ -189,9 +189,9 @@ If an axis has ZERO claims → flag as gap: "No [Completeness/Correctness/Cohere
|
|
|
189
189
|
UNCONFIRMED — 1 claim lacks evidence, 1 contradicted. Cannot proceed to commit.
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
### Step 4.5 — Cross-Phase
|
|
192
|
+
### Step 4.5 — Integration Check (Cross-Phase + Cross-Layer)
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
Check for integration gaps — between phases AND between layers:
|
|
195
195
|
|
|
196
196
|
1. **Orphaned exports** — files/functions created in this phase that claim to be used by future phases (see `## Cross-Phase Context → Exports`) but are not yet importable:
|
|
197
197
|
```
|
|
@@ -201,19 +201,28 @@ When validating a completed phase in a multi-phase plan, check for integration g
|
|
|
201
201
|
- Expected export missing entirely → UNCONFIRMED ("Phase N claims to export X but X not found")
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
-
2. **Uncalled routes** — API endpoints added in this
|
|
205
|
-
-
|
|
206
|
-
-
|
|
204
|
+
2. **Uncalled routes** — API endpoints added in this task but not wired to any frontend/consumer:
|
|
205
|
+
- **BLOCK** if the route was created in THIS task AND a user story/AC references the interaction it serves — an uncalled route behind a story's UI is a dead path, not future work
|
|
206
|
+
- WARN (deferral allowed) ONLY if a NAMED future-phase task explicitly references consuming this route (verifiable in the master plan/phase files — "a future phase will handle it" without a task ID is not an excuse)
|
|
207
207
|
|
|
208
208
|
3. **Auth gaps** — new endpoints or pages without authentication/authorization:
|
|
209
209
|
- `Grep` for route handlers without auth middleware
|
|
210
210
|
- Flag as WARN (may be intentional for public endpoints, but worth checking)
|
|
211
211
|
|
|
212
|
-
4. **E2E flow trace** — for the primary user flow this
|
|
213
|
-
- Trace: entry point → business logic → data layer → response
|
|
212
|
+
4. **E2E flow trace** — for the primary user flow this task enables:
|
|
213
|
+
- Trace: entry point → handler → business logic → data layer → response
|
|
214
214
|
- If any step in the chain is missing or stubbed → CONTRADICTED
|
|
215
215
|
|
|
216
|
-
**
|
|
216
|
+
**When this step is MANDATORY** (any one triggers it — single-phase tasks included):
|
|
217
|
+
- The diff touches BOTH a UI file (`.tsx/.jsx/.vue/.svelte/.html`) AND an api/service/data file — where "api/service/data file" = any file whose path contains a segment from: `api`, `routes`, `handlers`, `services`, `service`, `stores`, `store`, `db`, `database`, `models`, `repositories`, `repo`, `queries` — OR any file exporting functions matching `create*`/`update*`/`delete*`/`fetch*`/`save*`/`post*` verb patterns
|
|
218
|
+
- The feature spec has a `## Key Entities` section
|
|
219
|
+
- The task description contains any of these exact words: `click`, `submit`, `save`, `login`, `signup`, `search`, `checkout`, `upload`, `delete`, `order`, `pay` — EXCEPT when the phrase is explicitly local-only ("save to clipboard", "save locally", "client-side only")
|
|
220
|
+
- Multi-phase master plan (always, as before)
|
|
221
|
+
|
|
222
|
+
Skip ONLY when none of the above hold (pure-UI styling, pure-backend plumbing, docs/config).
|
|
223
|
+
"Single-phase" is NOT a skip reason — most dead-button escapes are single-phase tasks.
|
|
224
|
+
|
|
225
|
+
**De-dup**: if preflight (Step 4/4.5) or verification (Level 3.5) already flagged the same element/route in this session, cite the cross-reference instead of emitting a duplicate finding — one dead button = one finding + cross-refs, not three findings.
|
|
217
226
|
|
|
218
227
|
### Step 5 — Evidence Quality Gate
|
|
219
228
|
|
|
@@ -286,7 +295,9 @@ Completion Gate Report with status (CONFIRMED/UNCONFIRMED/CONTRADICTED), claim v
|
|
|
286
295
|
| Completion-gate itself claims "all confirmed" without evidence | CRITICAL | Gate report MUST include the evidence table — no table = report is invalid |
|
|
287
296
|
| Existence Theater — agent creates files but they're stubs | HIGH | Step 1b stub detection: grep for Placeholder/TODO/NotImplementedError in new files |
|
|
288
297
|
| Cross-phase integration gaps — exports exist but wrong signature | HIGH | Step 4.5: verify exports match Code Contracts from phase file |
|
|
289
|
-
| Phase complete but E2E flow broken — missing link in the chain |
|
|
298
|
+
| Phase complete but E2E flow broken — missing link in the chain | HIGH | Step 4.5 E2E flow trace: entry → handler → logic → data → response must all be connected |
|
|
299
|
+
| Skipping Step 4.5 because the task is single-phase | CRITICAL | Mandatory triggers: UI+data diff, Key Entities in spec, or interaction-implying task — single-phase is where most dead buttons escape |
|
|
300
|
+
| Excusing an uncalled route with "a future phase will wire it" (no task named) | HIGH | Step 4.5 #2: deferral requires a NAMED future-phase task referencing the route — vibes-deferral = BLOCK |
|
|
290
301
|
| Rubber-stamping — all CONFIRMED without scrutiny | HIGH | Default-FAIL mindset: actively seek 3-5 issues. Zero issues = red flag, apply skeptic sweep on weakest 2 claims |
|
|
291
302
|
| Partial completion claimed as full — 80% done but "implemented" | HIGH | Adversarial checklist: check for partial completion, scope mismatch, evidence-claim alignment |
|
|
292
303
|
| Self-Validation skipped — skill has checks but gate ignores them | HIGH | Step 1c: extract Self-Validation from skill's SKILL.md, treat each as implicit claim. Missing = UNCONFIRMED |
|