@rune-kit/rune 2.13.0 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +31 -12
  2. package/compiler/__tests__/adapter-model-mapping.test.js +152 -0
  3. package/compiler/__tests__/adr-scoring.test.js +91 -0
  4. package/compiler/__tests__/context-md-format.test.js +180 -0
  5. package/compiler/__tests__/context-pack-smell-tests.test.js +215 -0
  6. package/compiler/__tests__/context-preview-signal.test.js +166 -0
  7. package/compiler/__tests__/diversity-score.test.js +117 -0
  8. package/compiler/__tests__/improve-architecture.test.js +171 -0
  9. package/compiler/__tests__/openclaw-adapter.test.js +11 -6
  10. package/compiler/__tests__/oracle-bundle-format.test.js +210 -0
  11. package/compiler/__tests__/oracle-pending-schema.test.js +209 -0
  12. package/compiler/__tests__/out-of-scope-format.test.js +303 -0
  13. package/compiler/__tests__/skill-description-quality.test.js +147 -0
  14. package/compiler/__tests__/zoom-out-output.test.js +112 -0
  15. package/compiler/adapters/antigravity.js +17 -1
  16. package/compiler/adapters/claude.js +4 -0
  17. package/compiler/adapters/codex.js +16 -1
  18. package/compiler/adapters/cursor.js +4 -0
  19. package/compiler/adapters/generic.js +14 -1
  20. package/compiler/adapters/openclaw.js +15 -1
  21. package/compiler/adapters/opencode.js +17 -1
  22. package/compiler/adapters/windsurf.js +4 -0
  23. package/package.json +2 -2
  24. package/skills/adversary/SKILL.md +61 -1
  25. package/skills/adversary/evals.md +79 -0
  26. package/skills/adversary/references/context-bundle-format.md +122 -0
  27. package/skills/adversary/references/oracle-mode.md +116 -0
  28. package/skills/asset-creator/SKILL.md +1 -1
  29. package/skills/audit/SKILL.md +3 -1
  30. package/skills/autopsy/SKILL.md +1 -1
  31. package/skills/ba/SKILL.md +242 -83
  32. package/skills/ba/references/context-md-format.md +136 -0
  33. package/skills/ba/references/explore-first.md +107 -0
  34. package/skills/ba/references/out-of-scope-format.md +152 -0
  35. package/skills/brainstorm/SKILL.md +78 -2
  36. package/skills/brainstorm/references/design-it-twice.md +155 -0
  37. package/skills/browser-pilot/SKILL.md +1 -1
  38. package/skills/completion-gate/SKILL.md +1 -1
  39. package/skills/constraint-check/SKILL.md +1 -1
  40. package/skills/context-engine/SKILL.md +85 -1
  41. package/skills/context-engine/references/preview-gate.md +139 -0
  42. package/skills/context-pack/SKILL.md +68 -25
  43. package/skills/context-pack/evals.md +122 -0
  44. package/skills/context-pack/references/brief-template.md +121 -0
  45. package/skills/context-pack/references/durability-rules.md +109 -0
  46. package/skills/cook/SKILL.md +5 -4
  47. package/skills/db/SKILL.md +1 -1
  48. package/skills/debug/SKILL.md +7 -4
  49. package/skills/dependency-doctor/SKILL.md +1 -1
  50. package/skills/design/SKILL.md +1 -1
  51. package/skills/doc-processor/SKILL.md +1 -1
  52. package/skills/docs/SKILL.md +1 -1
  53. package/skills/docs-seeker/SKILL.md +1 -1
  54. package/skills/fix/SKILL.md +5 -3
  55. package/skills/git/SKILL.md +1 -1
  56. package/skills/hallucination-guard/SKILL.md +1 -1
  57. package/skills/improve-architecture/SKILL.md +275 -0
  58. package/skills/improve-architecture/evals.md +145 -0
  59. package/skills/improve-architecture/references/deepening.md +87 -0
  60. package/skills/improve-architecture/references/interface-design.md +68 -0
  61. package/skills/improve-architecture/references/language.md +81 -0
  62. package/skills/improve-architecture/references/scoring.md +122 -0
  63. package/skills/integrity-check/SKILL.md +1 -1
  64. package/skills/journal/SKILL.md +34 -7
  65. package/skills/journal/references/adr-criteria.md +109 -0
  66. package/skills/logic-guardian/SKILL.md +1 -1
  67. package/skills/marketing/SKILL.md +1 -1
  68. package/skills/mcp-builder/SKILL.md +1 -1
  69. package/skills/onboard/SKILL.md +1 -1
  70. package/skills/perf/SKILL.md +1 -1
  71. package/skills/plan/SKILL.md +1 -1
  72. package/skills/preflight/SKILL.md +1 -1
  73. package/skills/research/SKILL.md +1 -1
  74. package/skills/retro/SKILL.md +1 -1
  75. package/skills/review/SKILL.md +3 -2
  76. package/skills/review-intake/SKILL.md +26 -3
  77. package/skills/safeguard/SKILL.md +1 -1
  78. package/skills/scaffold/SKILL.md +1 -1
  79. package/skills/scout/SKILL.md +33 -1
  80. package/skills/sentinel/SKILL.md +1 -1
  81. package/skills/sentinel-env/SKILL.md +1 -1
  82. package/skills/session-bridge/SKILL.md +91 -4
  83. package/skills/session-bridge/references/detach-protocol.md +111 -0
  84. package/skills/skill-forge/SKILL.md +1 -1
  85. package/skills/slides/SKILL.md +1 -1
  86. package/skills/surgeon/SKILL.md +17 -2
  87. package/skills/team/SKILL.md +3 -0
  88. package/skills/test/SKILL.md +48 -1
  89. package/skills/test/evals.md +137 -0
  90. package/skills/test/references/mocking-policy.md +121 -0
  91. package/skills/test/references/test-quality.md +124 -0
  92. package/skills/test/references/vertical-tdd.md +110 -0
  93. package/skills/trend-scout/SKILL.md +1 -1
  94. package/skills/video-creator/SKILL.md +1 -1
  95. package/skills/watchdog/SKILL.md +1 -1
  96. package/skills/worktree/SKILL.md +1 -1
