@delete101020/aidlc 4.0.39 → 4.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,10 @@
27
27
  1.
28
28
  2.
29
29
 
30
+ **Batches** — consecutive steps one fresh session can finish, tests passing.
31
+
32
+ **Batch 1** — steps 1–2:
33
+
30
34
  ## 4. Risks
31
35
 
32
36
  | Risk | Likelihood | What we do about it |
@@ -15,7 +15,16 @@
15
15
  | Branch | |
16
16
  | PR | |
17
17
 
18
- ## 2. What was built
18
+ ## 2. Progress
19
+
20
+ > *One row per batch. A session in a batched run reads this first; rows marked
21
+ > done are not redone.*
22
+
23
+ | Batch | Plan steps | Commits | Tests run | State |
24
+ |---|---|---|---|---|
25
+ | 1 | | | | done |
26
+
27
+ ## 3. What was built
19
28
 
20
29
  > *Per plan step: what changed, in which files.*
21
30
 
@@ -23,7 +32,7 @@
23
32
  |---|---|---|
24
33
  | 1 | | |
25
34
 
26
- ## 3. Proofs executed
35
+ ## 4. Proofs executed
27
36
 
28
37
  > *The real command and its real output, per acceptance criterion. Never a claim
29
38
  > without output.*
@@ -35,11 +44,11 @@ $ <command>
35
44
  <output>
36
45
  ```
37
46
 
38
- ## 4. Deviations from the plan
47
+ ## 5. Deviations from the plan
39
48
 
40
49
  > *Anything done differently, and why. If nothing, say so explicitly.*
41
50
 
42
- ## 5. Discovered work
51
+ ## 6. Discovered work
43
52
 
44
53
  > *Found but deliberately not done, and where it went — a plan amendment, a new
45
54
  > intent, an issue.*
@@ -48,8 +57,12 @@ $ <command>
48
57
  |---|---|
49
58
  | | |
50
59
 
51
- ## 6. Known gaps
60
+ ## 7. Known gaps
52
61
 
53
62
  > *What a reviewer should look at hardest.*
54
63
 
55
64
  -
65
+
66
+ ---
67
+
68
+ Status: done
@@ -10,9 +10,10 @@
10
10
 
11
11
  ## 1. Verdict
12
12
 
13
- > *One line. Any `blocker` row below makes the verdict a hold.*
13
+ > *One line, exactly `Verdict: ship` or `Verdict: hold` — a validator reads it.
14
+ > Any `blocker` row below makes the verdict a hold.*
14
15
 
15
- **Overall:** ship / hold
16
+ Verdict: ship / hold
16
17
 
17
18
  ## 2. Scope reviewed
18
19
 
@@ -10,9 +10,10 @@
10
10
 
11
11
  ## 1. Verdict
12
12
 
13
- > *One line. Any `fail` or `untested` row below makes the overall verdict a fail.*
13
+ > *One line, exactly `Verdict: pass` or `Verdict: fail` — a validator reads it.
14
+ > Any `fail` or `untested` row below makes the overall verdict a fail.*
14
15
 
15
- **Overall:** pass / fail
16
+ Verdict: pass / fail
16
17
 
17
18
  ## 2. Acceptance criteria
18
19
 
@@ -42,6 +42,15 @@ A table, not prose. Real paths.
42
42
  Numbered steps in dependency order, each one independently reviewable. Say what is
43
43
  true after each step that was not true before it.
44
44
 
45
+ Then group the steps into **batches**: runs of consecutive steps that one fresh
46
+ agent session can finish, with tests passing, in about half an hour. A run with
47
+ `batches: true` on `implement` gives each batch its own session, so reviewing the
48
+ plan is also reviewing where those sessions start and stop. Keep a batch to one
49
+ area of the code, and end it where the tests pass. A small plan is one batch.
50
+
51
+ **Batch 1** — steps 1–2: <what is true when it ends>
52
+ **Batch 2** — steps 3–5: <what is true when it ends>
53
+
45
54
  ### Risks
46
55
 
47
56
  | Risk | Likelihood | What we do about it |
@@ -34,8 +34,30 @@ With no run state, default all three to true. Honour these flags throughout.
34
34
  7. Write `docs/epics/$0/artifacts/implement.md`.
35
35
  8. Push and open the PR per Step 0, linking the epic and the spec.
36
36
 
37
+ ## Batches
38
+
39
+ When the run tells you this step **runs in batches**, you are one session of
40
+ several, and the next session remembers nothing but what is on disk:
41
+
42
+ - Do **one** batch — the one the run names, as the plan groups them. You may split
43
+ a batch smaller when it does not fit in your context; never do two in one
44
+ session, and never regroup the plan's batches otherwise.
45
+ - Read the **Progress** table in `implement.md` first, if there is one. Rows marked
46
+ done are done: do not redo them.
47
+ - Sent back for another revision? The first batch is the fixes the feedback asks
48
+ for. Keep the earlier revision's Progress rows and add the fix batch below them.
49
+ - Before you stop, commit, then update `implement.md`: the Progress row for this
50
+ batch (steps, commits, tests run), and the rest of the report so far.
51
+ - End `implement.md` with a line of its own: `Status: continue` when any of the
52
+ plan is left, `Status: done` when all of it is built and every proof executed.
53
+ Without that line the run stops with an error.
54
+
55
+ Not batched, you build the whole plan in this session and end with `Status: done`.
56
+
37
57
  ## implement.md Contents
38
58
 
59
+ - **Progress** — one row per batch: the plan steps it covered, its commits, the
60
+ tests it ran.
39
61
  - **Branch / PR** — branch name, PR link.
40
62
  - **What was built** — per plan step: what changed, in which files.
41
63
  - **Proofs executed** — the command and its real output, per `$0-ACnn`.
@@ -54,9 +76,11 @@ With no run state, default all three to true. Honour these flags throughout.
54
76
  - **Stay inside the plan.** Scope found mid-flight becomes a plan amendment or a new
55
77
  intent; it never lands silently in the diff.
56
78
  - **Small, ordered commits.** The reviewer reads the sequence, not just the endpoint.
79
+ - **Sent back for another revision?** Continue on the same branch and PR. Add new
80
+ commits; never amend, rebase or force-push what is already there.
57
81
  - If a plan step turns out to be wrong, stop and amend `plan.md` before continuing.
58
82
 
59
83
  ## Output
60
84
 
61
- Write `docs/epics/$0/artifacts/implement.md`, with the branch pushed and the PR open
62
- unless Step 0 says otherwise.
85
+ Write `docs/epics/$0/artifacts/implement.md`, ending in its `Status:` line, with the
86
+ branch pushed and the PR open unless Step 0 says otherwise.
@@ -77,6 +77,10 @@ broken rule, and stage 6 is where it gets fixed.
77
77
 
78
78
  ## Output
79
79
 
80
- Write `docs/epics/$0/artifacts/review.md`, ending with a one-line verdict —
81
- **ship** or **hold** — and, when it is a hold, the shortest list of changes that
82
- would turn it into a ship.
80
+ Write `docs/epics/$0/artifacts/review.md`. State the verdict once, on a line of
81
+ its own, exactly `Verdict: ship` or `Verdict: hold`. When it is a hold, list the
82
+ shortest set of changes that would turn it into a ship under a
83
+ `## Shortest path to ship` heading.
84
+
85
+ A validator reads that line. A missing, misspelled or contradictory verdict counts as a
86
+ hold, and the changes you list are what the engineer is handed next.
@@ -56,5 +56,10 @@ Every acceptance criterion gets exactly one row:
56
56
 
