fix: clarify outside review fallback and CEO decisions

Render one applicable own-harness fallback path and retain native review,
disabled policy, and missing-coverage semantics. Align report field names
and mode labels, and make the existing per-cut scope approval explicit.

Regenerate skill outputs and keep the workflow judge's model, thresholds,
and retry policy unchanged.
This commit is contained in:
Garry Tan committed 2026-09-11 18:11:57 +00:00
1 parent 5114f8c59f
commit 4ce67de60b
21 files changed
+116 -94

No files matched your search

+1 -1
View File
@@ -152,7 +152,7 @@ echo "CODEX_MODE: $${m}"
Branch on the echoed \`CODEX_MODE\`:
- **\`disabled\`** — the user turned Codex reviews off (\`codex_reviews=disabled\`). ${disabledLine}
- **\`not_installed\`** — Codex CLI absent. Print: "Codex not installed — falling back to a Claude subagent (fresh context, but the same harness; model identity is unknown). Install Codex for an actual outside-model read: \`npm install -g @openai/codex\`." Fall back to the Claude subagent path.
- **\`under_codex\`** — stale artifact selected its own harness. Print: "Codex outside review unavailable: harness mismatch; no outside process started. Missing coverage. Repair: setup --host codex." Skip the outside invocation; retain the section's native pass if defined. Conflicting inherited harness markers are not grounds to guess another provider.
- **\`under_codex\`** — stale artifact selected its own harness. Print: "Codex outside review unavailable: harness mismatch; no outside process started. Missing coverage. Repair: setup --host codex." Skip the outside invocation and follow the workflow's native-review instructions below. Conflicting inherited harness markers are not grounds to guess another provider.
- **\`not_authed\`** — installed but no credentials. Print: "Codex installed but not authenticated — falling back to a Claude subagent (same harness; model identity is unknown). Run \`codex login\` or set \`$CODEX_API_KEY\`." Fall back to the Claude subagent path.
- **\`broken_install\`** — the CLI is on PATH but cannot execute (spawn ENOENT, non-executable binary, missing vendor payload). Print: "Codex is installed but its binary cannot run — Codex passes skipped. Reinstall: \`npm install -g @openai/codex\`." Relay the probe's HINT lines and fall back to the Claude subagent path. This state exists because a missing binary used to land in the model probe's fail-open bucket and report \`ready\`, so every Codex pass was skipped silently (#2742).
- **\`model_unusable\`** — authed but the account cannot use gstack's selected Codex model (#2477: HTTP 400 on every call). Relay the probe's HINT lines, tell the user the one-line fix (set \`GSTACK_CODEX_MODEL=<supported-model>\` or pass an explicit \`-c model=...\` override), and fall back to the Claude subagent path. The ~10s round trip is cached for 1h; timeouts fail open to \`ready\`.
+1 -1
View File
@@ -71,7 +71,7 @@ export function outsideVoicePreflight(ctx: TemplateContext, opts: { disabledBeha
if (v.id === 'codex' && opts.disabledBehavior !== 'opt-in') {
const preflight = outsideVoiceLabels(ctx, codexPreflight(opts))
.replace('```bash\n', `\`\`\`bash\n${outsideVoiceRuntime(ctx)}\n`);
return preflight + '\n\nA stale artifact selecting its own harness must report missing coverage and run no outside CLI. Repair: `setup --host codex`. Never infer a replacement provider from inherited environment markers. The invocation below repeats this guard.\n';
return preflight;
}
const bin = toShellPath(ctx.paths.binDir);
const probe = v.id === 'codex'
+14 -13
View File
@@ -203,16 +203,16 @@ ${approvals}1. Read the plan file with the Read tool (after your most recent wri
does NOT count — only the structured \`## GSTACK REVIEW REPORT\` section
satisfies this check.
3. Confirm the report has a Runs / Status / Findings table and a VERDICT line
(CODEX / CROSS-MODEL absorbed if applicable).
(OUTSIDE COVERAGE / CROSS-MODEL included when applicable).
4. Confirm the report's FINAL non-whitespace line is the unresolved-decisions
status: the exact unbolded \`NO UNRESOLVED DECISIONS\`, or a bullet of a final
\`**UNRESOLVED DECISIONS:**\` block. BLOCKING, no "if applicable" escape — a
bolded sentinel, any trailing CODEX/CROSS-MODEL/VERDICT/prose, or a missing
bolded sentinel, any trailing report field or prose, or a missing
status each FAILS the gate.
5. If a plan file is in context for this skill invocation: confirm
\`gstack-review-log\` was called and \`gstack-review-read\` was run at least
once. If no plan file is in context (e.g. \`/codex consult\` against a
diff with no plan), this check short-circuits — checks 1-4 already
once. If no plan file is in context (e.g. a diff review with no plan),
this check short-circuits — checks 1-4 already
short-circuit when no plan file exists.
Failing this gate and calling ExitPlanMode anyway is a contract violation —
@@ -230,7 +230,8 @@ export function generateAntiShortcutClause(_ctx: TemplateContext): string {
export function generateSpecReviewLoop(_ctx: TemplateContext): string {
return `## Spec Review Loop
Before presenting the document to the user for approval, run an adversarial review.
Run an adversarial review before presenting the final document to the user.
Follow the calling workflow's approval steps.
**Step 1: Dispatch reviewer subagent**
@@ -706,10 +707,10 @@ Immediately before dispatching, check the preflight result again. On
\`CODEX_MODE: disabled\`, finish this section with \`outside_status: disabled\`;
do not dispatch. Otherwise, use this fallback for missing/broken CLI, failed
authentication/model selection, a failed preflight, or a failed outside invocation.
The disabled branch never reaches this fallback. In this section, \`under_codex\`
or \`under_current_harness\` also follows this native fallback: run no outside CLI,
report the setup repair and \`outside_status: unavailable\`, then use the native
subagent below. A native result never supplies outside coverage.
The disabled branch never reaches this fallback.
On \`CODEX_MODE: ${outsideVoiceFor(ctx).id === 'codex' ? 'under_codex' : 'under_current_harness'}\`, report the setup repair and
\`outside_status: unavailable\`, run no outside CLI, and use the native subagent below.
A native result never supplies outside coverage.
Dispatch via the Agent tool with \`run_in_background: false\` (subagents default to background since ${CC_BACKGROUND_DEFAULT_SINCE}; the findings must land before the workflow continues). The subagent has fresh context and no conversation bias — but it is the same harness; model identity stays unknown unless the runtime reports it; weigh its agreement accordingly.
Bound it the same way as ${outsideVoiceFor(ctx).label}: cap the dispatch at a 5-minute timeout so "never blocking"
@@ -846,10 +847,10 @@ Immediately before dispatching, check the preflight result again. On
\`CODEX_MODE: disabled\`, finish this section with \`outside_status: disabled\`;
do not dispatch. Otherwise, use this fallback for missing/broken CLI, failed
authentication/model selection, a failed preflight, or a failed outside invocation.
The disabled branch never reaches this fallback. In this section, \`under_codex\`
or \`under_current_harness\` also follows this native fallback: run no outside CLI,
report the setup repair and \`outside_status: unavailable\`, then use the native
subagent below. A native result never supplies outside coverage.
The disabled branch never reaches this fallback.
On \`CODEX_MODE: ${outsideVoiceFor(ctx).id === 'codex' ? 'under_codex' : 'under_current_harness'}\`, report the setup repair and
\`outside_status: unavailable\`, run no outside CLI, and use the native subagent below.
A native result never supplies outside coverage.
Dispatch via the Agent tool with the same prompt, passing \`run_in_background: false\` (subagents default to background since ${CC_BACKGROUND_DEFAULT_SINCE}). Bound it at a 5-minute timeout; if it never completes, treat the review as unavailable and continue.
Present findings under \`DOCUMENTATION REVIEW (${outsideVoiceFor(ctx).nativeLabel} subagent):\`. If it fails: "Doc review unavailable. Continuing to Step 9." Skip the apply gate, persist \`status: unavailable\`, \`outside_status: unavailable\`, and \`source: none\` below, then continue; unavailable is not a clean review.