@@ -0,0 +1,109 @@
1
+ # Durability Rules — Why Briefs Rot, How to Stop It
2
+
3
+ A subagent receives a context packet. A day later, after a refactor, that packet's file paths point to renamed files, line numbers point to shifted code, and "the function in `src/auth/login.ts:42`" no longer exists. The subagent burns tokens grepping to recover or — worse — generates hallucinated edits matching the stale brief.
4
+
5
+ The fix is to write briefs that describe **types and contracts**, which survive moves, instead of **paths and line numbers**, which don't.
6
+
7
+ ## The 5 rules
8
+
9
+ ### 1. Behavioral over procedural
10
+
11
+ Describe what the system *does*, not *where* the code lives.
12
+
13
+ | ❌ Bad | ✅ Good |
14
+ |--------|---------|
15
+ | "Open `src/handlers/login.ts` and modify line 42" | "When a login fails 5 times, the rate limiter should reject the next attempt with a 429 response and a `Retry-After` header" |
16
+ | "Add the field to the type at `src/types.ts:18`" | "The `LoginInput` type should accept an optional `device_id: string`" |
17
+ | "Refactor the function around line 150 in `main.ts`" | "Extract the password-hashing path into its own module so it can be tested independently" |
18
+
19
+ ### 2. Type names over file paths in narrative
20
+
21
+ When you must reference code in narrative prose, refer to **type names, function names, or contracts** — not file paths.
22
+
23
+ | ❌ Bad | ✅ Good |
24
+ |--------|---------|
25
+ | "Update the function in `src/auth/`" | "Update the `authenticate` method on `AuthService`" |
26
+ | "Modify `src/db/migrations/0042.sql`" | "The new migration should add a `device_id` column to the `sessions` table, nullable, with a default of `NULL`" |
27
+
28
+ File paths may appear in a clearly-marked `### Files Touched` table — never in narrative prose.
29
+
30
+ ### 3. Type Surface section
31
+
32
+ Add a `### Type Surface` section listing the contracts that *won't* change even if files do. This is the durable spine of the brief.
33
+
34
+ ```markdown
35
+ ### Type Surface (durable)
36
+ - `LoginInput { email: string; password: string; device_id?: string }` — payload accepted by the login route
37
+ - `AuthService.authenticate(input: LoginInput): Result<Session, AuthError>` — primary contract
38
+ - `AuthError = "invalid_credentials" | "rate_limited" | "account_locked"` — error union the caller switches on
39
+ ```
40
+
41
+ If a file gets renamed but `AuthService.authenticate` keeps its shape, the brief still applies. If the contract changes, the brief is invalidated — that's a feature, not a bug.
42
+
43
+ ### 4. Out of scope is mandatory
44
+
45
+ Every brief includes `### Out of scope`. Receivers expand into adjacent work without this anchor. Empty list is fine *if explicitly empty* (`### Out of scope\n- (none)`); missing section is rejected by completion-gate.
46
+
47
+ ```markdown
48
+ ### Out of scope
49
+ - Changing the rate-limit window (currently 1 hour — keep it)
50
+ - Touching the audit log writer (separate ticket)
51
+ - Anything in `src/billing/` — different domain
52
+ ```
53
+
54
+ ### 5. Behavioral verbs in acceptance criteria
55
+
56
+ Each acceptance criterion must start with a verb from the whitelist:
57
+
58
+ ```
59
+ accepts, rejects, produces, notifies, persists, retries, times-out, validates,
60
+ returns, dispatches, redirects, throws, logs, increments, decrements, retrieves
61
+ ```
62
+
63
+ Banned verb-less constructs ("the field should be present", "the type is exported") describe shape, not behavior.
64
+
65
+ | ❌ Bad | ✅ Good |
66
+ |--------|---------|
67
+ | "The new field should exist" | "Persists the device_id when login succeeds" |
68
+ | "An error type should be defined" | "Returns AuthError 'rate_limited' when 5 failures occur within 1 hour" |
69
+
70
+ ## Smell tests (mechanical regex gates)
71
+
72
+ `context-pack` Phase 4.5 runs these regex against the packet body before emit. Any BLOCK-tier hit fails the gate.
73
+
74
+ | Regex | Tier | Reason |
75
+ |-------|------|--------|
76
+ | `\b\S+\.[a-z]{1,4}:\d+\b` | BLOCK | file:line reference (e.g., `login.ts:42`) — line numbers go stale |
77
+ | `^- \S*[\\/]\S+\.(ts\|js\|py\|go\|rs\|java)\b` (in non-`Files Touched` sections) | BLOCK | Path-only bullet in narrative |
78
+ | `\b(line \|on line )\d+\b` | BLOCK | "line 42" / "on line 100" |
79
+ | `\b(src\|lib\|app)/\S+` (in narrative paragraphs) | WARN | Path mention; check if it's in the right section |
80
+
81
+ Whitelist for `### Files Touched` table — paths there must include the type/function name in parens for durability:
82
+
83
+ ```
84
+ - `src/auth/login.ts` (LoginInput, AuthService.authenticate) — the route handler
85
+ ```
86
+
87
+ Without the parens annotation, even the table entry is too brittle.
88
+
89
+ ## When durability rules can be relaxed
90
+
91
+ Two narrow exceptions:
92
+
93
+ 1. **Single-cycle short tasks** (<300 tokens, <3 files) — the brief lives only as long as one cycle, and the receiving agent will execute immediately. Type Surface section becomes optional.
94
+ 2. **Bug-fix briefs with concrete repro** — sometimes the bug *is* on a specific line of a specific file as it exists right now. In that case, paths may appear in narrative IF accompanied by the type/function name. Example: *"In `AuthService.authenticate` (currently `src/auth/service.ts`), the comparison uses `<` instead of `<=`."*
95
+
96
+ The rules above are defaults; the exceptions are explicit and rare. When in doubt, follow the rules.
97
+
98
+ ## Self-check before emit
99
+
100
+ ```
101
+ [ ] Every narrative reference uses type/function names, not file paths
102
+ [ ] Type Surface section lists contracts that won't change with file moves
103
+ [ ] Out of scope section exists (even if "(none)")
104
+ [ ] Every Acceptance Criterion starts with a behavior verb
105
+ [ ] No file:line references appear anywhere
106
+ [ ] Files Touched table entries have (Type, function) annotations
107
+ ```
108
+
109
+ If any check fails, fix before the receiving agent gets the packet. A stale brief is worse than no brief at all.
@@ -361,12 +361,12 @@ If the coder model needs info from other phases, it's in the Cross-Phase Context
361
361
 