57
57
  ## Output
58
58
 
59
- Write `docs/epics/$0/artifacts/verify.md`, ending with a one-line overall verdict and,
60
- if it is a fail, the shortest list of things that would turn it into a pass.
59
+ Write `docs/epics/$0/artifacts/verify.md`. State the overall verdict once, on a line
60
+ of its own, exactly `Verdict: pass` or `Verdict: fail`. When it is a fail, list the
61
+ shortest set of things that would turn it into a pass under a
62
+ `## Shortest path to pass` heading.
63
+
64
+ A validator reads that line. A missing, misspelled or contradictory verdict counts as a
65
+ fail, and the changes you list are what the engineer is handed next.
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Auto-review runner that reads the verdict a verify or review step wrote.
3
+ *
4
+ * The step's artifact (`verify.md`, `review.md`) carries one line
5
+ *
6
+ * Verdict: pass | fail (verify)
7
+ * Verdict: ship | hold (review)
8
+ *
9
+ * and this validator turns it into `{ decision, reason }`: `pass` / `ship`
10
+ * let the step through, `fail` / `hold` reject it. Bold and heading markup
11
+ * around the line is fine; a comment after a dash is fine
12
+ * (`Verdict: hold — two blockers`).
13
+ *
14
+ * It fails closed. No artifact, no verdict line, a word it does not know,
15
+ * a placeholder left unfilled (`Verdict: ship / hold`) or two lines that
16
+ * disagree all reject — a review nobody can read is not a ship.
17
+ *
18
+ * On a reject, the reason is the report's "Shortest path to …" section (or
19
+ * the lines under the verdict when there is none), so the step that gets the
20
+ * work back is told what to change, not just that it failed.
21
+ *
22
+ * Contract (see packages/core/src/runs/AutoReviewer.ts):
23
+ * export default async ({ workspaceRoot, state, step, pipeline, paths }) =>
24
+ * ({ decision: 'pass' | 'reject', reason: string })
25
+ */
26
+ import { readFileSync } from 'node:fs';
27
+ import { basename } from 'node:path';
28
+
29
+ const DECISIONS = { pass: 'pass', ship: 'pass', fail: 'reject', hold: 'reject' };
30
+
31
+ // `Verdict: hold`, `**Verdict:** hold`, `## Verdict: **hold**`, `> Verdict: hold`
32
+ const LINE = /^[\s>#*_-]*verdict[\s*_]*:[\s*_`]*([a-z]+)[*_`]*(.*)$/i;
33
+ // What may follow the word: nothing, or a comment set off by a dash or a bracket.
34
+ const TAIL = /^\s*(?:$|[—–-]\s|[(.,;])/;
35
+
36
+ export function readVerdict(text, file = 'the report') {
37
+ const expected = /verify/i.test(file) ? '`Verdict: pass` or `Verdict: fail`' : '`Verdict: ship` or `Verdict: hold`';
38
+ const lines = text.split(/\r?\n/);
39
+ const found = [];
40
+ lines.forEach((line, i) => {
41
+ const m = LINE.exec(line);
42
+ if (m) { found.push({ i, word: m[1].toLowerCase(), tail: m[2] }); }
43
+ });
44
+
45
+ if (found.length === 0) {
46
+ return { decision: 'reject', reason: `${file} has no verdict line. Add one: ${expected}.` };
47
+ }
48
+ for (const f of found) {
49
+ if (!(f.word in DECISIONS) || !TAIL.test(f.tail)) {
50
+ return {
51
+ decision: 'reject',
52
+ reason: `${file} line ${f.i + 1}: unreadable verdict "${lines[f.i].trim()}". Expected ${expected}.`,
53
+ };
54
+ }
55
+ }
56
+ const decisions = new Set(found.map((f) => DECISIONS[f.word]));
57
+ if (decisions.size > 1) {
58
+ return {
59
+ decision: 'reject',
60
+ reason: `${file} gives conflicting verdicts (${found.map((f) => f.word).join(', ')}). Keep one.`,
61
+ };
62
+ }
63
+
64
+ const last = found[found.length - 1];
65
+ if (DECISIONS[last.word] === 'pass') {
66
+ return { decision: 'pass', reason: `Verdict: ${last.word}` };
67
+ }
68
+ const changes = shortestPath(lines) ?? body(lines, last.i + 1);
69
+ return {
70
+ decision: 'reject',
71
+ reason: changes
72
+ ? `Verdict: ${last.word}. Changes needed:\n${changes}`
73
+ : `Verdict: ${last.word}. ${file} lists no changes; read its findings.`,
74
+ };
75
+ }
76
+
77
+ /** Body of the "Shortest path to ship/pass" section, minus template hints. */
78
+ function shortestPath(lines) {
79
+ const start = lines.findIndex((l) => /^#+\s.*shortest path/i.test(l));
80
+ return start < 0 ? null : body(lines, start + 1);
81
+ }
82
+
83
+ /** Lines from `from` up to the next heading or rule. */
84
+ function body(lines, from) {
85
+ const out = [];
86
+ for (let i = from; i < lines.length; i++) {
87
+ const l = lines[i];
88
+ if (/^#+\s/.test(l) || /^---\s*$/.test(l)) { break; }
89
+ if (/^\s*>/.test(l)) { continue; } // template hint
90
+ if (/^\s*(\d+\.|[-*])\s*$/.test(l)) { continue; } // empty list item
91
+ out.push(l);
92
+ }
93
+ const text = out.join('\n').trim();
94
+ return text || null;
95
+ }
96
+
97
+ export default async function verdict({ paths }) {
98
+ const file = paths.produces.find((p) => p.endsWith('.md'));
99
+ if (!file) {
100
+ return { decision: 'reject', reason: 'This step declares no .md artifact to read a verdict from.' };
101
+ }
102
+ let text;
103
+ try {
104
+ text = readFileSync(file, 'utf8');
105
+ } catch (err) {
106
+ return { decision: 'reject', reason: `Cannot read ${basename(file)}: ${err.message}` };
107
+ }
108
+ return readVerdict(text, basename(file));
109
+ }
@@ -9,7 +9,9 @@
9
9
  * Wire your project's CI into `CHECKS` below: each command runs in the
10
10
  * workspace root, and a non-zero exit maps to a `reject` verdict so the step
11
11
  * does not advance. With no checks configured it passes with a note, so the
12
- * pipeline still works out of the box.
12
+ * pipeline still works out of the box — but an `autopilot: true` run (the
13
+ * `native-autopilot` recipe) refuses to start while `CHECKS` is empty, and
14
+ * `aidlc doctor` says so: nobody reads the step, so this is its only gate.
13
15
  *
14
16
  * To turn auto-review off for this step instead, set `auto_review: false` on
15
17
  * the implement step in `.aidlc/workspace.yaml`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delete101020/aidlc",
3
- "version": "4.0.39",
3
+ "version": "4.0.42",
4
4
  "description": "AIDLC Native CLI, a fork of AIDLC — drive Claude through the six-stage AI-Native SDLC Playbook: Plan → Design → Build → Test → Deploy → Maintain, with artifact gates, requirements traceability, an incident loop back to Plan, and Spec Kit support.",
5
5
  "license": "MIT",
6
6
  "repository": {