Skip to content

feat: faster review start, parallel passes, one PR comment per pass, fewer preventable findings - #54

Merged
sebastian-iancu merged 5 commits into
mainfrom
feat/review-flow
Oct 13, 2026
Merged

sebastian-iancu merged 5 commits into
mainfrom
feat/review-flow

Conversation

@sebastian-iancu

Copy link
Copy Markdown
Contributor

Summary

This PR acts on the 2026-10-13 analysis of every session since the 0.12 release. That analysis covered:

  • 12 Claude Code sessions with 161 subagents;
  • 13 Cursor sessions with 101 subagents;
  • the posts on 13 pull requests;
  • 28 findings files.

It implements the agreed plan, A to I. F is reshaped as the maintainer asked, G4 has no numeric cap, and D and H go in as proposed.

A. sdd-pr start prepares a review pass in one call.

  • What it does:
    • pulls the PR's threads and checks this checkout holds its head;
    • notes the pass and settles the lane (the flag, else the PR body's Lane: line, else a hint);
    • writes into .sdd/review/<head>/ each reviewer's hunks, the drift gate's new lines, the settled lines and one shared brief;
    • prints the dispatch plan.
  • What it skips: it never runs the gate. The brief names .sdd/gate-<head>.log when one exists.
  • Why: on Cursor a review start took a median of 32 tool calls and 7.6 min before the first reviewer. On Claude Code it was 3 calls and 0.6 min.

B and C. The review no longer runs the gate, and needs no disk search.

  • Each skill takes the plugin root from its own path. On Cursor, 77 calls had gone to searching the disk for the plugin.
  • add --help prints the line grammar. Cursor had read sdd-pr.py's source 73 times to learn it.
  • --version names the root, and every run names a newer sdd-pr installed beside this one. Two Cursor sessions had run stale 0.11.0 tools.

D. Passes run side by side.

  • pass: running no longer stops a pass: each names the others running beside it, and record clears only its own note.
  • With --pr, a review checkout whose local branch has another name works on the pull request's findings file. 0.12 left 10 stray pr-N-review*.md files this way.

E. A command instead of a brief. --panel and the end of /sdd-deliver print <name>: /sdd-review --pr N for each panel host. Only a name in the new agents.review_panel.external gets the paste block. 7 of 14 deliveries had ended with about 1k-character blocks for hosts that already load the plugin.

F. One PR comment per pass (as you specified: not a sticky comment, not the PR body).

  • The comment holds:
    • who reviewed, with repeated reviewers counted;
    • the blocking verdict;
    • how many lines that do not block are new in the pass, and how many are open on the branch;
    • the new lines, in one fold.
  • A review is posted only for the inline threads, plus the lines that cannot be anchored, which keep their evidence. An edit keeps a pass comment's header.
  • Text shows as written: outside code spans, <, >, & and @ are defused, the anchor is code, and everything reads back exactly. Comments from 0.12 still read.

G. Prevent the preventable.

  • Documents are reconciled on both profiles, which removes the largest class: the ripple, 32 findings, 11 of them blocking.
  • The brief lists the sentences that describe changed behaviour.
  • In-session spec edits follow /sdd-specify's form.
  • The close-out ticks the delivered acceptance criteria and writes the changelog line, and reviewers no longer file either before it.
  • The doc reviewer files a form suggestion only on a section the branch added or rewrote, and only where it changes how a sentence binds or reads. There is no numeric cap; the text says a pass with none is normal.
  • The PR body's Verification counts the per-task review.

H. Cut the real token sink.

  • A per-task review's findings, and each triage fix round, go to a new sdd-implementer instead of a resumed one. Resumed implementers were 59% of subagent cost.
  • Reviewers ask for every file in one turn and don't rerun the suite.

I. Fixes from the friction log.

  • Code that does not meet a sentence is fixed in the code; narrowing the sentence is the maintainer's call.
  • A test that pins an earlier fix is never deleted or weakened.
  • Questions to the maintainer come in plain words.

Docs

  • references/review.md:
    • § Severity: what the close-out writes is no finding before it;
    • § The forge mirror: one comment per pass;
    • § The tool: start, passes side by side, the --pr keying.
  • Methodology §9: the close-out ticks the acceptance criteria and writes the changelog line.
  • traceability-schema.md: the new review_panel.external field.
  • Templates: sdd.yaml, ai-workflow.md, brief.md, task-review.md and development-process.md.
  • User docs:
    • New: upgrading.md gets From 0.12.x to 0.13.0.
    • Updated: README, AGENTS.md, examples.md, quick-start.md and testing.md describe the new flow.
    • CHANGELOG entries under Unreleased.

Word budgets grow, as agreed. The table lists only the files that grew; sdd-review shrinks from 939 to 883.

File Words added
review.md +214
sdd-deliver +166
sdd-triage +83
sdd-doc-reviewer +58
conformance reviewer +40
brief.md +37
sdd-scaffold, sdd-specify, sdd-trace, router +18 each (the plugin-root line)
ai-workflow.md +17

Verification

  • ./scripts/validate.sh: OK, including word budgets and forge-neutral text; hook tests OK.
  • python3 -m unittest discover -s tools/tests: 559 OK (was 545). New tests cover:
    • start: the plan, the files, the lane from the PR body, the drift gate, an empty range, a head missing from this checkout, a missing descriptor;
    • the --pr keying;
    • the add --help grammar and the newer-install warning;
    • passes side by side;
    • the escaping round trip;
    • 0.12 comments still reading;
    • an edit keeping its pass header;
    • repeated reviewers being counted.
  • python3 tools/sdd-check.py selftest: OK, 26 cases. claude plugin validate .: passed.
  • Real git: in a throwaway repository with a vendored gate, sdd-pr start:
    • wrote the three patches, drift.txt and the brief;
    • printed the plan with absolute paths and the gate's verdict;
    • reported a second agent's pass running beside it;
    • left the tree clean.
  • A regression the new tests found and fixed: a refusal while resolving --pr in the session constructor kept the clone's lock, which hung the next command in the same process.

Notes for review

Look hardest at:

  • cmd_start and lane_of;
  • sync_suggestions, now the carrier of a pass's comment, and how it keeps a pass header on edit;
  • md_escape and md_unescape, which skip code spans.

Not verified here:

  • GitHub accepting a review with inline threads and an empty body. Production data from 0.12 shows such reviews exist, but the change relies on it for every pass with blocking lines.
  • The new layout as it renders on GitHub and Azure DevOps. The bodies are checked; the rendered pages are not.

Left as is:

  • The per-task review and the whole-branch go-review both stay.
  • The question of guard-removal tests for SHOULD sentences (methodology §13).

Checklist

  • Scoped to one logical change (the 2026-10-13 analysis's plan)
  • The gates above pass locally and their output was read
  • CHANGELOG entry under Unreleased
  • AGENTS.md, README.md synced; no component added or renamed (start is a new sdd-pr subcommand; the tables name it)
  • No internal or private repository names, absolute paths or organisation-private details

🤖 Generated with Claude Code

sebastian-iancu and others added 5 commits October 13, 2026 16:54
…run side by side

`sdd-pr start --agent <a> [--pr N] [--since-last] [--lane] [--base]` pulls the
pull request's threads, checks this checkout holds its head, notes the pass,
settles the lane (the flag, the PR body's Lane: line, else a hint), writes each
reviewer's hunks, the drift gate's new lines, the settled lines and one shared
brief under .sdd/review/<head>/, and prints the dispatch plan. It never runs the
gate; the brief names the gate log when one exists at HEAD.

A pass note no longer stops another agent: scope --start and start report the
passes running beside it, and record clears only its own agent's note (the
scratch worktree goes when no pass is left). With --pr, a checkout whose local
branch has another name works on the pull request's findings file, so review
worktrees stop leaving stray files; a refusal while resolving the pull request
releases the clone's lock. The PR record carries its body.

`add --help` prints the line grammar, `--version` the plugin root, and every
run warns when a newer sdd-pr sits beside this one in a plugin cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pass is one comment: who reviewed (repeated reviewers counted), the blocking
verdict, how many lines that do not block are new in the pass and how many are
open on the branch, then those lines in one fold, defects first. A review is
posted only for what sits on a line: the inline threads, and the lines that
cannot be anchored, which now keep their evidence and fix. Lines posted between
passes get a comment of their own; an edit keeps a pass comment's header.
`unsummarised` finds a pass in a comment, or in a review for passes posted
before; `pull` skips the plugin's own pass comments.

Comments and inline threads show what was written: outside code spans, `<`, `>`
and `&` are entities and `@` mentions nobody; a line's anchor is code. Both read
back exactly, so harvest and pull get the original text; comments written by
0.12 still read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A subagent reads the brief and its patch from wherever it runs, so the plan's
paths are absolute. The drift line is the gate's own verdict line, not its
list of families; the doc reviewer's mode follows the lane when it is still
undecided; the range is shown short.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mmand, not a brief

sdd-review runs `sdd-pr start` before reading anything, dispatches each plan
line with "Read <brief>; your hunks: <patch>", never runs the gate, and lets
passes run side by side. `--panel` and the end of sdd-deliver print
`/sdd-review --pr N` per panel host; only a name in the new
`agents.review_panel.external` gets the request block. Every skill takes the
plugin root from its own path and never searches the disk for it.

Delivery and triage prevent what reviewers kept finding: documents are
reconciled on both profiles, the brief lists the sentences that describe
changed behaviour, an in-session spec edit keeps sdd-specify's form, a pinning
test is never deleted or weakened, code that does not meet a sentence is fixed
rather than the sentence narrowed, and the close-out ticks the delivered
acceptance criteria and writes the changelog line. A per-task review's findings
and each triage fix round go to a new worker, not a resumed one. The reviewers
ask for every file in one turn and do not rerun the suite; the doc reviewer
files a form suggestion only where it changes how a sentence binds or reads,
and neither files what the close-out writes. Questions to the maintainer come
in plain words.

references/review.md, the methodology's close-out, the schema and templates,
README, AGENTS.md, docs and the CHANGELOG follow; upgrading.md covers 0.12.x to
0.13.0. Word budgets grow: sdd-deliver +166, sdd-triage +83, the four other
skills +18 each for the root line (sdd-review shrinks 939 to 883), review.md
+214, sdd-doc-reviewer +58, the conformance reviewer +40, brief.md +37,
ai-workflow.md +17.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A post that published inline threads while the pass's comment had nothing
new printed its thread count and then "post: nothing to post". The
sentence now prints only when neither the review nor the comment sent
anything, and the review's own "nothing new to post" is gone, so it
prints once.

docs/testing.md still described the 0.12 mirror (the pass summary as a
review body, a second `scope --start` stopped by `pass: running`); it
now checks one comment per pass, a review only for the lines that
block, and passes side by side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sebastian-iancu
sebastian-iancu merged commit 777d6a9 into main Oct 13, 2026
2 checks passed
@sebastian-iancu
sebastian-iancu deleted the feat/review-flow branch October 13, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant