@open-agent-toolkit/cli 0.3.18 → 0.3.20

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.
Files changed (132) hide show
  1. package/README.md +2 -1
  2. package/assets/agents/oat-phase-implementer.md +104 -3
  3. package/assets/agents/oat-reviewer.md +20 -5
  4. package/assets/bundle-metadata.json +1 -1
  5. package/assets/docs/reference/cli-reference.md +15 -7
  6. package/assets/docs/reference/oat-directory-structure.md +2 -0
  7. package/assets/docs/reference/project-artifacts.md +72 -1
  8. package/assets/docs/reference/project-state-machine.md +55 -6
  9. package/assets/docs/skills/brainstorm.md +3 -1
  10. package/assets/docs/skills/index.md +13 -9
  11. package/assets/docs/workflows/advanced/autonomy.md +12 -2
  12. package/assets/docs/workflows/advanced/dispatch-ceiling.md +2 -2
  13. package/assets/docs/workflows/advanced/workflow-gates.md +25 -7
  14. package/assets/docs/workflows/approvals-and-automation.md +25 -9
  15. package/assets/docs/workflows/choose-workflow.md +24 -8
  16. package/assets/docs/workflows/ideas/index.md +1 -1
  17. package/assets/docs/workflows/ideas/lifecycle.md +3 -2
  18. package/assets/docs/workflows/projects/closeout/closeout-skills.md +83 -5
  19. package/assets/docs/workflows/projects/closeout/pr-flow.md +9 -1
  20. package/assets/docs/workflows/projects/execution/execution-skills.md +27 -2
  21. package/assets/docs/workflows/projects/execution/implementation-execution.md +15 -0
  22. package/assets/docs/workflows/projects/execution/picking-up-projects.md +20 -1
  23. package/assets/docs/workflows/projects/lifecycle.md +172 -9
  24. package/assets/docs/workflows/projects/planning/hill-checkpoints.md +18 -1
  25. package/assets/docs/workflows/projects/planning/planning-skills.md +13 -10
  26. package/assets/docs/workflows/projects/planning/starting-projects.md +138 -20
  27. package/assets/docs/workflows/projects/reviews/index.md +36 -2
  28. package/assets/docs/workflows/projects/reviews/review-flavors.md +7 -3
  29. package/assets/public-package-versions.json +4 -4
  30. package/assets/skills/oat-brainstorm/SKILL.md +58 -9
  31. package/assets/skills/oat-brainstorm/references/destinations.md +12 -4
  32. package/assets/skills/oat-docs/SKILL.md +13 -4
  33. package/assets/skills/oat-pjm-review-backlog/SKILL.md +2 -2
  34. package/assets/skills/oat-project-autonomous/SKILL.md +20 -8
  35. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +156 -122
  36. package/assets/skills/oat-project-brief/SKILL.md +592 -0
  37. package/assets/skills/oat-project-brief/references/brief-contract.md +743 -0
  38. package/assets/skills/oat-project-brief/references/docs/autonomy-contract.md +412 -0
  39. package/assets/skills/oat-project-brief/references/docs/gate-approval-record.md +93 -0
  40. package/assets/skills/oat-project-capture/SKILL.md +2 -2
  41. package/assets/skills/oat-project-complete/SKILL.md +16 -2
  42. package/assets/skills/oat-project-discover/SKILL.md +4 -2
  43. package/assets/skills/oat-project-dispatch-subagents/SKILL.md +9 -1
  44. package/assets/skills/oat-project-document/SKILL.md +17 -1
  45. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +156 -122
  46. package/assets/skills/oat-project-goal/SKILL.md +697 -0
  47. package/assets/skills/oat-project-goal/references/docs/autonomy-contract.md +412 -0
  48. package/assets/skills/oat-project-goal/references/docs/gate-approval-record.md +93 -0
  49. package/assets/skills/oat-project-implement/SKILL.md +1 -1
  50. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +107 -0
  51. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +156 -122
  52. package/assets/skills/oat-project-implement/references/docs/gate-approval-record.md +13 -0
  53. package/assets/skills/oat-project-implement/references/phase-execution.md +173 -1
  54. package/assets/skills/oat-project-implement/references/plan-and-resume.md +124 -3
  55. package/assets/skills/oat-project-import-plan/SKILL.md +5 -1
  56. package/assets/skills/oat-project-lite/SKILL.md +4 -1
  57. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +156 -122
  58. package/assets/skills/oat-project-new/SKILL.md +5 -1
  59. package/assets/skills/oat-project-next/SKILL.md +71 -14
  60. package/assets/skills/oat-project-next/references/docs/gate-approval-record.md +13 -0
  61. package/assets/skills/oat-project-plan/SKILL.md +24 -3
  62. package/assets/skills/oat-project-plan-writing/SKILL.md +8 -4
  63. package/assets/skills/oat-project-pr-final/SKILL.md +65 -3
  64. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +156 -122
  65. package/assets/skills/oat-project-pr-progress/SKILL.md +125 -4
  66. package/assets/skills/oat-project-progress/SKILL.md +63 -8
  67. package/assets/skills/oat-project-progress/references/docs/gate-approval-record.md +13 -0
  68. package/assets/skills/oat-project-promote-spec-driven/SKILL.md +2 -2
  69. package/assets/skills/oat-project-quick-start/SKILL.md +65 -1
  70. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +156 -122
  71. package/assets/skills/oat-project-quick-start/references/docs/gate-approval-record.md +13 -0
  72. package/assets/skills/oat-project-reconcile/SKILL.md +94 -3
  73. package/assets/skills/oat-project-review-provide/SKILL.md +397 -12
  74. package/assets/skills/oat-project-review-receive/SKILL.md +155 -1
  75. package/assets/skills/oat-project-revise/SKILL.md +51 -4
  76. package/assets/skills/oat-project-summary/SKILL.md +150 -2
  77. package/assets/skills/oat-wave-execute/SKILL.md +3 -2
  78. package/assets/templates/implementation-brief.md +165 -0
  79. package/assets/templates/plan-brief.md +140 -0
  80. package/assets/templates/plan.md +1 -1
  81. package/assets/templates/state.md +8 -2
  82. package/dist/commands/project/closeout-check/closeout-invariant.d.ts +119 -3
  83. package/dist/commands/project/closeout-check/closeout-invariant.d.ts.map +1 -1
  84. package/dist/commands/project/closeout-check/closeout-invariant.js +454 -2
  85. package/dist/commands/project/closeout-check/index.d.ts +21 -3
  86. package/dist/commands/project/closeout-check/index.d.ts.map +1 -1
  87. package/dist/commands/project/closeout-check/index.js +190 -4
  88. package/dist/commands/project/complete-state/index.d.ts +2 -1
  89. package/dist/commands/project/complete-state/index.d.ts.map +1 -1
  90. package/dist/commands/project/complete-state/index.js +7 -1
  91. package/dist/commands/project/delivery/check.d.ts +66 -0
  92. package/dist/commands/project/delivery/check.d.ts.map +1 -0
  93. package/dist/commands/project/delivery/check.js +232 -0
  94. package/dist/commands/project/delivery/evidence.d.ts +171 -0
  95. package/dist/commands/project/delivery/evidence.d.ts.map +1 -0
  96. package/dist/commands/project/delivery/evidence.js +902 -0
  97. package/dist/commands/project/delivery/index.d.ts +7 -0
  98. package/dist/commands/project/delivery/index.d.ts.map +1 -0
  99. package/dist/commands/project/delivery/index.js +13 -0
  100. package/dist/commands/project/delivery/refresh.d.ts +110 -0
  101. package/dist/commands/project/delivery/refresh.d.ts.map +1 -0
  102. package/dist/commands/project/delivery/refresh.js +441 -0
  103. package/dist/commands/project/index.d.ts.map +1 -1
  104. package/dist/commands/project/index.js +2 -0
  105. package/dist/commands/project/log/append.d.ts +6 -0
  106. package/dist/commands/project/log/append.d.ts.map +1 -1
  107. package/dist/commands/project/log/append.js +6 -1
  108. package/dist/commands/project/new/scaffold.d.ts +1 -1
  109. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  110. package/dist/commands/project/new/scaffold.js +81 -7
  111. package/dist/commands/project/promote/promote.d.ts +46 -1
  112. package/dist/commands/project/promote/promote.d.ts.map +1 -1
  113. package/dist/commands/project/promote/promote.js +646 -5
  114. package/dist/commands/project/validate-plan/frontmatter.d.ts +12 -0
  115. package/dist/commands/project/validate-plan/frontmatter.d.ts.map +1 -0
  116. package/dist/commands/project/validate-plan/frontmatter.js +27 -0
  117. package/dist/commands/project/validate-plan/index.d.ts.map +1 -1
  118. package/dist/commands/project/validate-plan/index.js +62 -18
  119. package/dist/commands/project/validate-plan/profiles.d.ts +69 -0
  120. package/dist/commands/project/validate-plan/profiles.d.ts.map +1 -0
  121. package/dist/commands/project/validate-plan/profiles.js +420 -0
  122. package/dist/commands/project/validate-plan/validate-plan.d.ts +3 -19
  123. package/dist/commands/project/validate-plan/validate-plan.d.ts.map +1 -1
  124. package/dist/commands/project/validate-plan/validate-plan.js +5 -82
  125. package/dist/commands/shared/frontmatter.d.ts +1 -1
  126. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  127. package/dist/commands/shared/frontmatter.js +2 -0
  128. package/dist/commands/state/generate.d.ts.map +1 -1
  129. package/dist/commands/state/generate.js +82 -2
  130. package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -1
  131. package/dist/commands/tools/shared/pack-manifest.js +4 -0
  132. package/package.json +2 -2
