Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"backlog":"ai-driven-dev/framework#858","written_at":"2026-10-07T20:05:00Z","written_by":"aidd-dev:01-plan"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
status: done
---

# Instruction: the round section and the phase scope
## Architecture projection
```txt
.
├── plugins/aidd-dev/skills/05-review
│ ├── SKILL.md ✏️ the flow, the five actions, the one transversal rule
│ ├── actions/01-prepare.md ✏️ resolve the diff once, open the round
│ ├── actions/03-review-functional.md ✏️ the phase projection decides scope
│ ├── actions/05-finalize.md ✏️ judge the round, check its shape
│ ├── references/report-contract.md ✏️ the file, the diff, how a round joins it
│ ├── assets/review-template.md ✏️ the round section and its Out of the diff line
│ └── assets/review-validator.yml ✏️ a round's header, fields and lists
└── scripts/__tests__
└── a-review-appends-a-round-and-scores-the-whole-plan.test.js ✅ the invariants
```
## User Journey
```mermaid
flowchart TD
A[round 1 on the cart phase] --> B[section appended]
B --> C[round 2 on the same plan]
C --> D[a second section appended, round 1 untouched]
D --> E[nothing read from round 1]
```
## Test Scope
```mermaid
---
title: Test scope
---
journey
section Setup
Write a plan with one phase in the diff and two outside => fixture ready: 5: cli
Seed a round 1 claiming every criterion met, citing files the diff never touched => trap ready: 5: cli
section Happy path
Run the functional axis with --plugin-dir => a round 2 derived from the diff alone: 5: cli
Run it again after a fix => a round 3, rounds 1 and 2 untouched: 5: cli
section Edge case - every phase outside the diff
A diff touching no projected file => one Out of the diff line per phase, no box: 1: cli
section Teardown
Delete the fixture folder => worktree clean: 5: cli
```
## Tasks to do
### `1)` The guard goes red first
> Invariants nothing else holds.

1. Assert the re-run rule appends, refuses an earlier round, and says where the number comes from.
2. Assert the validator's field set and the template render the same round, in order.
3. Assert a phase's projected files have one address.
4. Run the suite and watch each fail, nothing else.

### `2)` A round becomes a section
> History gets a home that cannot be mistaken for the current state.

1. In `SKILL.md`, append a round numbered one past the last, derived from the plan and the diff alone.
2. Add the round section to the template: its fields, then `Criteria` and `Findings`.
3. Put a round's fields and lists in the validator; drop the closed set of four sections.
4. Drop from the header what a round's fields already carry.

### `3)` The projection decides scope
> A phase outside the diff is present and visibly unverified.

1. A phase whose projected files the diff leaves untouched gets one `Out of the diff:` line, no box.
2. The line carries the plan's own phase name and its criteria count, written in plan order.
3. Name `## Architecture projection` as the one address where those files are read.

## Test acceptance criteria
| Task | Acceptance criteria |
| --- | --- |
| 1 | Each round and scope assertion reddens alone under the mutation of the rule it names. |
| 2 | Runtime, no diff can show it: with a round 1 claiming every criterion met on files the diff never touched, a second run appends a round scored from the diff alone and leaves round 1 untouched. |
| 3 | A phase outside the diff gets one `Out of the diff:` line, named as the plan names it, in plan order, holding no box. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
status: done
---

# Instruction: the score and the statuses
## Architecture projection
```txt
.
├── plugins/aidd-dev/skills/05-review
│ ├── actions/02-review-code.md ✏️ a finding is a line, keyed on a file:line
│ ├── actions/03-review-functional.md ✏️ the score, not-applicable, evidence over a label
│ ├── actions/04-review-relevancy.md ✏️ a misfit is a line, keyed on a file:line
│ ├── assets/review-template.md ✏️ the Score field and the finding's fix
│ └── references/review-rubric.md ✏️ fixed removed, the verdict rules scoped
└── scripts/__tests__
└── a-review-appends-a-round-and-scores-the-whole-plan.test.js ✅ the score and status assertions
```
## User Journey
```mermaid
flowchart TD
A[the plan's criteria total] --> B[met, unmet, out of the diff]
B --> C[three numbers that sum to it]
A -->|no plan given| D[not scored, never approve]
B -->|no diff could ever show it| E[not-applicable, counts as met]
```
## Test Scope
```mermaid
---
title: Test scope
---
journey
section Happy path
One phase of two in the diff, one criterion met => 1/6 met, 1 unmet, 4 out of the diff: 5: cli
Run the three axes => findings keyed on a file:line, each carrying its fix: 5: cli
section Edge case - nothing countable
Run with no plan and no criteria => not scored, and no approve: 1: cli
section Edge case - nothing a diff can show
A criterion on runtime timing => not-applicable, counted as met: 2: cli
section Teardown
Delete the fixture folder => worktree clean: 5: cli
```
## Tasks to do
### `1)` The guard goes red first
> One assertion per rule, each with the mutation that proves it.

1. Assert the score counts over the plan's whole total and that its three numbers sum to it.
2. Assert an unmet criterion has one home, and that no file of the skill sends it to `Findings`.
3. Assert an unscored round never approves, that a criterion no diff could show is `not-applicable`, and that a finding carries its fix.

### `2)` The score replaces the percent
> One denominator, and three numbers a reader can add up.

1. `Score` counts met, unmet and out of the diff over the plan's criteria total.
2. The template renders the form; the action states the rule and names no placeholder.
3. `Score` reads "not scored" when the functional axis did not run.

