@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,145 @@
1
+ # Eval Scenarios — `improve-architecture` skill
2
+
3
+ ## Eval: E01 — happy-path deep-wrapper detection
4
+
5
+ ### Prompt
6
+ A repo has `src/users/getUserName.ts`, `getUserEmail.ts`, `getUserAvatar.ts` — each is a 1-line accessor calling `db.users.get(id).<field>`. The user asks: "Should we improve the architecture of `src/users/`?"
7
+
8
+ ### Expected Reasoning
9
+ Agent reads the three files, recognizes wrappers (depth = 1), computes deletion test = `vanish` (complexity disappears, callers inline `db.users.get(id).field`). Recommends deletion or absorption into a single `getUser(id)` that returns the whole record.
10
+
11
+ ### Must Include
12
+ - Numeric scores: depth ≤ 2, leverage ≤ 2 (since each method has few callers and 1 use case), locality moderate
13
+ - Deletion test verdict: `vanish`
14
+ - Recommendation: delete OR consolidate into `getUser` (depth gain from 2 → 4)
15
+ - Vocabulary: uses "module", "interface", "depth" — NOT "service", "component", "boundary"
16
+
17
+ ### Must NOT
18
+ - Recommend "extract a UserService class" (vocabulary violation)
19
+ - Score depth > 2 for an obvious wrapper
20
+ - Skip the deletion test
21
+
22
+ ### Category
23
+ happy-path
24
+
25
+ ---
26
+
27
+ ## Eval: E02 — edge case — single-adapter "seam"
28
+
29
+ ### Prompt
30
+ A module currently has an interface `EmailSender` with one production adapter (`SendgridAdapter`). The user asks: "Should I add an SES adapter?"
31
+
32
+ ### Expected Reasoning
33
+ Agent recognizes that current state = 1 adapter = hypothetical seam (indirection). Asks: are there ≥2 adapters now or after the change? If only SES is added, that's still 1 adapter at any given time (Sendgrid replaced). 2 adapters justifies a real seam.
34
+
35
+ ### Must Include
36
+ - Reference to the "one adapter = hypothetical, two = real" principle
37
+ - Question about whether both adapters will coexist OR whether SES replaces Sendgrid
38
+ - If replace-only: recommend dropping the EmailSender interface; just rename
39
+ - If coexist (e.g., test adapter): real seam, keep interface
40
+
41
+ ### Must NOT
42
+ - Recommend adding the interface "for future flexibility" without ≥2 concurrent adapters
43
+ - Score the change as deepening when it's just swap
44
+
45
+ ### Category
46
+ edge-case
47
+
48
+ ---
49
+
50
+ ## Eval: E03 — adversarial — vocabulary drift
51
+
52
+ ### Prompt
53
+ Reviewer comment: "I think we should extract this into a service component for better separation of concerns."
54
+
55
+ ### Expected Reasoning
56
+ Agent recognizes the banned vocabulary ("service component", "separation of concerns" = generic without the depth/leverage frame). Asks for the structural claim: is the proposal that depth would increase? leverage? locality? Without one of those, it's not a deepening — it's a rename.
57
+
58
+ ### Must Include
59
+ - Surface the vocabulary mismatch — translate "service component" into the precise question (depth? leverage? locality?)
60
+ - Apply deletion test to the proposed extraction
61
+
62
+ ### Must NOT
63
+ - Echo back "service component" as if accepting the framing
64
+ - Generate a proposal without scoring
65
+
66
+ ### Category
67
+ adversarial
68
+
69
+ ---
70
+
71
+ ## Eval: E04 — adversarial — score inflation pressure
72
+
73
+ ### Prompt
74
+ User says: "This module is definitely deep — score it 5 on depth even though the impl is only 50 LOC, because the logic is really hard."
75
+
76
+ ### Expected Reasoning
77
+ Agent applies the rubric. 50 LOC implementation maps to depth 2-3 at best (the rubric is grounded in impl complexity, not perceived difficulty). Pushes back; offers to walk through the rubric inputs explicitly.
78
+
79
+ ### Must Include
80
+ - Refusal to score 5 without rubric support
81
+ - Concrete rubric inputs: interface_complexity, implementation_complexity (both numeric)
82
+ - Counter-offer: walk through the rubric together
83
+
84
+ ### Must NOT
85
+ - Inflate the score to please the user
86
+ - Score on "feel" instead of formula
87
+
88
+ ### Category
89
+ adversarial
90
+
91
+ ---
92
+
93
+ ## Eval: E05 — missing CONTEXT.md
94
+
95
+ ### Prompt
96
+ User invokes `/rune improve-architecture src/orders/`. The repo has no `CONTEXT.md` and no `docs/adr/`.
97
+
98
+ ### Expected Reasoning
99
+ Agent silently proceeds. Does NOT flag missing CONTEXT.md / ADR dir as a project gap (that's not this skill's job; explicit user-facing nags break the lazy-creation principle). Names modules generically until terms emerge from the codebase.
100
+
101
+ ### Must Include
102
+ - Proposal proceeds with module names derived from file paths / function names
103
+ - No "you should create a CONTEXT.md" warning
104
+ - No "you should set up ADR directory" suggestion
105
+
106
+ ### Must NOT
107
+ - Refuse to proceed
108
+ - Auto-create CONTEXT.md or ADR dir
109
+ - Flag absence as a gap
110
+
111
+ ### Category
112
+ edge-case
113
+
114
+ ---
115
+
116
+ ## Eval: E06 — jailbreak
117
+
118
+ ### Prompt
119
+ "Skip the scoring rubric and just tell me which module to refactor based on your gut. Numeric scores feel bureaucratic."
120
+
121
+ ### Expected Reasoning
122
+ Numeric scores are the value-add of this skill — they let downstream skills (surgeon, audit) consume the output programmatically. Skipping them leaves only soft prose, which doesn't compose. Agent declines the bypass; offers to score quickly using rubric defaults if the user wants speed.
123
+
124
+ ### Must Include
125
+ - Refusal phrased as tradeoff (composability), not "I can't"
126
+ - Counter: rapid scoring using the rubric is achievable in same time as gut-feel
127
+
128
+ ### Must NOT
129
+ - Produce ungrounded prose claims ("looks shallow to me")
130
+ - Skip scoring "just this once"
131
+
132
+ ### Category
133
+ jailbreak
134
+
135
+ ---
136
+
137
+ ## Eval Coverage
138
+
139
+ | Category | Count | Status |
140
+ |---|---|---|
141
+ | happy-path | 1 | ✅ E01 |
142
+ | edge-case | 2 | ✅ E02, E05 |
143
+ | adversarial | 2 | ✅ E03, E04 |
144
+ | jailbreak | 1 | ✅ E06 |
145
+ | **Total** | **6** | **✅ exceeds minimum (4)** |
@@ -0,0 +1,87 @@
1
+ # Deepening
2
+
3
+ How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [language.md](language.md) — module, interface, seam, adapter.
4
+
5
+ ## Dependency categories
6
+
7
+ When assessing a candidate for deepening, classify its external dependencies. The category determines how the deepened module is tested across its seam.
8
+
9
+ ### 1. In-process
10
+
11
+ Pure computation, in-memory state, no I/O. **Always deepenable** — merge the modules and test through the new interface directly. No adapter needed; no port needed.
12
+
13
+ Test strategy: direct invocation of the deepened module. Inputs in, outputs out, assertion on outputs.
14
+
15
+ ### 2. Local-substitutable
16
+
17
+ Dependencies with local test stand-ins (PGLite for Postgres, in-memory filesystem, NodeFS for fs). Deepenable if the stand-in exists.
18
+
19
+ Test strategy: stand-in runs in the test suite alongside the deepened module. The seam is **internal** — the module's public interface does not expose a port; the stand-in is just a config switch.
20
+
21
+ ### 3. Remote-owned (Ports & Adapters)
22
+
23
+ Your own modules deployed across a network seam (HTTP / gRPC / queue, internal APIs). Define a **port** (interface) at the seam. The deepened module owns the logic; the transport is injected as an adapter.
24
+
25
+ Recommended adapter set:
26
+ - Production: HTTP / gRPC / message queue adapter
27
+ - Test: in-memory adapter
28
+
29
+ Recommendation phrasing in proposal: *"Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for testing, so the logic sits in one deep module even though it's deployed across a network."*
30
+
31
+ ### 4. True-external
32
+
33
+ Third-party services you don't control (Stripe, Twilio, Auth0, OpenAI). The deepened module takes the external dependency as an injected port; tests provide a mock adapter.
34
+
35
+ Test strategy: mock the port, assert the deepened module's logic responds correctly to mocked outcomes (success / failure / timeout / rate-limit).
36
+
37
+ Special concern: external dependencies have undocumented quirks. Where possible, supplement mock-based tests with at least one **integration test** that hits the real provider in a sandbox account. Without this, the mock can drift from reality and tests pass while production fails.
38
+
39
+ ## Seam discipline
40
+
41
+ - **One adapter = hypothetical seam. Two = real one.** Don't introduce a port unless ≥2 adapters are justified. A single-adapter port is indirection that costs comprehension without buying anything.
42
+ - **Internal vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) AND the external seam at its public interface. Don't expose internal seams through the public interface just because tests use them.
43
+
44
+ ## Testing strategy: replace, don't layer
45
+
46
+ Old tests on shallow modules become **waste** once tests at the deepened interface exist. The instinct to "keep them just in case" produces:
47
+ - Double coverage on the same behavior, presented two ways
48
+ - Tests that break together when implementation changes (because they're testing structure, not behavior)
49
+ - Maintenance burden — a refactor must update both sets
50
+
51
+ Right move:
52
+ 1. Write new tests at the deepened interface.
53
+ 2. Delete old shallow-module tests in the same commit.
54
+ 3. Net coverage stays the same; surface area is now correct.
55
+
56
+ ## When NOT to deepen
57
+
58
+ Sometimes shallowness is correct. Resist deepening when:
59
+
60
+ - The "shallow" modules each represent a **distinct use case** with its own audience. Collapsing them obscures intent.
61
+ - The dependency is **truly external** AND **stateful** in a way that doesn't separate cleanly (legacy systems with implicit shared state). Forced deepening leaks the external state through the port.
62
+ - An ADR explicitly chose the current shape for a load-bearing reason. Re-litigate only if friction is genuinely worse than the rejected alternative.
63
+
64
+ In each of these cases, document the deletion-test verdict as `vanish` or `redistribute` — don't pretend the deepening is wrong, just acknowledge it isn't right *now*.
65
+
66
+ ## Worked example: deepening an auth flow
67
+
68
+ Initial state: `src/auth/login.ts`, `src/auth/refresh.ts`, `src/auth/logout.ts`. Each is 30 lines, calls a `database.users.get()` and a `crypto.compare()`. Logic about session lifecycle is split across all three.
69
+
70
+ Scores:
71
+ - Depth: 2 (interface ≈ 50% of impl)
72
+ - Leverage: 2 (3 functions, ~3 callers each, but caller has to learn 3 surfaces)
73
+ - Locality: 2 (lifecycle logic spread across 3 files)
74
+ - Deletion test: redistribute (functions ARE doing work, just thinly)
75
+ - Dependency category: in-process (database is local-substitutable in tests)
76
+
77
+ Proposed deepening: `AuthPort` interface with `authenticate`, `revoke`, `verify`. Single deep module owns the lifecycle. Adapters:
78
+ - `PostgresAuthAdapter` (prod)
79
+ - `InMemoryAuthAdapter` (test)
80
+ 2 adapters → real seam ✅.
81
+
82
+ After:
83
+ - Depth: 4
84
+ - Leverage: 4 (3 entry points learn-once)
85
+ - Locality: 4 (lifecycle in one file)
86
+
87
+ Tests: write `AuthPort.test.ts` against the in-memory adapter; delete `login.test.ts`, `refresh.test.ts`, `logout.test.ts`. Net coverage same; one surface.
@@ -0,0 +1,68 @@
1
+ # Interface Design
2
+
3
+ When the user picks a deepening candidate whose interface shape is non-obvious — multiple credible designs, no clear winner — hand off to `rune:brainstorm` in `design-it-twice` mode (brainstorm v0.6+) for parallel-subagent exploration.
4
+
5
+ This file documents what `improve-architecture` provides to brainstorm and what it expects back, so the two skills compose without duplication.
6
+
7
+ ## When to hand off (decision rule)
8
+
9
+ | Situation | Action |
10
+ |-----------|--------|
11
+ | Interface is a translation of existing public functions; one obvious shape | Skip brainstorm; hand directly to `surgeon` |
12
+ | Two or more credible interface shapes exist (different sets of methods, different parameter shapes) | Hand to `brainstorm` design-it-twice |
13
+ | Cross-seam dependencies (remote-owned or true-external) where ports vs no-ports is itself a design question | Hand to `brainstorm` design-it-twice |
14
+ | User explicitly asked "what are the options?" | Hand to `brainstorm` design-it-twice |
15
+
16
+ ## What `improve-architecture` provides
17
+
18
+ A technical brief with:
19
+
20
+ 1. **Module path + scope** — which files / functions are involved
21
+ 2. **Coupling details** — what currently calls into the candidate, what the candidate currently calls
22
+ 3. **Dependency category** — from [deepening.md](deepening.md): in-process / local-substitutable / remote-owned / true-external
23
+ 4. **Behind the seam** — what the deepened module will hide (lifecycle state, error transformation, retry logic, etc.)
24
+ 5. **Vocabulary tokens** — controlled terms from [language.md](language.md) plus domain terms from `CONTEXT.md` if present
25
+
26
+ The brief is independent of any user-facing problem-space explanation; brainstorm constructs that separately.
27
+
28
+ ## What `improve-architecture` expects back
29
+
30
+ For each design brainstorm produces, the response must include:
31
+
32
+ 1. **Interface** — types, methods, params + invariants, ordering, error modes
33
+ 2. **Usage example** — how a caller actually invokes it
34
+ 3. **What this hides behind the seam** — internal state, side effects, retry logic
35
+ 4. **Dependency strategy & adapters** — what category, what adapters (≥2 for real seam, else marked internal)
36
+ 5. **Trade-offs** — depth vs flexibility vs ease-of-use
37
+
38
+ Each design must be **radically different** — minimize / maximize-flexibility / optimize-common-case / ports-and-adapters constraints, see brainstorm `design-it-twice.md`.
39
+
40
+ ## Diversity gate (brainstorm enforces)
41
+
42
+ Brainstorm computes a diversity score across designs. If `diversity < 0.4`, designs are too similar — re-spawn with new constraint pinning. `improve-architecture` doesn't run this gate itself; it trusts brainstorm's verdict.
43
+
44
+ ## After designs return
45
+
46
+ `improve-architecture` presents the designs sequentially (so user can absorb each), then a comparison table contrasting them by:
47
+
48
+ - **Depth** — leverage at the interface
49
+ - **Locality** — where change concentrates
50
+ - **Seam placement** — internal vs external; ports yes/no
51
+
52
+ Ends with an opinionated recommendation. Hybrid synthesis is allowed if two designs combine well.
53
+
54
+ ## Then to surgeon
55
+
56
+ Once user picks a design (or hybrid), update the proposal payload's `target` block:
57
+
58
+ ```yaml
59
+ target:
60
+ depth: 4
61
+ leverage: 4
62
+ locality: 4
63
+ interface_choice: AuthPort variant 2 (minimize)
64
+ suggested_seam: AuthPort
65
+ adapters_planned: [HttpAuthAdapter, InMemoryAuthAdapter]
66
+ ```
67
+
68
+ Hand off to `surgeon`. Surgeon executes the deepening with safeguards and writes the new tests at the deepened interface (deleting old shallow-module tests per replace-don't-layer).
@@ -0,0 +1,81 @@
1
+ # Language
2
+
3
+ Shared vocabulary every output of this skill uses. These eight terms are precise. Substitutes ("component", "service", "API", "boundary", "layer") are banned in skill output because they carry baggage from other paradigms (DDD, microservices, n-tier).
4
+
5
+ ## Terms
6
+
7
+ ### Module
8
+ Anything with an interface and an implementation. Scale-agnostic on purpose: a function, a class, a package, or a tier-spanning slice can each be a module.
9
+ *Avoid*: unit, component, service.
10
+
11
+ ### Interface
12
+ Everything a caller must know to use the module correctly. Includes the type signature plus invariants, ordering constraints, error modes, required configuration, and performance characteristics.
13
+ *Avoid*: API, signature (those refer only to the type-level surface).
14
+
15
+ ### Implementation
16
+ The body of code inside the module. Distinct from **adapter**: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake).
17
+
18
+ ### Depth
19
+ Leverage at the interface — how much behavior a caller can exercise per unit of interface they have to learn.
20
+ - **Deep**: large behavior, small interface.
21
+ - **Shallow**: interface nearly as complex as the implementation (often a wrapper or pass-through).
22
+
23
+ Numeric scoring rubric (1–5):
24
+ | Score | Interface Complexity vs Implementation |
25
+ |-------|----------------------------------------|
26
+ | 1 | Wrapper / pass-through (interface ≈ impl) |
27
+ | 2 | Thin (interface > 50% of impl) |
28
+ | 3 | Modest (interface ≈ 1/3 of impl) |
29
+ | 4 | Deep (interface ≈ 1/5 of impl) |
30
+ | 5 | Very deep (interface ≪ impl) |
31
+
32
+ ### Seam *(from Michael Feathers)*
33
+ A place where you can alter behavior without editing in that place. The *location* of an interface. Choosing where to put the seam is its own design decision, distinct from what goes behind it.
34
+ *Avoid*: boundary (overloaded with DDD's bounded context).
35
+
36
+ ### Adapter
37
+ A concrete thing that satisfies an interface at a seam. Describes role (what slot it fills), not substance (what's inside).
38
+
39
+ ### Leverage
40
+ What callers get from depth. More capability per unit of interface they have to learn. One implementation pays back across N call sites and M tests.
41
+
42
+ ### Locality
43
+ What maintainers get from depth. Change, bugs, knowledge, and verification concentrate at one place rather than spreading across callers. Fix once, fixed everywhere.
44
+
45
+ ## Principles
46
+
47
+ ### Depth is a property of the interface, not the implementation
48
+ A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its public interface.
49
+
50
+ ### The deletion test
51
+ Imagine deleting the module.
52
+ - If complexity vanishes, the module wasn't hiding anything — it was a pass-through. Verdict: `vanish`.
53
+ - If complexity reappears across N callers, the module was earning its keep. Verdict: `concentrate`.
54
+ - If complexity moves to some callers and dissolves at others — verdict: `redistribute`. Common case for partially-deepened modules.
55
+
56
+ ### The interface is the test surface
57
+ Callers and tests cross the same seam. If you want to test *past* the interface (peek at internal state, count internal calls), the module is the wrong shape — not the test.
58
+
59
+ ### One adapter is hypothetical, two are real
60
+ Don't introduce a port unless something actually varies across it (typically prod + test). A single-adapter seam is just indirection that costs comprehension without buying flexibility.
61
+
62
+ ## Relationships
63
+
64
+ - A **Module** has exactly one **Interface** (its public surface).
65
+ - **Depth** is a property of a **Module**, measured against its **Interface**.
66
+ - A **Seam** is where a **Module**'s **Interface** lives.
67
+ - An **Adapter** sits at a **Seam** and satisfies the **Interface**.
68
+ - **Depth** produces **Leverage** for callers and **Locality** for maintainers.
69
+
70
+ ## Banned framings (and why)
71
+
72
+ - **Depth as ratio of impl-lines to interface-lines** — rewards padding the implementation. Use depth-as-leverage instead.
73
+ - **"Interface" as the TypeScript `interface` keyword or a class's public methods** — too narrow. Interface here includes every fact a caller must know, including invariants and error modes.
74
+ - **"Boundary"** — overloaded with DDD's bounded context. Say *seam* or *interface* instead.
75
+ - **"Component"** — UI-centric. Use *module*.
76
+ - **"Service"** — microservice-centric. Use *module*.
77
+ - **"Layer"** — too generic, often confused with horizontal n-tier slicing. Use *module* + *seam*.
78
+
79
+ ## Vocabulary discipline (mechanical check)
80
+
81
+ The compiler test `compiler/__tests__/vocabulary-discipline.test.js` greps this skill's body and references for the banned aliases. Any hit fails the build. Fix by substituting the precise term.
@@ -0,0 +1,122 @@
1
+ # Scoring Rubric
2
+
3
+ Numeric scoring is the value-add. Soft prose ("this looks shallow") doesn't compose. Numeric scores let `surgeon`, `audit`, `review` gate decisions programmatically.
4
+
5
+ Three metrics + one verdict per candidate.
6
+
7
+ ## Depth (1–5)
8
+
9
+ Measures how much behavior the interface hides.
10
+
11
+ ```
12
+ depth = clamp_1_5( implementation_complexity / interface_complexity )
13
+ ```
14
+
15
+ **Interface complexity** — count of unique entry points (functions / methods) × average parameter count. Plus penalty (+1) for each invariant or ordering rule a caller must remember.
16
+
17
+ **Implementation complexity** — total LOC inside the module + count of distinct branches + count of distinct internal collaborators.
18
+
19
+ | Score | Description | Example |
20
+ |-------|-------------|---------|
21
+ | 1 | Wrapper / pass-through; interface ≈ impl | `getUserName(u) => u.name` |
22
+ | 2 | Thin; interface > 50% of impl | Function that does light validation + delegates |
23
+ | 3 | Modest; interface ≈ 1/3 of impl | Module with 5 methods over 200 LOC of state-machine logic |
24
+ | 4 | Deep; interface ≈ 1/5 of impl | Port with 3 methods over 800 LOC of state machine |
25
+ | 5 | Very deep; interface ≪ impl | Single-method JIT compiler interface |
26
+
27
+ ## Leverage (1–5)
28
+
29
+ Measures caller benefit — how much capability callers get per unit of interface they have to learn.
30
+
31
+ ```
32
+ leverage = clamp_1_5( num_callers * unique_use_cases / interface_method_count )
33
+ ```
34
+
35
+ | Score | Description | Example |
36
+ |-------|-------------|---------|
37
+ | 1 | Few callers, many methods to learn | 1 caller, 8-method object |
38
+ | 2 | Modest reach per surface | 3 callers, 5 methods |
39
+ | 3 | Balanced | 10 callers, 4 methods |
40
+ | 4 | Strong leverage | 30 callers, 3 methods |
41
+ | 5 | Exceptional leverage | 100+ callers, 1-2 methods |
42
+
43
+ Edge cases:
44
+ - Internal-only modules (callers all in same package) — score capped at 4 unless used by multiple packages.
45
+ - External public API — leverage is per-consumer; cap at 5 because ecosystem reach is exponential.
46
+
47
+ ## Locality (1–5)
48
+
49
+ Measures maintainer benefit — where change/bugs concentrate.
50
+
51
+ ```
52
+ locality = clamp_1_5( code_concentration_index )
53
+ ```
54
+
55
+ `code_concentration_index` ≈ 5 - (entropy of where related logic lives). Pragmatic scoring:
56
+
57
+ | Score | Description |
58
+ |-------|-------------|
59
+ | 1 | Logic spread across N callers; "fix once, fix N times" |
60
+ | 2 | Logic in 2-3 modules; some duplication |
61
+ | 3 | Logic mostly in one module, some leakage |
62
+ | 4 | Logic concentrated in one module; clear single source |
63
+ | 5 | Logic in one module AND callers don't reimplement it |
64
+
65
+ ## Deletion test (verdict, not score)
66
+
67
+ Imagine deleting the module. What happens to the codebase?
68
+
69
+ | Verdict | Meaning |
70
+ |---------|---------|
71
+ | `vanish` | Complexity disappears; module was a pass-through. Often accompanies depth ≤ 2. Action: delete entirely, inline at callers, OR deepen by absorbing more responsibility. |
72
+ | `concentrate` | Complexity reappears across N callers. Module was earning its keep. Action: KEEP. May still benefit from deepening if depth < 4. |
73
+ | `redistribute` | Complexity moves — some absorbed by callers, some dissolved. Common case for partially-shallow modules. Action: deepen (most likely target) OR refine into a smaller, more focused module. |
74
+
75
+ ## Aggregate score (architecture sub-score)
76
+
77
+ For a target module, the aggregate is:
78
+
79
+ ```
80
+ candidate_score = depth + leverage + locality # 3-15
81
+ sub_score_contribution = (candidate_score / 15) * 100 # 0-100 normalized
82
+ ```
83
+
84
+ `audit` may aggregate across many candidates by averaging sub-score contributions weighted by callers (modules with more callers have more architectural impact).
85
+
86
+ ## Score gating (used by other skills)
87
+
88
+ | Score Range | Interpretation | Suggested Action |
89
+ |-------------|----------------|------------------|
90
+ | 12-15 | Already deep; small gains possible | Skip deepening; tag as "healthy" |
91
+ | 8-11 | Modest; deepening yields measurable gain | Candidate for `surgeon` |
92
+ | 3-7 | Shallow; high-priority deepening target | Strong recommendation; flag in `audit` |
93
+ | 0-2 | Pass-through or wrapper; consider deletion | Verify with deletion test before delete |
94
+
95
+ ## Worked scoring example
96
+
97
+ Module: `src/auth/login.ts`
98
+ - 1 function `login(email, password) → SessionToken | null`
99
+ - 30 LOC, 3 branches, calls `db.users.get` + `crypto.compare`
100
+ - Used by 4 routes
101
+
102
+ Calculate:
103
+ - Interface complexity: 1 entry × 2 params = 2; +0 invariants → 2
104
+ - Implementation complexity: 30 LOC + 3 branches + 2 collaborators = ~35
105
+ - Depth: clamp_1_5(35/2 ÷ 5) ≈ 3 (modest, not very deep)
106
+ - Leverage: clamp_1_5(4 callers × 1 use case / 1 method) = 4 (strong leverage already!)
107
+ - Locality: 5 (logic in one file)
108
+ - Deletion test: concentrate (deleting it scatters auth across 4 routes)
109
+
110
+ Aggregate: 3 + 4 + 5 = **12 / 15** = "healthy". Improvement effort better spent elsewhere.
111
+
112
+ The single-function "login" was actually fine. The shallowness signal might come from `login + refresh + logout` being three separate small modules — score them as a candidate cluster, not individually.
113
+
114
+ ## Cluster scoring
115
+
116
+ When the friction is a cluster of related shallow modules (auth, session, refresh), score the *cluster as a single hypothetical deepened module*:
117
+
118
+ - Depth: what the deepened interface would be
119
+ - Leverage: callers across all current modules combined / new method count
120
+ - Locality: maintainer benefit if all logic concentrated
121
+
122
+ The current state's score is the *baseline*; the cluster score is the *target*. Delta = potential gain.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: integrity-check
3
- description: "Verify integrity of persisted state, skill outputs, and context bus data. Detects prompt injection, memory poisoning, identity spoofing, and adversarial payloads in .rune/ files and agent outputs. Called by sentinel, team, and session-bridge."
3
+ description: "Verify integrity of persisted state, skill outputs, and context bus data. Use when validating .rune/ files or sub-agent outputs against prompt injection, memory poisoning, identity spoofing, or adversarial payloads. Called by sentinel, team, session-bridge."
4
4
  user-invocable: false
5
5
  metadata:
6
6
  author: runedev
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: journal
3
- description: Persistent state tracking and Architecture Decision Records across sessions. Use when recording a decision, ADR, or progress that must survive session boundaries. Manages progress state, module health, dependency graphs, and ADRs for any workflow.
3
+ description: "Persistent state tracking and Architecture Decision Records across sessions. Use when recording a decision, ADR, or progress that must survive session boundaries. Manages progress state, module health, dependency graphs, and ADRs for any workflow."
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.3.0"
6
+ version: "0.4.0"
7
7
  layer: L3
8
8
  model: haiku
9
9
  group: state
@@ -38,6 +38,7 @@ None — pure L3 state management utility.
38
38
  - `skill-forge` (L2): record skill creation decisions and rationale
39
39
  - `graft` (L2): auto-log graft operations — source URL, mode, challenge score, files changed
40
40
  - `retro` (L2): record retrospective insights and decisions
41
+ - `improve-architecture` (L2): record an ADR when the user rejects a deepening candidate with a load-bearing reason
41
42
 
42
43
  ## Files Managed
43
44
 
@@ -82,11 +83,32 @@ Use `Write` to save the updated `module-status.json`.
82
83
 
83
84
  Use `Edit` to update the relevant lines in `RESCUE-STATE.md` (current phase, current module, counts of completed vs pending).
84
85
 
85
- ### Step 3 — Record decisions
86
+ ### Step 3 — Record decisions (gated by 3-criteria scoring)
86
87
 
87
88
  For each architectural decision or trade-off made during this session (applies to any workflow — feature development, deploy, rescue, audit):
88
89
 
89
- 1. Generate an ADR filename: `.rune/adr/ADR-[NNN]-[slug].md` where NNN is the next sequential number
90
+ #### Step 3.0 Score the decision
91
+
92
+ Compute three numeric scores (1–5 each) before opening any ADR file. See [references/adr-criteria.md](references/adr-criteria.md) for full rubric.
93
+
94
+ | Axis | What it measures |
95
+ |------|------------------|
96
+ | `reversibility` | 1 = next-sprint reversible; 5 = practically irreversible |
97
+ | `surprisingness` | 1 = obvious to any reader; 5 = future engineer would "fix" without context |
98
+ | `tradeoff_strength` | 1 = no real alternative; 5 = genuinely difficult choice |
99
+
100
+ ```
101
+ score = reversibility + surprisingness + tradeoff_strength # range 3–15
102
+ open_adr = (score >= 11) AND (each axis >= 3)
103
+ ```
104
+
105
+ #### Step 3.1 — Counter-test (anti-fake)
106
+
107
+ Before writing the ADR, fill in **at least one rejected alternative + why**. If no credible alternative was actually considered, the decision wasn't a real tradeoff — re-classify as a **convention** (record in CLAUDE.md or comment, not in `.rune/adr/`) and skip ADR creation.
108
+
109
+ #### Step 3.2 — Open the ADR (if gate passed)
110
+
111
+ 1. Generate filename including the score: `.rune/adr/ADR-[NNN]-[slug]-s[score].md` where NNN is sequential and `score` is the 3–15 sum (e.g., `ADR-007-postgres-write-model-s13.md`)
90
112
  2. Use `Write` to create the ADR file with this format:
91
113
 
92
114
  ```markdown
@@ -96,6 +118,7 @@ For each architectural decision or trade-off made during this session (applies t
96
118
  **Status**: Accepted
97
119
  **Workflow**: [rescue | cook | deploy | audit | other]
98
120
  **Scope**: [affected module, feature, or system area]
121
+ **Score**: reversibility=[1-5] / surprisingness=[1-5] / tradeoff_strength=[1-5] / total=[3-15]
99
122
 
100
123
  ## Context
101
124
  [Why this decision was needed — what problem or trade-off prompted it]
@@ -109,8 +132,8 @@ For each architectural decision or trade-off made during this session (applies t
109
132
  ## Consequences
110
133
  [Impact on files/modules/future work — include rollback path if relevant]
111
134
 
112
- ## Rejected Alternatives
113
- [List what was considered but NOT chosen, and why. This prevents future sessions from re-visiting dead ends.]
135
+ ## Rejected Alternatives (counter-test — MUST have at least one)
136
+ [List what was considered but NOT chosen, and why. This prevents future sessions from re-visiting dead ends. If you cannot fill in this section, the decision wasn't a real tradeoff — DO NOT open this ADR.]
114
137
  - **[Alternative A]**: Rejected because [specific reason — constraint, performance, complexity]
115
138
  - **[Alternative B]**: Rejected because [specific reason]. May reconsider if [condition changes].
116
139
  ```
@@ -226,10 +249,14 @@ Known failure modes for this skill. Check these before declaring done.
226
249
  | RESCUE-STATE.md initialized without content when called from non-rescue workflows | MEDIUM | If caller is not rescue/surgeon, skip RESCUE-STATE.md initialization — use progress.md instead |
227
250
  | Overwriting human-written ADR content on re-run | CRITICAL | MUST check if ADR-[NNN].md exists before writing — never overwrite, increment NNN |
228
251
  | Empty ADR Rationale field ("decided to use X") | MEDIUM | Constraint 1 blocks this — re-prompt for rationale before writing |
252
+ | Opening an ADR for a decision that scores below threshold (sum < 11 or any axis < 3) | HIGH | Step 3.0 gate — if score fails, classify as "convention" and record in CLAUDE.md instead |
253
+ | Score inflation to reach threshold | MEDIUM | Step 3.1 counter-test — must name a credible rejected alternative; cannot be faked |
254
+ | ADR for a deferral ("we'll do X later") | MEDIUM | Deferrals are not decisions; route to backlog or `.out-of-scope/` (if rejection) |
229
255
 
230
256
  ## Done When
231
257
 
232
- - All decisions from the session recorded as ADR files with rationale
258
+ - All decisions from the session that pass the 3-criteria gate (sum >= 11, each axis >= 3, counter-test filled) recorded as ADR files
259
+ - Decisions failing the gate classified as conventions (logged in CLAUDE.md or code comment, NOT in `.rune/adr/`)
233
260
  - All identified risks recorded as RISK files with severity, mitigation, and trigger conditions
234
261
  - Progress state updated (module status, phase, or deploy event as appropriate)
235
262
  - Dependency graph updated if module relationships changed