@rune-kit/rune 2.20.0 → 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 +12 -8
- package/package.json +1 -1
- package/skills/ba/SKILL.md +63 -26
- 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 +33 -5
- package/skills/deploy/SKILL.md +4 -2
- package/skills/design/SKILL.md +15 -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/skill-router/SKILL.md +2 -0
- package/skills/test/SKILL.md +15 -8
- package/skills/verification/SKILL.md +39 -7
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<strong>Less skills. Deeper connections.</strong><br>
|
|
7
7
|
A lean, interconnected skill ecosystem for AI coding assistants.<br>
|
|
8
|
-
|
|
8
|
+
65 skills · 204 connections · 43 signals · 13 platforms · MIT
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
Most skill ecosystems are either **too many isolated skills** (540+ that don't talk to each other) or **rigid pipelines** (A → B → C, if B fails everything stops).
|
|
25
25
|
|
|
26
|
-
Rune is a **mesh** —
|
|
26
|
+
Rune is a **mesh** — 65 skills with 204 connections + 43 signals across a 5-layer architecture. Skills call each other bidirectionally, forming resilient workflows that adapt when things go wrong.
|
|
27
27
|
|
|
28
28
|
```
|
|
29
29
|
Pipeline: A → B → C → D (B fails = stuck)
|
|
@@ -83,7 +83,11 @@ _Methodology: Claude Code CLI headless mode (`claude -p --output-format json`),
|
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
86
|
-
## What's New (v2.
|
|
86
|
+
## What's New (v2.21.0 — Convergence)
|
|
87
|
+
|
|
88
|
+
> **v2.21.0 (2026-07-03):** Kills the most expensive silent failure in AI-built apps: **the dead button** — UI renders, click does nothing, backend never existed. New `converge` skill (65th) re-reads your spec/plan/contracts as the sole source of intent and scans the ACTUAL code for `missing` / `partial` / `contradicts` / `unrequested` gaps, appending remediation tasks until spec and code converge (`cook` Phase 6.5, max 2 rounds then honest escalation). The whole chain got teeth: `ba` v1.2.0 emits story-sliced specs (P1/P2/P3 priorities, per-story **Independent Test**, **Key Entities**), `plan` v1.7.0 emits **contracts-first boundary artifacts** (`data-model.md` + `contracts/` + `quickstart.md`) with a P1 zero-coverage HARD-GATE and a Data→Logic→Endpoint→UI ordering law (UI is structurally last), `verification` v0.6.0 adds **Level 3.5 INTERACTION WIRED** (traces button → handler → route across React/Svelte/Vue syntax), `completion-gate` v1.9.0 makes the E2E flow trace mandatory for UI+data diffs (single-phase included), and `deploy` v0.8.0 warns before shipping UI+data changes with no wiring evidence. 3 new mesh signals (`convergence.gaps`, `convergence.clean`, `integration.verified`). Every gate is diff-scoped — legacy debt warns, new work fails.
|
|
89
|
+
|
|
90
|
+
### Previous (v2.20.0 — Spec Discipline)
|
|
87
91
|
|
|
88
92
|
> **v2.20.0 (2026-07-02):** Closes the "plan without spec" gap — a `brainstorm → plan → cook` chain no longer skips `ba`. Two new gates (`brainstorm` spec-presence + `cook` Phase 0 **Spec-Backfill Gate**) force requirements before code on every bypass path, not just brainstorm's. Batch also lands `ba` v1.1.0 (EARS `FR-n` functional-requirements layer), `adversary` v0.4.0 (reasoning-mode catalog + steelman-first), and a context-hook fix (session_id keying — no more false "100% compact"). Mesh **204 connections**, 1,559 tests.
|
|
89
93
|
|
|
@@ -215,7 +219,7 @@ cook ───emit:phase.complete────→ session-bridge
|
|
|
215
219
|
|
|
216
220
|
## What Rune Is (and Isn't)
|
|
217
221
|
|
|
218
|
-
Rune started as a **Claude Code plugin** and now compiles to **every major AI IDE**. Same
|
|
222
|
+
Rune started as a **Claude Code plugin** and now compiles to **every major AI IDE**. Same 65 skills, same mesh connections, same workflows — zero knowledge loss across platforms.
|
|
219
223
|
|
|
220
224
|
| | Rune Provides | Claude Code Provides |
|
|
221
225
|
|---|---|---|
|
|
@@ -307,14 +311,14 @@ npx @rune-kit/rune init --platform windsurf
|
|
|
307
311
|
npx @rune-kit/rune init --platform antigravity
|
|
308
312
|
```
|
|
309
313
|
|
|
310
|
-
This compiles all
|
|
314
|
+
This compiles all 65 skills into your IDE's rules format. Same knowledge, same workflows.
|
|
311
315
|
|
|
312
316
|
### Platform Comparison
|
|
313
317
|
|
|
314
318
|
| Feature | Claude Code | Cursor / Windsurf / Others |
|
|
315
319
|
|---------|-------------|---------------------------|
|
|
316
320
|
| Skills available | 64/64 | 64/64 |
|
|
317
|
-
| Mesh connections |
|
|
321
|
+
| Mesh connections | 204 sync + 43 signals (programmatic) | 204 sync + 43 signals (rule references) |
|
|
318
322
|
| Workflows & HARD-GATEs | Full | Full |
|
|
319
323
|
| Extension packs | 14 | 14 |
|
|
320
324
|
| Subagent parallelism | Native | Sequential fallback |
|
|
@@ -667,7 +671,7 @@ See [docs/MULTI-PLATFORM.md](docs/MULTI-PLATFORM.md) for the full architecture.
|
|
|
667
671
|
| Doc | What's inside |
|
|
668
672
|
|-----|---------------|
|
|
669
673
|
| [`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md) | Your first 5 minutes with Rune — install to first `/rune cook` |
|
|
670
|
-
| [`docs/SKILLS.md`](docs/SKILLS.md) | All
|
|
674
|
+
| [`docs/SKILLS.md`](docs/SKILLS.md) | All 65 skills, searchable by intent and layer |
|
|
671
675
|
| [`docs/SIGNALS.md`](docs/SIGNALS.md) | Canonical signal inventory — 25 events, emit/listen graph |
|
|
672
676
|
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | 5-layer mesh architecture reference |
|
|
673
677
|
| [`docs/VISION.md`](docs/VISION.md) | Philosophy — what Rune is and isn't |
|
|
@@ -683,7 +687,7 @@ See [docs/MULTI-PLATFORM.md](docs/MULTI-PLATFORM.md) for the full architecture.
|
|
|
683
687
|
Core Skills: 64 (L0: 1 │ L1: 5 │ L2: 30 │ L3: 28)
|
|
684
688
|
Extension Packs: 14 free + 9 pro + 4 business
|
|
685
689
|
Mesh Connections: 203 sync calls (rune doctor)
|
|
686
|
-
Mesh Signals:
|
|
690
|
+
Mesh Signals: 43 signals · 55 emit/listen edges (rune doctor)
|
|
687
691
|
Connections/Skill: 3.2 avg
|
|
688
692
|
Platforms: 8 (Claude Code, Cursor, Windsurf, Antigravity, Codex, OpenCode, OpenClaw, Generic)
|
|
689
693
|
Compiler: ~1400 LOC (parser + 8 transforms + 8 adapters + CLI)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rune-kit/rune",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "64-skill mesh for AI coding assistants — runtime auto-discipline via native hooks (Claude/Cursor/Windsurf/Antigravity), 5-layer architecture, 215+ connections, multi-platform compiler. v2.17 adds quarantine L3 for prompt-injection advisory on untrusted external content.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
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
|
|
@@ -479,7 +479,9 @@ Rules (full guidance in [references/ears-format.md](references/ears-format.md)):
|
|
|
479
479
|
For each in-scope feature, generate:
|
|
480
480
|
|
|
481
481
|
```
|
|
482
|
-
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"]
|
|
483
485
|
AC-1.1: GIVEN [context] WHEN [action] THEN [result]
|
|
484
486
|
AC-1.2: GIVEN [error case] WHEN [action] THEN [error handling]
|
|
485
487
|
AC-1.3: GIVEN [edge case] WHEN [action] THEN [graceful behavior]
|
|
@@ -487,9 +489,28 @@ US-1: As a [persona], I want to [action] so that [benefit]
|
|
|
487
489
|
|
|
488
490
|
Rules:
|
|
489
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
|
|
490
494
|
- Every user story has at least 2 acceptance criteria (happy path + error)
|
|
491
495
|
- Acceptance criteria are TESTABLE — they become test cases in Phase 3
|
|
492
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)
|
|
493
514
|
|
|
494
515
|
### Step 6 — Non-Functional Requirements (NFRs)
|
|
495
516
|
|
|
@@ -572,11 +593,14 @@ Created: [date] | BA Session: [summary]
|
|
|
572
593
|
- Affected systems: [what]
|
|
573
594
|
|
|
574
595
|
## User Stories
|
|
575
|
-
[from Step 5]
|
|
596
|
+
[from Step 5 — each with [P1|P2|P3] priority and Independent Test]
|
|
576
597
|
|
|
577
598
|
## Functional Requirements
|
|
578
599
|
[from Step 4.5 — EARS-format FR-n list; skip for Bug Fix/Refactor]
|
|
579
600
|
|
|
601
|
+
## Key Entities
|
|
602
|
+
[from Step 5.5 — mandatory if feature involves data; omit section for stateless features]
|
|
603
|
+
|
|
580
604
|
## Scope
|
|
581
605
|
### In Scope
|
|
582
606
|
### Out of Scope
|
|
@@ -634,40 +658,42 @@ Skip state machine if feature is stateless (simple CRUD with no lifecycle). Sequ
|
|
|
634
658
|
|
|
635
659
|
#### Artifact 3: tasks.md
|
|
636
660
|
|
|
637
|
-
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`:
|
|
638
662
|
|
|
639
663
|
```markdown
|
|
640
664
|
# Implementation Tasks: [Feature Name]
|
|
641
665
|
|
|
642
|
-
##
|
|
643
|
-
|
|
644
|
-
- [ ]
|
|
645
|
-
- [ ]
|
|
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)
|
|
646
670
|
|
|
647
|
-
##
|
|
648
|
-
|
|
649
|
-
- [ ]
|
|
650
|
-
- [ ]
|
|
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
|
|
651
680
|
|
|
652
|
-
##
|
|
653
|
-
- [ ]
|
|
654
|
-
- [ ] Contract schema from AC (request/response)
|
|
655
|
-
- [ ] Error handling for [each AC error]
|
|
656
|
-
|
|
657
|
-
## Test Layer
|
|
658
|
-
- [ ] Unit: [each business rule → one test]
|
|
659
|
-
- [ ] Integration: [each AC happy path]
|
|
660
|
-
- [ ] Regression: [each AC error case]
|
|
681
|
+
## US-2 [P2]: [story title]
|
|
682
|
+
- [ ] ... (same internal structure)
|
|
661
683
|
|
|
662
684
|
## NFR Verification
|
|
663
685
|
- [ ] [each NFR from Step 6 → one measurement task]
|
|
664
686
|
```
|
|
665
687
|
|
|
666
688
|
Derivation rules:
|
|
667
|
-
- 1 User Story →
|
|
668
|
-
- 1 Business Rule → 1 Logic task + 1
|
|
669
|
-
- 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)
|
|
670
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.
|
|
671
697
|
|
|
672
698
|
#### Handoff
|
|
673
699
|
|
|
@@ -720,6 +746,10 @@ Inside `requirements.md` the **Decision Classification** table MUST appear verba
|
|
|
720
746
|
8. MUST NOT write code or plan implementation — BA produces WHAT, plan produces HOW
|
|
721
747
|
9. MUST ask ONE question at a time by default; bundle yes/no batches only after user shows concise replies
|
|
722
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
|
|
723
753
|
|
|
724
754
|
## Returns
|
|
725
755
|
|
|
@@ -727,7 +757,7 @@ Inside `requirements.md` the **Decision Classification** table MUST appear verba
|
|
|
727
757
|
|----------|--------|----------|
|
|
728
758
|
| Requirements document | Markdown | `.rune/features/<feature-name>/requirements.md` |
|
|
729
759
|
| Visual model | Mermaid (sequence + optional state machine) | `.rune/features/<feature-name>/requirements.mermaid` |
|
|
730
|
-
| 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` |
|
|
731
761
|
| Logic Consistency Report | Markdown section | Embedded in requirements.md |
|
|
732
762
|
| Ambiguity + Completeness scores | Markdown display blocks | Embedded in requirements.md |
|
|
733
763
|
|
|
@@ -761,7 +791,11 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
761
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 |
|
|
762
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 |
|
|
763
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 |
|
|
764
|
-
| 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 |
|
|
765
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 |
|
|
766
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 |
|
|
767
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 |
|
|
@@ -784,6 +818,9 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
784
818
|
- Scope defined (in/out/assumptions/dependencies)
|
|
785
819
|
- Functional requirements written in EARS format (FR-n) — skip for Bug Fix/Refactor
|
|
786
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
|
|
787
824
|
- Non-functional requirements assessed (relevant ones only)
|
|
788
825
|
- Logic Consistency Report produced — 0 🔴 before handoff (🟡 logged as Risks)
|
|
789
826
|
- Tiered recommendations generated (Quick Win / Differentiation / Moat) — skip for Bug Fix/Refactor
|
|
@@ -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 |
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: converge
|
|
3
|
+
description: "Spec↔code convergence scan. Use after implementation to verify the ACTUAL codebase matches the spec/plan — detects missing backends, dead buttons, partial wiring, scope creep. Classifies gaps (missing/partial/contradicts/unrequested), appends remediation tasks, loops until converged. The direct answer to 'the UI renders but nothing works' syndrome."
|
|
4
|
+
metadata:
|
|
5
|
+
author: runedev
|
|
6
|
+
version: "0.1.0"
|
|
7
|
+
layer: L3
|
|
8
|
+
model: sonnet
|
|
9
|
+
group: verification
|
|
10
|
+
tools: "Read, Glob, Grep"
|
|
11
|
+
emit: convergence.gaps, convergence.clean
|
|
12
|
+
listen: verification.complete
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# converge
|
|
16
|
+
|
|
17
|
+
## Purpose
|
|
18
|
+
|
|
19
|
+
Post-implementation gap detector. Re-reads the spec, plan, and tasks as the **sole source of intent**, inspects the ACTUAL codebase (present state, not the diff), and classifies every intent key as implemented or gapped. Where verification asks "does it build?", converge asks "**is everything the spec promised actually in the code?**"
|
|
20
|
+
|
|
21
|
+
This is the skill that catches the most expensive silent failure: a P1 story's UI exists, renders, passes lint/type/build — and its backend was never written.
|
|
22
|
+
|
|
23
|
+
<HARD-GATE>
|
|
24
|
+
Converge DETECTS — it never fixes. No Edit, no Write to source files.
|
|
25
|
+
Its ONLY write is APPENDING a `## Convergence` task section to the plan's task file.
|
|
26
|
+
Existing file content is never rewritten, reordered, or deleted. Zero gaps = zero writes.
|
|
27
|
+
</HARD-GATE>
|
|
28
|
+
|
|
29
|
+
## Called By (inbound)
|
|
30
|
+
|
|
31
|
+
- `cook` (L1): Phase 6.5 CONVERGE — after VERIFY, before COMMIT, for feature/greenfield chains with a requirements.md
|
|
32
|
+
- User: `/rune converge` — "did it fully implement the spec?", "check completeness", "does the code match the spec?"
|
|
33
|
+
|
|
34
|
+
## Calls (outbound)
|
|
35
|
+
|
|
36
|
+
None — pure L3 verification utility. Reports gaps; cook decides what to execute.
|
|
37
|
+
|
|
38
|
+
## Executable Steps
|
|
39
|
+
|
|
40
|
+
### Step 1 — Build the Intent Inventory
|
|
41
|
+
|
|
42
|
+
Load intent sources (all that exist; requirements.md is mandatory — without it, STOP and report `NO_SPEC`):
|
|
43
|
+
|
|
44
|
+
1. `.rune/features/<name>/requirements.md` — extract keys: every `FR-n`, every `US-n` with priority + Independent Test, every `AC-n.m` (as `US-n/AC-n.m`), every Key Entity
|
|
45
|
+
2. `.rune/plan-<feature>.md` + phase files — Key Decisions, Coverage Summary, task list with `P<phase>-T<seq>` IDs
|
|
46
|
+
3. `.rune/features/<name>/contracts/*.md` — each contract: its endpoint, its `Serves:` story, its `Consumers:` list
|
|
47
|
+
4. `.rune/features/<name>/data-model.md` — entities, state transitions
|
|
48
|
+
5. `.rune/features/<name>/quickstart.md` — per-story validation steps
|
|
49
|
+
6. `.rune/ui-spec.md` `## Unwired Elements` (if present) — designed placeholders that MUST NOT count as implemented
|
|
50
|
+
|
|
51
|
+
The inventory is a flat list of keys: `FR-3`, `US-1/AC-1.2`, `contract:create-order`, `entity:Order`, `decision:<slug>`.
|
|
52
|
+
|
|
53
|
+
### Step 2 — Build the Code-Scope Map
|
|
54
|
+
|
|
55
|
+
Map intent → code locations. NO full-repo read — targeted lookups only:
|
|
56
|
+
|
|
57
|
+
1. `Glob` every file path named in plan tasks — does it exist?
|
|
58
|
+
2. `Grep` entity names (from data-model.md) across schema/model directories
|
|
59
|
+
3. `Grep` each contract's endpoint path/route across the codebase — implementation AND callers
|
|
60
|
+
4. `Grep` component names from UI tasks — definition AND the handler symbols they bind
|
|
61
|
+
|
|
62
|
+
### Step 3 — Classify Gaps
|
|
63
|
+
|
|
64
|
+
For every intent key, assign exactly one verdict:
|
|
65
|
+
|
|
66
|
+
| Verdict | Meaning | Example |
|
|
67
|
+
|---------|---------|---------|
|
|
68
|
+
| `implemented` | Code fully realizes the key | Endpoint exists, has logic, has a caller |
|
|
69
|
+
| `missing` | Required work absent entirely | Contract file exists, no route implements it |
|
|
70
|
+
| `partial` | Started but a link in the chain is dead | Button + handler exist; handler's fetch targets a route that doesn't exist |
|
|
71
|
+
| `contradicts` | Code diverges from a locked decision or AC | Spec says soft-delete; code hard-deletes |
|
|
72
|
+
| `unrequested` | Code maps to NO intent key (scope creep — surfaced, not blocked) | New admin page no story asked for |
|
|
73
|
+
|
|
74
|
+
**Dead-interaction trace** (run for every UI element an AC references):
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
element → handler bound? → handler body non-trivial? → calls service/fetch?
|
|
78
|
+
→ target route/function EXISTS in codebase? → route touches the entity the AC names?
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
First broken link = `partial`, keyed to that element's `US-n/AC-n.m`. Elements listed in `## Unwired Elements` are automatically `missing` (designed placeholder, never wired). Heuristics: `onClick={() => {}}`, `href="#"` on action links, `console.log`-only handlers, `preventDefault()`-only submits, `fetch('/api/...')` where no route file matches — all break the chain.
|
|
82
|
+
|
|
83
|
+
### Step 4 — Assign Severity
|
|
84
|
+
|
|
85
|
+
| Severity | Condition |
|
|
86
|
+
|----------|-----------|
|
|
87
|
+
| CRITICAL | `missing` or `contradicts` gap that blocks a **P1 story's** acceptance scenario or Independent Test |
|
|
88
|
+
| HIGH | `partial` on a P1 story, or `missing`/`contradicts` on P2 |
|
|
89
|
+
| MEDIUM | Any gap on P3; `unrequested` code touching shared modules |
|
|
90
|
+
| LOW | `unrequested` isolated code; cosmetic divergence |
|
|
91
|
+
|
|
92
|
+
### Step 5 — Append Remediation Tasks (APPEND-ONLY)
|
|
93
|
+
|
|
94
|
+
If gaps exist, append to the ACTIVE phase file (or master plan task section if no phase file):
|
|
95
|
+
|
|
96
|
+
```markdown
|
|
97
|
+
## Convergence (round N)
|
|
98
|
+
> Appended by converge — spec↔code gaps found. Do not edit rows above this section.
|
|
99
|
+
- [ ] CV-N.1 [CRITICAL] Implement POST /api/orders route per contract:create-order (missing) — `src/api/orders.ts`
|
|
100
|
+
- [ ] CV-N.2 [HIGH] Wire OrderForm submit to POST /api/orders per US-1/AC-1.1 (partial: handler fetches nonexistent route) — `src/components/OrderForm.tsx`
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Task format: `CV-<round>.<seq> [severity] <imperative> per <intent-key> (<gap-type>) — <file path>`. Every task cites its intent key — a remediation task with no key is itself a converge violation.
|
|
104
|
+
|
|
105
|
+
**Deduplication**: when multiple intent keys trace to the SAME absent/broken artifact (e.g., `contract:create-order` missing AND `US-1/AC-1.1` partial, both resolved by implementing `src/api/orders.ts`), emit ONE combined CV task citing all keys — `CV-1.1 [CRITICAL] Implement POST /api/orders per contract:create-order + US-1/AC-1.1 (missing/partial) — src/api/orders.ts`. One target file = one task; the report table still lists every key's verdict separately.
|
|
106
|
+
|
|
107
|
+
If ZERO gaps: write nothing (task file stays byte-identical), emit `convergence.clean`.
|
|
108
|
+
|
|
109
|
+
### Step 6 — Emit Verdict
|
|
110
|
+
|
|
111
|
+
- Gaps found → emit `convergence.gaps` with `{feature, round, counts: {missing, partial, contradicts, unrequested}, critical: N}`
|
|
112
|
+
- Clean → emit `convergence.clean` with `{feature, round, keys_checked: N}`
|
|
113
|
+
|
|
114
|
+
The caller (cook Phase 6.5) executes appended tasks and re-invokes converge — loop until clean, max 2 remediation rounds before escalation.
|
|
115
|
+
|
|
116
|
+
## Output Format
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
## Convergence Report — <feature> (round N)
|
|
120
|
+
|
|
121
|
+
Intent keys checked: 23 | implemented: 19 | gaps: 4
|
|
122
|
+
|
|
123
|
+
| Key | Verdict | Severity | Evidence |
|
|
124
|
+
|-----|---------|----------|----------|
|
|
125
|
+
| contract:create-order | missing | CRITICAL | contracts/create-order.md exists; no route matches POST /api/orders (grep: 0 hits in src/) |
|
|
126
|
+
| US-1/AC-1.1 | partial | HIGH | OrderForm.tsx:42 fetch('/api/orders') → route absent |
|
|
127
|
+
| US-3/AC-3.1 | implemented | — | route src/api/list.ts:12, caller OrderList.tsx:8 |
|
|
128
|
+
| (none) | unrequested | LOW | src/pages/admin-stats.tsx maps to no story |
|
|
129
|
+
|
|
130
|
+
Verdict: 2 gaps blocking P1 → convergence.gaps emitted, 2 tasks appended (CV-1.1, CV-1.2)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Every row needs `file:line` evidence or a grep result count — verdicts without evidence are hallucinations.
|
|
134
|
+
|
|
135
|
+
## Constraints
|
|
136
|
+
|
|
137
|
+
1. MUST treat spec/plan/contracts as the sole source of intent — never infer intent from the code itself
|
|
138
|
+
2. MUST inspect present codebase state, not the git diff — earlier phases may have broken older work
|
|
139
|
+
3. MUST give every gap an intent key, a gap-type, a severity, and file-level evidence
|
|
140
|
+
4. MUST append remediation tasks — never rewrite, reorder, or delete existing task content
|
|
141
|
+
5. MUST NOT edit source code — converge detects, fix/cook remediate
|
|
142
|
+
6. MUST surface `unrequested` code as findings, never silently delete or block on it
|
|
143
|
+
7. MUST report `NO_SPEC` and stop when no requirements.md exists — converge without a spec is vibes
|
|
144
|
+
|
|
145
|
+
## Sharp Edges
|
|
146
|
+
|
|
147
|
+
| Failure Mode | Severity | Mitigation |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| Inferring intent from code ("this helper implies a story") | CRITICAL | Intent inventory comes ONLY from Step 1 artifacts — code is evidence, never intent |
|
|
150
|
+
| Verdict without file:line or grep evidence | CRITICAL | Output format requires Evidence column — no evidence, no verdict |
|
|
151
|
+
| Rewriting the task file instead of appending | CRITICAL | HARD-GATE: append-only; zero gaps = zero writes (byte-identical file) |
|
|
152
|
+
| Marking `implemented` because the file exists | HIGH | Existence ≠ implementation — run the dead-interaction trace; a route with `res.status(501)` is `partial` |
|
|
153
|
+
| Counting a designed placeholder as implemented | HIGH | `.rune/ui-spec.md` Unwired Elements are automatically `missing` |
|
|
154
|
+
| Infinite converge loop (gaps never reach zero) | HIGH | Caller caps at 2 remediation rounds → Structured Escalation Report; same gap surviving 2 rounds = approach is wrong, not effort |
|
|
155
|
+
| Fixing the gap itself "since it's small" | HIGH | Converge never edits source — emit the task, let fix own the change |
|
|
156
|
+
| Scanning the whole repo (context blowout) | MEDIUM | Step 2 is targeted Glob/Grep from intent keys — not a repo read |
|
|
157
|
+
| Treating `unrequested` as an error to delete | MEDIUM | Scope creep is surfaced for human decision — it may be wanted, undocumented work |
|
|
158
|
+
|
|
159
|
+
## Done When
|
|
160
|
+
|
|
161
|
+
- Intent inventory built from requirements.md + plan + contracts (or NO_SPEC reported)
|
|
162
|
+
- Every intent key has a verdict with file-level evidence
|
|
163
|
+
- Dead-interaction trace run for every AC-referenced UI element
|
|
164
|
+
- Gaps appended as `CV-*` tasks with intent keys (or task file byte-identical when clean)
|
|
165
|
+
- `convergence.gaps` or `convergence.clean` emitted with counts
|
|
166
|
+
- Convergence Report rendered with evidence column
|
|
167
|
+
|
|
168
|
+
## Returns
|
|
169
|
+
|
|
170
|
+
| Artifact | Format | Location |
|
|
171
|
+
|----------|--------|----------|
|
|
172
|
+
| Convergence Report | Markdown table with evidence | inline |
|
|
173
|
+
| Remediation tasks | `CV-<round>.<seq>` checklist (append-only) | active phase file / master plan |
|
|
174
|
+
| Signal | `convergence.gaps` \| `convergence.clean` with counts | mesh |
|
|
175
|
+
|
|
176
|
+
## Cost Profile
|
|
177
|
+
|
|
178
|
+
~2000-5000 tokens input (spec + plan + targeted greps), ~500-1500 tokens output. Sonnet — the dead-interaction trace needs code comprehension, not just pattern matching. Runs once per feature (plus ≤2 remediation rounds).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Converge Eval Fixtures
|
|
2
|
+
|
|
3
|
+
> Behavioral test scenarios for `converge`. Each fixture defines inputs (spec + code state)
|
|
4
|
+
> and the EXACT expected verdict. Use these to verify converge behaves correctly after any
|
|
5
|
+
> edit to its SKILL.md — and as seeds for a future automated eval harness.
|
|
6
|
+
|
|
7
|
+
## Fixture 1 — Dead button (the canonical failure)
|
|
8
|
+
|
|
9
|
+
**Spec**: `US-1 [P1]` "submit an order", `AC-1.1: GIVEN valid items WHEN user clicks Save THEN order persisted and visible in list`. Contract `contracts/create-order.md` → `POST /api/orders`, Consumers: `OrderForm`.
|
|
10
|
+
|
|
11
|
+
**Code state**: `OrderForm.tsx` exists, renders `<button onClick={handleSave}>Save</button>`; `handleSave` calls `fetch('/api/orders', {method:'POST'})`. NO route file implements `POST /api/orders`.
|
|
12
|
+
|
|
13
|
+
**Expected**: `contract:create-order` → `missing` CRITICAL (P1). `US-1/AC-1.1` → `partial` (chain breaks at route-exists). Two `CV-1.*` tasks appended citing those keys. `convergence.gaps` emitted. **FAIL IF**: verdict is `implemented` because OrderForm exists, or converge edits OrderForm itself.
|
|
14
|
+
|
|
15
|
+
## Fixture 2 — Fully wired (clean pass)
|
|
16
|
+
|
|
17
|
+
**Spec**: same as Fixture 1.
|
|
18
|
+
|
|
19
|
+
**Code state**: `OrderForm.tsx` handler → `fetch POST /api/orders`; `src/api/orders.ts` implements the route, validates items, persists via `Order` model; `OrderList.tsx` fetches and renders.
|
|
20
|
+
|
|
21
|
+
**Expected**: all keys `implemented` with file:line evidence. ZERO writes — task file byte-identical. `convergence.clean` emitted. **FAIL IF**: any "improvement" task is appended (converge is not a reviewer), or the task file is touched at all.
|
|
22
|
+
|
|
23
|
+
## Fixture 3 — Contradicts a locked decision
|
|
24
|
+
|
|
25
|
+
**Spec**: requirements.md Decision (locked): "soft-delete only — records marked `deletedAt`, never removed". Plan Key Decisions repeats it.
|
|
26
|
+
|
|
27
|
+
**Code state**: `src/api/orders.ts` delete handler runs `DELETE FROM orders WHERE id = ?`.
|
|
28
|
+
|
|
29
|
+
**Expected**: `decision:soft-delete` → `contradicts`, CRITICAL if a P1 AC covers deletion (else HIGH). Task: `CV-1.1 [CRITICAL] Replace hard delete with deletedAt flag per decision:soft-delete (contradicts) — src/api/orders.ts`. **FAIL IF**: classified `implemented` because "a delete exists".
|
|
30
|
+
|
|
31
|
+
## Fixture 4 — Unrequested code (scope creep surfaced, not blocked)
|
|
32
|
+
|
|
33
|
+
**Spec**: stories US-1..US-3 cover order CRUD only.
|
|
34
|
+
|
|
35
|
+
**Code state**: everything from Fixture 2 PLUS `src/pages/admin-stats.tsx` (a dashboard no story mentions).
|
|
36
|
+
|
|
37
|
+
**Expected**: all spec keys `implemented`; one `unrequested` finding (LOW — isolated) listing admin-stats.tsx. `convergence.gaps` emitted (unrequested counts as a gap for reporting) BUT no CV task demanding deletion — the finding is informational for the user. **FAIL IF**: converge deletes the file, appends a "remove admin-stats" task, or hides the finding.
|
|
38
|
+
|
|
39
|
+
## Fixture 5 — Placeholder counted honestly
|
|
40
|
+
|
|
41
|
+
**Spec**: `US-2 [P2]` "browse products", AC-2.1 names a product grid.
|
|
42
|
+
|
|
43
|
+
**Code state**: `ProductGrid.tsx` renders `[ PLACEHOLDER: product-grid ]` boxes; `.rune/ui-spec.md` lists `product-grid` under `## Unwired Elements`.
|
|
44
|
+
|
|
45
|
+
**Expected**: `US-2/AC-2.1` → `missing` HIGH (P2) — Unwired Elements are auto-missing regardless of how substantive the placeholder markup looks. **FAIL IF**: `implemented` or `partial` (a designed placeholder is not "started work").
|
|
46
|
+
|
|
47
|
+
## Fixture 6 — No spec (honest refusal)
|
|
48
|
+
|
|
49
|
+
**Spec**: no `.rune/features/*/requirements.md` exists.
|
|
50
|
+
|
|
51
|
+
**Expected**: converge reports `NO_SPEC` and stops. No inventory invented from the code, no tasks appended. **FAIL IF**: converge scans the code and fabricates intent keys from what it finds.
|
|
52
|
+
|
|
53
|
+
## Fixture 7 — Remediation survives round 1 (escalation path)
|
|
54
|
+
|
|
55
|
+
**Spec**: same as Fixture 1. **Round 1**: converge found `contract:create-order` missing, appended `CV-1.1`. Cook executed CV-1.1 but implemented a stub: `src/api/orders.ts` exists, handler returns `res.status(501)`.
|
|
56
|
+
|
|
57
|
+
**Code state at round 2**: route file exists, body is a 501 stub; OrderForm unchanged.
|
|
58
|
+
|
|
59
|
+
**Expected**: round 2 verdict for `contract:create-order` → `partial` (file exists but Level-2-style stub — a 501 is not an implementation), still CRITICAL (P1). `CV-2.1` appended. After round 2 the caller's cap is exhausted → cook produces a Structured Escalation Report with the surviving gap named. **FAIL IF**: classified `implemented` because the route file now exists, or converge silently allows a round 3.
|