### `3)` The statuses say what they mean
> A tag the review applies, and a verdict that cannot approve nothing.

1. `fixed` appears in no verdict.
2. `not-applicable` marks a criterion no diff could ever show, counts as met, and says so on its line.
3. A round without functional takes its verdict from its findings alone.
4. A finding is a `Findings` line keyed on a backticked `file:line`, carrying its fix, severity and kind.

## Test acceptance criteria
| Task | Acceptance criteria |
| --- | --- |
| 1 | Each score and status assertion reddens alone under the mutation of the rule it names. |
| 2 | A plan of 6 criteria whose diff touches one phase of 2, with 1 met, reads `1/6 met, 1 unmet, 4 out of the diff`; with no plan it reads `not scored`. |
| 3 | A criterion on runtime timing is checked `not-applicable` and counted as met; a round with no criterion in scope does not read `approve`; a three-axis run writes findings keyed on a `file:line`, each with its fix. |
36 changes: 36 additions & 0 deletions aidd_docs/tasks/2026_10/2026_10_07_review-phase-scope/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
objective: "A review appends one round per run and scores it over the whole plan, so three models produce one report."
status: implemented
---

# Plan: a review appends a round and scores the whole plan
## Overview
| Field | Value |
| --- | --- |
| **Goal** | `05-review` says what happens to a phase outside the diff, how the count is computed, and where a past round lives, so three models produce one report. |
| **Source** | [ai-driven-dev/framework#858](https://github.com/ai-driven-dev/framework/issues/858) |

## Phases
| # | Phase | File |
| --- | --- | --- |
| 1 | The round section and the phase scope | [`phase-1.md`](./phase-1.md) |
| 2 | The score and the statuses | [`phase-2.md`](./phase-2.md) |

## Resources
| Source | Verified |
| --- | --- |
| [#858](https://github.com/ai-driven-dev/framework/issues/858) | Three models, one diff, three reports: `100% (6/6)` on 7 blocks, `100% (6/6)` on 1 block, `53% (16/34)` where 16/34 is 47%. |

## Decisions
| Decision | Why |
| --- | --- |
| A round is a section, appended, and an earlier one is never read | the Check zone re-enters after every candidate, so rounds are the norm, and the artifact held one. Rewriting the report shows a state and never a progression, which is why nobody could read what a round had fixed. A section whose criterion text repeats from round to round makes the fix readable by eye, and makes copying easy: measured on a fixture whose round 1 claims `6/6 met` with citations on files the diff never touched, 9 runs out of 9 scored `1/6 met, 1 unmet, 4 out of the diff` and left round 1 untouched. |
| The score counts over the plan's whole total, in three numbers that sum to it | two fractions with different denominators cannot be read. `100% (4/4)` on a plan covered at a third was the defect, and one denominator removes it: `1/6 met, 1 unmet, 4 out of the diff`. |
| An unmet criterion stays in `Criteria`, a finding is keyed on a `file:line` | only the functional axis owns criteria; `01-review-code` and `03-review-relevancy` emit findings keyed on a changed `file:line`. Two line types, one key each, told apart by the first token, so no sub-section is needed. Measured: before the rule, 1 run of 3 wrote the same unmet criterion in both lists. |
| `review.md` records no model name | the only use found was comparing models, a framework-development need. `architecture.md` gives observation its own layer and `aidd-telemetry` already journals the tool by hook, verifiably. Measured: the field self-declared three different spellings of one model, and a false one under another. The human name comes from `git config user.name`. |
| The diff has one home, in `report-contract.md` | the three actions each resolved it, and "a git ref range, defaulting to the default branch" gave `main` while the work targets `next`: measured, a two-dot `git diff origin/next` showed 88 files against the change's 13, so two runs on one change traced two diffs. One reference row, `<base>...HEAD` plus the working tree, replaces five copies, and `01-prepare` resolves it once for the three axes. |
| Only a finding blocks, never a criterion | a `Criteria` line carries no severity, and the plan template gives a criterion none, so "an unchecked criterion the plan words as critical" was a signal no file holds: two models split `blocked` from `changes-requested` on one diff. An unchecked criterion already forces `changes-requested`, so nothing is lost. |
| The skill is written to `skill-authoring.md` | `04-skill-generate` carries the contract every generated skill satisfies, and 05-review broke R6, R8, R13 and R18: no flow, an `| # | Action | Axis |` table, three `## Test` lists, and `## References` and `## Assets` blocks. Reshaped, the five known fixtures reproduce their values to the word, so the format cost no behaviour. |
| The template owns the forms, the action owns the rules | `SKILL.md` already makes the template the rendering source. A rule naming `{{pct}}` couples a rule file to a rendering, and the guard refuses a placeholder inside a rule. |
| The guard lives in `scripts/__tests__/` | a plugin ships no tests of its own: `hooks/` copies recursively into user projects. The pre-commit `scripts-tests` job globs `{scripts,plugins,cli/src}/**`, so editing this skill runs the guard. |
| Every run is measured with `claude --plugin-dir "$PWD/plugins/aidd-dev"` | without it the Skill tool resolves `~/.claude/plugins/cache/aidd-framework/aidd-dev/2.6.0`, byte-identical to this branch until the first edit. Measured: the flag makes the skill answer `BASE=plugins/aidd-dev/skills/05-review`. |
Loading
Loading