Study Command - #277
Conversation
Add a /study command that records each genuine surprise from a piece of work as one classified row in docs/study/<issue>.md, so the accumulated files answer a question no single PR can: which part of the harness keeps costing us, and therefore what to fix. Two guards keep the folder all-signal: a clean run writes nothing (there is no "nothing notable" row, so a file's presence means the work taught us something), and every row must be grounded in evidence the run can point at — a commit, a review comment, a failing test, a CI run. Rows are classified to exactly one of Execution, Plan-spec, Codebase or Environment; the levels say where the fix belongs, which is what makes a recurring level actionable. There is deliberately no Goal level: whether an issue should have existed is settled at drafting time, not downstream, so the level would sit empty and dilute the tally. /study never prompts, refuses to run from main, changes no source, test or configuration file, runs no tests, applies no formatting, and never pushes, opens a PR or merges. A finding that looks mechanically enforceable is flagged for /capture-learnings rather than acted on here. docs/study/README.md explains the four levels and how to read the accumulated files back. No existing command is changed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01YaRuiUQHdPMeGugFuvGfeK
Four clean-context reviewers audited the new command prompt as a program: its steps are the control flow and its specified failure behaviour is the error handling. Three independently found the same missing unwind path. Blockers fixed: - rows=0 could not distinguish "nothing was surprising" from "I could not look". Step 3 now classifies every evidence source as had / absent / errored, never folding errored into absent, and STOPs with FAILED reason=no evidence gathered when no source was had. - Step 6 had no rollback, so a rejected commit left a written, staged file while the report asserted the repository was unchanged — dirtying the tree and blocking /verify, the one thing the command promises never to do. The path is real in this repo: no-skipped-tests.sh is a PreToolUse hook on git commit that fails closed. - Step 3's evidence-source wording pointed at the artefact rather than the chat report, against the issue's confirmed decision that the file carries no evidence-sources line. Step 5 now states the file contains only the H1 and the table. - The re-run "everything already recorded" path fell through into the commit step and would have reported FAILED where AC 7 requires rows=0. - The description of /capture-learnings dropped its top-ranked destination; its actual order is fix the rule that misfired, then enforce deterministically, then a memory entry. Also: branch inference now mirrors /raise-pr's guards, so feature/net10- upgrade cannot yield 10 and a spec-kit NNN- branch cannot file against a sequence number; a detached HEAD is refused rather than committed onto; step 1 takes a baseline so "left pre-existing changes untouched" is measured rather than asserted; the title fetch moved into the new-file branch so a clean run is no longer turned into FAILED by an unrelated gh failure; and /study now refuses to author a replacement README rather than confabulating the document that defines its own classification. Docs: the workflow map now links the records folder, and the README drops an unverifiable claim about an unnamed repository and an example H1 that was coupled to a live GitHub issue title. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01YaRuiUQHdPMeGugFuvGfeK
|
@claude Review this pull request. Analyse the code changes and provide feedback covering:
End the review with a recommendation whether to merge the PR, and if not, what you suggest needs addressing first. |
|
Claude finished @FrankRay78's task in 3m 17s —— View job Review complete ✅
(Note: Bugs / correctness issuesMinor — the pre-existing-file guard in step 6 may not catch an untracked leftover.
This correctly protects against sweeping in someone else's uncommitted edit to an existing tracked file. But if a prior No other correctness issues found — the step-1 detached-HEAD/ Security concernsNone. This is a prompt-only change ( CLAUDE.md / constitution adherence
Test coverageNone added, and per the PR body and Constitution §I's carve-out, none is expected for a prompt-only artefact — agreed this is the right call, not a gap. The traceability point (three Spec/test-plan mismatchesNone — there is no spec-kit RecommendationMerge. The command is internally consistent, follows the established conventions of |
Why
/buildand/verifynow carry a piece of work from a GitHub issue to a reviewed, test-green branch, but neither leaves any record of where the work went sideways on the way. A reviewer finding gets fixed and disappears into a commit; an ambiguous criterion gets interpreted and never mentioned again. Individually invisible, collectively they are the only evidence of whether the harness itself needs work./studyrecords each genuine surprise as one classified row, so the accumulated files eventually answer a question no single PR can: which part of the harness keeps costing us, and therefore what to fix.What changes
Adds a
/studycommand and thedocs/study/folder it writes into. No existing command is altered.Rows are classified to exactly one of Execution (the doing went wrong), Plan-spec (the criteria were wrong), Codebase (the existing code was not what anyone assumed), or Environment (the surprise came from outside the repo). The levels are not severities — they say where the fix belongs, which is what makes a recurring level actionable.
Two guards keep the folder worth reading: a clean run writes nothing at all (there is no "nothing notable" row, so a file's presence means the work taught us something), and every row must be grounded in evidence the run can point at. Asked what surprised it, a model will readily invent plausible surprises; a folder of confabulation would be worse than no folder.
Non-obvious things a reviewer should know
Read the issue's
## Confirmed decisionsalongside its acceptance criteria. Ten bullets there override several defaults — the three-column self-grounding table (no Evidence column), the flat append-only shape (no per-pass sections or dates), the bare-number filename, refusing to run frommain, and the verdict line. A review against the AC checklist alone would flag correct behaviour as wrong.There are no tests, deliberately. Constitution §I's carve-out for configuration and tooling applies: the artefact is a prompt file, no code is added, and nothing under
src/is touched. The RED evidence is the real gate — before the change,.claude/commands/study.mddid not exist,docs/study/did not exist, and nothing in the repo defined/study; after it, the harness parsed the file and registered the command with its description. The issue's confirmed decisions record this explicitly and direct that no bespoke markdown test be written.Three
**Scenario:**labels carry zero// SCENARIO:markers, and that is deliberate rather than forgotten. The traceability gate readsspecs/*/spec.md, which does not exist here and which/buildforbids creating, so the gate is a verified no-op. The only way to host a marker would be an xUnit test asserting over prose in.claude/commands/— the hand-rolled stand-in §I explicitly bans, and unable to judge criteria like "only genuinely new findings are added" in any case. The scenarios are instead satisfied by named steps in the command.This invariant is verified once, by hand, not gated. §I also requires making a check repeatable in CI where the tool can run there. No tool can decide whether a prompt is correct, so that clause is vacuous here — worth knowing rather than worth pretending otherwise.
The second commit is larger than the first, and reshaped the command. Four clean-context reviewers audited the prompt as a program — its steps as control flow, its failure clauses as error handling — and three independently found the same missing unwind path. The substantive fixes:
rows=0could not distinguish "nothing was surprising" from "I could not look" (now a three-statehad/absent/erroredclassification per source, with aFAILED reason=no evidence gatheredstop); a rejected commit left a written, staged file while the report asserted the repository was unchanged, dirtying the tree and blocking/verify— the one thing the command promises never to do. That path is real in this repo, not hypothetical:no-skipped-tests.shis aPreToolUsehook ongit committhat fails closed.Two review findings were rejected on purpose. Making
README.mdthe normative source for the four levels with a cross-reference from the command would contradictfeedback_prompts_locality_over_dry— the executor should not need a second file open. And the third "never prompts" statement was kept because its position in the## User Inputblock mirrorsraise-pr.mdverbatim and is load-bearing exactly where an empty argument is discussed.One line lands outside
docs/study/.docs/agentic-workflow-NetPace.mdgains a single Related bullet, because two reviewers independently noted the README linked outward to the workflow map while the map never mentioned the folder. That documents this branch's own addition rather than folding in a second mission.How to verify
.claude/commands/study.md— the checklist alone is not the whole contract.main, refusing a detached HEAD, an un-inferable issue number, and the step-6 rollback when a commit is rejected.feature/net10-upgrademust not yield10, and a bareNNN-<slug>spec-kit branch must yield no candidate. This mirrors/raise-pr's existing rule.CLAUDE.md,.claude/memory/or hooks.docs/study/README.mdas a future analyst would, and check the four levels are distinguishable enough to classify against.Related
Closes #260
/studyas an ordinary caller and needs nothing beyond what is specified here..claude/commands/capture-learnings.md— the adjacent, deliberately different reflection step: it starts from what the invoker corrected and prefers a rule fix or a gate, where/studyrecords what surprised the agent and only ever writes a record.🤖 Generated with Claude Code
https://claude.ai/code/session_01YaRuiUQHdPMeGugFuvGfeK