@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.
- package/README.md +31 -12
- package/compiler/__tests__/adapter-model-mapping.test.js +152 -0
- package/compiler/__tests__/adr-scoring.test.js +91 -0
- package/compiler/__tests__/context-md-format.test.js +180 -0
- package/compiler/__tests__/context-pack-smell-tests.test.js +215 -0
- package/compiler/__tests__/context-preview-signal.test.js +166 -0
- package/compiler/__tests__/diversity-score.test.js +117 -0
- package/compiler/__tests__/improve-architecture.test.js +171 -0
- package/compiler/__tests__/openclaw-adapter.test.js +11 -6
- package/compiler/__tests__/oracle-bundle-format.test.js +210 -0
- package/compiler/__tests__/oracle-pending-schema.test.js +209 -0
- package/compiler/__tests__/out-of-scope-format.test.js +303 -0
- package/compiler/__tests__/skill-description-quality.test.js +147 -0
- package/compiler/__tests__/zoom-out-output.test.js +112 -0
- package/compiler/adapters/antigravity.js +17 -1
- package/compiler/adapters/claude.js +4 -0
- package/compiler/adapters/codex.js +16 -1
- package/compiler/adapters/cursor.js +4 -0
- package/compiler/adapters/generic.js +14 -1
- package/compiler/adapters/openclaw.js +15 -1
- package/compiler/adapters/opencode.js +17 -1
- package/compiler/adapters/windsurf.js +4 -0
- package/package.json +2 -2
- package/skills/adversary/SKILL.md +61 -1
- package/skills/adversary/evals.md +79 -0
- package/skills/adversary/references/context-bundle-format.md +122 -0
- package/skills/adversary/references/oracle-mode.md +116 -0
- package/skills/asset-creator/SKILL.md +1 -1
- package/skills/audit/SKILL.md +3 -1
- package/skills/autopsy/SKILL.md +1 -1
- package/skills/ba/SKILL.md +242 -83
- package/skills/ba/references/context-md-format.md +136 -0
- package/skills/ba/references/explore-first.md +107 -0
- package/skills/ba/references/out-of-scope-format.md +152 -0
- package/skills/brainstorm/SKILL.md +78 -2
- package/skills/brainstorm/references/design-it-twice.md +155 -0
- package/skills/browser-pilot/SKILL.md +1 -1
- package/skills/completion-gate/SKILL.md +1 -1
- package/skills/constraint-check/SKILL.md +1 -1
- package/skills/context-engine/SKILL.md +85 -1
- package/skills/context-engine/references/preview-gate.md +139 -0
- package/skills/context-pack/SKILL.md +68 -25
- package/skills/context-pack/evals.md +122 -0
- package/skills/context-pack/references/brief-template.md +121 -0
- package/skills/context-pack/references/durability-rules.md +109 -0
- package/skills/cook/SKILL.md +5 -4
- package/skills/db/SKILL.md +1 -1
- package/skills/debug/SKILL.md +7 -4
- package/skills/dependency-doctor/SKILL.md +1 -1
- package/skills/design/SKILL.md +1 -1
- package/skills/doc-processor/SKILL.md +1 -1
- package/skills/docs/SKILL.md +1 -1
- package/skills/docs-seeker/SKILL.md +1 -1
- package/skills/fix/SKILL.md +5 -3
- package/skills/git/SKILL.md +1 -1
- package/skills/hallucination-guard/SKILL.md +1 -1
- package/skills/improve-architecture/SKILL.md +275 -0
- package/skills/improve-architecture/evals.md +145 -0
- package/skills/improve-architecture/references/deepening.md +87 -0
- package/skills/improve-architecture/references/interface-design.md +68 -0
- package/skills/improve-architecture/references/language.md +81 -0
- package/skills/improve-architecture/references/scoring.md +122 -0
- package/skills/integrity-check/SKILL.md +1 -1
- package/skills/journal/SKILL.md +34 -7
- package/skills/journal/references/adr-criteria.md +109 -0
- package/skills/logic-guardian/SKILL.md +1 -1
- package/skills/marketing/SKILL.md +1 -1
- package/skills/mcp-builder/SKILL.md +1 -1
- package/skills/onboard/SKILL.md +1 -1
- package/skills/perf/SKILL.md +1 -1
- package/skills/plan/SKILL.md +1 -1
- package/skills/preflight/SKILL.md +1 -1
- package/skills/research/SKILL.md +1 -1
- package/skills/retro/SKILL.md +1 -1
- package/skills/review/SKILL.md +3 -2
- package/skills/review-intake/SKILL.md +26 -3
- package/skills/safeguard/SKILL.md +1 -1
- package/skills/scaffold/SKILL.md +1 -1
- package/skills/scout/SKILL.md +33 -1
- package/skills/sentinel/SKILL.md +1 -1
- package/skills/sentinel-env/SKILL.md +1 -1
- package/skills/session-bridge/SKILL.md +91 -4
- package/skills/session-bridge/references/detach-protocol.md +111 -0
- package/skills/skill-forge/SKILL.md +1 -1
- package/skills/slides/SKILL.md +1 -1
- package/skills/surgeon/SKILL.md +17 -2
- package/skills/team/SKILL.md +3 -0
- package/skills/test/SKILL.md +48 -1
- package/skills/test/evals.md +137 -0
- package/skills/test/references/mocking-policy.md +121 -0
- package/skills/test/references/test-quality.md +124 -0
- package/skills/test/references/vertical-tdd.md +110 -0
- package/skills/trend-scout/SKILL.md +1 -1
- package/skills/video-creator/SKILL.md +1 -1
- package/skills/watchdog/SKILL.md +1 -1
- 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.
|
|
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
|
package/skills/journal/SKILL.md
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
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
|