@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,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: evals
|
|
3
|
+
description: Author an Interlock eval case from an observed model-behaviour failure, and read a completed eval results run. Use when you have a reproduced failure — an archived proposal, a changelog entry, a run artifact, or a transcript — worth regression-testing against a real model, or when an eval run has finished and you need to know whether it is a regression, run-to-run variance, or no signal. Authoring needs cited evidence; the verdict comes from `interlock evals triage`, never from your own reading.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Requires the early-access eval harness (`claude plugin eval`, enabled with CLAUDE_CODE_WALNUT_SPIRE=1) to RUN a suite. Authoring a case and triaging an existing results file need only Node.js >= 18 and the bundled interlock CLI.
|
|
6
|
+
allowed-tools: Bash(interlock *) Bash(claude plugin eval *) Read Grep Glob Write
|
|
7
|
+
metadata:
|
|
8
|
+
type: authoring
|
|
9
|
+
outputs:
|
|
10
|
+
- evals/<case>/case.yaml
|
|
11
|
+
- evals/<case>/graders/*.md
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
This skill covers the two jobs the eval harness does not do for you: turning an
|
|
15
|
+
observed failure into a case, and reading a finished run. Everything with a
|
|
16
|
+
correct answer — is this a regression? — belongs to `interlock evals triage`, not
|
|
17
|
+
to you. Your job is evidence, grader choice, and explanation.
|
|
18
|
+
|
|
19
|
+
## 1. Authoring a case — only from an observed failure
|
|
20
|
+
|
|
21
|
+
A case regression-tests a **reproduced** failure: a model read correct
|
|
22
|
+
instructions and did the wrong thing anyway. Before you write anything, require
|
|
23
|
+
the evidence:
|
|
24
|
+
|
|
25
|
+
- an archived proposal (`openspec/changes/archive/*/proposal.md` `## Why`),
|
|
26
|
+
- a `CHANGELOG.md` entry,
|
|
27
|
+
- a run artifact or a transcript,
|
|
28
|
+
- a **captured skeleton** — `interlock evals capture --run <runId> [--task <id>]
|
|
29
|
+
--out <dir>` turns a recorded ship-run trajectory into a case draft whose
|
|
30
|
+
provenance names the trajectory and the events it was derived from, or
|
|
31
|
+
- a `file:line` span in the prompt or skill under test that shows the surface
|
|
32
|
+
the model talked past.
|
|
33
|
+
|
|
34
|
+
**A captured skeleton is a draft, not a finished case.** It is admissible
|
|
35
|
+
evidence because it is a run artifact and a reader can follow its citation back
|
|
36
|
+
to the trajectory. But every value capture derived rather than read carries a
|
|
37
|
+
`CONFIRM` marker — the grader pattern when no value could be quoted, and the
|
|
38
|
+
prompt when the trajectory recorded none. **Resolve every `CONFIRM` marker
|
|
39
|
+
against the cited trajectory, or ask the user, before authoring the case. Never
|
|
40
|
+
author a case that still carries one**, and never move a skeleton into `evals/`
|
|
41
|
+
unresolved: an unconfirmed pattern is a regression test for a failure nobody has
|
|
42
|
+
shown happened.
|
|
43
|
+
|
|
44
|
+
**If no observed failure is offered, say so and stop.** Do not author a
|
|
45
|
+
speculative case. A suite of hypotheticals teaches the team to ignore it, which
|
|
46
|
+
is the one thing an advisory gate cannot survive. A case that only duplicates an
|
|
47
|
+
existing `node:test` assertion is refused for the same reason — the unit suite
|
|
48
|
+
already covers it deterministically.
|
|
49
|
+
|
|
50
|
+
Record the citation in the case (`provenance:` in `case.yaml`, plus a comment
|
|
51
|
+
explaining what went wrong). The structural gate `test/evals.test.mjs` fails a
|
|
52
|
+
case with no provenance.
|
|
53
|
+
|
|
54
|
+
### The case files
|
|
55
|
+
|
|
56
|
+
Every case pins `schema_version` and lives in its own directory under `evals/` —
|
|
57
|
+
never under `skills/`, `agents/`, `commands/` or `workflows/`, which would shadow
|
|
58
|
+
a component. Follow `evals/handoff-status-enum/` as the format exemplar; it was
|
|
59
|
+
written to establish these conventions. Where a case needs a fixture workspace,
|
|
60
|
+
use `case.yaml` with `context.scaffold_script` and run with `--scaffold`;
|
|
61
|
+
otherwise the same `case.yaml` shape without it.
|
|
62
|
+
|
|
63
|
+
## 2. Choosing a grader — cheapest that expresses the assertion
|
|
64
|
+
|
|
65
|
+
The harness has six grader types. Four are free and deterministic — `regex`,
|
|
66
|
+
`tool_used`, `tool_order`, `file_exists` — and two call a judge — `llm`,
|
|
67
|
+
`baseline`.
|
|
68
|
+
|
|
69
|
+
**Pick the cheapest grader that expresses the assertion.** If the assertion is
|
|
70
|
+
set-membership, tool-invocation, file-existence, or ordering shaped, it is
|
|
71
|
+
deterministic and a judged grader is the wrong tool — more expensive, and prone
|
|
72
|
+
to run-to-run variance triage will (correctly) refuse to call a regression. The
|
|
73
|
+
strongest seed case, `handoff-status-enum`, needs no judge at all: the status is
|
|
74
|
+
in a fixed set, so a `regex` decides it.
|
|
75
|
+
|
|
76
|
+
**When you do reach for a judged grader, state in the grader body which part of
|
|
77
|
+
the assertion could not be expressed deterministically.** If you cannot name
|
|
78
|
+
that part, the assertion was deterministic and you chose the wrong grader.
|
|
79
|
+
|
|
80
|
+
A case you intend to run per-pull-request tag `smoke`, and a smoke case uses
|
|
81
|
+
**only** deterministic graders — the gate enforces this. A grader that asserts a
|
|
82
|
+
skill *fired* (`tool_used: Skill`) is marked `arm: with-only`: it is a
|
|
83
|
+
plugin-fired indicator, reported against the baseline arm, not part of the score.
|
|
84
|
+
|
|
85
|
+
## 3. Reading a run — triage owns the verdict
|
|
86
|
+
|
|
87
|
+
Given a finished results file, **get the classification from
|
|
88
|
+
`interlock evals triage --results <file>`, do not derive it yourself.** Its exit
|
|
89
|
+
code is the verdict: `0` pass, `1` regression, `2` no signal, `3` configuration.
|
|
90
|
+
This is deliberate — the one gate whose rule a model could re-argue on each run
|
|
91
|
+
would be exactly the wrong gate to ship in a suite built to catch models
|
|
92
|
+
re-arguing rules.
|
|
93
|
+
|
|
94
|
+
Your contribution is **explanation, not classification**:
|
|
95
|
+
|
|
96
|
+
- When triage reports a **regression**, explain which recent change to the
|
|
97
|
+
surface under test plausibly caused it — the prompt sentence, the skill edit,
|
|
98
|
+
the contract change. Do not reclassify it as variance because it looks flaky;
|
|
99
|
+
triage already separated a single judged dip (variance) from a judged majority
|
|
100
|
+
(regression).
|
|
101
|
+
- When triage reports **variance**, report it as variance and say what would
|
|
102
|
+
confirm it (further runs failing the same judged grader).
|
|
103
|
+
- When triage reports **no signal** — a partial run, an interrupted run, a
|
|
104
|
+
rejected credential — report that evals could not run. Do not present any case
|
|
105
|
+
as passing or failing.
|
|
106
|
+
|
|
107
|
+
Never restate, override, or soften a verdict triage gave you.
|
|
108
|
+
|
|
109
|
+
### Read a transcript before you explain a judged case
|
|
110
|
+
|
|
111
|
+
**For every case whose score depends on a judged grader, read at least one
|
|
112
|
+
transcript for that case before you write your explanation of it.** A score is
|
|
113
|
+
the outcome; the trace is the only place the cause is visible. The failure this
|
|
114
|
+
closes is a model that satisfied a judge by narrowing the task rather than by
|
|
115
|
+
doing it — the score moves, every other step in the loop sees a number, and
|
|
116
|
+
nobody sees why.
|
|
117
|
+
|
|
118
|
+
Reading is for explanation and **never for reclassification**. If the transcript
|
|
119
|
+
suggests a different classification than triage produced, report what you saw in
|
|
120
|
+
the trace and leave the verdict alone — the rule above still holds without
|
|
121
|
+
exception.
|
|
122
|
+
|
|
123
|
+
A run whose graders are all deterministic needs no transcript: the tool trace the
|
|
124
|
+
grader already read is the evidence.
|
|
125
|
+
|
|
126
|
+
Your report carries a `transcripts read:` line, always present:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
transcripts read: <case>/<id>, <case>/<id>
|
|
130
|
+
transcripts read: none
|
|
131
|
+
transcripts read: unavailable, because <what stopped you reading one>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Use the **none** form when you read no transcript — never omit the line, because
|
|
135
|
+
a reader cannot otherwise tell an unexamined result from an examined one. Use the
|
|
136
|
+
**unavailable, because …** form when the run produced no readable transcript, and
|
|
137
|
+
in that case do not present your explanation as transcript-grounded. Degradation
|
|
138
|
+
is spoken.
|
|
139
|
+
|
|
140
|
+
## 4. A failing case is a report, never a prompt edit
|
|
141
|
+
|
|
142
|
+
When a case fails, your output is a report: the case, the grader that failed, and
|
|
143
|
+
the sentence in the surface under test that plausibly caused it. **Do not edit
|
|
144
|
+
the skill, shared contract, agent definition, or prompt under test to make a case
|
|
145
|
+
pass.** Changing the surface under test is a separate, explicit decision the user
|
|
146
|
+
makes — silently editing a prompt to turn a case green is exactly the "edit the
|
|
147
|
+
test until it passes" failure the suite exists to prevent, one layer up.
|
|
148
|
+
|
|
149
|
+
## 5. When the harness is gated
|
|
150
|
+
|
|
151
|
+
`claude plugin eval` prints `` `plugin eval` is currently in early access `` and
|
|
152
|
+
does nothing until `CLAUDE_CODE_WALNUT_SPIRE=1` is set in the environment — never
|
|
153
|
+
in committed `.claude/settings.json`, which would produce a suite that looks
|
|
154
|
+
configured and does not run.
|
|
155
|
+
|
|
156
|
+
When the harness refuses because early access is not enabled, **report the
|
|
157
|
+
prerequisite and where to set it** (the environment, or the CI job's `env:`
|
|
158
|
+
block). Do not report an empty run as a passing suite. Authoring a case and
|
|
159
|
+
triaging an existing results file both work without the harness enabled — only
|
|
160
|
+
running a suite needs it.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explain-code
|
|
3
|
+
description: Explain code to a beginner in that stack — either a module walkthrough (what each function does, how calls link, where data flows, which patterns recur) or a commit teach-in (why each file changed, what changed, blast radius, what would break if it were left out). Use when asked to explain code, walk through a directory, or explain the last commit.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Requires git for commit teach-in mode. Optional openspec CLI for change scoping.
|
|
6
|
+
argument-hint: "[path | --commit | --commits N]"
|
|
7
|
+
allowed-tools: Bash(git *) Bash(interlock-graph *) Bash(openspec *) Read Write Grep Glob
|
|
8
|
+
metadata:
|
|
9
|
+
type: teaching
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Teach code to someone new to this stack. **Not reviewing, not judging — teaching.**
|
|
13
|
+
|
|
14
|
+
Calibrate to a reader who knows programming fundamentals but is new to this project's language and framework. Explain the idioms that stack takes for granted, one short aside each. Do not explain what a function is.
|
|
15
|
+
|
|
16
|
+
## Modes
|
|
17
|
+
|
|
18
|
+
| Mode | When | Load |
|
|
19
|
+
|------|------|------|
|
|
20
|
+
| **Module walkthrough** (default) | A file or directory is named, or the user asks how an area works | `${CLAUDE_SKILL_DIR}/module-walkthrough.md` |
|
|
21
|
+
| **Commit teach-in** | Last commit, a hash or range, "what changed", `--commit` / `--commits N` | `${CLAUDE_SKILL_DIR}/commit-teachin.md` |
|
|
22
|
+
|
|
23
|
+
When ambiguous, prefer the module walkthrough unless the user mentioned a commit or "what changed".
|
|
24
|
+
|
|
25
|
+
**After choosing a mode, read the matching sibling file and follow it** for steps, structure, and output format. This file only routes.
|
|
26
|
+
|
|
27
|
+
## Output path
|
|
28
|
+
|
|
29
|
+
Resolve the destination before writing. Both modes use the same rule:
|
|
30
|
+
|
|
31
|
+
| Situation | Write to |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Scoped to an OpenSpec change — a change name was passed, or one resolves via `openspec status --json` | `openspec/changes/<change-name>/code-explanation.md` |
|
|
34
|
+
| No change context (ad-hoc walkthrough) | `docs/CODE_EXPLANATION.md` |
|
|
35
|
+
|
|
36
|
+
**Do not "simplify" this back to a single path.** A change-scoped explanation belongs beside `manual-test-plan.md` in its own change directory. Writing every run to `docs/CODE_EXPLANATION.md` overwrites the previous change's explanation — and because `docs/` is the corpus `/interlock:docs-digest` indexes, each rewrite permanently marks `.claude/graph/DOCS_DIGEST.md` stale through its `source_hashes`.
|
|
37
|
+
|
|
38
|
+
## Shared rules
|
|
39
|
+
|
|
40
|
+
- **Single agent, no fan-out.** Understanding builds sequentially; parallel investigators produce four disconnected fragments, which is the opposite of a walkthrough.
|
|
41
|
+
- Write the full explanation to the resolved path (overwrite), then tell the user the file is ready with a 5–10 line summary.
|
|
42
|
+
- Pull domain context on demand: `.claude/graph/DOCS_DIGEST.md` first, then `interlock-graph context` / `docs`. Never preload all of `docs/` — see `${CLAUDE_PLUGIN_ROOT}/shared/TOOL-ECONOMY.md` Rule 0.5.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Commit teach-in — explain-code
|
|
2
|
+
|
|
3
|
+
Teach what changed and why — not a code review.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
Every source file touched in the commit range (skip binaries/lockfiles; cap ~25). Skip tests unless they are the only files and the user asked about them.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. Retrieve domain context on demand — Read `.claude/graph/DOCS_DIGEST.md` if present; then `interlock-graph context` / `docs` as needed (`${CLAUDE_PLUGIN_ROOT}/shared/TOOL-ECONOMY.md` Rule 0.5).
|
|
12
|
+
2. Resolve range: default `HEAD~1..HEAD`; `--commits N` → `HEAD~N..HEAD`; or an explicit hash/range from the user.
|
|
13
|
+
3. Gather:
|
|
14
|
+
```bash
|
|
15
|
+
git log -1 --format='%H%n%s%n%b' # or log for the range
|
|
16
|
+
git diff --stat "$FROM" "$TO"
|
|
17
|
+
git diff --name-status "$FROM" "$TO"
|
|
18
|
+
git diff "$FROM" "$TO" -- <each source file> # cap hunks ~300 lines/file
|
|
19
|
+
```
|
|
20
|
+
4. **Blast radius per file** — files that reference the import-specifier stem (basename without extension). For generic stems (`index`, `route`, `page`, `layout`, `config`, `types`, `utils`, `constants`, `main`, `mod`, `SKILL`, `README`, `PROMPT`) qualify with parent directory. Prefer `rg -l` / `git grep -l`; exclude self. Optional: `interlock-graph consumers <symbol>` when the graph exists. Name-match may false-positive — note incidental hits.
|
|
21
|
+
5. For each changed source file, fill the **Change Context** block (required). Optionally add function breakdown only for complex new/changed logic a beginner needs.
|
|
22
|
+
6. Write Commit Summary, Per-File Explanation, Change Flow, and Beginner Takeaway; write to the output path resolved in `SKILL.md`:
|
|
23
|
+
- Scoped to an OpenSpec change (name passed, or an active change resolves via `openspec status --json`) → `openspec/changes/<change-name>/code-explanation.md`, alongside `manual-test-plan.md`
|
|
24
|
+
- No change context → `docs/CODE_EXPLANATION.md`
|
|
25
|
+
- Per-change output is deliberate: one shared `docs/` file would overwrite the previous change's explanation and permanently mark `.claude/graph/DOCS_DIGEST.md` stale via its `source_hashes`.
|
|
26
|
+
|
|
27
|
+
## Change Context (required)
|
|
28
|
+
|
|
29
|
+
### Change Context (required in commit teach-in)
|
|
30
|
+
|
|
31
|
+
Use this block for every changed source file in commit mode. Status = Added / Modified / Deleted / Renamed from `git diff --name-status`.
|
|
32
|
+
|
|
33
|
+
```markdown
|
|
34
|
+
#### `path/to/file.ext` — <Added | Modified | Deleted | Renamed>
|
|
35
|
+
|
|
36
|
+
**Why this file needed to change:**
|
|
37
|
+
Plain-language reason this file was part of the commit. Tie it back to the commit's
|
|
38
|
+
goal — what would be incomplete without touching this file?
|
|
39
|
+
|
|
40
|
+
**What changed:**
|
|
41
|
+
- Bullet the concrete edits from the diff (new function, changed signature, added
|
|
42
|
+
field, deleted branch…). Skip boilerplate (import reordering, whitespace).
|
|
43
|
+
- Explain any TypeScript / React / Next.js concept a beginner wouldn't know,
|
|
44
|
+
in one short aside each.
|
|
45
|
+
|
|
46
|
+
**Blast radius:**
|
|
47
|
+
- Who is affected downstream, based on the referencing files gathered for this path.
|
|
48
|
+
- Rate it: **Isolated** (self-contained), **Local** (a few callers in one area),
|
|
49
|
+
or **Wide** (shared util/type/config touched by many files).
|
|
50
|
+
- Name the specific files most likely to feel the change and how.
|
|
51
|
+
|
|
52
|
+
**If this file had been left out:**
|
|
53
|
+
- What would break, fail to compile, or behave wrong if this file's change were
|
|
54
|
+
missing from the commit but every other file's change shipped?
|
|
55
|
+
- Be concrete: name the type error, runtime failure, broken flow, or silent bug.
|
|
56
|
+
- If the file is genuinely independent (nothing else depends on the change),
|
|
57
|
+
say so plainly — "nothing would break; this change is self-contained."
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Rules for Change Context:
|
|
61
|
+
- Teach, don't judge. No code-review verdicts, no "should have" critiques.
|
|
62
|
+
- Ground every claim in the diff and blast-radius data — do **not** invent callers, functions, or failure modes you can't see.
|
|
63
|
+
- Be concise but complete — every changed source file gets its own block.
|
|
64
|
+
|
|
65
|
+
## Output Format
|
|
66
|
+
|
|
67
|
+
### Commit teach-in
|
|
68
|
+
|
|
69
|
+
Match the explain-code loop structure (no review verdicts):
|
|
70
|
+
|
|
71
|
+
```markdown
|
|
72
|
+
# Code Explanation: commit <short-hash> — <subject>
|
|
73
|
+
|
|
74
|
+
## Commit Summary
|
|
75
|
+
|
|
76
|
+
One or two sentences, in plain language: what does this commit accomplish and why?
|
|
77
|
+
Reference the commit subject but translate any jargon for a beginner.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Per-File Explanation
|
|
82
|
+
|
|
83
|
+
[One Change Context block per changed source file — see above]
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Change Flow
|
|
88
|
+
|
|
89
|
+
If the commit spans multiple layers (e.g. type → data layer → component → route),
|
|
90
|
+
draw the dependency order as a short chain:
|
|
91
|
+
|
|
92
|
+
`types/batch.ts (new field)` → `lib/db.ts (reads field)` → `app/api/.../route.ts` → `components/BatchCard.tsx`
|
|
93
|
+
|
|
94
|
+
One line per chain. Write `(single-layer — no cross-layer flow)` if N/A.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Beginner Takeaway
|
|
99
|
+
|
|
100
|
+
One sentence naming the single most important concept a beginner should learn
|
|
101
|
+
from studying this commit (e.g. "shared types are a coupling point — changing one
|
|
102
|
+
field ripples through every consumer").
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If there are no commits to explain: write only `No commits to explain yet.` and stop.
|
|
106
|
+
|
|
107
|
+
## Tone & Style
|
|
108
|
+
|
|
109
|
+
## Tone & Style
|
|
110
|
+
|
|
111
|
+
- **Friendly, encouraging, zero condescension** — "we" language, like a senior sitting next to you
|
|
112
|
+
- **Skip the obvious** — don't explain what `const x = 5` does
|
|
113
|
+
- **Explain the non-obvious** — why this pattern? why server vs client? why does this call SQS here?
|
|
114
|
+
- **Name every external service call** — never skip an infra interaction, these are critical for understanding the system
|
|
115
|
+
- **Use analogies** — "Think of SQS like a to-do list for a background worker — we drop a note saying 'process this batch', and a separate service picks it up later"
|
|
116
|
+
- **Show the full journey** — from user action → through the code → to the database/service → back to the UI
|
|
117
|
+
- **Keep it scannable** — headers, bullet points, tables, code blocks. No walls of text.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## What NOT to Do
|
|
122
|
+
|
|
123
|
+
- Don't review or critique the code
|
|
124
|
+
- Don't suggest improvements (unless asked)
|
|
125
|
+
- Don't explain import statements, simple variable declarations, or trivial types
|
|
126
|
+
- Don't explain test files
|
|
127
|
+
- Don't use jargon without defining it on first use
|
|
128
|
+
- Don't be condescending ("as you probably know" / "this is simple")
|
|
129
|
+
- Don't explain node_modules or third-party library internals (just say what the library does)
|
|
130
|
+
- Don't skip infrastructure calls — every DB query, S3 operation, SQS message, and auth check must appear in the flow
|
|
131
|
+
- Don't use subagents or workflows — this skill requires sequential understanding across files
|
|
132
|
+
- In commit teach-in, don't skip Change Context fields — every changed source file needs Why / What / Blast radius / If left out
|
|
133
|
+
- Don't invent blast-radius callers or breakage modes not evidenced by the diff or reference search
|
|
134
|
+
|
|
135
|
+
- In commit teach-in, don't skip Change Context fields — every changed source file needs Why / What / Blast radius / If left out
|
|
136
|
+
- Don't invent blast-radius callers or breakage modes not evidenced by the diff or reference search
|