@@ -5,7 +5,7 @@ disable-model-invocation: false
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Glob, Grep, Write, Edit, Bash(git:*), Bash(oat:*), Bash(pnpm:*), Bash(mkdir:*), Bash(date:*), Bash(realpath:*), Bash(awk:*), AskUserQuestion
7
7
  metadata:
8
- version: 1.5.13
8
+ version: 1.5.15
9
9
  ---
10
10
 
11
11
  # Request Review
@@ -180,6 +180,20 @@ Inference rules (first match wins):
180
180
  | `implement` | `in_progress` | `code` with current phase scope (derive from `implementation.md` current task) |
181
181
  | `implement` | `complete` | `code final` |
182
182
 
183
+ When `WORKFLOW_MODE` is `brief`, the `implement` / `in_progress` row derives
184
+ the phase from `oat_current_task_id` by the brief pointer rule
185
+ (`oat-project-brief/references/brief-contract.md` section 8): a task ID
186
+ resolves to its phase, a phase ID to itself, and `null`, an unknown ID, or an
187
+ accepted unit to the first incomplete unit in document order. A brief code
188
+ scope is always a phase-unit (`pNN`, `p-revN`, `pNN-pMM`, or `final`), never an
189
+ execution record.
190
+
191
+ When `WORKFLOW_MODE` is `goal`, the same pointer rule applies within the active
192
+ milestone's ordered phase set, and an integrated milestone or delivery review
193
+ takes its scope from the router's `code` context (`code mNN: pAA, pBB` or
194
+ `code mNN/dNN: …`) or from a pending `oat_goal_recovery` record, never from the
195
+ phase table (Step 3.0g).
196
+
183
197
  If inference produces a result, propose it and proceed unless the user overrides:
184
198
 
185
199
  ```
@@ -193,7 +207,7 @@ If the user confirms (or just presses enter), use the inferred type and scope. I
193
207
 
194
208
  - Ask: "What type of review? (code / artifact)"
195
209
  - Ask: "What scope?"
196
- - For code: `pNN-tNN` task / `pNN` phase / `pNN-pMM` contiguous phase range / `final` / `base_sha=SHA` / `SHA..HEAD` range
210
+ - For code: `pNN-tNN` task / `pNN` phase / `pNN-pMM` contiguous phase range / `final` / `base_sha=SHA` / `SHA..HEAD` range (brief: `pNN` or `p-revN` phase / `pNN-pMM` / `final` / `base_sha=SHA` / `SHA..HEAD`)
197
211
  - For artifact: `discovery` / `spec` / `design` (and optionally `plan`)
198
212
 
199
213
  ### Step 1.5: Resolve Target Branch and Working Directory
@@ -312,6 +326,8 @@ WORKFLOW_MODE=$(oat project status --project-path "$PROJECT_PATH" --field projec
312
326
  - `quick`: `discovery.md`, `plan.md` (`spec.md`/`design.md` optional if present)
313
327
  - `import`: `plan.md` (`references/imported-plan.md` recommended, `spec.md`/`design.md` optional)
314
328
  - `lite`: `plan.md`, `implementation.md` (`discovery.md`/`spec.md`/`design.md` are absent by design)
329
+ - `brief`: `plan.md` (the Project Brief) and `implementation.md` (the per-phase journal, which carries the `**Base:**`/`**Head:**` anchors); `discovery.md`, `spec.md`, and `design.md` are absent by design, and research under `references/` is optional
330
+ - `goal`: the same as `brief`, plus the `## Milestones` table in `plan.md` and the goal state in `state.md` (milestone, recovery record, milestone gate carriers, delivery registry)
315
331
 
316
332
  **Required for artifact review:**
317
333
 
