@renzrollon/interlock 1.0.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/.claude-plugin/marketplace.json +19 -0
- package/.claude-plugin/plugin.json +58 -0
- package/CHANGELOG.md +380 -0
- package/LICENSE +21 -0
- package/README.md +358 -0
- package/agents/ping.md +8 -0
- package/agents/worker.md +8 -0
- package/bin/interlock +2655 -0
- package/bin/interlock-graph +6 -0
- package/bin/interlock-run +508 -0
- package/bin/interlock-ship-acp +39 -0
- package/hooks/_shared.mjs +162 -0
- package/hooks/guard-commit.mjs +77 -0
- package/hooks/guard-tasks.mjs +107 -0
- package/hooks/guard-tests.mjs +63 -0
- package/hooks/preflight.mjs +107 -0
- package/lib/artifacts.mjs +316 -0
- package/lib/autonomy.mjs +149 -0
- package/lib/conformance.mjs +132 -0
- package/lib/doctor.mjs +1176 -0
- package/lib/drift.mjs +409 -0
- package/lib/eval-history.mjs +304 -0
- package/lib/evals-calibrate.mjs +317 -0
- package/lib/evals-capture.mjs +437 -0
- package/lib/evals-promote.mjs +257 -0
- package/lib/evals-triage.mjs +216 -0
- package/lib/findings.mjs +340 -0
- package/lib/graph/cli.mjs +266 -0
- package/lib/graph/extract/config-json.mjs +74 -0
- package/lib/graph/extract/create-extractor.mjs +35 -0
- package/lib/graph/extract/memory.mjs +99 -0
- package/lib/graph/extract/openspec.mjs +80 -0
- package/lib/graph/extract/python.mjs +137 -0
- package/lib/graph/extract/regex-fallback.mjs +187 -0
- package/lib/graph/extract/shell.mjs +71 -0
- package/lib/graph/extract/typescript.mjs +217 -0
- package/lib/graph/extract/walk.mjs +272 -0
- package/lib/graph/format.mjs +51 -0
- package/lib/graph/graph/build.mjs +374 -0
- package/lib/graph/graph/query.mjs +249 -0
- package/lib/graph/graph/report.mjs +122 -0
- package/lib/graph/graph/update.mjs +47 -0
- package/lib/graph/paths.mjs +66 -0
- package/lib/graph/retrieve/context.mjs +86 -0
- package/lib/graph/retrieve/docs-index.mjs +116 -0
- package/lib/graph/retrieve/markdown.mjs +246 -0
- package/lib/host/acp.mjs +551 -0
- package/lib/host/claude-cli.mjs +285 -0
- package/lib/host/codex.mjs +231 -0
- package/lib/host/model-map.mjs +129 -0
- package/lib/host/qwen.mjs +176 -0
- package/lib/host/registry.mjs +213 -0
- package/lib/host.mjs +393 -0
- package/lib/ledger.mjs +444 -0
- package/lib/limits.mjs +525 -0
- package/lib/locators.mjs +99 -0
- package/lib/merge-lanes.mjs +148 -0
- package/lib/metrics.mjs +99 -0
- package/lib/notify.mjs +229 -0
- package/lib/outcomes.mjs +560 -0
- package/lib/plan-fingerprint.mjs +570 -0
- package/lib/project-slug.mjs +18 -0
- package/lib/prompts/commit.mjs +26 -0
- package/lib/prompts/dimensions.mjs +70 -0
- package/lib/prompts/handoff.mjs +86 -0
- package/lib/prompts/implementer.mjs +150 -0
- package/lib/prompts/index.mjs +250 -0
- package/lib/prompts/planner.mjs +70 -0
- package/lib/prompts/remediate.mjs +137 -0
- package/lib/prompts/replan.mjs +23 -0
- package/lib/prompts/review.mjs +107 -0
- package/lib/prompts/schemas.mjs +206 -0
- package/lib/prompts/stage.mjs +48 -0
- package/lib/prompts/verify.mjs +88 -0
- package/lib/ready.mjs +812 -0
- package/lib/receipt.mjs +434 -0
- package/lib/remediate.mjs +275 -0
- package/lib/report-html.mjs +623 -0
- package/lib/report.mjs +1124 -0
- package/lib/review-core.mjs +713 -0
- package/lib/risk.mjs +370 -0
- package/lib/run-log.mjs +1004 -0
- package/lib/run-paths.mjs +239 -0
- package/lib/run.mjs +2921 -0
- package/lib/ship-stage.mjs +223 -0
- package/lib/spill.mjs +150 -0
- package/lib/surface.mjs +195 -0
- package/lib/verify.mjs +1074 -0
- package/lib/waves.mjs +2661 -0
- package/package.json +40 -0
- package/shared/CONTEXT-HYGIENE.md +84 -0
- package/shared/DECISION-LEDGER.md +141 -0
- package/shared/EXPLORE-BRIEF.md +96 -0
- package/shared/INVARIANT-SWEEP.md +57 -0
- package/shared/SESSION-SHAPES.md +261 -0
- package/shared/SKILL-CANDIDATE-BRIEF.md +106 -0
- package/shared/TEST-PROFILE.md +204 -0
- package/shared/TOOL-ECONOMY.md +155 -0
- package/skills/bootstrap/SKILL.md +226 -0
- package/skills/commit/SKILL.md +99 -0
- package/skills/dispatch/SKILL.md +78 -0
- package/skills/docs-digest/SKILL.md +109 -0
- package/skills/evals/SKILL.md +160 -0
- package/skills/explain-code/SKILL.md +42 -0
- package/skills/explain-code/commit-teachin.md +136 -0
- package/skills/explain-code/module-walkthrough.md +358 -0
- package/skills/explore/SKILL.md +159 -0
- package/skills/fix-tests/SKILL.md +120 -0
- package/skills/graph/SKILL.md +136 -0
- package/skills/manual-test-plan/SKILL.md +121 -0
- package/skills/mr/SKILL.md +170 -0
- package/skills/report/SKILL.md +121 -0
- package/skills/review-artifacts/SKILL.md +127 -0
- package/skills/review-code/REVIEW.template.md +49 -0
- package/skills/review-code/SKILL.md +156 -0
- package/skills/review-code/dimensions/architecture.md +10 -0
- package/skills/review-code/dimensions/devops.md +12 -0
- package/skills/review-code/dimensions/language.md +12 -0
- package/skills/review-code/dimensions/qa.md +12 -0
- package/skills/review-code/dimensions/security.md +12 -0
- package/skills/review-code/dimensions/technical-lead.md +19 -0
- package/skills/ship/SKILL.md +67 -0
- package/skills/spec/SKILL.md +264 -0
- package/skills/spec/continuity.md +66 -0
- package/workflows/ship.js +565 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# Session Shapes
|
|
2
|
+
|
|
3
|
+
Patterns that produce expert-level sessions. Use these as mental models when
|
|
4
|
+
starting a session — or let `/interlock:dispatch` orient you first.
|
|
5
|
+
|
|
6
|
+
The key insight: expert sessions are not longer or harder — they are better
|
|
7
|
+
structured from the start. The right shape chosen upfront eliminates
|
|
8
|
+
backtracking, scope drift, and wasted exploration. Score a live session against
|
|
9
|
+
these shapes and against `${CLAUDE_PLUGIN_ROOT}/shared/TOOL-ECONOMY.md`.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Shape 1: Plan-then-Execute
|
|
14
|
+
|
|
15
|
+
**Duration:** 15-25 min | **Agents:** 4-6 | **Pattern:** think → structure → do
|
|
16
|
+
|
|
17
|
+
**Entry signal:** "I want to build X" — no active change exists, scope spans multiple files
|
|
18
|
+
|
|
19
|
+
**Flow:**
|
|
20
|
+
1. `/interlock:explore` (optional — skip if the domain is well-understood)
|
|
21
|
+
2. `/interlock:spec` — generates proposal, design, tasks, delta specs, then gates them through an artifact review and **stops at the human checkpoint**
|
|
22
|
+
3. Human reads the spec
|
|
23
|
+
4. `/interlock:ship` — dependency-ordered waves of parallel implementers → verify → commit
|
|
24
|
+
|
|
25
|
+
**Expert version:** State the full scope upfront. Let `spec` generate all artifacts
|
|
26
|
+
and pass Gate 1 in one pass. Read the spec once. `ship` handles execution in
|
|
27
|
+
parallel and produces one feature-level commit. No mid-session design changes.
|
|
28
|
+
|
|
29
|
+
**Common failure mode (advanced, not expert):** Starting to code before speccing.
|
|
30
|
+
Scope drifts mid-implementation. Multiple commits for what should be one logical
|
|
31
|
+
change. 30+ minutes because exploration and execution are interleaved.
|
|
32
|
+
|
|
33
|
+
**Preconditions for expert execution:**
|
|
34
|
+
- Clear one-sentence scope statement before starting
|
|
35
|
+
- No ambiguity about boundaries (what's in / out)
|
|
36
|
+
- Domain knowledge sufficient to skip the explore phase
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Shape 2: Structured Execute
|
|
41
|
+
|
|
42
|
+
**Duration:** 7-15 min | **Agents:** 3-13 (depends on task count) | **Pattern:** load → classify → do
|
|
43
|
+
|
|
44
|
+
**Entry signal:** "Ship the change" or "execute the tasks" — an active change with reviewed artifacts already exists
|
|
45
|
+
|
|
46
|
+
**Flow:**
|
|
47
|
+
1. `/interlock:ship` — the workflow loads all artifacts, classifies tasks, and runs them in dependency-ordered waves
|
|
48
|
+
2. Unit verification, then a single commit
|
|
49
|
+
|
|
50
|
+
**Expert version:** Artifacts already exist and passed the checkpoint in a prior
|
|
51
|
+
session. This session is pure execution — zero exploration, zero design decisions.
|
|
52
|
+
Fastest path to done. The workflow reads everything before writing anything.
|
|
53
|
+
|
|
54
|
+
**Common failure mode:** Re-implementing the change inline in the conversation
|
|
55
|
+
instead of launching the `ship` workflow. Making implementation decisions that
|
|
56
|
+
contradict the design doc. Speccing again when the spec is already reviewed.
|
|
57
|
+
|
|
58
|
+
**Preconditions for expert execution:**
|
|
59
|
+
- All artifacts exist and were reviewed (Gate 1 passed)
|
|
60
|
+
- Tasks are well-defined with clear acceptance criteria
|
|
61
|
+
- The Workflow tool is available (Claude Code v2.1.154+, dynamic workflows on)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Shape 3: Investigate-then-Propose
|
|
66
|
+
|
|
67
|
+
**Duration:** 20-35 min | **Agents:** 2-5 | **Pattern:** understand → capture → structure
|
|
68
|
+
|
|
69
|
+
**Entry signal:** "How does X work? I might need to change it." — needs understanding before committing to a design
|
|
70
|
+
|
|
71
|
+
**Flow:**
|
|
72
|
+
1. `/interlock:explore` — fan out read-only investigators across subsystems, write a durable brief
|
|
73
|
+
2. Synthesize findings into a scope definition
|
|
74
|
+
3. `/interlock:spec` — convert understanding into durable artifacts (auto-loads the latest explore brief)
|
|
75
|
+
4. Stop at the checkpoint (or continue to ship in the same session if scope is small)
|
|
76
|
+
|
|
77
|
+
**Expert version:** Run `/interlock:explore` and let it fan out across threads
|
|
78
|
+
without asking which to follow; it writes `.claude/handoff/explore-<slug>-<ts>.md`.
|
|
79
|
+
Then `/interlock:spec` (possibly after `/clear` or cache expiry) auto-loads the
|
|
80
|
+
latest matching brief and generates proposal artifacts — no re-discovery from chat.
|
|
81
|
+
|
|
82
|
+
**Common failure mode:** Exploring in one long single-threaded chat. Findings live
|
|
83
|
+
only in chat history and are lost after `/clear` or prompt-cache expiry. Never
|
|
84
|
+
converting understanding into a spec or explore brief — the next session
|
|
85
|
+
re-discovers everything.
|
|
86
|
+
|
|
87
|
+
**Preconditions for expert execution:**
|
|
88
|
+
- Multiple subsystems or modules are involved (justifies fan-out)
|
|
89
|
+
- The question is specific enough to decompose into parallel investigations
|
|
90
|
+
- Memory / prior briefs are checked first (avoid re-investigating known territory)
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Shape 4: Targeted Fix
|
|
95
|
+
|
|
96
|
+
**Duration:** 5-12 min | **Agents:** 0-1 | **Pattern:** locate → fix → verify
|
|
97
|
+
|
|
98
|
+
**Entry signal:** "X is broken" or "fix the error in Y" — specific bug, narrow scope
|
|
99
|
+
|
|
100
|
+
**Flow:**
|
|
101
|
+
1. Check memory / known constraints about this area
|
|
102
|
+
2. Locate the issue (often a single file or function) — graph query or grep, not a full-file read sweep
|
|
103
|
+
3. Fix it
|
|
104
|
+
4. `/interlock:fix-tests` or run the suite to verify
|
|
105
|
+
5. `/interlock:commit` (or report if more investigation is needed)
|
|
106
|
+
|
|
107
|
+
**Expert version:** The relevant constraint is already known. No exploration needed
|
|
108
|
+
— go directly to the fix. Verify immediately. Done in under 10 minutes.
|
|
109
|
+
|
|
110
|
+
**Common failure mode:** Guessing at solutions without reading constraints. Trying
|
|
111
|
+
three wrong approaches before finding the right one. Exploring broadly when the fix
|
|
112
|
+
is narrow. Not running tests after the fix.
|
|
113
|
+
|
|
114
|
+
**Preconditions for expert execution:**
|
|
115
|
+
- The error is specific (not "something is slow" — that's Investigate-then-Propose)
|
|
116
|
+
- Scope is genuinely narrow (one file, one concept)
|
|
117
|
+
- If the fix touches a shared or derived value, its consumers are swept
|
|
118
|
+
(`${CLAUDE_PLUGIN_ROOT}/shared/INVARIANT-SWEEP.md`)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Shape 5: Workflow-Orchestrated
|
|
123
|
+
|
|
124
|
+
**Duration:** 10-40 min | **Agents:** 10-50+ | **Pattern:** script controls flow, agents do work
|
|
125
|
+
|
|
126
|
+
**Entry signal:** Complex work that benefits from deterministic orchestration — a reviewed change ready to ship, or a diff ready to review.
|
|
127
|
+
|
|
128
|
+
**Flow (ship):**
|
|
129
|
+
1. `/interlock:ship` launches `workflows/ship.js` on the Workflow runtime
|
|
130
|
+
2. Load artifacts → classify tasks (schema-validated) → execute in parallel waves
|
|
131
|
+
3. Inter-wave verification gates catch interface mismatches immediately
|
|
132
|
+
4. Unit verify, then commit. `--strict` adds adversarial review, remediation, handoff, conformance
|
|
133
|
+
5. Resumable — a stopped run picks up where it left off
|
|
134
|
+
|
|
135
|
+
**Flow (review):**
|
|
136
|
+
1. `/interlock:review-code` fans out up to six dimension reviewers (language, architecture, QA, delivery; devops and security when the diff earns them)
|
|
137
|
+
2. Two skeptics try to refute every blocker and warning; a dismissal must cite a `file:line` span
|
|
138
|
+
3. Only surviving findings reach you; the report states how many were dismissed
|
|
139
|
+
|
|
140
|
+
**Expert version:** The script holds the plan, not the model's context window.
|
|
141
|
+
Intermediate results stay in script variables, not chat history. Deterministic
|
|
142
|
+
retry logic instead of prompt-based "hopefully it retries."
|
|
143
|
+
|
|
144
|
+
**Common failure mode:** Re-implementing a workflow's job inline in the
|
|
145
|
+
conversation. Using a workflow for work that is genuinely sequential or needs a
|
|
146
|
+
human decision between steps.
|
|
147
|
+
|
|
148
|
+
**Preconditions for expert execution:**
|
|
149
|
+
- Tasks are independent (can parallelize without file conflicts)
|
|
150
|
+
- Verification commands are detectable (typecheck, test, lint)
|
|
151
|
+
- For `ship`: artifacts exist and passed Gate 1
|
|
152
|
+
- For `review-code`: implementation is complete (files to review exist)
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Shape 6: Agent-Team Investigation
|
|
157
|
+
|
|
158
|
+
**Duration:** 15-45 min | **Agents:** 3-6 persistent teammates | **Pattern:** debate → converge → decide
|
|
159
|
+
|
|
160
|
+
**Entry signal:** "The root cause is unclear" or "we need to investigate from multiple angles simultaneously" — when competing hypotheses need adversarial testing, not just parallel exploration.
|
|
161
|
+
|
|
162
|
+
**Flow:**
|
|
163
|
+
1. Spawn 3-5 teammates, each assigned a different hypothesis or angle
|
|
164
|
+
2. Teammates investigate independently AND challenge each other's findings
|
|
165
|
+
3. The debate structure surfaces the theory that survives scrutiny
|
|
166
|
+
4. The lead synthesizes consensus into a decision or a spec
|
|
167
|
+
|
|
168
|
+
**Expert version:** Unlike a workflow fan-out (which collects results silently),
|
|
169
|
+
agent teams *communicate*. Teammate A finds evidence that contradicts Teammate B's
|
|
170
|
+
theory and messages them directly. The adversarial communication is the value — it
|
|
171
|
+
prevents anchoring on the first plausible explanation.
|
|
172
|
+
|
|
173
|
+
**Best use cases:**
|
|
174
|
+
- Debugging with an unclear root cause (an investigator per hypothesis)
|
|
175
|
+
- Architecture decisions with genuine tradeoffs (an advocate per approach)
|
|
176
|
+
- Cross-layer coordination where subsystem owners negotiate interfaces
|
|
177
|
+
|
|
178
|
+
**Common failure mode:** Using teams for work that's purely mechanical parallelism
|
|
179
|
+
(use a workflow instead). Teams add coordination overhead — only worth it when
|
|
180
|
+
agents need to *talk to each other*.
|
|
181
|
+
|
|
182
|
+
**Preconditions:**
|
|
183
|
+
- Requires `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` in settings
|
|
184
|
+
- The problem has multiple plausible approaches / causes (not a single clear path)
|
|
185
|
+
- Value comes from inter-agent communication, not just parallel execution
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Shape Selection Heuristic
|
|
190
|
+
|
|
191
|
+
When in doubt, start with the simplest shape that fits:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
Specific error + narrow scope → Targeted Fix
|
|
195
|
+
"Ship the tasks" + reviewed artifacts → Structured Execute
|
|
196
|
+
"Build X" + clear scope → Plan-then-Execute
|
|
197
|
+
"How / why / what if" + broad scope → Investigate-then-Propose
|
|
198
|
+
Reviewed change ready, or a diff to vet → Workflow-Orchestrated (ship / review-code)
|
|
199
|
+
Unclear root cause + competing theories → Agent-Team Investigation
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
If you pick Targeted Fix and discover the scope is broader than expected, escalate
|
|
203
|
+
to Investigate-then-Propose. If you pick Plan-then-Execute and the change is already
|
|
204
|
+
reviewed, downgrade to Structured Execute. Shape classification is a starting point,
|
|
205
|
+
not a commitment.
|
|
206
|
+
|
|
207
|
+
**Choosing between Workflow and Agent Team:**
|
|
208
|
+
- Tasks are independent and the orchestration is known → Workflow (deterministic, cheaper)
|
|
209
|
+
- Agents need to communicate, challenge, or negotiate → Agent Team (higher cost, richer coordination)
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Anti-Patterns (What NOT to Do)
|
|
214
|
+
|
|
215
|
+
| Anti-Pattern | Why It Fails | Instead |
|
|
216
|
+
|-------------|-------------|---------|
|
|
217
|
+
| "Explore everything first" | Burns 20 min before any output | Pick a shape, start executing |
|
|
218
|
+
| "Let me read the whole codebase" | Context window fills with irrelevant code | Query the graph / read artifacts, then act |
|
|
219
|
+
| "I'll figure out the approach as I go" | Leads to backtracking and scope drift | Classify shape, announce scope, then execute |
|
|
220
|
+
| "Just one more thing…" | Scope creep extends sessions past 30 min | Handoff + new session for new scope |
|
|
221
|
+
| Single-threading work that could parallelize | 3x wall-clock for independent tasks | `ship` or an explore fan-out |
|
|
222
|
+
| Re-implementing `ship` inline | Context fills, intermediate results lost | Launch the `ship` workflow — results stay in script variables |
|
|
223
|
+
| Bridging `spec` → `ship` automatically | Skips the one human checkpoint | Stop at the checkpoint; let the human read |
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Expertise Level
|
|
228
|
+
|
|
229
|
+
**expertise_level**: Rate the USER's demonstrated expertise in the domain/task of THIS
|
|
230
|
+
session — command of its terminology, structures, and conventions — ONCE for the WHOLE
|
|
231
|
+
conversation, from the user's turns only. Rate domain familiarity with the work AT HAND,
|
|
232
|
+
NOT general intelligence, NOT the agent's performance, NOT task difficulty (a senior
|
|
233
|
+
engineer can be a beginner at Rust or differential privacy). Weigh three CO-EQUAL signals
|
|
234
|
+
together:
|
|
235
|
+
- Setup specificity: does the framing use named entities/constraints that require domain
|
|
236
|
+
knowledge to even reach for? Naming files/paths visible on screen is NOT domain
|
|
237
|
+
knowledge — anyone using the agent does that.
|
|
238
|
+
- Verification type: generic asks ("please double-check", "are you sure?") are epistemic
|
|
239
|
+
humility, not expertise; targeted asks ("did you actually call commit()?", "what's the
|
|
240
|
+
cardinality of that join?") require knowing WHAT to check.
|
|
241
|
+
- Direction of correction: the agent correcting the user's terminology/mental model pulls
|
|
242
|
+
DOWN (1-2); the user catching the agent's domain mistakes pulls UP (4-5); neither
|
|
243
|
+
correcting the other is neutral.
|
|
244
|
+
Emit exactly ONE value (default `2_beginner` only when there's nothing to go on, e.g. a
|
|
245
|
+
warmup session):
|
|
246
|
+
- `1_novice` — generic/imprecise framing, no domain names; verification absent or fully
|
|
247
|
+
generic; doesn't notice wrong output; agent supplies basic domain concepts.
|
|
248
|
+
- `2_beginner` — some correct terms used loosely; mostly generic verification; pushes back
|
|
249
|
+
only on obvious errors; agent reframes the user at least once. A fluent technologist
|
|
250
|
+
working OUTSIDE their domain lands here.
|
|
251
|
+
- `3_intermediate` — precise at a directive level (names files, outputs, libraries) but
|
|
252
|
+
doesn't engage methodology/tradeoffs; mix of generic and targeted checks; catches
|
|
253
|
+
meaningful mistakes. A domain expert delegating a routine task can also land here.
|
|
254
|
+
- `4_advanced` — structural domain knowledge NOT readable off the screen (a specific edge
|
|
255
|
+
case, non-obvious constraint/invariant, version-specific behavior, known failure mode);
|
|
256
|
+
moderately specific verification; catches at least one of the agent's domain mistakes;
|
|
257
|
+
the agent doesn't have to correct the user's domain model.
|
|
258
|
+
- `5_expert` — insider-only jargon/conventions, unprompted tradeoff discussion, surgical
|
|
259
|
+
verification, authoritative corrections invoking specific technical reasoning,
|
|
260
|
+
preemptive edge-case handling. Direction of correction is user->agent. "Insider talking
|
|
261
|
+
to an equal," even in a short session.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Skill Candidate Brief — Author Contract
|
|
2
|
+
|
|
3
|
+
A durable handoff from a retro/review skill into a skill-author agent. It
|
|
4
|
+
captures evidence that a repeatable session procedure should become a new
|
|
5
|
+
`SKILL.md`, without writing the skill itself.
|
|
6
|
+
|
|
7
|
+
**Path:** `.claude/handoff/skill-candidate-<slug>-<YYYYMMDD-HHMMSS>.md`
|
|
8
|
+
Slug = the proposed skill name in kebab-case. Same handoff directory as explore
|
|
9
|
+
briefs (`${CLAUDE_PLUGIN_ROOT}/shared/EXPLORE-BRIEF.md`).
|
|
10
|
+
|
|
11
|
+
**When to write**
|
|
12
|
+
|
|
13
|
+
- The retro finds a repeatable procedure not covered by an existing skill.
|
|
14
|
+
- Cap at the top 3 candidates per review. Skip one-offs, pure chat, and duplicates
|
|
15
|
+
of existing skills (suggest extending those instead).
|
|
16
|
+
|
|
17
|
+
**Bound the brief** (~1–3k tokens): cite the concrete moments and the tool pattern;
|
|
18
|
+
treat the procedure steps as hypotheses the author must refine.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Template (stable — skill-author agents depend on these headings)
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
# Skill Candidate Brief: <slug>
|
|
26
|
+
|
|
27
|
+
## Meta
|
|
28
|
+
- source: interactive | loop
|
|
29
|
+
- slug: <kebab-case proposed skill name>
|
|
30
|
+
- confidence: high | med | low
|
|
31
|
+
- created: <ISO-8601 timestamp>
|
|
32
|
+
- session_refs: <e.g. this session, 2026-08-20>
|
|
33
|
+
- evidence_basis: current-session (live context, no transcript re-read)
|
|
34
|
+
|
|
35
|
+
## Proposed Skill
|
|
36
|
+
- name: <kebab-case>
|
|
37
|
+
- description: <pushy trigger description — what it does AND when to use it>
|
|
38
|
+
- when_to_use: <bullet list of user phrases / contexts>
|
|
39
|
+
- when_not_to_use: <bullet list — overlaps, one-offs, better existing skills>
|
|
40
|
+
|
|
41
|
+
## Evidence
|
|
42
|
+
<!-- The concrete moments this session, the tool pattern, the assigned shape + score.
|
|
43
|
+
State clearly which steps below are inferred rather than directly observed. -->
|
|
44
|
+
|
|
45
|
+
## Procedure to Encode
|
|
46
|
+
<!-- Ordered steps a SKILL.md should teach. Hypotheses from what the session did — author must refine. -->
|
|
47
|
+
1. ...
|
|
48
|
+
2. ...
|
|
49
|
+
|
|
50
|
+
## Inputs / Outputs / Exit Criteria
|
|
51
|
+
- inputs: <args, flags, natural-language triggers>
|
|
52
|
+
- outputs: <files written, chat summary shape>
|
|
53
|
+
- exit_criteria:
|
|
54
|
+
- [ ] ...
|
|
55
|
+
|
|
56
|
+
## Related Existing Skills
|
|
57
|
+
<!-- From the enumerated skill list. Name overlaps and why this is NOT a duplicate
|
|
58
|
+
(or: "extend <skill> instead" and stop — do not invent a parallel skill). -->
|
|
59
|
+
|
|
60
|
+
## Open Questions
|
|
61
|
+
<!-- Gaps the author must resolve before writing SKILL.md (scope, tools, output path, etc.). -->
|
|
62
|
+
|
|
63
|
+
## Author Checklist
|
|
64
|
+
- [ ] Name + description are distinct from Related Existing Skills
|
|
65
|
+
- [ ] Trigger phrases are concrete enough to avoid under-triggering
|
|
66
|
+
- [ ] Procedure steps refined against at least one real session or user confirmation
|
|
67
|
+
- [ ] Inputs / outputs / exit criteria are testable
|
|
68
|
+
- [ ] Open questions resolved or explicitly deferred in the skill body
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Section rules
|
|
74
|
+
|
|
75
|
+
| Section | Rule |
|
|
76
|
+
|---------|------|
|
|
77
|
+
| **Meta.confidence** | `high` = a repeated procedural shape with durable domain knowledge; `med` = a single strong session; `low` = weak signal / thin evidence |
|
|
78
|
+
| **Evidence** | Cite the concrete moments. Never invent tool calls, quotes, or token counts. |
|
|
79
|
+
| **Procedure to Encode** | Hypotheses labeled as such. Prefer a locate → act → verify shape. |
|
|
80
|
+
| **Related Existing Skills** | Must check the enumerated skill list. Prefer "extend X" over a new skill when overlap is high. |
|
|
81
|
+
| **Author Checklist** | If unchecked blockers remain, say so when pointing the user at the brief. |
|
|
82
|
+
|
|
83
|
+
## Candidacy signals (what a retro looks for)
|
|
84
|
+
|
|
85
|
+
- The same multi-step procedure performed by hand that no skill covers
|
|
86
|
+
- A long, high-tool-count stretch reinventing a workflow absent from existing skills
|
|
87
|
+
- A mid/low shape score where a skill would have prevented the named failure mode
|
|
88
|
+
- A clear procedural shape (locate → transform → verify) with durable domain knowledge
|
|
89
|
+
|
|
90
|
+
**Skip:** one-off Targeted Fixes, chat-only stretches, and work already covered by
|
|
91
|
+
an existing skill (suggest extending that skill instead).
|
|
92
|
+
|
|
93
|
+
## Chat reply after write
|
|
94
|
+
|
|
95
|
+
Do **not** re-dump full briefs into chat. Reply with:
|
|
96
|
+
|
|
97
|
+
1. Paths to each `.claude/handoff/skill-candidate-*.md` written
|
|
98
|
+
2. A one-line summary per candidate (slug + confidence + why)
|
|
99
|
+
3. "Hand these to a skill-author agent to write the SKILL.md"
|
|
100
|
+
|
|
101
|
+
## Author consumption
|
|
102
|
+
|
|
103
|
+
A skill-author agent reads the brief, resolves the Open Questions with the user,
|
|
104
|
+
then writes `skills/<name>/SKILL.md` (and docs / manifest wiring as needed). Prefer
|
|
105
|
+
the brief's recommendations over re-deriving the procedure; reopen the session only
|
|
106
|
+
for gaps or contradictions.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Test Profile — Discovery & Persistence Contract
|
|
2
|
+
|
|
3
|
+
Durable, machine-readable record of how a project's tests run. Owned by
|
|
4
|
+
`/interlock:fix-tests` and reused by `/interlock:ship`, so neither has to
|
|
5
|
+
re-sniff `package.json` on every run.
|
|
6
|
+
|
|
7
|
+
**Path:** `.claude/testing/profile.json`
|
|
8
|
+
**Human mirror:** idempotent `## Testing` block in `CLAUDE.md` (or `AGENTS.md`
|
|
9
|
+
on Cursor-only projects) between HTML comment markers (see below).
|
|
10
|
+
|
|
11
|
+
Learned gotchas discovered mid-fix go to
|
|
12
|
+
`.claude/memory/failure-modes/<slug>.md` (max 3 per session) — **not** into
|
|
13
|
+
the profile.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Schema (`profile.json`)
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"version": 1,
|
|
22
|
+
"updated": "<ISO-8601>",
|
|
23
|
+
"discovered_from": ["package.json#scripts.test", "CI", "interview"],
|
|
24
|
+
"unit": {
|
|
25
|
+
"command": "npm test",
|
|
26
|
+
"cwd": ".",
|
|
27
|
+
"filter_syntax": "node --test --test-name-pattern <pattern> <file>",
|
|
28
|
+
"single_file": "node --test path/to/file.test.mjs",
|
|
29
|
+
"env": {},
|
|
30
|
+
"timeout_ms": 120000,
|
|
31
|
+
"prerequisites": []
|
|
32
|
+
},
|
|
33
|
+
"e2e": {
|
|
34
|
+
"enabled": false,
|
|
35
|
+
"command": null,
|
|
36
|
+
"cwd": ".",
|
|
37
|
+
"filter_syntax": null,
|
|
38
|
+
"single_file": null,
|
|
39
|
+
"env": {},
|
|
40
|
+
"timeout_ms": 600000,
|
|
41
|
+
"prerequisites": []
|
|
42
|
+
},
|
|
43
|
+
"coverage": {
|
|
44
|
+
"enabled": false,
|
|
45
|
+
"command": null,
|
|
46
|
+
"report_path": "coverage/lcov.info",
|
|
47
|
+
"format": "lcov"
|
|
48
|
+
},
|
|
49
|
+
"typecheck": {
|
|
50
|
+
"command": null,
|
|
51
|
+
"cwd": "."
|
|
52
|
+
},
|
|
53
|
+
"lint": {
|
|
54
|
+
"command": null,
|
|
55
|
+
"cwd": "."
|
|
56
|
+
},
|
|
57
|
+
"known_flaky": [],
|
|
58
|
+
"notes": []
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
| Field | Meaning |
|
|
63
|
+
|-------|---------|
|
|
64
|
+
| `unit.command` / `e2e.command` | Full shell command that runs the suite (as in CI / `package.json`) |
|
|
65
|
+
| `filter_syntax` | How to run a subset by name/pattern (string with `<pattern>` placeholder) |
|
|
66
|
+
| `single_file` | How to run one file (string with path implied, or template) |
|
|
67
|
+
| `env` | Extra env vars required for a green run (not secrets — names/placeholders only) |
|
|
68
|
+
| `prerequisites` | Human-readable setup steps (dev server, seeded DB, `npx playwright install`, …) |
|
|
69
|
+
| `timeout_ms` | Soft budget for one full suite run; do not raise to mask races |
|
|
70
|
+
| `coverage.enabled` | Whether a coverage command is known. `false` = not configured (never an error) |
|
|
71
|
+
| `coverage.command` | Full shell command that produces a coverage report (e.g. `npm run coverage`) |
|
|
72
|
+
| `coverage.report_path` | Where the report lands, relative to `unit.cwd` (`coverage/lcov.info`, `coverage/coverage-summary.json`, …) |
|
|
73
|
+
| `coverage.format` | Report format the path holds: `lcov`, `json-summary`, `cobertura`, … |
|
|
74
|
+
| `typecheck.command` | Full shell command that type-checks the project (e.g. `npm run typecheck`). `null` = none found; the step is skipped with a reason, never guessed |
|
|
75
|
+
| `lint.command` | Full shell command that lints the project (e.g. `npm run lint`). `null` = none found; the step is skipped with a reason, never guessed |
|
|
76
|
+
| `known_flaky` | Paths or test-name patterns that flip on re-run (recorded, not "fixed") |
|
|
77
|
+
| `notes` | Short freeform caveats (≤5 lines total) |
|
|
78
|
+
|
|
79
|
+
`e2e.enabled` defaults to `false`. The skill never runs e2e unless the user
|
|
80
|
+
passes `--e2e` **and** `e2e.command` is set.
|
|
81
|
+
|
|
82
|
+
`coverage.enabled` also defaults to `false`, and coverage is always **advisory**
|
|
83
|
+
— a missing coverage tool, a failed coverage run, or 0% covered changed lines
|
|
84
|
+
must never fail a gate or turn a green suite red.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Discovery precedence
|
|
89
|
+
|
|
90
|
+
First run (or `--reconfigure`): derive in order, stop when confident enough to
|
|
91
|
+
write a profile. Ask at most **4 questions** only when still ambiguous.
|
|
92
|
+
|
|
93
|
+
1. **`package.json` / language manifests**
|
|
94
|
+
- `scripts.test`, `scripts.test:unit`, `scripts.test:e2e`, `scripts.test:ci`
|
|
95
|
+
- Python: `pytest` / `tox` / `pyproject.toml` `[tool.pytest]`
|
|
96
|
+
- Go: `go test ./…`
|
|
97
|
+
- Rust: `cargo test`
|
|
98
|
+
2. **Runner config files** (infer filter + single-file syntax)
|
|
99
|
+
- `vitest.config.*`, `jest.config.*`, `playwright.config.*`
|
|
100
|
+
- `pytest.ini`, `pyproject.toml`, `.mocharc.*`
|
|
101
|
+
- Node built-in: `node --test` (filter: `--test-name-pattern`)
|
|
102
|
+
3. **CI workflows** (`.github/workflows/*`, `.gitlab-ci.yml`, etc.)
|
|
103
|
+
- Prefer the job that runs unit tests on PRs
|
|
104
|
+
- Capture env and prerequisites from the job definition
|
|
105
|
+
4. **Ask (≤4 questions, once)** — only for gaps that block a correct run:
|
|
106
|
+
- Unit command (if none found)
|
|
107
|
+
- Single-file / filter syntax (if not inferable)
|
|
108
|
+
- Required env or prerequisites
|
|
109
|
+
- E2e command (only if user asked about e2e / passed `--e2e`)
|
|
110
|
+
|
|
111
|
+
Every later run is **zero-question** unless `--reconfigure`.
|
|
112
|
+
|
|
113
|
+
### Coverage discovery
|
|
114
|
+
|
|
115
|
+
`coverage` is resolved independently of `unit`/`e2e` and **never blocks**. Derive
|
|
116
|
+
in this order, stop at the first hit, and persist what you find:
|
|
117
|
+
|
|
118
|
+
1. `coverage.command` already in the profile → use it as-is
|
|
119
|
+
2. `package.json` `scripts.coverage`
|
|
120
|
+
3. `package.json` `scripts["test:coverage"]`
|
|
121
|
+
4. `vitest --coverage` / `jest --coverage` when vitest or jest is the runner
|
|
122
|
+
5. `c8` / `nyc` present in `devDependencies` → wrap `unit.command`
|
|
123
|
+
6. `node --test --experimental-test-coverage` when the runner is node:test
|
|
124
|
+
|
|
125
|
+
Never ask for a coverage command and never install tooling to obtain one —
|
|
126
|
+
nothing found → `enabled:false`, report and continue; never block.
|
|
127
|
+
|
|
128
|
+
### Typecheck and lint discovery
|
|
129
|
+
|
|
130
|
+
`typecheck` and `lint` are resolved the same way `coverage` is — independently,
|
|
131
|
+
never by asking, never by inventing a command. Without them a ship run's
|
|
132
|
+
inter-wave checkpoint has no typecheck to run, and `typecheck` is a **halting**
|
|
133
|
+
kind there: a type error must stop the next wave from building on top of it.
|
|
134
|
+
|
|
135
|
+
Derive in this order, stop at the first hit, and persist what you find:
|
|
136
|
+
|
|
137
|
+
1. the command already in the profile → use it as-is
|
|
138
|
+
2. `package.json` `scripts.typecheck`, then `scripts["type-check"]`; for lint,
|
|
139
|
+
`scripts.lint`
|
|
140
|
+
3. the step in the CI job that runs it (`.github/workflows/*`, `.gitlab-ci.yml`)
|
|
141
|
+
|
|
142
|
+
Nothing found → `command: null`. **Never ask, and never invent one** — a guessed
|
|
143
|
+
`tsc --noEmit` against a project that does not typecheck that way is a red step
|
|
144
|
+
nobody asked for. A `null` command is skipped with
|
|
145
|
+
`reason=no-detectable-command`, which is a stated absence rather than a silent
|
|
146
|
+
one.
|
|
147
|
+
|
|
148
|
+
**Stale profile:** rewrite when `unit.command` no longer exists in
|
|
149
|
+
`package.json` / manifests, or the command exits 127 / "not found". Otherwise
|
|
150
|
+
reuse as-is.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Human mirror (`## Testing` block)
|
|
155
|
+
|
|
156
|
+
Write (or replace) content **between** these markers inside `CLAUDE.md`
|
|
157
|
+
(prefer) or `AGENTS.md` (if that is the project's agent doc and `CLAUDE.md`
|
|
158
|
+
is absent):
|
|
159
|
+
|
|
160
|
+
```markdown
|
|
161
|
+
## Testing
|
|
162
|
+
|
|
163
|
+
<!-- BEGIN interlock:testing -->
|
|
164
|
+
**Unit:** `<unit.command>` (cwd: `<unit.cwd>`)
|
|
165
|
+
**Filter:** `<unit.filter_syntax>`
|
|
166
|
+
**Single file:** `<unit.single_file>`
|
|
167
|
+
**E2E:** `<e2e.command or "opt-in via /fix-tests --e2e (not configured)">`
|
|
168
|
+
**Prerequisites:** <list or "none">
|
|
169
|
+
**Profile:** `.claude/testing/profile.json` (managed by `/interlock:fix-tests`)
|
|
170
|
+
<!-- END interlock:testing -->
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Idempotency rules**
|
|
174
|
+
|
|
175
|
+
- If both markers exist: replace only the interior; leave surrounding prose alone.
|
|
176
|
+
- If `## Testing` exists without markers: insert markers + block immediately
|
|
177
|
+
under the heading (preserve any pre-existing bullet notes above the markers
|
|
178
|
+
only if they are clearly human-authored and outside a prior managed block).
|
|
179
|
+
- If no `## Testing` section: append the full section (heading + markers) at
|
|
180
|
+
end of file (or before `## Git` / `## Hooks` if those headings exist).
|
|
181
|
+
- Never duplicate the managed block. A second `/interlock:fix-tests` run must leave a
|
|
182
|
+
single pair of markers.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Consumers
|
|
187
|
+
|
|
188
|
+
Anything that needs to run this project's tests reads
|
|
189
|
+
`.claude/testing/profile.json` first instead of sniffing `package.json`.
|
|
190
|
+
|
|
191
|
+
- `/interlock:fix-tests` — owns discovery, and is the only skill allowed to
|
|
192
|
+
interview the user to fill a field.
|
|
193
|
+
- `/interlock:ship` — reads the profile during its test wave and final
|
|
194
|
+
verification. Where the discovery ladder would ask a question, ship leaves the
|
|
195
|
+
field `null` and notes it. **Ship never interviews.**
|
|
196
|
+
|
|
197
|
+
**Two writers, no fighting.** `/interlock:fix-tests` and `/interlock:ship` both write this file.
|
|
198
|
+
Each writes only the fields it actually resolved and preserves every other key
|
|
199
|
+
verbatim — `/interlock:ship` never clears `known_flaky`, human-authored `notes`, or
|
|
200
|
+
`e2e` settings it did not discover, and `/interlock:fix-tests` leaves `coverage` alone
|
|
201
|
+
unless it discovered coverage tooling itself. Neither writer interviews the user
|
|
202
|
+
on behalf of the other: `/interlock:ship` is always headless and records
|
|
203
|
+
unresolvable fields as `null` plus a line in `notes`, where the ladder above
|
|
204
|
+
would have asked.
|