362
362
  1. Mark Phase 3 as `in_progress`
363
363
  2. **Eval definitions** (Full/Critical rigor only): Before writing tests, define capability evals (pass@k) and regression evals (pass^k) in `.rune/evals/<feature>.md`. Capability evals test "can the system do this new thing?" — regression evals test "did we break existing behavior?" Skip for Fast/Standard rigor levels.
364
- 3. Write test files based on the plan cover primary use case + edge cases; tests MUST be runnable
364
+ 3. Write ONE test for the next behaviorvertical slicing required, see `rune:test` `references/vertical-tdd.md`. Bulk-writing tests = horizontal violation, blocks Phase 4
365
365
  4. **Python async pre-check** (if async-first Python flagged in Phase 1): verify `pytest-asyncio` is installed and `asyncio_mode = "auto"` is in `pyproject.toml` — if missing, warn user before writing async tests
366
- 5. Run tests to verify they FAIL — expected: RED because implementation doesn't exist yet
367
- 6. Mark Phase 3 as `completed`
366
+ 5. Run the test to verify it FAILS — expected: RED because implementation doesn't exist yet
367
+ 6. Mark Phase 3 as `completed` (one cycle); Phase 4 implements that one cycle, then loop returns here for the next test
368
368
 
369
- **Gate**: Tests MUST exist and MUST fail. If tests pass without implementation → tests are wrong, rewrite them.
369
+ **Gate**: Test MUST exist and MUST fail. If test passes without implementation → test is wrong, rewrite. If 2+ tests staged before any GREEN → `tdd.horizontal.violation` signal, unwind to one test.
370
370
 
371
371
  ## Phase 4: IMPLEMENT (TDD Green)
372
372
 
@@ -384,6 +384,7 @@ If the coder model needs info from other phases, it's in the Cross-Phase Context
384
384
  4. Run tests after each significant change — if fail → debug and fix
385
385
  - **Python async** (if async-first flagged): no blocking calls in async functions — `time.sleep` → `asyncio.sleep`, `requests` → `httpx.AsyncClient`, use `asyncio.gather()` for parallel I/O
