@open-agent-toolkit/cli 0.2.24 → 0.2.26
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.
- package/assets/agents/oat-reviewer.md +12 -1
- package/assets/docs/cli-utilities/configuration.md +44 -15
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +67 -16
- package/assets/docs/workflows/projects/reviews.md +19 -10
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +4 -4
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +9 -11
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +18 -9
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/references/phase-execution.md +42 -4
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-review-provide/SKILL.md +124 -26
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +64 -15
- package/assets/skills/oat-project-review-receive/SKILL.md +21 -1
- package/assets/skills/oat-project-review-receive-remote/SKILL.md +39 -2
- package/assets/skills/oat-review-provide-remote/SKILL.md +55 -12
- package/assets/templates/plan.md +13 -7
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +35 -11
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +90 -0
- package/dist/commands/review/latest.d.ts.map +1 -1
- package/dist/commands/review/latest.js +22 -9
- package/dist/config/dispatch-notices.d.ts +8 -0
- package/dist/config/dispatch-notices.d.ts.map +1 -0
- package/dist/config/dispatch-notices.js +79 -0
- package/dist/config/dispatch-policy-options.d.ts +2 -0
- package/dist/config/dispatch-policy-options.d.ts.map +1 -1
- package/dist/config/dispatch-policy-options.js +14 -2
- package/dist/config/resolve.js +1 -1
- package/dist/providers/identity/dispatch-report.d.ts +17 -0
- package/dist/providers/identity/dispatch-report.d.ts.map +1 -1
- package/dist/providers/identity/dispatch-report.js +30 -0
- package/dist/review-remote/body-builder.d.ts +12 -3
- package/dist/review-remote/body-builder.d.ts.map +1 -1
- package/dist/review-remote/body-builder.js +11 -0
- package/dist/review-remote/marker-parser.d.ts +8 -3
- package/dist/review-remote/marker-parser.d.ts.map +1 -1
- package/dist/review-remote/marker-parser.js +13 -2
- package/dist/review-remote/narrowing.d.ts +44 -8
- package/dist/review-remote/narrowing.d.ts.map +1 -1
- package/dist/review-remote/narrowing.js +106 -10
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-review-provide-remote
|
|
3
|
-
version: 1.0
|
|
3
|
+
version: 1.1.0
|
|
4
4
|
description: Use when reviewing a GitHub PR opened on another machine for an active OAT project and posting findings back as a single PR review. Resolves the project from the PR diff, reads project artifacts for mode-aware review, and posts via gh api.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: true
|
|
@@ -56,7 +56,7 @@ If you catch yourself:
|
|
|
56
56
|
- Pushing or committing anything from this machine -> STOP; machine A's receive-remote owns all project-state mutations.
|
|
57
57
|
- Posting the review to GitHub without explicit user confirmation -> STOP and present the body + verdict for approval first.
|
|
58
58
|
- Narrowing against a prior review SHA without running the existence + ancestry guard -> STOP and run the guard first.
|
|
59
|
-
- Narrowing against a prior review for a different project or
|
|
59
|
+
- Narrowing against a prior review for a different project, scope, or lineage -> STOP; only the same `(project, scope, lineage)` prior review narrows this one.
|
|
60
60
|
- Forgetting to remove the ephemeral worktree after posting (or on failure) -> STOP and release it in a `finally`.
|
|
61
61
|
|
|
62
62
|
## Progress Indicators (User-Facing)
|
|
@@ -90,7 +90,7 @@ oat-project-review-provide-remote [code <scope>|artifact <scope>]
|
|
|
90
90
|
- `--pr <N>`: target PR number. When omitted, auto-detect from the current branch.
|
|
91
91
|
- `--project <path>`: explicit OAT project directory. Takes precedence over the diff scan. Required when the diff touches zero or multiple projects' `state.md`.
|
|
92
92
|
- `--no-checkout`: skip the ephemeral worktree and review from `gh pr diff` only (degraded context; project artifacts read from `gh` blob fetches instead of the checkout).
|
|
93
|
-
- `--narrow` / `--no-narrow`: force or forbid re-review narrowing against a prior provide-remote review for this `(project, scope)`. When neither is passed, honor `workflow.autoNarrowReReviewScope`
|
|
93
|
+
- `--narrow` / `--no-narrow`: force or forbid re-review narrowing against a prior provide-remote review for this `(project, scope, lineage)`. `--narrow` takes precedence over the configured preference; `--no-narrow` forces full scope. When neither is passed, honor `workflow.autoNarrowReReviewScope`: unset and `true` narrow automatically, while only `false` forces full scope. This path never prompts for a narrowing decision.
|
|
94
94
|
|
|
95
95
|
Inputs are CLI-style args parsed from `$ARGUMENTS`. No file inputs. No file outputs on this machine.
|
|
96
96
|
|
|
@@ -186,26 +186,69 @@ NEVER mutate, commit, or push any project artifact. This is a read-only project
|
|
|
186
186
|
|
|
187
187
|
### Step 4: Detect Prior Reviews + Narrow Scope
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
Resolve the current invocation lineage before selecting a candidate:
|
|
190
|
+
|
|
191
|
+
- `manual` and `auto` are the lifecycle lineage and are interchangeable.
|
|
192
|
+
- `gate` is a separate lineage qualified by the exact `oat_gate_target`.
|
|
193
|
+
|
|
194
|
+
Resolve preference and per-invocation flags before candidate enumeration:
|
|
195
|
+
|
|
196
|
+
1. `--no-narrow` forces full PR scope with reason `narrowing-disabled` and skips `gh api` review enumeration entirely.
|
|
197
|
+
2. `--narrow` forces a narrowing attempt even when the configured preference is `false`.
|
|
198
|
+
3. With neither flag, unset and `true` attempt narrowing; only `false` forces full PR scope with reason `narrowing-disabled` and skips `gh api` review enumeration entirely.
|
|
199
|
+
|
|
200
|
+
Only when narrowing will be attempted, list prior PR reviews and parse each body's target-qualified GitHub review marker block. Capture command status and stderr separately:
|
|
190
201
|
|
|
191
202
|
```bash
|
|
192
|
-
|
|
203
|
+
REVIEWS_ERROR_FILE=""
|
|
204
|
+
REVIEWS_DIAGNOSTIC=""
|
|
205
|
+
REVIEWS_DISCOVERY_OK=false
|
|
206
|
+
|
|
207
|
+
if ! REVIEWS_ERROR_FILE=$(mktemp "${TMPDIR:-/tmp}/oat-review-errors.XXXXXX"); then
|
|
208
|
+
REVIEWS_DIAGNOSTIC="diagnostic-file-unavailable: unable to create a temporary stderr file"
|
|
209
|
+
elif REVIEWS_JSON=$(gh api "/repos/{owner}/{repo}/pulls/$PR/reviews" 2>"$REVIEWS_ERROR_FILE"); then
|
|
210
|
+
REVIEWS_DISCOVERY_OK=true
|
|
211
|
+
rm -f -- "$REVIEWS_ERROR_FILE"
|
|
212
|
+
REVIEWS_ERROR_FILE=""
|
|
213
|
+
else
|
|
214
|
+
REVIEWS_DIAGNOSTIC=$(dd if="$REVIEWS_ERROR_FILE" bs=500 count=1 2>/dev/null)
|
|
215
|
+
rm -f -- "$REVIEWS_ERROR_FILE"
|
|
216
|
+
REVIEWS_ERROR_FILE=""
|
|
217
|
+
fi
|
|
193
218
|
```
|
|
194
219
|
|
|
195
|
-
|
|
220
|
+
Do not run `gh api` when diagnostic-file creation fails. Treat that failure, a nonzero `gh api` result, or a response-level enumeration/parsing failure as discovery failure. Before removing the diagnostic file, preserve at most 500 bytes from stderr. If response parsing later fails, set `REVIEWS_DISCOVERY_OK=false` and put at most 500 characters of the parse error in `REVIEWS_DIAGNOSTIC`. Apply the forced/automatic policy below whenever `REVIEWS_DISCOVERY_OK=false`. Do not treat individual irrelevant or lineage-ineligible marker blocks as response-level failure.
|
|
221
|
+
|
|
222
|
+
- With forced `--narrow`, discovery failure is a hard error with reason `prior-reviews-unavailable`; report the diagnostic and stop instead of pretending to narrow.
|
|
223
|
+
- On the automatic path, discovery failure fails open to full PR scope with stable reason `prior-reviews-unavailable` plus the diagnostic detail, then continues to review the full PR diff.
|
|
224
|
+
|
|
225
|
+
After successful enumeration, candidate discovery belongs to this rail: use only marker blocks where `oat_provide_remote: true`, `oat_project == "$PROJECT_PATH"`, and `oat_review_scope == "<current-scope-token>"`, then require the same lineage. A lifecycle invocation accepts only a prior `manual` or `auto` marker. A gate invocation accepts only a prior `gate` marker carrying the same exact non-empty `oat_gate_target`; a target-less gate marker is ineligible, and a gate never inherits a lifecycle review or another gate target. Invocation-less or unknown legacy markers, and markers for another project or scope, remain unknown and ineligible. Do not read the local lifecycle Reviews table or use a project-plan fallback on this rail.
|
|
226
|
+
|
|
227
|
+
Take the most recent eligible marker by submitted timestamp. Candidate discovery and marker provenance remain rail-specific; only after this rail supplies that candidate apply the shared guard, fallback, and classification semantics mirrored by `packages/cli/src/review-remote/narrowing.ts`. When no eligible marker supplies a full 40-character hexadecimal `oat_review_head_sha`, use full PR scope with reason `no-prior-review`. Do not run Git guards for an invalid candidate.
|
|
228
|
+
|
|
229
|
+
Before accepting `<prior_sha>..<PR_HEAD_SHA>`, run the stale-SHA guard (design.md → Error Handling → Stale prior-review SHA):
|
|
196
230
|
|
|
197
231
|
Run the guard in the available git context `$GIT_CTX` — `$EPHEMERAL_PATH` in rich-context (checkout) mode, or `$REPO_ROOT` in diff-only mode (where no worktree exists):
|
|
198
232
|
|
|
199
233
|
1. **Existence:** `git -C "$GIT_CTX" cat-file -e <prior_sha>` (diff-only mode: `git -C "$REPO_ROOT" fetch origin <prior_sha>:refs/oat-prior-review` first, then re-check; if that fetch fails, fall back to full PR scope).
|
|
200
234
|
2. **Ancestry:** `git -C "$GIT_CTX" merge-base --is-ancestor <prior_sha> "$PR_HEAD_SHA"`.
|
|
201
235
|
|
|
202
|
-
Guard outcomes:
|
|
236
|
+
Guard outcomes and reasons:
|
|
203
237
|
|
|
204
|
-
- Both pass -> narrow to `<prior_sha>..<
|
|
205
|
-
-
|
|
238
|
+
- Both pass -> narrow to exactly `<prior_sha>..<PR_HEAD_SHA>` with reason `narrowed from guarded prior reviewed head`.
|
|
239
|
+
- Object missing or fetch failure -> fall back to full PR scope with reason `stale-sha` and detail `prior-commit-missing`.
|
|
240
|
+
- Ancestry failure -> fall back to full PR scope with reason `stale-sha` and detail `prior-commit-not-ancestor`.
|
|
206
241
|
- `--narrow` set AND guard fails -> hard error; surface unreachability and stop.
|
|
207
|
-
-
|
|
208
|
-
|
|
242
|
+
- The automatic path fails open for every candidate or guard failure and preserves the applicable reason.
|
|
243
|
+
|
|
244
|
+
When a guarded narrow range is accepted, enumerate its changed files with `git diff --name-only "<prior_sha>..<PR_HEAD_SHA>"` and classify it for reporting. Resolve `PROJECT_RELATIVE` as the active project's repository-relative path first:
|
|
245
|
+
|
|
246
|
+
- `empty`: no changed files.
|
|
247
|
+
- `bookkeeping-only`: every changed path is inside the exact active project prefix `"$PROJECT_RELATIVE/"`.
|
|
248
|
+
- `substantive`: any changed path is outside that exact prefix.
|
|
249
|
+
- If changed-file enumeration fails, conservatively classify as `substantive` and add `changed-files-unavailable` to the reason.
|
|
250
|
+
|
|
251
|
+
Classification is reporting-only: `empty`, `bookkeeping-only`, and `substantive` all dispatch the review over the same resolved range. It never skips, gates, or shortens the review. Print one narrowing resolution line containing the resolved full-scope or narrow range, classification when narrowed, and the explicit reason. Do not print another narrowing prompt or decision line elsewhere.
|
|
209
252
|
|
|
210
253
|
### Step 5: Run the Review (Tier 1/2/3 Dispatch)
|
|
211
254
|
|
|
@@ -311,11 +354,12 @@ oat_provide_remote: true
|
|
|
311
354
|
oat_review_head_sha: <PR_HEAD_SHA>
|
|
312
355
|
oat_review_scope: <scope token, e.g. p02 | final>
|
|
313
356
|
oat_project: <PROJECT_PATH>
|
|
314
|
-
oat_review_invocation: manual
|
|
357
|
+
oat_review_invocation: <manual | auto | gate>
|
|
358
|
+
oat_gate_target: <exact configured gate target; omit for lifecycle>
|
|
315
359
|
-->
|
|
316
360
|
```
|
|
317
361
|
|
|
318
|
-
`oat_project` carries the resolved project path so machine A's `oat-project-review-receive-remote` routes findings into the right project's plan tasks. Verdict: `REQUEST_CHANGES` when any critical or important finding exists; `COMMENT` otherwise (including a clean, zero-findings review — never auto-`APPROVE`).
|
|
362
|
+
`oat_project` carries the resolved project path so machine A's `oat-project-review-receive-remote` routes findings into the right project's plan tasks. Preserve the current invocation lineage in the GitHub marker: omit `oat_gate_target` for lifecycle reviews and include the exact target for gate reviews. Verdict: `REQUEST_CHANGES` when any critical or important finding exists; `COMMENT` otherwise (including a clean, zero-findings review — never auto-`APPROVE`).
|
|
319
363
|
|
|
320
364
|
### Step 8: Post the Review + Clean Up
|
|
321
365
|
|
|
@@ -353,6 +397,9 @@ Posting failure handling (design.md → Error Handling → Posting failures): on
|
|
|
353
397
|
Always release the ephemeral worktree in a `finally`, even when review or posting fails:
|
|
354
398
|
|
|
355
399
|
```bash
|
|
400
|
+
if [[ -n "${REVIEWS_ERROR_FILE:-}" ]]; then
|
|
401
|
+
rm -f -- "$REVIEWS_ERROR_FILE"
|
|
402
|
+
fi
|
|
356
403
|
git -C "$REPO_ROOT" worktree remove --force "$EPHEMERAL_PATH" || git -C "$REPO_ROOT" worktree prune
|
|
357
404
|
rm -rf "$EPHEMERAL_PATH"
|
|
358
405
|
```
|
|
@@ -378,7 +425,7 @@ At completion, report:
|
|
|
378
425
|
- Review type and scope token.
|
|
379
426
|
- Read mode (worktree checkout vs diff-only).
|
|
380
427
|
- Dispatch tier used (Tier 1 structured-output / Tier 2 fresh session / Tier 3 inline).
|
|
381
|
-
- Narrowing decision (full scope vs `<prior_sha>..<
|
|
428
|
+
- Narrowing decision (full scope vs `<prior_sha>..<PR_HEAD_SHA>`), reporting-only classification when narrowed, and the explicit reason.
|
|
382
429
|
- Severity counts and total findings.
|
|
383
430
|
- Inline-comment count posted vs findings downgraded to the body (out-of-diff).
|
|
384
431
|
- Verdict (`REQUEST_CHANGES` or `COMMENT`).
|
|
@@ -391,7 +438,9 @@ At completion, report:
|
|
|
391
438
|
- PR scope resolved and confirmed.
|
|
392
439
|
- OAT project resolved from the diff (or `--project` override) and validated; project artifacts read read-only for mode-aware context.
|
|
393
440
|
- PR content acquired via ephemeral worktree (or diff-only fallback) without mutating the caller's working tree.
|
|
394
|
-
- Prior provide-remote
|
|
441
|
+
- Prior provide-remote GitHub markers detected and filtered to this `(project, scope, lineage)`; re-review narrowing applied only after the full-SHA, existence, and ancestry guards pass, with explicit fail-open reasons and no local Reviews-table or project-plan fallback.
|
|
442
|
+
- Unset and `true` narrow automatically, only `false` forces full scope, per-invocation flags retain precedence, and no narrowing prompt remains.
|
|
443
|
+
- Narrowed ranges are classified as `empty`, `bookkeeping-only`, or `substantive` for reporting only; changed-file enumeration failure conservatively reports `substantive`.
|
|
395
444
|
- Review executed via Tier 1 (`oat-reviewer` structured-output, NO artifact) /
|
|
396
445
|
Tier 2 (fresh session) / Tier 3 (inline), with fallthrough limited to
|
|
397
446
|
dispatch unavailability or explicit pre-start native role rejection.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-review-receive
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.6.0
|
|
4
4
|
description: Use when the user explicitly asks to receive review findings for an OAT project — e.g. "receive review", "process review", "process the project review", or confirms a previously offered review-receive step. Do NOT auto-invoke merely because a review file exists. Resolves the latest review and offers before acting.
|
|
5
5
|
disable-model-invocation: false
|
|
6
6
|
user-invocable: true
|
|
@@ -139,6 +139,14 @@ Use this fallback only for active project reviews. It cannot discover ad-hoc rev
|
|
|
139
139
|
|
|
140
140
|
**Read the selected review file completely.**
|
|
141
141
|
|
|
142
|
+
For a code review, read `oat_review_head_sha`, `oat_review_invocation`, and
|
|
143
|
+
`oat_gate_target` from frontmatter. Accept the reviewed head only when it is a
|
|
144
|
+
full 40-character hexadecimal SHA; never expand or infer an abbreviated,
|
|
145
|
+
symbolic, or range value during receive. A missing invocation remains unknown;
|
|
146
|
+
do not assume a legacy artifact was manual. Write `-` for absent provenance
|
|
147
|
+
rather than borrowing values from another review event. `oat_gate_target` is
|
|
148
|
+
meaningful only when the invocation is `gate`.
|
|
149
|
+
|
|
142
150
|
Derive archive bookkeeping before making lifecycle edits:
|
|
143
151
|
|
|
144
152
|
```bash
|
|
@@ -406,8 +414,17 @@ Add new tasks to plan.md in the target phase. When adding or editing tasks, pres
|
|
|
406
414
|
**Review-fix bookkeeping (required):**
|
|
407
415
|
- When you add review-generated fix tasks:
|
|
408
416
|
- Locate the Reviews event matching the selected review's Scope, Type, and `SOURCE_REVIEW_FILENAME`, then update it to `fixes_added` (work queued), set the Date, and replace its Artifact with `reviews/archived/$REVIEW_FILENAME`.
|
|
417
|
+
- For code events, populate or preserve `Reviewed Head`, `Invocation`, and
|
|
418
|
+
`Gate Target` from the selected artifact's validated frontmatter. Never
|
|
419
|
+
replace known provenance with `-`; if the artifact is legacy or a value is
|
|
420
|
+
invalid, preserve existing cells and otherwise leave the value unknown.
|
|
409
421
|
- The written `REVIEW_FILENAME` becomes the event's artifact filename and identity for every later mutation; use the already-resolved final basename in every plan and implementation reference.
|
|
410
422
|
- Never select a row by scope alone or move an event status backward. If the exact bound event is missing, stop and reconcile the ledger instead of mutating another event.
|
|
423
|
+
- Mutate cells by header name. If the table is still the legacy five-column
|
|
424
|
+
shape, add `Reviewed Head`, `Invocation`, and `Gate Target` to the header
|
|
425
|
+
and separator and pad every existing row with `-`. If it is already
|
|
426
|
+
widened, preserve all existing and unknown trailing cells; never rebuild a
|
|
427
|
+
row as only five or eight cells.
|
|
411
428
|
- Update `## Implementation Complete` totals (phase counts + total task count) so downstream PR/review summaries don’t go stale.
|
|
412
429
|
- If the plan includes any phase rollups that reference task counts, update those too.
|
|
413
430
|
|
|
@@ -429,6 +446,9 @@ Add new tasks to plan.md in the target phase. When adding or editing tasks, pres
|
|
|
429
446
|
- Status: `fixes_added` (if tasks were added) or `passed` (if no Critical/Important/Medium and no unresolved final-scope gates)
|
|
430
447
|
- Date: `{today}`
|
|
431
448
|
- Artifact: `reviews/archived/$REVIEW_FILENAME`
|
|
449
|
+
- Reviewed Head: validated full `oat_review_head_sha` for code reviews
|
|
450
|
+
- Invocation: `oat_review_invocation` for code reviews
|
|
451
|
+
- Gate Target: exact `oat_gate_target` for gate code reviews; `-` otherwise
|
|
432
452
|
````
|
|
433
453
|
|
|
434
454
|
**Status semantics (v1):**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-project-review-receive-remote
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.5.0
|
|
4
4
|
description: Use when processing GitHub PR review comments within project context. Fetches PR comments, creates plan tasks, and updates project artifacts.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: true
|
|
@@ -115,6 +115,33 @@ Confirm resolved PR number with user.
|
|
|
115
115
|
npx agent-reviews --json --unresolved --pr <N>
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
+
Resolve provenance from the GitHub review event that produced the fetched
|
|
119
|
+
feedback, not from the PR's current head. Parse its OAT marker block when
|
|
120
|
+
present:
|
|
121
|
+
|
|
122
|
+
- accept `oat_review_head_sha` only as a full 40-character hexadecimal SHA;
|
|
123
|
+
- preserve `oat_review_invocation` as the invocation kind;
|
|
124
|
+
- preserve `oat_gate_target` only for a gate invocation.
|
|
125
|
+
|
|
126
|
+
If the source review is legacy, multiple source reviews disagree, or the
|
|
127
|
+
lineage cannot be associated with this receive event, leave the corresponding
|
|
128
|
+
ledger cells unknown (`-`). Never infer lineage from the reviewer identity or
|
|
129
|
+
substitute the current PR head for the commit that was actually reviewed.
|
|
130
|
+
|
|
131
|
+
**Reviews ledger write contract (all receive paths):**
|
|
132
|
+
|
|
133
|
+
- Resolve `Scope`, `Type`, `Status`, `Date`, `Artifact`, `Reviewed Head`,
|
|
134
|
+
`Invocation`, and `Gate Target` by header name before mutating a row; never
|
|
135
|
+
use fixed cell positions.
|
|
136
|
+
- If the Reviews table has only the legacy five columns, add `Reviewed Head`,
|
|
137
|
+
`Invocation`, and `Gate Target` to its header and separator and pad every
|
|
138
|
+
existing row with `-`. In an already widened table, pad a shorter row with
|
|
139
|
+
`-` through the current header width before mutation.
|
|
140
|
+
- Mutate only the event selected by the event-identity rules below. Preserve
|
|
141
|
+
every unknown column in its original position and every existing known value
|
|
142
|
+
unless the operation explicitly advances that cell. Never truncate a row to
|
|
143
|
+
five, eight, or any other assumed width.
|
|
144
|
+
|
|
118
145
|
If no unresolved comments:
|
|
119
146
|
|
|
120
147
|
1. Create a UTC timestamp and event-distinct filename:
|
|
@@ -125,10 +152,14 @@ If no unresolved comments:
|
|
|
125
152
|
remain in top-level `reviews/`.
|
|
126
153
|
3. Record the clean result as a `passed` Reviews event whose event identity
|
|
127
154
|
combines `Scope`, `Type`, and artifact filename:
|
|
155
|
+
- Apply the Reviews ledger write contract above before claiming, appending,
|
|
156
|
+
or mutating the event.
|
|
128
157
|
- Claim only an unbound `pending` placeholder with matching Scope + Type and
|
|
129
158
|
Artifact `-`; otherwise append a distinct row.
|
|
130
159
|
- Set Date and Artifact to this clean event. Advance only this event and
|
|
131
160
|
never mutate another row by scope alone.
|
|
161
|
+
- Populate `Reviewed Head`, `Invocation`, and `Gate Target` only from the
|
|
162
|
+
validated source-review provenance above; use `-` when it is unknown.
|
|
132
163
|
4. Commit `plan.md` and the clean review artifact atomically with
|
|
133
164
|
`chore(oat): record clean remote review (pr-#<N>)`. Do not stop with
|
|
134
165
|
uncommitted bookkeeping.
|
|
@@ -176,7 +207,8 @@ For each converted finding:
|
|
|
176
207
|
### Step 6: Update Project Artifacts
|
|
177
208
|
|
|
178
209
|
Before changing the ledger, write an event-distinct review artifact containing
|
|
179
|
-
the PR number, fetch timestamp, normalized findings, and
|
|
210
|
+
the PR number, fetch timestamp, normalized findings, dispositions, and any
|
|
211
|
+
validated source-review head/invocation/gate-target provenance:
|
|
180
212
|
`reviews/archived/remote-pr-<N>-review-YYYY-MM-DDTHHMMSSZ.md`. Remote receive
|
|
181
213
|
fully dispositions the event as `passed` or `fixes_added`, so the artifact is
|
|
182
214
|
consumed immediately and belongs in `reviews/archived/`, not top-level
|
|
@@ -198,11 +230,16 @@ Update `plan.md`:
|
|
|
198
230
|
- status `passed` when no actionable findings remain
|
|
199
231
|
- date set to today
|
|
200
232
|
- artifact `reviews/archived/remote-pr-<N>-review-YYYY-MM-DDTHHMMSSZ.md`
|
|
233
|
+
- reviewed head set to the validated full source-review SHA, or `-`
|
|
234
|
+
- invocation set to the source-review invocation kind, or `-`
|
|
235
|
+
- gate target set only for a gate source review, or `-`
|
|
201
236
|
- Claim an unbound `pending` placeholder only when its Scope + Type matches and
|
|
202
237
|
its Artifact is `-`; otherwise append the event. Later mutations select it by
|
|
203
238
|
Scope + Type + artifact filename, never by scope or `github-pr #<N>` alone.
|
|
204
239
|
- Never move an event status backward or overwrite an earlier event from the
|
|
205
240
|
same PR.
|
|
241
|
+
- Apply the Reviews ledger write contract above before claiming, appending, or
|
|
242
|
+
mutating the event.
|
|
206
243
|
- Update `## Implementation Complete` totals.
|
|
207
244
|
|
|
208
245
|
Update `implementation.md`:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-review-provide-remote
|
|
3
|
-
version: 1.0
|
|
3
|
+
version: 1.1.0
|
|
4
4
|
description: Use when reviewing a GitHub PR opened on another machine and posting findings back as a single PR review, outside any OAT project context. Fetches the PR via gh, reviews it, and posts via gh api.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: true
|
|
@@ -77,7 +77,7 @@ oat-review-provide-remote [--pr <N>] [--no-checkout] [--narrow|--no-narrow]
|
|
|
77
77
|
|
|
78
78
|
- `--pr <N>`: target PR number. When omitted, auto-detect from the current branch.
|
|
79
79
|
- `--no-checkout`: skip the ephemeral worktree and review from `gh pr diff` only (degraded context).
|
|
80
|
-
- `--narrow` / `--no-narrow`: force or forbid re-review narrowing against a prior provide-remote review. When neither is passed, honor `workflow.autoNarrowReReviewScope`
|
|
80
|
+
- `--narrow` / `--no-narrow`: force or forbid re-review narrowing against a prior ad-hoc provide-remote review. `--narrow` takes precedence over the configured preference; `--no-narrow` forces full scope. When neither is passed, honor `workflow.autoNarrowReReviewScope`: unset and `true` narrow automatically, while only `false` forces full scope. This path never prompts for a narrowing decision.
|
|
81
81
|
|
|
82
82
|
Inputs are CLI-style args parsed from `$ARGUMENTS`. No file inputs. No file outputs on this machine.
|
|
83
83
|
|
|
@@ -143,26 +143,63 @@ gh pr view "$PR" --json title,body,headRefOid,baseRefName,state
|
|
|
143
143
|
|
|
144
144
|
### Step 3: Detect Prior Reviews + Narrow Scope
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
Resolve preference and per-invocation flags before candidate enumeration:
|
|
147
|
+
|
|
148
|
+
1. `--no-narrow` forces full PR scope with reason `narrowing-disabled` and skips `gh api` review enumeration entirely.
|
|
149
|
+
2. `--narrow` forces a narrowing attempt even when the configured preference is `false`.
|
|
150
|
+
3. With neither flag, unset and `true` attempt narrowing; only `false` forces full PR scope with reason `narrowing-disabled` and skips `gh api` review enumeration entirely.
|
|
151
|
+
|
|
152
|
+
Only when narrowing will be attempted, list prior PR reviews and parse each body's GitHub review marker block. Capture command status and stderr separately:
|
|
147
153
|
|
|
148
154
|
```bash
|
|
149
|
-
|
|
155
|
+
REVIEWS_ERROR_FILE=""
|
|
156
|
+
REVIEWS_DIAGNOSTIC=""
|
|
157
|
+
REVIEWS_DISCOVERY_OK=false
|
|
158
|
+
|
|
159
|
+
if ! REVIEWS_ERROR_FILE=$(mktemp "${TMPDIR:-/tmp}/oat-review-errors.XXXXXX"); then
|
|
160
|
+
REVIEWS_DIAGNOSTIC="diagnostic-file-unavailable: unable to create a temporary stderr file"
|
|
161
|
+
elif REVIEWS_JSON=$(gh api "/repos/{owner}/{repo}/pulls/$PR/reviews" 2>"$REVIEWS_ERROR_FILE"); then
|
|
162
|
+
REVIEWS_DISCOVERY_OK=true
|
|
163
|
+
rm -f -- "$REVIEWS_ERROR_FILE"
|
|
164
|
+
REVIEWS_ERROR_FILE=""
|
|
165
|
+
else
|
|
166
|
+
REVIEWS_DIAGNOSTIC=$(dd if="$REVIEWS_ERROR_FILE" bs=500 count=1 2>/dev/null)
|
|
167
|
+
rm -f -- "$REVIEWS_ERROR_FILE"
|
|
168
|
+
REVIEWS_ERROR_FILE=""
|
|
169
|
+
fi
|
|
150
170
|
```
|
|
151
171
|
|
|
152
|
-
|
|
172
|
+
Do not run `gh api` when diagnostic-file creation fails. Treat that failure, a nonzero `gh api` result, or a response-level enumeration/parsing failure as discovery failure. Before removing the diagnostic file, preserve at most 500 bytes from stderr. If response parsing later fails, set `REVIEWS_DISCOVERY_OK=false` and put at most 500 characters of the parse error in `REVIEWS_DIAGNOSTIC`. Apply the forced/automatic policy below whenever `REVIEWS_DISCOVERY_OK=false`. Do not treat individual irrelevant or lineage-ineligible marker blocks as response-level failure.
|
|
173
|
+
|
|
174
|
+
- With forced `--narrow`, discovery failure is a hard error with reason `prior-reviews-unavailable`; report the diagnostic and stop instead of pretending to narrow.
|
|
175
|
+
- On the automatic path, discovery failure fails open to full PR scope with stable reason `prior-reviews-unavailable` plus the diagnostic detail, then continues to review the full PR diff.
|
|
176
|
+
|
|
177
|
+
After successful enumeration, candidate discovery belongs to this rail: use only marker blocks where `oat_provide_remote: true`, `oat_review_scope == "ad-hoc"`, no `oat_project` key is present, and the invocation is in the ad-hoc lifecycle lineage (`manual` or `auto`). Project-rail, gate, and invocation-less or unknown legacy markers remain unknown and ineligible. This rail has no project-plan or local lifecycle Reviews-table fallback.
|
|
178
|
+
|
|
179
|
+
Take the most recent eligible marker by submitted timestamp. Candidate discovery and marker provenance remain rail-specific; only after this rail supplies that candidate apply the shared guard, fallback, and classification semantics mirrored by `packages/cli/src/review-remote/narrowing.ts`. When no eligible marker supplies a full 40-character hexadecimal `oat_review_head_sha`, use full PR scope with reason `no-prior-review`. Do not run Git guards for an invalid candidate.
|
|
180
|
+
|
|
181
|
+
Before accepting `<prior_sha>..<PR_HEAD_SHA>`, run the stale-SHA guard (design.md → Error Handling → Stale prior-review SHA):
|
|
153
182
|
|
|
154
183
|
Run the guard in the available git context `$GIT_CTX` — `$EPHEMERAL_PATH` in rich-context (checkout) mode, or `$REPO_ROOT` in diff-only mode (where no worktree exists):
|
|
155
184
|
|
|
156
185
|
1. **Existence:** `git -C "$GIT_CTX" cat-file -e <prior_sha>` (diff-only mode: `git -C "$REPO_ROOT" fetch origin <prior_sha>:refs/oat-prior-review` first, then re-check; if that fetch fails, fall back to full PR scope).
|
|
157
186
|
2. **Ancestry:** `git -C "$GIT_CTX" merge-base --is-ancestor <prior_sha> "$PR_HEAD_SHA"`.
|
|
158
187
|
|
|
159
|
-
Guard outcomes:
|
|
188
|
+
Guard outcomes and reasons:
|
|
160
189
|
|
|
161
|
-
- Both pass -> narrow to `<prior_sha>..<
|
|
162
|
-
-
|
|
190
|
+
- Both pass -> narrow to exactly `<prior_sha>..<PR_HEAD_SHA>` with reason `narrowed from guarded prior reviewed head`.
|
|
191
|
+
- Object missing or fetch failure -> fall back to full PR scope with reason `stale-sha` and detail `prior-commit-missing`.
|
|
192
|
+
- Ancestry failure -> fall back to full PR scope with reason `stale-sha` and detail `prior-commit-not-ancestor`.
|
|
163
193
|
- `--narrow` set AND guard fails -> hard error; surface unreachability and stop.
|
|
164
|
-
-
|
|
165
|
-
|
|
194
|
+
- The automatic path fails open for every candidate or guard failure and preserves the applicable reason.
|
|
195
|
+
|
|
196
|
+
When a guarded narrow range is accepted, enumerate its changed files with `git diff --name-only "<prior_sha>..<PR_HEAD_SHA>"` and classify it for reporting:
|
|
197
|
+
|
|
198
|
+
- `empty`: no changed files.
|
|
199
|
+
- `substantive`: any non-empty range. The ad-hoc rail has no active project prefix, so it cannot classify a range as `bookkeeping-only`.
|
|
200
|
+
- If changed-file enumeration fails, conservatively classify as `substantive` and add `changed-files-unavailable` to the reason.
|
|
201
|
+
|
|
202
|
+
The shared vocabulary remains `empty`, `bookkeeping-only`, or `substantive`; `bookkeeping-only` is reachable only on a project rail with an exact active-project prefix. Classification is reporting-only: it never skips, gates, or shortens the review. Print one narrowing resolution line containing the resolved full-scope or narrow range, classification when narrowed, and the explicit reason. Do not print another narrowing prompt or decision line elsewhere.
|
|
166
203
|
|
|
167
204
|
### Step 4: Run the Review (Inline)
|
|
168
205
|
|
|
@@ -233,6 +270,9 @@ Posting failure handling (design.md → Error Handling → Posting failures): on
|
|
|
233
270
|
Always release the ephemeral worktree in a `finally`, even when review or posting fails:
|
|
234
271
|
|
|
235
272
|
```bash
|
|
273
|
+
if [[ -n "${REVIEWS_ERROR_FILE:-}" ]]; then
|
|
274
|
+
rm -f -- "$REVIEWS_ERROR_FILE"
|
|
275
|
+
fi
|
|
236
276
|
git -C "$REPO_ROOT" worktree remove --force "$EPHEMERAL_PATH" || git -C "$REPO_ROOT" worktree prune
|
|
237
277
|
rm -rf "$EPHEMERAL_PATH"
|
|
238
278
|
```
|
|
@@ -252,7 +292,7 @@ At completion, report:
|
|
|
252
292
|
|
|
253
293
|
- PR number and HEAD SHA reviewed.
|
|
254
294
|
- Read mode (worktree checkout vs diff-only).
|
|
255
|
-
- Narrowing decision (full scope vs `<prior_sha>..<
|
|
295
|
+
- Narrowing decision (full scope vs `<prior_sha>..<PR_HEAD_SHA>`), reporting-only classification when narrowed, and the explicit reason.
|
|
256
296
|
- Severity counts and total findings.
|
|
257
297
|
- Inline-comment count posted vs findings downgraded to the body (out-of-diff).
|
|
258
298
|
- Verdict (`REQUEST_CHANGES` or `COMMENT`).
|
|
@@ -263,7 +303,10 @@ At completion, report:
|
|
|
263
303
|
|
|
264
304
|
- PR scope resolved and confirmed.
|
|
265
305
|
- PR content acquired via ephemeral worktree (or diff-only fallback) without mutating the caller's working tree.
|
|
266
|
-
- Prior
|
|
306
|
+
- Prior ad-hoc GitHub markers detected and restricted to the ad-hoc lifecycle lineage; project and gate markers are ineligible, and no project-plan or local Reviews-table fallback is used.
|
|
307
|
+
- Re-review narrowing applies only after the full-SHA, existence, and ancestry guards pass, with explicit fail-open reasons.
|
|
308
|
+
- Unset and `true` narrow automatically, only `false` forces full scope, per-invocation flags retain precedence, and no narrowing prompt remains.
|
|
309
|
+
- Narrowed ranges are classified as `empty` or `substantive` for reporting only; changed-file enumeration failure conservatively reports `substantive`.
|
|
267
310
|
- Findings produced with consistent 4-tier severities and file:line references.
|
|
268
311
|
- Inline comments mapped to in-diff positions; out-of-diff findings downgraded to the body, never dropped.
|
|
269
312
|
- Posted-review body carries the marker block first, correct severity counts, and the minor-fix nudge when minors are present.
|
package/assets/templates/plan.md
CHANGED
|
@@ -168,13 +168,19 @@ git commit -m "feat(p01-t02): {description}"
|
|
|
168
168
|
|
|
169
169
|
{Keep both code + artifact rows below. Add additional code rows (p03, p04, etc.) as needed, but do not delete `spec`/`design`.}
|
|
170
170
|
|
|
171
|
-
| Scope | Type | Status | Date | Artifact |
|
|
172
|
-
| ------ | -------- | ------- | ---- | -------- |
|
|
173
|
-
| p01 | code | pending | - | - |
|
|
174
|
-
| p02 | code | pending | - | - |
|
|
175
|
-
| final | code | pending | - | - |
|
|
176
|
-
| spec | artifact | pending | - | - |
|
|
177
|
-
| design | artifact | pending | - | - |
|
|
171
|
+
| Scope | Type | Status | Date | Artifact | Reviewed Head | Invocation | Gate Target |
|
|
172
|
+
| ------ | -------- | ------- | ---- | -------- | ------------- | ---------- | ----------- |
|
|
173
|
+
| p01 | code | pending | - | - | - | - | - |
|
|
174
|
+
| p02 | code | pending | - | - | - | - | - |
|
|
175
|
+
| final | code | pending | - | - | - | - | - |
|
|
176
|
+
| spec | artifact | pending | - | - | - | - | - |
|
|
177
|
+
| design | artifact | pending | - | - | - | - | - |
|
|
178
|
+
|
|
179
|
+
For code-review events, `Reviewed Head` is the full 40-character SHA at the
|
|
180
|
+
head of the reviewed range. `Invocation` records `manual`, `auto`, or `gate`;
|
|
181
|
+
`Gate Target` is populated only for gate events. Legacy five-column rows remain
|
|
182
|
+
valid. Writers must preserve every existing row and every unknown trailing
|
|
183
|
+
cell; never truncate a widened row back to five columns.
|
|
178
184
|
|
|
179
185
|
**Status values:** `pending` → `received` → `fixes_added` → `fixes_completed` → `passed`
|
|
180
186
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,iCAAiC,CAAC;AAmBzC,OAAO,EAML,KAAK,SAAS,EACd,KAAK,cAAc,EAGnB,KAAK,UAAU,EAehB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAGL,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC/B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,mCAAmC,EACnC,0BAA0B,EAC3B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoGpC,UAAU,yBAAyB;IACjC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAC/C,cAAc,CAAC;IACpB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAClE,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,KACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,cAAc,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,mBAAmB,EAAE,CACnB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,EAAE,CAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC7C,mCAAmC,EAAE,OAAO,mCAAmC,CAAC;IAChF,0BAA0B,EAAE,OAAO,0BAA0B,CAAC;IAC9D,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AA46ED,wBAAgB,mBAAmB,CACjC,SAAS,GAAE,OAAO,CAAC,yBAAyB,CAAM,GACjD,OAAO,CAsKT"}
|
|
@@ -6,6 +6,7 @@ import { confirmAction, } from '../shared/shared.prompts.js';
|
|
|
6
6
|
import { readGlobalOptions } from '../shared/shared.utils.js';
|
|
7
7
|
import { compileDispatchCeilingPreset } from '../../config/dispatch-ceiling-preset.js';
|
|
8
8
|
import { normalizeDispatchMatrix, validateDispatchRouteTarget, walkDispatchMatrix, } from '../../config/dispatch-matrix.js';
|
|
9
|
+
import { formatDispatchNotices, terminalReviewerNoticesForMatrix, } from '../../config/dispatch-notices.js';
|
|
9
10
|
import { dispatchPolicyModeDescription, dispatchPolicyPolicyDescription, managedDispatchPolicyValueList, } from '../../config/dispatch-policy-options.js';
|
|
10
11
|
import { VALID_DISPATCH_POLICY_MODES, VALID_MANAGED_DISPATCH_POLICIES, MAX_GATE_TIMEOUT_MS, MIN_GATE_TIMEOUT_MS, isValidGateTimeoutMs, normalizeWorkflowPostImplementSequence, readOatConfig, readOatLocalConfig, readUserConfig, writeOatConfig, writeOatLocalConfig, writeUserConfig, } from '../../config/oat-config.js';
|
|
11
12
|
import { resolveEffectiveConfig, } from '../../config/resolve.js';
|
|
@@ -508,7 +509,7 @@ const CONFIG_CATALOG = [
|
|
|
508
509
|
defaultValue: 'unset',
|
|
509
510
|
mutability: 'read/write',
|
|
510
511
|
owningCommand: 'oat config set workflow.hillCheckpointDefault <value>',
|
|
511
|
-
description: 'Default HiLL checkpoint behavior in oat-project-implement: "every" pauses after every phase, "final" pauses only after the last phase. When unset, the skill prompts. Resolution:
|
|
512
|
+
description: 'Default HiLL checkpoint behavior in oat-project-implement: "every" pauses after every phase, "final" pauses only after the last phase. When unset, the skill prompts. Resolution: local > shared > user > default.',
|
|
512
513
|
},
|
|
513
514
|
{
|
|
514
515
|
key: 'workflow.archiveOnComplete',
|
|
@@ -519,7 +520,7 @@ const CONFIG_CATALOG = [
|
|
|
519
520
|
defaultValue: 'unset',
|
|
520
521
|
mutability: 'read/write',
|
|
521
522
|
owningCommand: 'oat config set workflow.archiveOnComplete <true|false>',
|
|
522
|
-
description: 'Skip the "Archive after completion?" prompt in oat-project-complete. When unset, the skill prompts. Resolution:
|
|
523
|
+
description: 'Skip the "Archive after completion?" prompt in oat-project-complete. When unset, the skill prompts. Resolution: local > shared > user > default.',
|
|
523
524
|
},
|
|
524
525
|
{
|
|
525
526
|
key: 'workflow.createPrOnComplete',
|
|
@@ -530,7 +531,7 @@ const CONFIG_CATALOG = [
|
|
|
530
531
|
defaultValue: 'unset',
|
|
531
532
|
mutability: 'read/write',
|
|
532
533
|
owningCommand: 'oat config set workflow.createPrOnComplete <true|false>',
|
|
533
|
-
description: 'Skip the "Open a PR?" prompt in oat-project-complete. When true, completion auto-triggers PR creation. Resolution:
|
|
534
|
+
description: 'Skip the "Open a PR?" prompt in oat-project-complete. When true, completion auto-triggers PR creation. Resolution: local > shared > user > default.',
|
|
534
535
|
},
|
|
535
536
|
{
|
|
536
537
|
key: 'workflow.postImplementSequence',
|
|
@@ -541,7 +542,7 @@ const CONFIG_CATALOG = [
|
|
|
541
542
|
defaultValue: 'unset',
|
|
542
543
|
mutability: 'read/write',
|
|
543
544
|
owningCommand: "oat config set workflow.postImplementSequence '<legacy-or-json>'",
|
|
544
|
-
description: 'Default post-implementation chaining. Legacy strings remain supported unchanged. Structured JSON uses {"preApproval":[...],"postApproval":[...]} with the canonical sequence steps. Plain get/list/dump output serializes structured values as compact JSON; get --json preserves the object value. When unset, the skill prompts. Resolution:
|
|
545
|
+
description: 'Default post-implementation chaining. Legacy strings remain supported unchanged. Structured JSON uses {"preApproval":[...],"postApproval":[...]} with the canonical sequence steps. Plain get/list/dump output serializes structured values as compact JSON; get --json preserves the object value. When unset, the skill prompts. Resolution: local > shared > user > default.',
|
|
545
546
|
},
|
|
546
547
|
{
|
|
547
548
|
key: 'workflow.reviewExecutionModel',
|
|
@@ -552,7 +553,7 @@ const CONFIG_CATALOG = [
|
|
|
552
553
|
defaultValue: 'unset',
|
|
553
554
|
mutability: 'read/write',
|
|
554
555
|
owningCommand: 'oat config set workflow.reviewExecutionModel <value>',
|
|
555
|
-
description: 'Default execution model for the final review step in oat-project-implement: "subagent" dispatches a review subagent, "inline" runs the review in-context, "fresh-session" prints guidance for running the review in a separate session (with an escape hatch to subagent/inline). When unset, the skill prompts. Resolution:
|
|
556
|
+
description: 'Default execution model for the final review step in oat-project-implement: "subagent" dispatches a review subagent, "inline" runs the review in-context, "fresh-session" prints guidance for running the review in a separate session (with an escape hatch to subagent/inline). When unset, the skill prompts. Resolution: local > shared > user > default.',
|
|
556
557
|
},
|
|
557
558
|
{
|
|
558
559
|
key: 'workflow.autoReviewAtHillCheckpoints',
|
|
@@ -563,7 +564,7 @@ const CONFIG_CATALOG = [
|
|
|
563
564
|
defaultValue: 'unset',
|
|
564
565
|
mutability: 'read/write',
|
|
565
566
|
owningCommand: 'oat config set workflow.autoReviewAtHillCheckpoints <true|false>',
|
|
566
|
-
description: 'Automatically run the extra lifecycle review when a HiLL checkpoint is reached. This does not control Tier 1 per-phase oat-reviewer gates. When unset, the skill prompts. Resolution:
|
|
567
|
+
description: 'Automatically run the extra lifecycle review when a HiLL checkpoint is reached. This does not control Tier 1 per-phase oat-reviewer gates. When unset, the skill prompts. Resolution: local > shared > user > legacy autoReviewAtCheckpoints > default.',
|
|
567
568
|
},
|
|
568
569
|
{
|
|
569
570
|
key: 'workflow.autoNarrowReReviewScope',
|
|
@@ -571,10 +572,10 @@ const CONFIG_CATALOG = [
|
|
|
571
572
|
file: '.oat/config.local.json | .oat/config.json | ~/.oat/config.json',
|
|
572
573
|
scope: 'workflow',
|
|
573
574
|
type: 'boolean',
|
|
574
|
-
defaultValue: '
|
|
575
|
+
defaultValue: 'true',
|
|
575
576
|
mutability: 'read/write',
|
|
576
577
|
owningCommand: 'oat config set workflow.autoNarrowReReviewScope <true|false>',
|
|
577
|
-
description: '
|
|
578
|
+
description: 'Automatically narrows re-review scope to changes since the prior same-lineage review. Narrowing is enabled by default; false opts out to full scope. Has no effect on initial reviews (there is nothing to narrow to). Resolution: local > shared > user > default.',
|
|
578
579
|
},
|
|
579
580
|
{
|
|
580
581
|
key: 'workflow.autoArtifactReview.plan',
|
|
@@ -1698,45 +1699,65 @@ function applyDispatchMatrixRecommendation(workflow, recommendation) {
|
|
|
1698
1699
|
},
|
|
1699
1700
|
};
|
|
1700
1701
|
}
|
|
1702
|
+
async function effectiveTerminalReviewerNotices(repoRoot, userConfigDir, dependencies) {
|
|
1703
|
+
const resolved = await dependencies.resolveEffectiveConfig(repoRoot, userConfigDir, dependencies.processEnv);
|
|
1704
|
+
const effectiveProviders = {};
|
|
1705
|
+
for (const config of [resolved.user, resolved.shared, resolved.local]) {
|
|
1706
|
+
for (const [provider, value] of Object.entries(config.workflow?.dispatchCeiling?.providers ?? {})) {
|
|
1707
|
+
const existing = effectiveProviders[provider];
|
|
1708
|
+
effectiveProviders[provider] =
|
|
1709
|
+
isRecord(existing) && isRecord(value)
|
|
1710
|
+
? { ...existing, ...value }
|
|
1711
|
+
: value;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
return terminalReviewerNoticesForMatrix(effectiveProviders);
|
|
1715
|
+
}
|
|
1701
1716
|
async function adoptDispatchMatrixRecommendation(repoRoot, userConfigDir, options, context, dependencies) {
|
|
1702
1717
|
const source = options.surface === 'auto' ? 'local' : options.surface;
|
|
1703
1718
|
const recommendation = await loadDispatchMatrixRecommendation(dependencies);
|
|
1704
1719
|
if (source === 'user') {
|
|
1705
1720
|
const userConfig = await dependencies.readUserConfig(userConfigDir);
|
|
1706
1721
|
await validateRecommendationCells(repoRoot, recommendation, dependencies, context.logger.warn);
|
|
1722
|
+
const workflow = applyDispatchMatrixRecommendation(userConfig.workflow, recommendation);
|
|
1707
1723
|
await dependencies.writeUserConfig(userConfigDir, {
|
|
1708
1724
|
...userConfig,
|
|
1709
|
-
workflow
|
|
1725
|
+
workflow,
|
|
1710
1726
|
});
|
|
1711
1727
|
return {
|
|
1712
1728
|
key: 'workflow.dispatchCeiling.providers',
|
|
1713
1729
|
value: recommendation.version,
|
|
1714
1730
|
source,
|
|
1731
|
+
notices: await effectiveTerminalReviewerNotices(repoRoot, userConfigDir, dependencies),
|
|
1715
1732
|
};
|
|
1716
1733
|
}
|
|
1717
1734
|
if (source === 'local') {
|
|
1718
1735
|
const localConfig = await dependencies.readOatLocalConfig(repoRoot);
|
|
1719
1736
|
await validateRecommendationCells(repoRoot, recommendation, dependencies, context.logger.warn);
|
|
1737
|
+
const workflow = applyDispatchMatrixRecommendation(localConfig.workflow, recommendation);
|
|
1720
1738
|
await dependencies.writeOatLocalConfig(repoRoot, {
|
|
1721
1739
|
...localConfig,
|
|
1722
|
-
workflow
|
|
1740
|
+
workflow,
|
|
1723
1741
|
});
|
|
1724
1742
|
return {
|
|
1725
1743
|
key: 'workflow.dispatchCeiling.providers',
|
|
1726
1744
|
value: recommendation.version,
|
|
1727
1745
|
source,
|
|
1746
|
+
notices: await effectiveTerminalReviewerNotices(repoRoot, userConfigDir, dependencies),
|
|
1728
1747
|
};
|
|
1729
1748
|
}
|
|
1730
1749
|
const sharedConfig = await dependencies.readOatConfig(repoRoot);
|
|
1731
1750
|
await validateRecommendationCells(repoRoot, recommendation, dependencies, context.logger.warn);
|
|
1751
|
+
const workflow = applyDispatchMatrixRecommendation(sharedConfig.workflow, recommendation);
|
|
1732
1752
|
await dependencies.writeOatConfig(repoRoot, {
|
|
1733
1753
|
...sharedConfig,
|
|
1734
|
-
workflow
|
|
1754
|
+
workflow,
|
|
1735
1755
|
});
|
|
1736
1756
|
return {
|
|
1737
1757
|
key: 'workflow.dispatchCeiling.providers',
|
|
1738
1758
|
value: recommendation.version,
|
|
1739
1759
|
source,
|
|
1760
|
+
notices: await effectiveTerminalReviewerNotices(repoRoot, userConfigDir, dependencies),
|
|
1740
1761
|
};
|
|
1741
1762
|
}
|
|
1742
1763
|
function formatList(values) {
|
|
@@ -1870,6 +1891,9 @@ async function runAdopt(templateArg, options, context, dependencies) {
|
|
|
1870
1891
|
}
|
|
1871
1892
|
else {
|
|
1872
1893
|
context.logger.info(`Adopted dispatch matrix recommendation ${result.value} to ${result.source} config.`);
|
|
1894
|
+
if (result.notices.length > 0) {
|
|
1895
|
+
context.logger.info(formatDispatchNotices(result.notices));
|
|
1896
|
+
}
|
|
1873
1897
|
}
|
|
1874
1898
|
process.exitCode = 0;
|
|
1875
1899
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAkB9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAyBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAkwFD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CA0GT"}
|