Files
msd-core/docs/features/code-review-pipeline.md
Tom Boucher acb903c2e8 enhance(#3661): make the code-review hook point configurable (#4159)
* feat(#3661): make the code-review hook point configurable

Add `workflow.code_review_point` (`execute:post` default, or
`execute:wave:post`) so a multi-wave phase can run code review once per
wave instead of once at the end, scoped to what changed since the phase's
prior review.

The code-review capability now declares its step at both loop points via a
new generic `pointFrom` step field: `pointFrom` names an enum config key,
and the step is only active at its own `point` when that key resolves to
a matching value. `_resolvePointGate` (capability-activation.cts) is the
single shared implementation consumed identically by loop-resolver.cts and
capability-state.cts, and capability-validator.cjs enforces that `pointFrom`
references an enum key whose values cover the declaring step's own point.

code-review.md's manual-invocation gate now reads `workflow.code_review`
directly instead of probing registry presence at the hardcoded execute:post
point (so manual `/gsd-code-review` keeps working regardless of which
automatic point is configured), and its file-scope tiers narrow to what
changed since the phase's last review commit when one exists.

execute-phase.md's wave-post step dispatch gets a small, precedented
carve-out so the code-review skill still receives its required phase
argument when dispatched generically (caught by the isolated spec review).

Closes #3661

Emitted-Drift-Ack-Growth: code-review.md — #3661 adds a point-aware config gate check and LAST_REVIEW_COMMIT-based incremental scoping to the file-scope tiers.
Emitted-Drift-Ack-Growth: execute-phase.md — #3661 adds one carve-out sentence so the wave-post generic step dispatch passes PHASE_NUMBER to the code-review skill.

* docs: backfill changeset PR number for #3661 (#4159)

* fix: scope tests/io.test.cjs's fs.writeSync fault-injection mocks by fd

Five fault-injection mocks in the "bug #1008" describe blocks intercepted
every fs.writeSync call regardless of file descriptor, and several threw or
truncated unconditionally on the first call. This surfaced as an
intermittent macOS CI failure: node:test's own IPC channel back to the
parent process (which also goes through fs.writeSync internally) could get
a bogus injected error or truncated write if node's internal machinery
called it while one of these mocks was active, corrupting the message
frame the parent tried to deserialize ("Unable to deserialize cloned
data.", location tests/io.test.cjs:1:1, uncaughtException — a whole-file
IPC crash, not a test assertion failure).

Root cause confirmed by a working counter-example already in the same
file: the "#3912 A6" mocks gate on `fd !== 2` before any fault injection
and were never implicated. Applied the same fd-scoped pattern to the five
unscoped mocks (four output()-targeting tests gate on fd 1, one
error()-targeting test gates on fd 2), and added a regression test proving
an unrelated fd passes through untouched while the fault-injection mock is
active.

Found while verifying #3661; unrelated to that change's own diff.

---------

Co-authored-by: sim <sim@local>
2026-09-02 11:01:54 -04:00

4.1 KiB

id, title, group
id title group
93 Code Review Pipeline v1.34.0 Features

Commands: /gsd-code-review, /gsd-code-review --fix

Purpose: Structured review of source files changed during a phase, with a separate auto-fix pass that commits each fix atomically.

Requirements:

  • REQ-REVIEW-01: gsd-code-review MUST scope files to the phase using SUMMARY.md and git diff fallback
  • REQ-REVIEW-02: Review MUST support three depth levels: quick, standard, deep
  • REQ-REVIEW-03: Findings MUST be severity-classified: Critical, Warning, Info
  • REQ-REVIEW-04: gsd-code-review --fix MUST read REVIEW.md and fix Critical + Warning findings by default
  • REQ-REVIEW-05: Each fix MUST be committed atomically with a descriptive message
  • REQ-REVIEW-06: --auto flag MUST enable fix + re-review iteration loop, capped at 3 iterations
  • REQ-REVIEW-07: Feature MUST be gated by workflow.code_review config flag
  • REQ-REVIEW-08: workflow.code_review_point MUST select which loop point the automatic review step registers at (execute:post default, or execute:wave:post), independent of the workflow.code_review on/off gate and of manual /gsd-code-review invocation (#3661)

Config:

Setting Type Default Description
workflow.code_review boolean true Enable code review commands
workflow.code_review_point string execute:post Loop point for the automatic review: execute:post (once per phase, default) or execute:wave:post (once per completed wave, scoped to what changed since the phase's prior review). See below.
workflow.code_review_depth string standard Default review depth: quick, standard, or deep
workflow.code_review_depth_overrides array [] Ordered { paths, depth } rules that escalate depth for directories matched by path prefix against the changed-file set (#2554). See below.

Reviewing per wave instead of per phase (#3661)

Setting workflow.code_review_point to execute:wave:post moves the automatic review from "once, after the whole phase's waves have all landed" to "once per completed wave." Each wave's review scopes to what changed since the phase's previous review — the whole phase's diff on the first wave, then just that wave's diff on every wave after — so review batches stay small instead of growing with the phase. A finding introduced early is caught after the wave that introduced it, not after the last wave of the phase.

This only affects the automatic dispatch inside a wave-based phase execution. Manual /gsd-code-review <phase> runs are gated by workflow.code_review alone and are unaffected by this key. /gsd-autonomous and /gsd-quick have no wave granularity of their own, so setting this to execute:wave:post means automatic review does not run inside those two flows — the same way every other wave-scoped capability step already behaves for them.

Path-scoped code review depth overrides

workflow.code_review_depth_overrides matches rules against the review's changed-file set by whole-segment directory-path prefix — src/auth matches src/auth/token.ts and src/auth itself, never src/authfoo/x.ts or docs/src/auth/x.ts — and is case-sensitive, following git.

Escalation is whole-review, not per-file: depth is a single scalar handed to the reviewer agent, not a per-file setting, so the strongest matching tier across the whole rule set applies to every file in the review — a sensitive file is never reviewed shallowly because it shared a review with an unrelated one.

v1 supports directory-prefix matching only, not glob syntax: no glob engine (minimatch, picomatch, fast-glob) exists in this project and none was added for this feature. A path containing * or ? (e.g. src/auth/**) is a configuration error rather than a silent near-miss, because accepting it as sugar for a prefix would make unsupported patterns look armed when they match nothing. Every use case in the issue is expressible as a directory prefix. See Scope code review depth by path for the resolution order, error table, and a worked example.