386
386
  5. If stuck → invoke `rune:debug` (max 3 debug↔fix loops). Fixes outside plan scope require user approval (R4).
387
+ - **Oracle reattach check** — between tasks, glob `.rune/oracle-pending/*.json`. For any record with `status=pending`, invoke `session-bridge --reattach <sessionId>`. If `complete` → consume the response (route to debug/fix per `sourceSkill`). If `pending` → continue with next independent task. If `failed` → continue without second opinion.
387
388
  6. **Re-plan check** — evaluate before Phase 5: max debug loops hit? out-of-scope files changed? new dep changes approach? user scope change? If any fire → invoke `rune:plan` with delta context, get user approval before resuming.
388
389
  7. **Approach Pivot Gate** — if re-plan ALSO fails:
389
390
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: db
3
- description: Database workflow specialist. Generates migration files with rollback scripts, detects breaking schema changes, and validates query parameterization.
3
+ description: "Database workflow specialist. Generates migration files with rollback scripts, detects breaking schema changes, and validates query parameterization."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.2.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: debug
3
- description: Root cause analysis for bugs and unexpected behavior. Traces errors through code, uses structured reasoning, and hands off to fix when cause is found. Core of the debug↔fix mesh.
3
+ description: "Root cause analysis for bugs and unexpected behavior. Traces errors through code, uses structured reasoning, and hands off to fix when cause is found. Core of the debug↔fix mesh."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "1.1.0"
@@ -8,8 +8,8 @@ metadata:
8
8
  model: sonnet
9
9
  group: development
10
10
  tools: "Read, Bash, Glob, Grep"
11
- emit: bug.diagnosed
12
- listen: tests.failed
11
+ emit: bug.diagnosed, agent.stuck
12
+ listen: tests.failed, oracle.response
13
13
  ---
14
14
 
15
15
  # debug
@@ -21,7 +21,9 @@ Root cause analysis ONLY. Debug investigates — it does NOT fix. It traces erro
21
21
  <HARD-GATE>
22
22
  Do NOT fix the code. Debug investigates only. Any code change is out of scope.
23
23
  If root cause cannot be identified after 3 hypothesis cycles:
