fix(skills): redraw patch versus defer, prefer patch over bad_spec, route scope-line findings on their merits - #2817
Draft
pbean wants to merge 1 commit into
Draft
fix(skills): redraw patch versus defer, prefer patch over bad_spec, route scope-line findings on their merits#2817pbean wants to merge 1 commit into
pbean wants to merge 1 commit into
Conversation
…oute scope-line findings on their merits Two triage-routing changes ported from #2805 onto current main, at all four triage sites (bmad-build step-04 and oneshot, bmad-build-auto step-04, bmad-code-review step-03). Patch versus defer. Patch is any local fix inside the change's blast radius: the files in the diff, their tests, the code a test in the diff exercises, direct callers of symbols the diff changed, and sibling sites of a pattern the diff fixed. Size is not the criterion. A pre-existing defect in code this change edited is this story's problem, and so is a gap in the change's own verification. Patch also takes a defect the change did not cause when the fix is smaller than writing it up. Defer requires every condition to hold: neither caused nor exposed by the change, in a file and symbol it did not touch, not a sibling copy of a pattern it fixed, a fix larger than the entry, and not an agent-context file it made stale. The all-maybe-false gate from #2809 is kept unchanged inside the new defer definition. bad_spec and scope lines. A design decision says how the work is done; a scope line says where it stops. bad_spec now means a local fix would contradict a recorded design decision, or the defect recurs wherever that design applies. A deviation from a spec that is itself right is a patch. When in doubt, prefer patch: name the spec sentence a local fix would contradict, or it is a patch. A finding only a scope line excludes is routed on its merits, never deferred on that ground; in the interactive skills a patch that crosses a scope line or changes an agent-context rule is confirmed by the human once, together, and declined ones become defers with the human's reason. In code review, no-spec mode no longer reclassifies an ambiguous fix as defer; the user is present and settles it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The line between
patchanddeferis drawn by size.patchis "trivial, adds no public surface";deferis "pre-existing issue not caused by this story". Under those definitions a real defect in a file the change edited, whose fix is a private helper and a test, is neither trivial nor caused by the change — so it is deferred. It lands in the ledger, the next run reads it back, and someone re-derives the context this run already had. The change that touched the file was the cheapest moment to fix it.bad_spechas the same lean. "When in doubt between bad_spec and patch, prefer bad_spec" sends a deviation from a spec that is itself right into a revert-and-re-derive loop, when restoring what the spec says is a local edit.And a finding that only a spec scope line excludes — a Never non-goal, a Code Map do-not-change — routes to
intent_gaporbad_spectoday, or gets deferred as out of scope. A scope line says where the work stops; it does not say the defect on the far side of it is not the change's problem.What changed
Instruction text at all four triage sites:
bmad-buildstep-04 and one-shot,bmad-build-autostep-04,bmad-code-reviewstep-03. The two step-04 files stay in lockstep; only the human-present branches differ.Patch is a locality test, not a size test. A patch is a fix inside the change's blast radius — the files in the diff, their tests, the code a test in the diff exercises, direct callers of symbols the diff introduced or changed, and sibling sites of a pattern the diff fixed or replaced when the fix is the one already in the diff — that contradicts no design decision the spec records, adds no external contract, and guards no state the finding did not demonstrate. A private helper, a new test, or a fifteen-line fix is still a patch. Patch also takes a defect the change did not cause when the fix is a direct correction smaller than the deferred entry would be; writing it up costs more than fixing it.
Defer is a positive test with every condition required. The defect was neither caused nor exposed by the change; it lives in a file and symbol the change did not touch, and is not a sibling copy of a pattern the change fixed; its fix is larger than the entry would be; and it is not an agent-context file the change made stale. The triage row names the tests it passes. A pre-existing defect in code the change edited is the change's problem. So is a gap in the change's own verification — a test that would still pass with the change reverted, or a touched site that skips the helper the change introduced — which is a patch, never a coverage-only defer. The existing severity-if-true gate for all-
maybe-falseentries is unchanged inside the new definition.Design decisions versus scope lines. A design decision says how the work is done — the Approach, a Design Notes rationale, a forbidden approach. A scope line says where the work stops.
intent_gapnow includes a fix that would contradict a design decision inside the frozen block or intent contract.bad_specmeans a local fix would contradict a recorded design decision outside it, or the same defect recurs wherever that design is applied. A deviation from a spec that is itself right is a patch. When in doubt, prefer patch: name the spec sentence a local fix would contradict; if you cannot, it is a patch.Out of scope routes on its merits. A finding only a scope line, the plan, or the shape of the diff excludes is kept and routed like any other. In
bmad-build-autoa local fix is applied with the crossed line named in its triage row and under residual risks. Inbmad-buildand one-shot, patches that cross a scope line or change a rule in an agent-context file are put to the human once, together; confirmed ones are applied, declined ones become defers with the human's reason as evidence.Agent-context files split two ways. A description of behavior the change altered is stale documentation inside the blast radius — a patch. A new or changed rule, or an edit to another spec, is a policy change: the unattended skill defers it with the rule it would change as evidence; the interactive skills ask.
Code review without a spec keeps
decision_needed. No spec means no recorded design decisions or scope lines, sodecision_neededrests on the other grounds. An ambiguous fix staysdecision_needed— the user is present and settles it in step 4 — and is no longer reclassified asdeferfor want of a spec.Docs
docs/build/review-a-change.md"What a Run Does" describes the verdicts and the three routes as they now work.Verification
npm testgreen: renderer 24/24, skill validator, lint, markdownlint, prettier.