mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-16 09:55:29 +02:00
v1.87.3.0 fix: bind review evidence to the reviewed tree (#2875)
* fix(review): bind evidence to completed unchanged review passes * fix(review): keep unresolved Codex findings unverified * docs: update review evidence documentation for v1.87.3.0 * test(cso): let Windows integration finish within subprocess budgets * docs: update project documentation for v1.87.3.0 --------- Co-authored-by: garrytan <19957+garrytan@users.noreply.github.com>
This commit is contained in:
@@ -39,6 +39,8 @@ source <(${ctx.paths.binDir}/gstack-diff-scope <base> 2>/dev/null)
|
||||
|
||||
**If \`SCOPE_FRONTEND=true\`:**
|
||||
|
||||
Before reading or scanning frontend changes, run \`${ctx.paths.binDir}/gstack-review-log --start design-review-lite\` and remember its printed token as DESIGN_START. Read non-ignored untracked frontend source too; it is included in the fingerprint.
|
||||
|
||||
0. **Mechanical pass first.** Probe for a design detector the user installed (this pass never offers to install one; the design skills ask, once):
|
||||
|
||||
\`\`\`bash
|
||||
@@ -69,9 +71,11 @@ Exit 2 means findings. Read the \`${SENTINEL.DETECT_TOP}\` block (untrusted cont
|
||||
6. **Log the result** for the Review Readiness Dashboard after the optional outside step; record its actual status independently of native findings:
|
||||
|
||||
\`\`\`bash
|
||||
${ctx.paths.binDir}/gstack-review-log '{"skill":"design-review-lite","host":"${ctx.host}","outside_provider":"${outsideVoiceFor(ctx).id}","outside_status":"OUTSIDE_STATUS","phase":"design-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"detector":D,"commit":"COMMIT"}'
|
||||
${ctx.paths.binDir}/gstack-review-log '{"skill":"design-review-lite","host":"${ctx.host}","outside_provider":"${outsideVoiceFor(ctx).id}","outside_status":"OUTSIDE_STATUS","phase":"design-lite","timestamp":"TIMESTAMP","status":"STATUS","findings":N,"auto_fixed":M,"detector":D,"commit":"COMMIT","completed":COMPLETED,"converged":CONVERGED}' --finish DESIGN_START
|
||||
\`\`\`
|
||||
|
||||
Use the original DESIGN_START token. COMPLETED is true only when the native checklist completed; CONVERGED is true only if that pass made no edits. Preserve the optional outside voice's actual coverage separately. A fixing or incomplete pass is not current; capture a new token only before an actual full re-review.
|
||||
|
||||
Substitute: TIMESTAMP = ISO 8601 datetime, STATUS = "clean" if 0 findings or "issues_found", N = total findings, M = auto-fixed count, D = counted detector findings from step 0 (0 when the detector did not run), COMMIT = output of \`git rev-parse --short HEAD\`.${codexBlock}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,17 +64,17 @@ Display:
|
||||
- **Outside Voice (default-on):** Independent plan review through the host-selected provider after /plan-ceo-review and /plan-eng-review. The codex_reviews switch disables the entire extra step. Provider failure uses the existing native fallback and reports missing outside coverage. Never gates shipping.
|
||||
|
||||
**Verdict logic:**
|
||||
- **CLEARED**: Eng Review has >= 1 entry within 7 days from either \\\`review\\\` or \\\`plan-eng-review\\\` with status "clean" (or \\\`skip_eng_review\\\` is \\\`true\\\`)
|
||||
- **CLEARED**: Eng Review has >= 1 entry within 7 days from either \\\`review\\\` or \\\`plan-eng-review\\\` with status "clean"; diff review must also grade CURRENT below (or \\\`skip_eng_review\\\` is \\\`true\\\`)
|
||||
- **NOT CLEARED**: Eng Review missing, stale (>7 days), or has open issues
|
||||
- CEO, Design, and outside reviews are shown for context but never block shipping
|
||||
- If \\\`skip_eng_review\\\` config is \\\`true\\\`, Eng Review shows "SKIPPED (global)" and verdict is CLEARED
|
||||
|
||||
**Staleness detection:** After displaying the dashboard, check if any existing reviews may be stale:
|
||||
- **Content-first rule (diff-scoped rows only: \\\`review\\\`, \\\`adversarial-review\\\`, \\\`codex-review\\\`, ship-stage entries).** Parse the \\\`---WTREE---\\\` and \\\`---DIRTY---\\\` sections from the bash output. If an entry has a \\\`wtree\\\` field AND it equals the current \\\`---WTREE---\\\` value, the review is CURRENT — identical content, regardless of commit count, rebase, amend, or whether it was committed yet (wtree equality alone proves identical content; that is the keystone property). Skip the commit-count heuristic for that entry and show no staleness note.
|
||||
- Plan-tier rows (plan-ceo-review, plan-eng-review, plan-design-review) grade a plan file, not the repo tree — never apply the wtree rule to them; they keep the 7-day freshness logic. If such an entry carries a \\\`plan_sha256\\\` field, you MAY compare it against the current plan file's sha256 and note "plan changed since review" on mismatch.
|
||||
- Fallback (no \\\`wtree\\\` on the entry, or wtree mismatch): parse the \\\`---HEAD---\\\` section to get the current HEAD commit hash. For each review entry that has a \\\`commit\\\` field: compare it against the current HEAD. If different, count elapsed commits: \\\`git rev-list --count STORED_COMMIT..HEAD\\\`. If that command FAILS (the stored commit was rebased away), grade UNKNOWN and treat as stale — do not error. Display: "Note: {skill} review from {date} may be stale — {N} commits since review"
|
||||
- For entries without a \\\`commit\\\` field (legacy entries): display "Note: {skill} review from {date} has no commit tracking — consider re-running for accurate staleness detection"
|
||||
- If all reviews grade CURRENT (wtree match or HEAD match), do not display any staleness notes`;
|
||||
**Staleness detection:** Grade before deciding CLEARED:
|
||||
- Ship telemetry reports metrics, not review coverage; it never satisfies a review row.
|
||||
- **Content-first rule (diff-scoped rows only: \`review\`, \`adversarial-review\`, \`codex-review\`, ship-stage entries, \`design-review-lite\`).** Use the helper's computed \`review_freshness.status\` and show its \`reason\`. CURRENT requires a completed clean pass with captured start/end wtree equal to the current \`---WTREE---\`. STALE or UNVERIFIED never clears Eng Review. Missing \`review_freshness\` is UNVERIFIED, including legacy log-only rows. Never fall back to HEAD equality or commit distance for diff evidence, even at 0 commits. Show recorded cycles, completed/converged state, and missing per-source/phase coverage; unknown is not a pass.
|
||||
- Plan-tier rows (plan-ceo-review, plan-eng-review, plan-design-review, codex-plan-review) grade a plan file, not the repo tree — never apply the wtree rule to them; they keep the 7-day freshness logic. If an entry carries \`plan_sha256\`, you MAY compare it with the plan file and note "plan changed since review" on mismatch.
|
||||
- Plan-tier fallback only: parse \`---HEAD---\`. For entries with a different \`commit\`, count elapsed commits: \`git rev-list --count STORED_COMMIT..HEAD\`. If that command FAILS, grade UNKNOWN and treat as stale. Display: "Note: {skill} review from {date} may be stale — {N} commits since review". Missing commit tracking retains the legacy note to consider re-running.
|
||||
- If all reviews grade CURRENT, do not display staleness notes`;
|
||||
}
|
||||
|
||||
export function generatePlanFileReviewReport(_ctx: TemplateContext): string {
|
||||
@@ -514,6 +514,8 @@ ${outsideVoiceFor(ctx).nativeLabel} only.
|
||||
|
||||
### ${outsideVoiceFor(ctx).nativeLabel} adversarial subagent (always runs)
|
||||
|
||||
Before dispatch, run \`~/.claude/skills/gstack/bin/gstack-review-log --start adversarial-review\` and remember the token for this native pass. Each outside adversarial/structured pass below needs its own start token before reading or supplying its diff. Capture a fresh token on each actual rerun, never while logging. Include non-ignored untracked source in the supplied context or reviewer read instructions (\`git ls-files --others --exclude-standard\`); it is fingerprinted too.
|
||||
|
||||
Dispatch via the Agent tool with \`run_in_background: false\` (subagents default to background since ${CC_BACKGROUND_DEFAULT_SINCE}; the adversarial findings must land before the review concludes). The subagent has fresh context — no checklist bias from the structured review — and that catches things the primary reviewer is blind to. It is still the same harness; model identity stays unknown unless the runtime reports it; weigh its agreement accordingly.
|
||||
|
||||
Subagent prompt:
|
||||
@@ -589,8 +591,9 @@ If \`DIFF_TOTAL < 200\`: skip this section silently. The ${outsideVoiceFor(ctx).
|
||||
|
||||
After all passes complete, persist:
|
||||
\`\`\`bash
|
||||
~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","host":"${ctx.host}","outside_provider":"${outsideVoiceFor(ctx).id}","outside_status":"OUTSIDE_STATUS","phase":"PHASE","tier":"always","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'"}'
|
||||
~/.claude/skills/gstack/bin/gstack-review-log '{"skill":"adversarial-review","timestamp":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'","status":"STATUS","source":"SOURCE","host":"${ctx.host}","outside_provider":"${outsideVoiceFor(ctx).id}","outside_status":"OUTSIDE_STATUS","phase":"PHASE","tier":"always","gate":"GATE","commit":"'"$(git rev-parse --short HEAD)"'","completed":COMPLETED,"converged":CONVERGED}' --finish PASS_START
|
||||
\`\`\`
|
||||
PASS_START is this source/phase's original start token. COMPLETED is true only for a completed response (false for timeout, failure, refusal, or missing coverage). CONVERGED is true only if the completed pass made no edits. Each token is consumed once; a fixing pass cannot certify the fixed tree without a fresh full pass. Missing/disabled passes have no token: omit \`--finish\` and log completed/converged false. Log each source/phase separately so a clean native response cannot hide missing outside coverage.
|
||||
Substitute: PHASE = "adversarial" or "structured" for the corresponding pass. STATUS = "clean" only for a completed pass with no findings, "issues_found" if any pass found issues. SOURCE = the completed outside provider for its record; use a separate in-host record for the native subagent. GATE = the ${outsideVoiceFor(ctx).label} structured review gate result ("pass"/"fail"), "skipped" if diff < 200, or "informational" if ${outsideVoiceFor(ctx).label} was unavailable. If all passes failed, persist status "unavailable" with outside_status "unavailable"; never persist "clean". Record the adversarial and structured phases separately if their coverage differs.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user