@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/skills/test/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: test
|
|
|
3
3
|
description: "TDD test writer. Writes failing tests FIRST (red), then verifies they pass after implementation (green). Covers unit, integration, and e2e tests."
|
|
4
4
|
metadata:
|
|
5
5
|
author: runedev
|
|
6
|
-
version: "1.
|
|
6
|
+
version: "1.4.0"
|
|
7
7
|
layer: L2
|
|
8
8
|
model: sonnet
|
|
9
9
|
group: development
|
|
@@ -414,23 +414,29 @@ assert(result.output.includes(oracle), "Oracle not found — pipeline lost data"
|
|
|
414
414
|
|
|
415
415
|
## Spec→Test Traceability
|
|
416
416
|
|
|
417
|
-
When a plan with acceptance criteria exists (`.rune/features/<name>/plan.md
|
|
417
|
+
When a spec or plan with acceptance criteria exists (`.rune/features/<name>/requirements.md`, `plan.md`, or phase file), every criterion MUST map to at least one test case.
|
|
418
418
|
|
|
419
419
|
```
|
|
420
|
-
|
|
420
|
+
Spec Acceptance Criteria → Test Case → Implementation
|
|
421
421
|
|
|
422
|
-
AC-1: "User can reset password via email" → test_password_reset_sends_email()
|
|
423
|
-
AC-2: "Rate limit: max 3 reset attempts/hour" → test_password_reset_rate_limit()
|
|
424
|
-
|
|
422
|
+
US-1/AC-1.1: "User can reset password via email" → test_password_reset_sends_email()
|
|
423
|
+
US-1/AC-1.2: "Rate limit: max 3 reset attempts/hour" → test_password_reset_rate_limit()
|
|
424
|
+
FR-3: "Expired tokens rejected" → test_expired_reset_token_rejected()
|
|
425
425
|
```
|
|
426
426
|
|
|
427
|
-
**Validation step** (after writing tests): Cross-check
|
|
427
|
+
**Validation step** (after writing tests): Cross-check acceptance criteria against test names. For each criterion:
|
|
428
428
|
- Has test → OK
|
|
429
429
|
- No test → flag as UNTESTED REQUIREMENT (more serious than uncovered lines)
|
|
430
430
|
|
|
431
|
+
**Cross-boundary minimum**: every user story whose path crosses the UI↔data boundary (story has both a UI task and an endpoint/data task) needs **≥1 L2 integration test** exercising handler → service/endpoint with the REAL route wired (contract-level is fine; mocking the ENTIRE chain does not count). A story covered only by unit tests with the handler mocked = the story is NOT covered — that's how dead buttons reach 80% coverage.
|
|
432
|
+
|
|
433
|
+
**Contract tests first**: when plan emitted `.rune/features/<name>/contracts/`, each contract gets a failing contract test (request/response shape, error cases) BEFORE the endpoint is implemented — the RED phase for the API surface.
|
|
434
|
+
|
|
431
435
|
**Why this is stronger than coverage**: Coverage checks that lines were EXECUTED. Traceability checks that INTENT was VERIFIED. You can have 100% coverage but miss a requirement if the test doesn't assert the right behavior.
|
|
432
436
|
|
|
433
|
-
**Skip if**: No plan exists (ad-hoc fix), or
|
|
437
|
+
**Skip if**: No spec AND no plan exists (ad-hoc fix), or neither has an acceptance criteria section. A requirements.md with US/AC IDs makes this section MANDATORY — "no plan file" alone is not a skip reason.
|
|
438
|
+
|
|
439
|
+
**Browser click-through (advisory)**: when a UI story completes, SUGGEST a `browser-pilot` run of the story's Independent Test (from requirements.md) — one real click-path beats ten mocked renders. Advisory, not a gate: skip freely in headless/CI-only environments.
|
|
434
440
|
|
|
435
441
|
## Eval-Driven Development
|
|
436
442
|
|
|
@@ -571,6 +577,7 @@ Examples of test slop:
|
|
|
571
577
|
- "route responds with 200" without checking response body (tests Express, not your handler)
|
|
572
578
|
- Asserting a mock was called N times without checking the RESULT of those calls
|
|
573
579
|
- Type existence tests (`typeof result === 'object'`) when you should test the actual value
|
|
580
|
+
- Component renders + handler fully mocked, presented as story coverage — the click path was never exercised; the story's dead button ships with "green" tests
|
|
574
581
|
|
|
575
582
|
**Red flags — any of these means STOP and rethink:**
|
|
576
583
|
- Mock setup longer than test logic
|
|
@@ -3,13 +3,13 @@ name: verification
|
|
|
3
3
|
description: "Universal verification runner. Runs lint, type-check, tests, and build. Use after any code change to verify nothing is broken."
|
|
4
4
|
metadata:
|
|
5
5
|
author: runedev
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.6.0"
|
|
7
7
|
layer: L3
|
|
8
8
|
model: haiku
|
|
9
9
|
group: validation
|
|
10
10
|
tools: "Read, Bash, Glob, Grep"
|
|
11
11
|
listen: code.changed
|
|
12
|
-
emit: verification.complete
|
|
12
|
+
emit: verification.complete, integration.verified
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# verification
|
|
@@ -120,6 +120,9 @@ Glob("path/to/expected/file") → found
|
|
|
120
120
|
| `useEffect` with empty body / `async function` with no `await` | React/JS | Hollow implementation |
|
|
121
121
|
| File has only type/interface exports but no implementation | TypeScript | Stub types-only file |
|
|
122
122
|
| `// TODO` or `# TODO` as the only content in a function | Any | Placeholder |
|
|
123
|
+
| `onClick={() => {}}` / handler bound to an empty or `console.log`-only function | React/Vue/Svelte | Dead handler — wired to nothing |
|
|
124
|
+
| `href="#"` on an action link (not navigation) | HTML/JSX | Dead action link |
|
|
125
|
+
| Submit handler whose body is only `event.preventDefault()` | Any UI | Form that swallows input |
|
|
123
126
|
|
|
124
127
|
If ANY stub pattern detected → mark file as STUB, Level 2 FAIL.
|
|
125
128
|
|
|
@@ -138,10 +141,29 @@ If file has 0 consumers → mark as UNWIRED, Level 3 FAIL.
|
|
|
138
141
|
|
|
139
142
|
**Exception**: Entry-point files (main.ts, index.ts, App.tsx, routes config) are exempt from Level 3 — they ARE the top-level consumers.
|
|
140
143
|
|
|
144
|
+
**Level 3.5 — INTERACTION WIRED** (UI files in this task's diff only — `.tsx/.jsx/.vue/.svelte/.html`):
|
|
145
|
+
|
|
146
|
+
Level 3 proves the component is *rendered*; Level 3.5 proves its interactive elements *do something*. For each UI file created or modified in this task:
|
|
147
|
+
|
|
148
|
+
1. `Grep` interactive elements in the file — framework-aware patterns: `<button`, `<form`, `type="submit"`, `action=`, plus binding syntax per framework: React `onClick=`/`onSubmit=`, Svelte `on:click=`/`on:submit=`, Vue `@click`/`@submit`/`v-on:`, plain HTML `addEventListener`
|
|
149
|
+
2. For each element, trace INWARD:
|
|
150
|
+
- **Handler bound?** Interactive element with NO binding in any framework syntax above and no enclosing form handler → `UNWIRED-INTERACTIVE`. **Prop-origin handlers PASS**: `onClick={props.onSave}`, `on:click={dispatch('save')}`, or a callback-library pattern (`onSubmit={handleSubmit(onSubmit)}` — react-hook-form et al.) count as bound; wiring the prop is the parent's/caller's responsibility, checked at the parent's own 3.5 pass
|
|
151
|
+
- **Handler resolves?** The bound symbol is locally defined OR imported (imported = resolves; do not demand the import's body) and its body is non-trivial (not caught by the Level 2 dead-handler patterns)
|
|
152
|
+
- **Target exists?** If the handler calls `fetch`/`axios`/a service function → the route path or service symbol EXISTS somewhere in the codebase (`Grep` the path/symbol). Handler → nonexistent target = `UNWIRED-INTERACTIVE`. Pure-navigation handlers (`router.push`, `navigate(...)`, framework `<Link>`) PASS — navigation is their target
|
|
153
|
+
3. **Reverse check**: every API route file created in this task has ≥1 caller (`Grep` the route path across UI/service files). Route with 0 callers → `UNCALLED-ROUTE`
|
|
154
|
+
4. Pure-display elements (no user expectation of action: decorative buttons in mockups explicitly listed in `.rune/ui-spec.md` `## Unwired Elements`) are reported as INFO, not failures — they are design's declared debt, tracked by `converge`
|
|
155
|
+
5. **De-dup**: if preflight already flagged the same element as dead-interactive in this session, cite the cross-reference ("preflight Step 4.5 already flagged") instead of emitting a duplicate finding
|
|
156
|
+
|
|
157
|
+
**Scope guard**: Level 3.5 runs ONLY on files in this task's diff. Pre-existing files with dead interactive elements → WARN (legacy debt, don't punish), never FAIL.
|
|
158
|
+
|
|
159
|
+
**Signal**: when the diff touches both UI and api/service/data files AND every Level 3.5 check passes, emit `integration.verified` with `{files_checked, interactions_traced}`. Downstream `deploy` uses this as its cross-layer wiring evidence.
|
|
160
|
+
|
|
141
161
|
<HARD-GATE name="3-level-verification">
|
|
142
162
|
ALL new files must pass Level 1 + Level 2 + Level 3.
|
|
163
|
+
UI files in this task's diff must ALSO pass Level 3.5.
|
|
143
164
|
EXISTS but STUB = "Existence Theater" — agent created files but didn't implement them.
|
|
144
165
|
EXISTS and SUBSTANTIVE but UNWIRED = dead code — created but never connected.
|
|
166
|
+
SUBSTANTIVE and WIRED but UNWIRED-INTERACTIVE = dead button — renders, does nothing. Same failure tier as UNWIRED.
|
|
145
167
|
Report which level failed for each file in the Verification Report.
|
|
146
168
|
</HARD-GATE>
|
|
147
169
|
|
|
@@ -224,11 +246,12 @@ Tests: [PASS/FAIL/SKIP] ([passed]/[total], [coverage]%)
|
|
|
224
246
|
Build: [PASS/FAIL/SKIP]
|
|
225
247
|
|
|
226
248
|
### 3-Level File Verification
|
|
227
|
-
| File | L1 Exists | L2 Substantive | L3 Wired | Verdict |
|
|
228
|
-
|
|
229
|
-
| src/auth/login.ts | ✓ | ✓ | ✓ (imported by routes.ts) | PASS |
|
|
230
|
-
| src/auth/reset.ts | ✓ | STUB (returns null) | — | FAIL L2 |
|
|
231
|
-
| src/utils/format.ts | ✓ | ✓ | UNWIRED (0 importers) | FAIL L3 |
|
|
249
|
+
| File | L1 Exists | L2 Substantive | L3 Wired | L3.5 Interaction | Verdict |
|
|
250
|
+
|------|-----------|----------------|----------|------------------|---------|
|
|
251
|
+
| src/auth/login.ts | ✓ | ✓ | ✓ (imported by routes.ts) | ✓ (submit → POST /api/login, route exists) | PASS |
|
|
252
|
+
| src/auth/reset.ts | ✓ | STUB (returns null) | — | — | FAIL L2 |
|
|
253
|
+
| src/utils/format.ts | ✓ | ✓ | UNWIRED (0 importers) | n/a (not UI) | FAIL L3 |
|
|
254
|
+
| src/ui/OrderForm.tsx | ✓ | ✓ | ✓ (rendered by OrdersPage) | UNWIRED-INTERACTIVE (Save → fetch '/api/orders', route absent) | FAIL L3.5 |
|
|
232
255
|
|
|
233
256
|
Overall: [PASS/FAIL]
|
|
234
257
|
|
|
@@ -239,6 +262,8 @@ Overall: [PASS/FAIL]
|
|
|
239
262
|
- Build: [first 5 build errors]
|
|
240
263
|
- Stubs: [files that failed Level 2 with stub pattern detected]
|
|
241
264
|
- Unwired: [files that failed Level 3 with 0 consumers]
|
|
265
|
+
- Dead interactions: [elements that failed Level 3.5 with the broken link named (no handler / dead handler / missing target)]
|
|
266
|
+
- Uncalled routes: [route files created this task with 0 callers]
|
|
242
267
|
```
|
|
243
268
|
|
|
244
269
|
## Output Completion Enforcement
|
|
@@ -303,6 +328,7 @@ When any skill calls verification and then reports results upstream:
|
|
|
303
328
|
4. MUST NOT skip checks because "changes are small"
|
|
304
329
|
5. MUST include stdout/stderr capture in every check result — empty output noted explicitly
|
|
305
330
|
6. MUST mark Overall as INCOMPLETE if any check was skipped without valid reason (tool not installed = valid, "changes are small" = invalid)
|
|
331
|
+
7. MUST run the 3-Level Artifact Verification on every file created/modified this task, AND Level 3.5 INTERACTION WIRED on every UI file (`.tsx/.jsx/.vue/.svelte/.html`) in the diff — skip 3.5 only when the diff contains no UI files (note "L3.5: n/a — no UI files")
|
|
306
332
|
|
|
307
333
|
## Sharp Edges
|
|
308
334
|
|
|
@@ -319,6 +345,10 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
319
345
|
| Trusting exit code 0 without output verification | CRITICAL | Artifact Verification HARD-GATE: always confirm success indicator in stdout (pass count, "0 errors", output file exists) |
|
|
320
346
|
| Existence Theater — file exists but is a stub | HIGH | 3-Level check: Level 2 scans for stub patterns (`<div>Placeholder</div>`, `return null`, `NotImplementedError`) |
|
|
321
347
|
| Dead code — file created but never imported/used | MEDIUM | 3-Level check: Level 3 greps for consumers. 0 importers = UNWIRED |
|
|
348
|
+
| Dead button — component rendered, interactive element wired to nothing | CRITICAL | Level 3.5: trace element → handler → target for every UI file in the diff. Rendering ≠ working |
|
|
349
|
+
| Punishing legacy files for pre-existing dead interactions | MEDIUM | Level 3.5 scope guard: FAIL only for this task's diff; pre-existing = WARN |
|
|
350
|
+
| Route created this task with zero callers passes silently | HIGH | Level 3.5 reverse check: new route files need ≥1 caller or FAIL |
|
|
351
|
+
| `integration.verified` read as "quickstart validated" | LOW | Standalone verification runs do NOT execute quickstart.md (that's cook Phase 6's job) — the signal proves static wiring, not a live end-to-end run |
|
|
322
352
|
| Truncated code — agent hit output limit mid-file | HIGH | Output Completion Enforcement: scan for `// ...`, `// rest of code`, bare ellipsis patterns. TRUNCATED = Level 2 FAIL |
|
|
323
353
|
|
|
324
354
|
## Done When
|
|
@@ -327,6 +357,8 @@ Known failure modes for this skill. Check these before declaring done.
|
|
|
327
357
|
- lint, type-check, tests, and build all executed (or SKIP with reason if tool missing)
|
|
328
358
|
- Each check shows actual command output
|
|
329
359
|
- Failures include specific file:line references (not just counts)
|
|
360
|
+
- 3-Level check run on all created/modified files; Level 3.5 INTERACTION WIRED run on all UI files in the diff (or "n/a — no UI files" noted)
|
|
361
|
+
- `integration.verified` emitted when the diff spans UI+data and all 3.5 checks pass
|
|
330
362
|
- Verification Report emitted with Overall PASS/FAIL verdict
|
|
331
363
|
|
|
332
364
|
## Cost Profile
|