@@ -324,6 +340,8 @@ WORKFLOW_MODE=$(oat project status --project-path "$PROJECT_PATH" --field projec
324
340
  - reviewing `plan` in `spec-driven` mode requires `spec.md` + `design.md`
325
341
  - reviewing `plan` in `quick/import` mode may use `discovery.md` and/or `references/imported-plan.md` instead; lite uses the separate rule below
326
342
  - reviewing `plan` in `lite` mode requires only `plan.md`; its Summary, Decisions, Assumptions, Out of Scope, and Validation Criteria sections are the complete upstream contract
343
+ - reviewing `plan` in `brief` mode requires only `plan.md`; the brief and `oat-project-brief/references/brief-contract.md` are the complete upstream contract. `discovery`, `spec`, and `design` are not reviewable artifacts in brief mode
344
+ - reviewing `plan` in `goal` mode follows the `brief` rule; for an amendment the request names the milestone under review and its ordered phase set
327
345
 
328
346
  **If missing:** Report missing required artifacts for the current mode and stop if requirements are not met.
329
347
 
@@ -337,6 +355,314 @@ If review type is `artifact`:
337
355
 
338
356
  If review type is `code`, use the scope resolution below.
339
357
 
358
+ **Step 3.0: Brief-Family Anchor Resolution (`brief` and goal phase-unit reviews)**
359
+
360
+ When `WORKFLOW_MODE` is `brief` — or `goal` for a phase-unit review routed
361
+ here by Step 3.0g — and the review type is `code`, the review range comes from
362
+ the phase anchors recorded in the journal, not from commit-message inference.
363
+ `oat-project-brief/references/brief-contract.md` section 10 is authoritative
364
+ where this step and the contract differ. This step is inert for every other
365
+ workflow mode and for goal integrated reviews (Step 3.0g).
366
+
367
+ Resolution order for brief code reviews:
368
+
369
+ 1. **Explicit user input** — unchanged. A supplied `base_sha=<sha>` or
370
+ `<sha1>..<sha2>` range skips this step; record
371
+ `oat_review_scope_source: explicit`, the range base as
372
+ `oat_review_base_sha`, and as `oat_review_phase_ids` the phases whose
373
+ `(pNN-` or `(prevN-` commit labels appear in the range (labels only),
374
+ listing a `prevN` label as its phase ID `p-revN`.
375
+ 2. **Guarded re-review narrowing** (Step 3a) — unchanged in its guards, with
376
+ the brief inputs described after the script below.
377
+ 3. **Anchor resolution** for a nominal `pNN`, `p-revN`, `pNN-pMM`, or `final`
378
+ token, by the script below.
379
+ 4. **Missing anchors** widen to the entire merge-base range.
380
+ 5. **Invalid or contradictory anchors** stop and route to
381
+ `oat-project-reconcile`; never narrow silently.
382
+ 6. Otherwise the explicit-range / merge-base fallback in the priority order
383
+ below (`oat_review_scope_source: merge-base` when the user selects
384
+ `merge-base..HEAD`).
385
+
386
+ A brief code scope names phase-units only. An execution-record token
387
+ (`pNN-tNN`) is not an anchored scope: offer its phase (`pNN`) or an explicit
388
+ `<sha>^..<sha>` range built from the record's `**Commit:**` line instead.
389
+
390
+ Run the resolver in bash from the reviewed checkout (after Step 1.5) with
391
+ `PROJECT_PATH` and `SCOPE_TOKEN` set. It never edits any file. It sets
392
+ `ANCHOR_VERDICT` (`accepted | fallback | reconcile | invalid-scope`),
393
+ `ANCHOR_REASON`, `PHASE_IDS` (document order), `SCOPE_RANGE`,
394
+ `REVIEW_BASE_SHA`, `AGGREGATE_HEAD`, `SCOPE_SOURCE`, `FALLBACK_REASON`, and
395
+ `INTEGRATION_COMMITS`:
396
+
397
+ ````bash
398
+ brief_phase_ids() {
399
+ # Phase IDs of the brief in document order; fenced code is excluded.
400
+ awk '
401
+ /^[ \t]*(```|~~~)/ { fence = !fence; next }
402
+ fence { next }
403
+ /^## Phase (p[0-9]+|p-rev[0-9]+): / { id = $3; sub(/:$/, "", id); print id }
404
+ ' "$PROJECT_PATH/plan.md"
405
+ }
406
+
407
+ brief_marker() {
408
+ # brief_marker PHASE_ID Status|Base|Head: the first exact marker line under
409
+ # the journal's phase heading. Ownership ends at the next line starting with
410
+ # "#"; fenced code is excluded; a Base or Head value that is not a full SHA,
411
+ # or a Status value outside the phase statuses, is not a marker.
412
+ awk -v id="$1" -v key="$2" '
413
+ /^[ \t]*(```|~~~)/ { fence = !fence; next }
414
+ fence { next }
415
+ /^#/ { owner = (index($0, "## Phase " id ": ") == 1); next }
416
+ !owner || found { next }
417
+ index($0, "**" key ":** ") == 1 {
418
+ v = substr($0, length("**" key ":** ") + 1); sub(/[ \t]+$/, "", v)
419
+ if (key == "Status" && v !~ /^(pending|in_progress|completed|failed|extracted)$/) next
420
+ if (key != "Status" && !((length(v) == 40 || length(v) == 64) && v ~ /^[0-9a-f]+$/)) next
421
+ print v; found = 1
422
+ }
423
+ ' "$PROJECT_PATH/implementation.md"
424
+ }
425
+
426
+ brief_group() {
427
+ # brief_group PHASE_ID: 1-based index of the declared parallel group in the
428
+ # brief's single-line oat_plan_parallel_groups that contains the phase.
429
+ awk -v id="$1" '
430
+ NR == 1 && /^---[ \t]*$/ { fm = 1; next }
431
+ fm && /^---[ \t]*$/ { exit }
432
+ fm && /^oat_plan_parallel_groups:/ {
433
+ line = $0; sub(/^oat_plan_parallel_groups:[ \t]*/, "", line); sub(/[ \t]+#.*$/, "", line)
434
+ n = split(line, groups, /\][ \t]*,[ \t]*\[/)
435
+ for (i = 1; i <= n; i++) {
436
+ g = groups[i]; gsub(/[^A-Za-z0-9,-]/, "", g)
437
+ m = split(g, members, ",")
438
+ for (j = 1; j <= m; j++) if (members[j] == id) { print i; exit }
439
+ }
440
+ }
441
+ ' "$PROJECT_PATH/plan.md"
442
+ }
443
+
444
+ brief_anchor_reject() { ANCHOR_VERDICT=reconcile; ANCHOR_REASON="$1"; }
445
+
446
+ brief_resolve_anchors() {
447
+ ANCHOR_VERDICT=""; ANCHOR_REASON=""; SCOPE_SOURCE=""; FALLBACK_REASON=""
448
+ SCOPE_RANGE=""; REVIEW_BASE_SHA=""; AGGREGATE_HEAD=""; INTEGRATION_COMMITS=""
449
+ PHASE_IDS=()
450
+ local all=() id first last i start=-1 end=-1 key sha missing=0
451
+ local base head group prev_head="" prev_group="" fork=""
452
+ while IFS= read -r id; do all+=("$id"); done < <(brief_phase_ids)
453
+
454
+ # 1. Expand the requested scope to phase IDs in document order.
455
+ if [ "$SCOPE_TOKEN" = final ]; then
456
+ for id in "${all[@]}"; do
457
+ [ "$(brief_marker "$id" Status)" = completed ] && PHASE_IDS+=("$id")
458
+ done
459
+ else
460
+ first=${SCOPE_TOKEN%%-p*}; last=${SCOPE_TOKEN#"$first"}; last=${last#-}; last=${last:-$first}
461
+ for i in "${!all[@]}"; do
462
+ [ "${all[$i]}" = "$first" ] && start=$i
463
+ [ "${all[$i]}" = "$last" ] && end=$i
464
+ done
465
+ if [ "$start" -lt 0 ] || [ "$end" -lt "$start" ]; then
466
+ ANCHOR_VERDICT=invalid-scope; ANCHOR_REASON="$SCOPE_TOKEN is not a document-order phase run"; return 0
467
+ fi
468
+ for ((i = start; i <= end; i++)); do
469
+ [ "$(brief_marker "${all[$i]}" Status)" = extracted ] || PHASE_IDS+=("${all[$i]}")
470
+ done
471
+ fi
472
+ if [ "${#PHASE_IDS[@]}" -eq 0 ]; then
473
+ ANCHOR_VERDICT=invalid-scope; ANCHOR_REASON="no reviewable phase-unit in $SCOPE_TOKEN"; return 0
474
+ fi
475
+
476
+ # 2. Existence: every recorded anchor names a commit.
477
+ for id in "${PHASE_IDS[@]}"; do
478
+ for key in Base Head; do
479
+ sha=$(brief_marker "$id" "$key")
480
+ if [ -z "$sha" ]; then missing=1; continue; fi
481
+ git cat-file -e "$sha^{commit}" 2>/dev/null || { brief_anchor_reject "existence: $id $key $sha is not a commit"; return 0; }
482
+ done
483
+ done
484
+
485
+ # 3. Missing anchors widen to the whole merge-base range; (pNN- commit
486
+ # matches only label commits and never narrow it.
487
+ if [ "$missing" = 1 ]; then
488
+ MERGE_BASE=$(git merge-base origin/main HEAD 2>/dev/null || git merge-base main HEAD 2>/dev/null)
489
+ REVIEW_BASE_SHA=$MERGE_BASE
490
+ if [ -z "$REVIEW_BASE_SHA" ]; then
491
+ ANCHOR_VERDICT=invalid-scope; ANCHOR_REASON="missing anchors and no merge base"; return 0
492
+ fi
493
+ AGGREGATE_HEAD=$(git rev-parse HEAD)
494
+ SCOPE_RANGE="$REVIEW_BASE_SHA..$AGGREGATE_HEAD"
495
+ INTEGRATION_COMMITS=$(git rev-list --merges "$SCOPE_RANGE")
496
+ ANCHOR_VERDICT=fallback; SCOPE_SOURCE=merge-base-range; FALLBACK_REASON=missing-anchors
497
+ return 0
498
+ fi
499
+
500
+ # 4. Per-phase ancestry, then sequential or parallel continuity.
501
+ for id in "${PHASE_IDS[@]}"; do
502
+ base=$(brief_marker "$id" Base); head=$(brief_marker "$id" Head); group=$(brief_group "$id")
503
+ git merge-base --is-ancestor "$base" "$head" 2>/dev/null || { brief_anchor_reject "ancestry: $id base is not an ancestor of its head"; return 0; }
504
+ if [ -n "$group" ] && [ -n "$prev_head" ] && [ "$group" = "$prev_group" ]; then
505
+ [ "$base" = "$fork" ] || { brief_anchor_reject "parallel continuity: $id base is not the group fork $fork"; return 0; }
506
+ git merge-base --is-ancestor "$prev_head" "$head" 2>/dev/null || { brief_anchor_reject "parallel continuity: $id head does not follow the previous member's integration head"; return 0; }
507
+ else
508
+ [ -z "$prev_head" ] || git merge-base --is-ancestor "$prev_head" "$base" 2>/dev/null || { brief_anchor_reject "sequential continuity: $id base does not equal or descend from the previous head"; return 0; }
509
+ fork=$base
510
+ fi
511
+ prev_head=$head; prev_group=$group
512
+ done
513
+ AGGREGATE_HEAD=$prev_head
514
+
515
+ # 5. Aggregate head: the last selected head contains every selected head and
516
+ # is on the reviewed branch.
517
+ for id in "${PHASE_IDS[@]}"; do
518
+ git merge-base --is-ancestor "$(brief_marker "$id" Head)" "$AGGREGATE_HEAD" 2>/dev/null || { brief_anchor_reject "aggregate head: $id head is not contained in $AGGREGATE_HEAD"; return 0; }
519
+ done
520
+ git merge-base --is-ancestor "$AGGREGATE_HEAD" HEAD 2>/dev/null || { brief_anchor_reject "aggregate head: $AGGREGATE_HEAD is not on the reviewed branch"; return 0; }
521
+
522
+ REVIEW_BASE_SHA=$(brief_marker "${PHASE_IDS[0]}" Base)
523
+ SCOPE_RANGE="$REVIEW_BASE_SHA..$AGGREGATE_HEAD"
524
+ INTEGRATION_COMMITS=$(git rev-list --merges "$SCOPE_RANGE")
525
+ ANCHOR_VERDICT=accepted; SCOPE_SOURCE=anchors
526
+ }
527
+
528
+ brief_resolve_anchors
529
+ ````
530
+
531
+ Act on the verdict:
532
+
533
+ - `accepted`: the range is `SCOPE_RANGE` (first selected base through the
534
+ aggregate head). Coverage holds by construction: the aggregate head contains
535
+ every selected phase head, and every selected base sits inside the range or
536
+ at its start. Bookkeeping commits between sequential phases (a next base
537
+ that descends from the previous head) are inside the range.
538
+ - `fallback`: the range is the entire merge-base range `MERGE_BASE..HEAD`.
539
+ On a `manual` invocation, show it and ask the user to confirm it; `auto` and
540
+ `gate` invocations print it and continue. Commit
541
+ matches by `(pNN-` or `(prevN-` (phase `p-revN`) label which commits belong
542
+ to which phase and never
543
+ narrow the range. Record `oat_review_scope_source: merge-base-range` and
544
+ `oat_review_fallback_reason: missing-anchors`.
545
+ - `reconcile`: stop. Print
546
+ `Brief anchors are invalid or contradictory ({ANCHOR_REASON}); run oat-project-reconcile before reviewing {SCOPE_TOKEN}.`
547
+ and write no review artifact. Never fall back to a narrower range, to the
548
+ commit grep, or to `merge-base..HEAD`.
549
+ - `invalid-scope`: the token is not a document-order phase run (for example
550
+ `pMM` precedes `pNN`, an unknown ID, or `final` with no accepted phase) or no
551
+ merge base exists for the fallback. Report `ANCHOR_REASON` and ask for a
552
+ valid scope or an explicit range; for a `gate` invocation, stop.
553
+
554
+ Scope expansion: `pNN` and `p-revN` select one phase; `pNN-pMM` selects the
555
+ contiguous document-order run, excluding extracted phases, and is invalid when
556
+ `pMM` precedes `pNN`; `final` selects every accepted (`**Status:** completed`)
557
+ non-extracted phase, revision phases included. Document order, not numeric
558
+ order, governs.
559
+
560
+ **Parallel continuity.** Phases in one declared group share a fork base (each
561
+ `**Base:**` is the group's fork commit, `EXPECTED_HEAD` at group start) and
562
+ each `**Head:**` is that phase's integration merge commit on the project
563
+ branch, written at fan-in; the group's aggregate head is the last integration
564
+ merge. Integration and conflict-resolution commits are inside the range: pass
565
+ `INTEGRATION_COMMITS` (the merge commits in the range) plus any
566
+ conflict-resolution commits the fan-in record names to the reviewer as
567
+ integration commits and record them as `oat_review_integration_commits`. A
568
+ group member's per-phase review runs before fan-in, when the member has no
569
+ journal anchors yet: `oat-project-implement` supplies the range
570
+ `EXPECTED_HEAD..<worktree head from the phase report>`, reviewed in that
571
+ member's worktree, with `oat_review_requested_scope: pNN`,
572
+ `oat_review_phase_ids: [pNN]`, `oat_review_base_sha: EXPECTED_HEAD`, and
573
+ `oat_review_scope_source: anchors`. When this skill runs that review, verify
574
+ `git merge-base --is-ancestor "$EXPECTED_HEAD" <worktree head>` first (a
575
+ failure routes to `oat-project-reconcile`), use the supplied range without
576
+ running the resolver, and never record it as `explicit`. The fan-in
577
+ `**Base:**`/`**Head:**` written afterwards govern `pNN-pMM` and `final` scopes.
578
+ The resolver verifies only the shared fork base and that member heads advance
579
+ in document order; it does not enforce that a member head is a merge commit,
580
+ because Parallel Group Execution step 7 may integrate a member by cherry-pick.
581
+
582
+ A single group member reviewed after fan-in (`pNN` naming one member) resolves
583
+ to `fork..<that member's integration head>`. For every member after the first
584
+ in document order, that range also carries the earlier siblings' integration
585
+ commits and their phase commits. Prefer the group's `pNN-pMM` run, or the
586
+ pre-fan-in member range above, for that case. When a single member is
587
+ requested, list its sibling phases in the Review Scope as context so the
588
+ reviewer can attribute the sibling commits inside the range.
589
+
590
+ **Late-fix rule.** A review-fix commit may advance a phase's `**Head:**`, base
591
+ unchanged, only while no later phase in document order has a `**Base:**`. Once
592
+ a later phase has started, the correction is an appended revision phase
593
+ `## Phase p-revN:` with its own anchors and `**Corrects:** pNN`; the corrected
594
+ phase keeps its original anchors. Revision phases resolve as ordinary later
595
+ phases, so aggregate containment and sequential continuity hold for the whole
596
+ history: a head advanced after a later phase took its base makes that later
597
+ base precede the previous head, fails sequential continuity, and routes to
598
+ reconcile. A `p-revN` review re-evaluates the corrected phase's findings: name
599
+ the `**Corrects:**` phase in the Review Scope so `oat-project-review-receive`
600
+ can update that phase's review row.
601
+
602
+ **Brief inputs to Step 3a.** Run this resolver before Step 3a's candidate
603
+ lookup. A `reconcile` or `invalid-scope` verdict stops before any narrowing.
604
+ After `accepted` or `fallback`, Step 3a sets `REVIEW_HEAD` to `AGGREGATE_HEAD`
605
+ (the anchored head, not the current `HEAD`) and keeps its guards unchanged.
606
+ When it narrows, record `oat_review_scope_source: narrowed`,
607
+ `oat_review_narrowed_from: {SCOPE_RANGE before narrowing}`,
608
+ `oat_review_base_sha: {PRIOR_REVIEWED_HEAD}`, and keep `PHASE_IDS` from the
609
+ resolver.
610
+
611
+ **Brief artifact record.** Every brief code review carries, beside
612
+ `oat_review_head_sha` (the aggregate head of the reviewed range):
613
+ `oat_review_requested_scope` (the scope token as requested),
614
+ `oat_review_phase_ids` (ordered `PHASE_IDS`), `oat_review_base_sha`,
615
+ `oat_review_scope_source` (`anchors | merge-base-range | explicit | merge-base | narrowed`),
616
+ and, when they apply, `oat_review_fallback_reason`,
617
+ `oat_review_integration_commits`, and `oat_review_narrowed_from`. Step 5 passes
618
+ them to the reviewer and Step 8 writes them; `oat-project-review-receive`
619
+ preserves them.
620
+
621
+ **Step 3.0g: Goal Explicit Review Scope (`goal` only)**
622
+
623
+ When `WORKFLOW_MODE` is `goal`, a phase-unit code review (`pNN`, `p-revN`)
624
+ runs Step 3.0 unchanged. An integrated milestone or delivery review follows
625
+ `oat-project-brief/references/brief-contract.md` section 12.6 (explicit goal
626
+ review scopes) and section 12.5 (the goal exception to the shared ladder):
627
+
628
+ 1. **Explicit identity only.** Accept only a milestone or delivery identity
629
+ with its ordered phase set: the router's `code mNN: pAA, pBB` or
630
+ `code mNN/dNN: …` context, a pending `oat_goal_recovery` record
631
+ (`milestone`, `delivery_id`, `phase_ids`), or the same form typed by the
632
+ user. Refuse a `pNN-pMM` or `final` token for an integrated goal review, and
633
+ never expand membership first to last or derive it from commit labels.
634
+ 2. **Validate the set.** It must equal the milestone's ordered phase set from
635
+ the shared Milestones reader (`oat project status --json`), the recovery
636
+ record's `phase_ids`, or a registered delivery's frozen scope with any
637
+ recorded correction phases. A mismatch stops with the two sets; membership
638
+ errors route to `oat-project-goal`.
639
+ 3. **Exit gate first.** Before dispatch, run
640
+ `oat project delivery check --project "$PROJECT_PATH" --subject <mNN|dNN> --json`
641
+ and read only its `exit` result (`source: milestone-carrier`); the command
642
+ exits 1 here because no passed integrated review exists yet. A missing,
643
+ blocked or stale exit carrier stops and routes to `oat-project-implement`
644
+ scoped closeout: the milestone exit gate precedes the integrated review.
645
+ 4. **Range.** Resolve each set member's anchors with the Step 3.0 per-phase
646
+ checks (existence, ancestry). The aggregate head is the last set member's
647
+ head in document order and must contain every member head; the range is the
648
+ first member's base through the aggregate head. Delivery evidence uses
649
+ integration heads: a parallel group member's pre-fan-in review is member
650
+ evidence only. Missing anchors widen to the merge-base range exactly as in
651
+ Step 3.0; invalid anchors route to `oat-project-reconcile`.
652
+ 5. **Disclose, never relabel.** The range may be wider than the set. Name every
653
+ phase whose anchored commits fall inside the range but outside the set
654
+ (for example `p03` of m02 between `p02` and `p-rev1`) under an
655
+ `Intervening changes:` line in the Review Scope, so the reviewer judges only
656
+ the set and treats the rest as context.
657
+ 6. **Record.** Write the brief artifact record with
658
+ `oat_review_requested_scope: mNN` (or `mNN/dNN`) and `oat_review_phase_ids`
659
+ equal to the exact ordered set; the semantic set survives in provenance even
660
+ when the Git range is wider.
661
+ 7. **No narrowing below the set.** Step 3a may narrow a re-review's Git range,
662
+ but a narrowed or revision-only goal review is never recorded as the full
663
+ integrated review without the prior review it builds on; its
664
+ `oat_review_phase_ids` stays the full set.
665
+
340
666
  **Step 3a: Detect Re-Review Context**
341
667
 
342
668
  After parsing the requested scope, distinguish an explicit range override from a
@@ -349,7 +675,9 @@ For every code review, detect re-review context independently from deciding
349
675
  whether to narrow:
350
676
 
351
677
  1. Set `REVIEW_HEAD` to the full commit from
352
- `git rev-parse HEAD^{commit}`. Resolve the current lineage:
678
+ `git rev-parse HEAD^{commit}` (in brief modes, `AGGREGATE_HEAD` from Step
679
+ 3.0 when its verdict is `accepted` or `fallback`). Resolve the current
680
+ lineage:
353
681
  - `manual` and `auto` invocations use lifecycle lineage.
354
682
  - A `gate` invocation uses gate lineage qualified by its exact
355
683
  `oat_gate_target`.
@@ -422,16 +750,19 @@ narrowed range):**
422
750
  - This is the canonical scope format for checkpoint auto-reviews that need to cover multiple previously unpassed phases in one review.
423
751
  - When a phase-range token is used, treat it as a range review for artifact naming/storage, but preserve the exact `oat_review_scope` value (for example `p02-p03`) in frontmatter and plan review rows.
424
752
 
425
- 2. **Automatic phase detection (if invoked at phase boundary):**
753
+ In brief modes a nominal `pNN`, `p-revN`, `pNN-pMM`, or `final` token
754
+ resolves through Step 3.0's anchors, never through rule 2 below.
755
+
756
+ 2. **Automatic phase detection (if invoked at phase boundary; not used in brief modes):**
426
757
  - Derive current phase from plan.md + implementation.md
427
758
  - Use commit convention grep to find commits:
428
759
 
429
760
  ```bash
430
761
  # Task commits: grep for (pNN-tNN)
431
- git log --oneline --grep="\(p${PHASE}-t" HEAD~50..HEAD
762
+ git log --oneline --fixed-strings --grep="(p${PHASE}-t" --max-count=50
432
763
 
433
764
  # Phase commits: grep for (pNN-
434
- git log --oneline --grep="\(p${PHASE}-" HEAD~50..HEAD
765
+ git log --oneline --fixed-strings --grep="(p${PHASE}-" --max-count=50
435
766
  ```
436
767
 
437
768
  - For contiguous phase-range scopes (`pNN-pMM`), aggregate commit matches for each phase in the inclusive range:
@@ -439,7 +770,7 @@ narrowed range):**
439
770
  ```bash
440
771
  for PHASE_NUM in $(seq "$START_PHASE_NUM" "$END_PHASE_NUM"); do
441
772
  PHASE_ID=$(printf "p%02d" "$PHASE_NUM")
442
- git log --oneline --grep="\\(${PHASE_ID}-" HEAD~50..HEAD
773
+ git log --oneline --fixed-strings --grep="(${PHASE_ID}-" --max-count=50
443
774
  done
444
775
  ```
445
776
 
@@ -449,6 +780,11 @@ narrowed range):**
449
780
  - Provide `<sha1>..<sha2>` range
450
781
  - Confirm "review merge-base..HEAD" (all changes on branch)
451
782
 
783
+ In brief modes this fallback applies only when Step 3.0 did not resolve a
784
+ range (for example no nominal token). A user-selected `merge-base..HEAD`
785
+ records `oat_review_scope_source: merge-base`; a user-supplied base or
786
+ range records `explicit`.
787
+
452
788
  **Merge-base approach:**
453
789
 
454
790
  ```bash
@@ -509,7 +845,9 @@ case "$SCOPE_TOKEN" in
509
845
  FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md" "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md")
510
846
  elif [[ "$WORKFLOW_MODE" == "quick" ]]; then
511
847
  FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md" "$PROJECT_PATH/discovery.md")
512
- elif [[ "$WORKFLOW_MODE" == "lite" ]]; then
848
+ elif [[ "$WORKFLOW_MODE" == "lite" || "$WORKFLOW_MODE" == "brief" || "$WORKFLOW_MODE" == "goal" ]]; then
849
+ # brief and goal: the reviewer also receives oat-project-brief/references/brief-contract.md
850
+ # as the contract reference (Step 5), not as a file in scope.
513
851
  FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md")
514
852
  else
515
853
  FILES_CHANGED=$(printf "%s\n" "$PROJECT_PATH/plan.md" "$PROJECT_PATH/references/imported-plan.md")
@@ -594,14 +932,14 @@ Build the "Review Scope" metadata for the reviewer:
594
932
 
595
933
  **Artifact Paths:**
596
934
 
597
- - Spec: {PROJECT_PATH}/spec.md (required in spec-driven mode; optional in quick/import/lite)
598
- - Design: {PROJECT_PATH}/design.md (required in spec-driven mode; optional in quick/import/lite)
935
+ - Spec: {PROJECT_PATH}/spec.md (required in spec-driven mode; optional in quick/import/lite; absent in brief and goal)
936
+ - Design: {PROJECT_PATH}/design.md (required in spec-driven mode; optional in quick/import/lite; absent in brief and goal)
599
937
  - Plan: {PROJECT_PATH}/plan.md
600
938
  - Implementation: {PROJECT_PATH}/implementation.md
601
939
  - Discovery: {PROJECT_PATH}/discovery.md
602
940
  - Imported Plan Reference: {PROJECT_PATH}/references/imported-plan.md (optional; import mode)
603
941
 
604
- **Tasks in Scope (code review only):** {task IDs from plan.md matching scope}
942
+ **Tasks in Scope (code review only):** {task IDs from plan.md matching scope; in brief modes, the execution-record IDs under the phases in scope in implementation.md, which label commits and never narrow the range}
605
943
 
606
944
  **Files Changed ({FILE_COUNT}):**
607
945
  {FILE_LIST}
@@ -658,6 +996,33 @@ and code-final Review Scope explicitly as:
658
996
  - Plan: `{PROJECT_PATH}/plan.md` (Summary, Decisions, Assumptions, Out of Scope, and Validation Criteria are the requirements contract)
659
997
  - Implementation: `{PROJECT_PATH}/implementation.md`
660
998
 
999
+ For `WORKFLOW_MODE=brief`, render the artifact-path portion of every
1000
+ artifact-plan and code Review Scope explicitly as:
1001
+
1002
+ - Discovery: not required (absent by design)
1003
+ - Spec: not required (absent by design)
1004
+ - Design: not required (absent by design; the brief's optional `### Design` subsection and `references/` notes are part of the brief)
1005
+ - Import reference: not required
1006
+ - Plan: `{PROJECT_PATH}/plan.md` (the Project Brief: Goal, Outcomes, Approach, Constraints and Out of Scope, Decisions, and the in-scope phases' `**Intent:**` and `**Exit evidence:**` are the requirements contract)
1007
+ - Implementation: `{PROJECT_PATH}/implementation.md` (the per-phase journal: anchors, execution records, verification evidence)
1008
+ - Brief contract: `oat-project-brief/references/brief-contract.md` (goal: sections 1–11 and section 12)
1009
+
1010
+ and append the brief anchor record to every brief code Review Scope:
1011
+
1012
+ ```markdown
1013
+ **Brief Anchor Record (brief code reviews only):**
1014
+
1015
+ - oat_review_requested_scope: {SCOPE_TOKEN as requested}
1016
+ - oat_review_phase_ids: [{PHASE_IDS in document order}]
1017
+ - oat_review_base_sha: {REVIEW_BASE_SHA, full SHA}
1018
+ - oat_review_head_sha: {AGGREGATE_HEAD, full SHA}
1019
+ - oat_review_scope_source: {anchors|merge-base-range|explicit|merge-base|narrowed}
1020
+ - oat_review_fallback_reason: {missing-anchors, or omit}
1021
+ - oat_review_integration_commits: [{INTEGRATION_COMMITS plus named conflict-resolution commits, or omit}]
1022
+ - oat_review_narrowed_from: {range before narrowing, or omit}
1023
+ - Corrects: {pNN named by a p-revN phase's `**Corrects:**` line, or omit}
1024
+ ```
1025
+
661
1026
  Always pass the resolved workflow mode. Never omit it and let the reviewer fall
662
1027
  back to its spec-driven default.
663
1028
 
@@ -987,7 +1352,7 @@ If running inline (Tier 3), execute the review and write artifact.
987
1352
  **Review checklist (from oat-reviewer):**
988
1353
 
989
1354
  1. Verify scope (don't review out-of-scope changes)
990
- 2. If code review: verify alignment to available requirements sources (`spec`/`design` for spec-driven mode; `discovery`/import reference for quick/import; plan.md Summary, Decisions, Assumptions, Out of Scope, and Validation Criteria for lite)
1355
+ 2. If code review: verify alignment to available requirements sources (`spec`/`design` for spec-driven mode; `discovery`/import reference for quick/import; plan.md Summary, Decisions, Assumptions, Out of Scope, and Validation Criteria for lite; the brief's Outcomes, Constraints and Out of Scope, Decisions, and the in-scope phases' Intent and Exit evidence for brief and goal)
991
1356
  3. If code review: verify code quality (correctness, tests, security, maintainability)
992
1357
  4. If artifact review: verify completeness/clarity/readiness of the artifact and its alignment with upstream artifacts
993
1358
  5. Categorize findings (Critical/High/Medium/Low)
@@ -1031,6 +1396,14 @@ oat_gate_runtime: { configured runtime }
1031
1396
  oat_invocation_model: { configured model|provider-default|unknown }
1032
1397
  oat_invocation_reasoning_effort: { configured effort|provider-default|unknown }
1033
1398
  oat_invocation_source: { exec-target-config|unknown }
1399
+ # Brief code-review only: copy the Step 5 Brief Anchor Record verbatim.
1400
+ oat_review_requested_scope: { scope token as requested }
1401
+ oat_review_phase_ids: [{ phase IDs in document order }]
1402
+ oat_review_base_sha: { full SHA at the base of the reviewed range }
1403
+ oat_review_scope_source: { anchors|merge-base-range|explicit|merge-base|narrowed }
1404
+ oat_review_fallback_reason: { missing-anchors, only when it applies }
1405
+ oat_review_integration_commits: [{ integration commit SHAs, only when they apply }]
1406
+ oat_review_narrowed_from: { range before narrowing, only when narrowed }
1034
1407
  ---
1035
1408
 
1036
1409
  # {Code|Artifact} Review: {scope}
@@ -1151,6 +1524,7 @@ Record this artifact as one append-ordered review event:
1151
1524
 
1152
1525
  - `Scope`: `{scope}` (examples: `p02`, `final`, `spec`, `design`)
1153
1526
  - Phase-range examples such as `p02-p03` are valid code-review scopes and should be preserved exactly.
1527
+ - Goal integrated reviews: exactly the milestone ID (`m01`) or, for a registered delivery, the delivery ID (`d01`); the ordered phase set lives in `oat_review_phase_ids`, never in the Scope cell (brief contract section 12.6).
1154
1528
  - `Type`: `code` or `artifact`
1155
1529
  - `Status`: `received` (receive-review will decide `fixes_added` vs `passed`; `passed` now requires no unresolved Critical/High/Medium and final deferred-medium disposition when applicable)
1156
1530
  - `Date`: `{today}`
@@ -1178,6 +1552,14 @@ eight columns.
1178
1552
 
1179
1553
  If plan.md is missing (e.g., spec/design review before planning), skip this update and rely on the review artifact + next-step routing.
1180
1554
 
1555
+ **Goal mode.** Review-provide records the event as `received` and never writes
1556
+ `passed`, `delivering`, or any milestone status: `oat-project-review-receive`
1557
+ owns the transition to `delivering`. When a pending `oat_goal_recovery` record
1558
+ names this scope at stage `reviewing`, advance it to `stage: receiving` and set
1559
+ `review_artifact: reviews/{filename}.md` in `state.md`; leave `oat_milestone`,
1560
+ `oat_milestone_status`, and the execution pointer unchanged. Step 9.5 then
1561
+ commits `state.md` with the review bookkeeping.
1562
+
1181
1563
  ### Step 9.5: Commit Review Bookkeeping Atomically (Required)
1182
1564
 
1183
1565
  **If `INLINE_ONLY=true`:** skip this step — no artifact was written to disk.
@@ -1190,6 +1572,7 @@ After writing the review artifact and applying the Step 9 Reviews-table update,
1190
1572
 
1191
1573
  - Always include the active review artifact file: `reviews/{filename}.md`
1192
1574
  - Include `plan.md` when Step 9 updated the Reviews table
1575
+ - Include `state.md` when Step 9 advanced a goal recovery record (`GOAL_RECOVERY_ADVANCED=true`)
1193
1576
  - Do not write or commit new review artifacts directly into `reviews/archived/`
1194
1577
  - Do not include unrelated implementation/code files in this commit
1195
1578
 
@@ -1214,6 +1597,8 @@ if [ "$PROJECT_SCOPE" = "synced" ]; then
1214
1597
  else
1215
1598
  OWNED_COMMIT_PATHS=("$ACTIVE_REVIEW_PATH")
1216
1599
  [ -f "$PROJECT_PATH/plan.md" ] && OWNED_COMMIT_PATHS+=("$PROJECT_PATH/plan.md")
1600
+ # goal: Step 9 advanced a pending oat_goal_recovery record
1601
+ [ "${GOAL_RECOVERY_ADVANCED:-false}" = true ] && OWNED_COMMIT_PATHS+=("$PROJECT_PATH/state.md")
1217
1602
  oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-review-provide:1" --message "chore(oat): record {scope} review artifact" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
1218
1603
  fi
1219
1604
  ```