24
- - Escalate to `rune:problem-solver` for structured 5-Whys or Fishbone analysis
24
+ - Emit `agent.stuck` signal — `scout` zoom-out mode surfaces broader module map (structural pivot); `adversary` oracle-mode dispatches a stateless second-model pass (semantic pivot); both fire in parallel
25
+ - If `oracle.response` arrives with confidence=high and cites file:line, treat as new hypothesis H_oracle and test directly (skip 3-cycle gate — it's externally validated)
26
+ - Otherwise, escalate to `rune:problem-solver` for structured 5-Whys or Fishbone analysis
25
27
  - Or escalate to `rune:sequential-thinking` for multi-variable analysis
26
28
  - Report escalation in the Debug Report with all evidence gathered so far
27
29
  </HARD-GATE>
@@ -45,6 +47,7 @@ If root cause cannot be identified after 3 hypothesis cycles:
45
47
  - `browser-pilot` (L3): capture browser console errors, network failures, visual bugs
46
48
  - `sequential-thinking` (L3): multi-variable root cause analysis
47
49
  - `neural-memory` (L3): after root cause found — capture error pattern for future recognition
50
+ - `adversary` (L2): on `agent.stuck` — oracle-mode dispatches stateless second-model pass to break confirmation-bias loop (parallel with scout zoom-out)
48
51
 
49
52
  ## Called By (inbound)
50
53
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: dependency-doctor
3
- description: Dependency health management. Detects package manager, checks outdated packages and vulnerabilities, and produces a prioritized update plan.
3
+ description: "Dependency health management. Detects package manager, checks outdated packages and vulnerabilities, and produces a prioritized update plan."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.2.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: design
3
- description: Design system reasoning. Maps product domain to style, palette, typography, and platform-specific patterns. Generates .rune/design-system.md as the shared design contract for all UI-generating skills.
3
+ description: "Design system reasoning. Maps product domain to style, palette, typography, and platform-specific patterns. Generates .rune/design-system.md as the shared design contract for all UI-generating skills."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.5.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: doc-processor
3
- description: Generate and parse office documents — PDF, DOCX, XLSX, PPTX, CSV. Pure format utility for creating reports, exporting data, and processing uploaded documents.
3
+ description: "Generate and parse office documents — PDF, DOCX, XLSX, PPTX, CSV. Use when creating reports, exporting tabular data, or processing uploaded office files. NOT for project documentation (use docs)."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.2.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: docs
3
- description: Auto-generate and maintain project documentation. Creates README, API docs, architecture docs, changelogs, and keeps them in sync with code changes. The "docs are never outdated" skill.
3
+ description: "Auto-generate and maintain project documentation. Creates README, API docs, architecture docs, changelogs, and keeps them in sync with code changes. The \"docs are never outdated\" skill."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.3.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: docs-seeker
3
- description: Find documentation for APIs, libraries, and error messages. Looks up official docs, changelog entries, and migration guides.
3
+ description: "Find documentation for APIs, libraries, and error messages. Looks up official docs, changelog entries, and migration guides."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.2.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fix
3
- description: Apply code changes and fixes. Writes implementation code, applies bug fixes, and verifies changes with tests. Core action hub in the development mesh.
3
+ description: "Apply code changes and fixes. Writes implementation code, applies bug fixes, and verifies changes with tests. Core action hub in the development mesh."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "1.0.0"
@@ -8,8 +8,8 @@ metadata:
8
8
  model: sonnet
9
9
  group: development
10
10
  tools: "Read, Write, Edit, Bash, Glob, Grep"
11
- emit: code.changed
12
- listen: bug.diagnosed, review.issues, preflight.blocked, security.blocked
11
+ emit: code.changed, agent.stuck
12
+ listen: bug.diagnosed, review.issues, preflight.blocked, security.blocked, oracle.response
13
13
  ---
14
14
 
15
15
  # fix
@@ -41,6 +41,7 @@ If unsure whether the test is wrong or the implementation is wrong → call `run
41
41
  - `hallucination-guard` (L3): verify imports after code changes
42
42
  - `scout` (L2): find related code before applying changes
43
43
  - `neural-memory` (L3): after fix verified — capture fix pattern (cause → solution)
44
+ - `adversary` (L2): on `agent.stuck` after 2+ failed attempts — oracle-mode dispatches stateless second-model pass to break confirmation-bias loop
44
45
 
45
46
  ## Called By (inbound)
46
47
 
@@ -142,6 +143,7 @@ When fix is called repeatedly (e.g., by cook Phase 4, or iterative fix loops), t
142
143
  **Thresholds:**
143
144
  - **>20% WTF-likelihood**: STOP fixing. Report current state to cook/user with: "Quality decay detected — continued fixes risk introducing more bugs than they resolve. {N} fixes applied, {score}% risk. Recommend: commit current progress, re-assess remaining issues."
144
145
  - **Hard cap: 30 fixes per session** — regardless of score. After 30, STOP and report.
146
+ - **2+ consecutive fixes on the same file all failed**: emit `agent.stuck` signal. `scout` zoom-out mode (structural pivot) and `adversary` oracle-mode (semantic pivot via stateless second-model dispatch) both listen and fire in parallel. If `oracle.response` arrives with confidence=high, apply its recommended edit (still routes through normal validation gates).
145
147
 
146
148
  **Reset conditions:** WTF-likelihood resets to 0% when:
147
149
  - User explicitly says "continue fixing"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: git
3
- description: Specialized git operations — semantic commits, PR descriptions, branch management, conflict resolution guidance. Replaces ad-hoc git commands with a dedicated, convention-aware utility.
3
+ description: "Specialized git operations — semantic commits, PR descriptions, branch management, conflict resolution guidance. Replaces ad-hoc git commands with a dedicated, convention-aware utility."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.3.0"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: hallucination-guard
3
- description: Verify AI-generated imports, API calls, and packages actually exist. Catches phantom functions, non-existent packages, and slopsquatting attacks.
3
+ description: "Verify AI-generated imports, API calls, and packages actually exist. Use when finishing AI-generated code that introduces new imports or external API calls — auto-fires after fix/cook to catch phantom functions, non-existent packages, and slopsquatting attacks."
4
4
  metadata:
5
5
  author: runedev
6
6
  version: "0.3.0"
@@ -0,0 +1,275 @@
1
+ ---
2
+ name: improve-architecture
3
+ description: "Find architectural friction in a codebase and propose deepening opportunities. Use when user wants to improve architecture, find refactor candidates, consolidate shallow modules, or make a codebase more testable. Outputs scored proposals (depth/leverage/locality) that surgeon and review can consume."
4
+ metadata:
5
+ author: runedev
6
+ version: "0.1.0"
7
+ layer: L2
8
+ model: opus
9
+ group: quality
10
+ tools: "Read, Glob, Grep"
11
+ emit: architecture.shallow.flagged, architecture.deletion.passed
12
+ listen: codebase.scanned
13
+ ---
14
+
15
+ # improve-architecture
16
+
17
+ ## Purpose
18
+
19
+ Surface architectural friction in a codebase and propose **deepening opportunities** — refactors that turn shallow modules into deep ones. Output is structured (numeric scores + JSON proposal payloads) so `surgeon`, `review`, and `audit` can consume it programmatically without re-reading the codebase.
20
+
21
+ The goal is **testability and AI-navigability**: a deep module presents a small interface that hides large machinery, so tests target one surface and future agents can reason about the system without traversing N small wrappers.
22
+
23
+ ## Vocabulary (controlled — use exactly)
24
+
25
+ These eight terms have precise meanings. Banned aliases: "boundary" (overloaded with DDD), "component" (UI-specific), "service" (microservice-specific), "layer" (too generic). See [references/language.md](references/language.md) for full definitions.
26
+
27
+ - **Module** — anything with an interface and an implementation (function, class, package, slice).
28
+ - **Interface** — everything a caller must know to use the module: types, invariants, ordering, error modes, config.
29
+ - **Implementation** — the code inside.
30
+ - **Depth** — leverage at the interface; large behavior behind a small interface.
31
+ - **Seam** — where an interface lives; place behavior can be altered without editing in place.
32
+ - **Adapter** — concrete thing satisfying an interface at a seam.
33
+ - **Leverage** — what callers get from depth.
34
+ - **Locality** — what maintainers get from depth.
35
+
36
+ ## Triggers
37
+
38
+ - Called by `cook` Phase 5 (quality gate) when refactor signals appear in scout output
39
+ - Called by `surgeon` before any deepening session — produces the proposal surgeon executes
40
+ - Called by `audit` to compute the architecture sub-score
41
+ - Called by `review` when a reviewer flag mentions "shallow", "wrapper", "indirection"
42
+ - Manual: `/rune improve-architecture <module-path>`
43
+
44
+ ## Calls (outbound)
45
+
46
+ - `scout` (L2): re-scan target module + callers when input context is stale
47
+ - `brainstorm` (L2): when the deepened module needs a new interface, hand off in `design-it-twice` mode (see brainstorm v0.6+)
48
+ - `journal` (L3): record an ADR if the user rejects a candidate with a load-bearing reason
49
+
50
+ ## Called By (inbound)
51
+
52
+ - `cook` (L1): Phase 5 quality gate
53
+ - `surgeon` (L2): pre-refactor input; consumes the proposal payload
54
+ - `audit` (L2): Phase 4 architecture sub-score
55
+ - `review` (L2): when shallow-module flag fires during review
56
+ - User: manual invocation
57
+
58
+ ## Cross-Hub Connections
59
+
60
+ - `improve-architecture` → `surgeon` — proposal payload feeds surgeon's deepening session
61
+ - `improve-architecture` ↔ `brainstorm` — when interface needs design-it-twice exploration
62
+ - `improve-architecture` → `audit` — emits architecture sub-score
63
+ - `improve-architecture` → `journal` — records ADRs for rejected candidates with load-bearing reasons
64
+
65
+ ## Inputs
66
+
67
+ - Required: target module path (e.g. `src/auth/`) OR signal `codebase.scanned` from a recent scout pass
68
+ - Optional: existing `CONTEXT.md` (domain glossary, used to name modules in their domain language)
69
+ - Optional: `docs/adr/` directory (existing ADRs that constrain proposals — do not re-litigate)
70
+
71
+ ## Executable Steps
72
+
73
+ ### Step 1 — Read existing context
74
+
75
+ Read in order, silently skipping any that don't exist:
76
+
77
+ 1. `CONTEXT.md` (or `CONTEXT-MAP.md` + per-bounded-context `CONTEXT.md`)
78
+ 2. Relevant `docs/adr/` files
79
+ 3. The target module's source files (use `Glob` to enumerate, cap at 30 files)
80
+ 4. Direct callers of the module (grep for imports / require / use)
81
+
82
+ If `CONTEXT.md` is missing, do not flag it — treat as "no domain glossary yet". If an ADR contradicts a candidate you're forming, mark it and only surface the candidate if the friction is genuine enough to warrant ADR revision.
83
+
84
+ ### Step 2 — Score the candidate(s)
85
+
86
+ For each candidate module, compute three numeric scores (1–5) and one verdict (enum):
87
+
88
+ | Metric | Formula / Rubric |
89
+ |--------|------------------|
90
+ | **Depth** | `clamp_1_5(implementation_complexity / interface_complexity)` — 1 = shallow wrapper, 5 = small interface hides large machine |
91
+ | **Leverage** | `clamp_1_5(num_callers * unique_use_cases / interface_method_count)` — 1 = thin caller benefit, 5 = many callers, fewer methods to learn |
92
+ | **Locality** | `clamp_1_5(code_concentration_index)` — 1 = logic spread across N callers, 5 = logic concentrated in one place |
93
+ | **Deletion test** | enum: `vanish` (was pass-through) \| `concentrate` (was earning keep) \| `redistribute` (mixed) |
94
+
95
+ Rubric details and edge cases: see [references/scoring.md](references/scoring.md).
96
+
97
+ ### Step 3 — Classify dependencies
98
+
99
+ For each candidate's external dependencies, classify into one of four categories. The category determines test strategy:
100
+
101
+ | Category | Definition | Test Strategy |
102
+ |----------|------------|---------------|
103
+ | `in-process` | Pure computation, in-memory state, no I/O | Test through deepened interface directly |
104
+ | `local-substitutable` | Has local test stand-in (PGLite, in-memory FS) | Use stand-in in tests; no port at module seam |
105
+ | `remote-owned` | Your own module deployed across a network seam | Define a port; in-memory adapter for tests, HTTP adapter for prod |
106
+ | `true-external` | Third-party (Stripe, Twilio) | Inject as port; mock adapter in tests |
107
+
108
+ Full doctrine in [references/deepening.md](references/deepening.md).
109
+
110
+ ### Step 4 — Apply seam discipline
111
+
112
+ Before recommending a port:
113
+
114
+ - **One adapter = hypothetical seam. Two adapters = real seam.** Don't introduce a port unless ≥2 adapters are justified (typically prod + test).
115
+ - Single-adapter "seams" are flagged "indirection-only" and dropped from the proposal.
116
+ - Internal seams (private to the implementation) MAY exist for the deepened module's own tests; they don't appear in the public interface.
117
+
118
+ ### Step 5 — Emit proposal payload
119
+
120
+ For each surviving candidate, produce a structured proposal in YAML:
121
+
122
+ ```yaml
123
+ architecture.proposal:
124
+ module_path: src/auth/
125
+ current:
126
+ depth: 2
127
+ leverage: 3
128
+ locality: 2
129
+ deletion_test: redistribute
130
+ target:
131
+ depth: 4
132
+ leverage: 4
133
+ locality: 4
134
+ dependency_category: remote-owned
135
+ suggested_seam: AuthPort
136
+ adapters_planned: [HttpAuthAdapter, InMemoryAuthAdapter] # 2 = real seam ✅
137
+ tests_to_replace: [auth/login.test.ts, auth/session.test.ts]
138
+ tests_to_write_new: [auth/AuthPort.test.ts]
139
+ domain_terms_used: [Customer, Session] # from CONTEXT.md if present
140
+ adr_conflicts: []
141
+ ```
142
+
143
+ ### Step 6 — Present candidates to user
144
+
145
+ Numbered list, each candidate showing:
146
+ - **Files involved** — file paths (+ key types/exports for durability)
147
+ - **Problem** — friction in the current architecture, in vocab terms (depth/leverage/locality)
148
+ - **Solution** — plain English, naming the deepened module by its domain term if `CONTEXT.md` provides one
149
+ - **Benefits** — leverage gain (caller-side) + locality gain (maintainer-side) + test surface change
150
+ - **Score delta** — current → target
151
+
152
+ Do NOT propose interfaces yet. Ask: "Which candidate to explore?"
153
+
154
+ ### Step 7 — On user pick
155
+
156
+ When user picks a candidate, hand off:
157
+ - To `brainstorm` in `design-it-twice` mode if the new interface is non-obvious (multiple credible shapes)
158
+ - To `surgeon` with the proposal payload otherwise
159
+
160
+ If user rejects a candidate with a load-bearing reason ("we don't want to centralize auth because of compliance audit isolation"), offer to record an ADR via `journal` (only if `score >= 11` per journal v0.4 criteria).
161
+
162
+ ## Output Format
163
+
164
+ ```
165
+ ## Architecture Improvement Report
166
+
167
+ ### Target
168
+ - **Path**: src/auth/
169
+ - **CONTEXT.md present**: yes / no
170
+ - **ADRs reviewed**: 3 (none conflicting)
171
+
172
+ ### Candidates
173
+
174
+ #### 1. Auth port consolidation (depth 2 → 4)
175
+ - **Files**: src/auth/login.ts, src/auth/session.ts, src/auth/middleware.ts
176
+ - **Problem**: 3 shallow modules each handle one HTTP-flavored verb; logic about `Customer` identity is split across all three (locality = 2)
177
+ - **Solution**: collapse into AuthPort exposing `authenticate`, `revoke`, `verify` — 3 methods, deep impl
178
+ - **Benefits**: callers learn 3 methods instead of N free functions; auth logic concentrated; tests target the port
179
+ - **Score delta**: depth 2→4, leverage 3→4, locality 2→4
180
+ - **Deletion test**: redistribute (current modules ARE doing work, just spread)
181
+
182
+ #### 2. ...
183
+
184
+ ### Recommendation
185
+ Candidate 1 — strongest leverage gain. Hand off to `brainstorm` design-it-twice for the AuthPort shape (3 credible alternatives), then `surgeon`.
186
+
187
+ ### Architecture sub-score
188
+ - Current: 58/100
189
+ - Projected after candidate 1: 78/100
190
+ ```
191
+
192
+ ## Returns
193
+
194
+ | Artifact | Format | Location |
195
+ |----------|--------|----------|
196
+ | Architecture Improvement Report | Markdown | inline |
197
+ | Proposal payloads | YAML | inline (per candidate) |
198
+ | Architecture sub-score | integer 0-100 | inline + emitted to audit |
199
+ | ADR draft (if user rejects with load-bearing reason) | Markdown | `.rune/adr/ADR-NNN-<slug>-s<score>.md` via journal |
200
+
201
+ ## Constraints
202
+
203
+ 1. MUST use the 8 controlled vocabulary terms exactly — no aliases ("boundary", "component", "service", "layer" are banned in skill output)
204
+ 2. MUST include numeric scores (depth/leverage/locality 1-5 each) on every candidate — soft prose claims are rejected
205
+ 3. MUST apply deletion test verdict — "vanish" candidates may be removed entirely; "concentrate" candidates are deepening targets
206
+ 4. MUST apply two-adapter rule — single-adapter seams are flagged "indirection-only" and dropped
207
+ 5. MUST NOT propose interfaces in the same step as candidate selection — present candidates first, hand to brainstorm Design-It-Twice if interface is non-obvious
208
+ 6. MUST silently skip missing `CONTEXT.md` / ADR directory — do not flag as project gap
209
+ 7. MUST emit JSON-shaped proposal payload — downstream skills (surgeon) consume it programmatically
210
+
211
+ ## Sharp Edges
212
+
213
+ | Failure Mode | Severity | Mitigation |
214
+ |---|---|---|
215
+ | Recommending a deepening that contradicts a documented ADR | HIGH | Step 1 reads ADRs; if conflict, surface only if friction is real enough to revise the ADR |
216
+ | Single-adapter seam slips into proposal | HIGH | Step 4 rule — drop or downgrade to "internal seam" |
217
+ | Vocabulary drift (using "boundary"/"component"/"service") | MEDIUM | Constraint 1 + linter pass in compiler/__tests__/vocabulary-discipline.test.js |
218
+ | Score inflation to make weak candidate look strong | HIGH | Each metric has rubric in scoring.md; judges show formula inputs |
219
+ | Missing CONTEXT.md domain terms — generic naming ("AuthService") | MEDIUM | If CONTEXT.md exists, names MUST come from it; otherwise OK |
220
+ | Proposing interface in same pass as candidates | MEDIUM | Step 6 hard-stops at candidate list; interface design = brainstorm Design-It-Twice |
221
+ | User rejects all candidates → no ADR recorded → next session re-litigates | MEDIUM | If reason is load-bearing AND score >= 11, offer journal ADR write |
222
+
223
+ ## Self-Validation
224
+
225
+ ```
226
+ SELF-VALIDATION (run before emitting Report):
227
+ - [ ] Every candidate has depth + leverage + locality scores (1-5 each)
228
+ - [ ] Every candidate has deletion-test verdict (vanish | concentrate | redistribute)
229
+ - [ ] Every candidate names a dependency category (in-process | local-substitutable | remote-owned | true-external)
230
+ - [ ] No banned vocabulary (grep candidate text for: boundary, component, service, layer in narrative)
231
+ - [ ] No interfaces drafted yet — that's brainstorm's job
232
+ - [ ] CONTEXT.md domain terms used if file present
233
+ - [ ] Each adapter list has >=2 entries OR seam is marked "internal-only"
234
+ IF ANY check fails → fix before reporting done.
235
+ ```
236
+
237
+ ## Done When
238
+
239
+ - Target module read + callers mapped
240
+ - ≥1 candidate scored on all 3 axes + deletion test
241
+ - Proposal payload(s) emitted in valid YAML
242
+ - Architecture sub-score computed (0-100)
243
+ - User has either picked a candidate (handed to brainstorm/surgeon) or rejected with reason (ADR offered)
244
+ - Report emitted with vocabulary discipline intact
245
+
246
+ ## Cost Profile
247
+
248
+ ~3000-7000 tokens input (codebase scan), ~2000-4000 tokens output (analysis + proposals). Opus model — architectural reasoning depth is the value. Called at most once per `audit` session, on-demand from `cook` / `surgeon`.
249
+
250
+ ## Chain Metadata
251
+
252
+ ```yaml
253
+ chain_metadata:
254
+ skill: "rune:improve-architecture"
255
+ version: "0.1.0"
256
+ status: "[DONE]"
257
+ domain: "[module path scored]"
258
+ exports:
259
+ architecture_subscore: 0-100
260
+ candidates: [{ module, depth, leverage, locality, verdict }]
261
+ proposal_payloads: [<yaml-per-candidate>]
262
+ suggested_next:
263
+ - skill: "rune:brainstorm"
264
+ mode: "design-it-twice"
265
+ reason: "Top candidate has multiple credible interface shapes — need diverse exploration before commit"
266
+ consumes: ["proposal_payloads"]
267
+ - skill: "rune:surgeon"
268
+ reason: "User picked candidate; interface shape is obvious; ready for deepening session"
269
+ consumes: ["proposal_payloads"]
270
+ - skill: "rune:journal"
271
+ reason: "User rejected candidate with load-bearing reason; record ADR (score >=11)"
272
+ consumes: ["candidates", "rejection_reason"]
273
+ ```
274
+
275
+ **Scope guardrail**: improve-architecture proposes and scores. It NEVER edits code. Refactor execution belongs to `surgeon`. Interface exploration belongs to `brainstorm` Design-It-Twice mode.