mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-06 00:44:07 +01:00
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:
1 parent
5114f8c59f
commit
4ce67de60b
21 files changed
+116
-94
No files matched your search
+1
-4
@@ -825,15 +825,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip the Codex passes only; the Claude adversarial subagent below STILL runs (it is free and fast). Print: "Codex passes skipped (codex_reviews disabled) — running Claude adversarial only."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
Disabled/unavailable: retain each applicable native pass. Recheck before each outside dispatch. Track provider and completed/unavailable/disabled/skipped per phase; CEO completion covers only CEO. Missing voices: N/A, never CONFIRMED. Skipped scope stays skipped.
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -779,16 +779,16 @@ missing work — do NOT call ExitPlanMode:
|
||||
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 —
|
||||
|
||||
@@ -236,15 +236,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip this section entirely; do NOT fall back to a Claude subagent — disabled means no extra review step. Print: "Codex review skipped (codex_reviews disabled). Re-enable: `gstack-config set codex_reviews enabled`."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
**Disabled is a terminal branch for this section.** If the preflight prints
|
||||
`CODEX_MODE: disabled`, persist `outside_status: disabled` with the guarded
|
||||
command below, then continue to Step 9. Do not construct a review prompt, invoke an outside CLI,
|
||||
@@ -346,10 +343,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: under_codex`, 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 Claude Code v2.1.198). Bound it at a 5-minute timeout; if it never completes, treat the review as unavailable and continue.
|
||||
Present findings under `DOCUMENTATION REVIEW (Claude 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.
|
||||
|
||||
@@ -166,7 +166,8 @@ Supersedes: {prior filename — omit this line if first design on this branch}
|
||||
|
||||
## 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**
|
||||
|
||||
|
||||
@@ -932,7 +932,7 @@ Present these approach options via AskUserQuestion using the preamble's AskUserQ
|
||||
|
||||
### 0F. Mode Selection
|
||||
After 0C-bis, before 0D; keep labels stable.
|
||||
Every mode requires your explicit approval for added scope.
|
||||
Every mode requires explicit user approval for scope changes.
|
||||
|
||||
The four modes are:
|
||||
1. **SCOPE EXPANSION:** The plan is good but could be great. Dream big — propose the ambitious version. Every expansion is presented individually for your approval. You opt in to each one.
|
||||
@@ -994,8 +994,8 @@ Both are outcome-framed. Only one makes the user feel the cathedral. Lead with t
|
||||
3. Keep stated invariants and acceptance criteria; repairs needed to meet them are in scope.
|
||||
|
||||
**For SCOPE REDUCTION** — run this:
|
||||
1. Ruthless cut: What is the absolute minimum that ships value to a user? Everything else is deferred. No exceptions.
|
||||
2. What can be a follow-up PR? Separate "must ship together" from "nice to ship together."
|
||||
1. Propose minimum scope for the core goal and work to defer.
|
||||
2. Explain each cut via AskUserQuestion; **STOP** for approval. Put approved cuts in "NOT in scope" and retain the rest.
|
||||
|
||||
### 0D-POST. Persist CEO Plan (EXPANSION and SELECTIVE EXPANSION only)
|
||||
|
||||
@@ -1050,7 +1050,8 @@ After writing the CEO plan, run the spec review loop on it:
|
||||
|
||||
## 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**
|
||||
|
||||
@@ -1157,16 +1158,16 @@ missing work — do NOT call ExitPlanMode:
|
||||
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 —
|
||||
|
||||
@@ -290,7 +290,7 @@ Present these approach options via AskUserQuestion using the preamble's AskUserQ
|
||||
|
||||
### 0F. Mode Selection
|
||||
After 0C-bis, before 0D; keep labels stable.
|
||||
Every mode requires your explicit approval for added scope.
|
||||
Every mode requires explicit user approval for scope changes.
|
||||
|
||||
The four modes are:
|
||||
1. **SCOPE EXPANSION:** The plan is good but could be great. Dream big — propose the ambitious version. Every expansion is presented individually for your approval. You opt in to each one.
|
||||
@@ -352,8 +352,8 @@ Both are outcome-framed. Only one makes the user feel the cathedral. Lead with t
|
||||
3. Keep stated invariants and acceptance criteria; repairs needed to meet them are in scope.
|
||||
|
||||
**For SCOPE REDUCTION** — run this:
|
||||
1. Ruthless cut: What is the absolute minimum that ships value to a user? Everything else is deferred. No exceptions.
|
||||
2. What can be a follow-up PR? Separate "must ship together" from "nice to ship together."
|
||||
1. Propose minimum scope for the core goal and work to defer.
|
||||
2. Explain each cut via AskUserQuestion; **STOP** for approval. Put approved cuts in "NOT in scope" and retain the rest.
|
||||
|
||||
### 0D-POST. Persist CEO Plan (EXPANSION and SELECTIVE EXPANSION only)
|
||||
|
||||
|
||||
@@ -362,15 +362,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip this section entirely; do NOT fall back to a Claude subagent — disabled means no extra review step. Print: "Codex review skipped (codex_reviews disabled). Re-enable: `gstack-config set codex_reviews enabled`."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
**Disabled is a terminal branch for this section.** If the preflight prints
|
||||
`CODEX_MODE: disabled`, persist `outside_status: disabled` with the guarded
|
||||
command below, then continue directly to the workflow's required outputs after this section. Do not construct a challenge,
|
||||
@@ -477,10 +474,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: under_codex`, 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 Claude Code v2.1.198; 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 Codex: cap the dispatch at a 5-minute timeout so "never blocking"
|
||||
@@ -711,11 +708,18 @@ this run (an empty file means "ran, no findings" — distinct from "didn't run")
|
||||
|
||||
|
||||
### Completion Summary
|
||||
|
||||
Use the full mode name from Step 0F; replace spaces with underscores only in the
|
||||
review log's `MODE` field. "System Audit" summarizes repository findings from
|
||||
Step 0 and the review sections. "Lake Score" counts complete options chosen
|
||||
out of decisions that compared a complete option with a shortcut; use `N/A`
|
||||
when there were no such decisions.
|
||||
|
||||
```
|
||||
+====================================================================+
|
||||
| MEGA PLAN REVIEW — COMPLETION SUMMARY |
|
||||
+====================================================================+
|
||||
| Mode selected | EXPANSION / SELECTIVE / HOLD / REDUCTION |
|
||||
| Mode selected | [full mode name from Step 0F] |
|
||||
| System Audit | [key findings] |
|
||||
| Step 0 | [mode + key decisions] |
|
||||
| Section 1 (Arch) | ___ issues found |
|
||||
|
||||
@@ -410,11 +410,18 @@ List every ASCII diagram in files this plan touches. Still accurate?
|
||||
{{TASKS_SECTION_EMIT:ceo-review}}
|
||||
|
||||
### Completion Summary
|
||||
|
||||
Use the full mode name from Step 0F; replace spaces with underscores only in the
|
||||
review log's `MODE` field. "System Audit" summarizes repository findings from
|
||||
Step 0 and the review sections. "Lake Score" counts complete options chosen
|
||||
out of decisions that compared a complete option with a shortcut; use `N/A`
|
||||
when there were no such decisions.
|
||||
|
||||
```
|
||||
+====================================================================+
|
||||
| MEGA PLAN REVIEW — COMPLETION SUMMARY |
|
||||
+====================================================================+
|
||||
| Mode selected | EXPANSION / SELECTIVE / HOLD / REDUCTION |
|
||||
| Mode selected | [full mode name from Step 0F] |
|
||||
| System Audit | [key findings] |
|
||||
| Step 0 | [mode + key decisions] |
|
||||
| Section 1 (Arch) | ___ issues found |
|
||||
|
||||
@@ -1192,16 +1192,16 @@ missing work — do NOT call ExitPlanMode:
|
||||
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 —
|
||||
|
||||
@@ -1131,16 +1131,16 @@ missing work — do NOT call ExitPlanMode:
|
||||
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 —
|
||||
|
||||
@@ -286,15 +286,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip this section entirely; do NOT fall back to a Claude subagent — disabled means no extra review step. Print: "Codex review skipped (codex_reviews disabled). Re-enable: `gstack-config set codex_reviews enabled`."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
**Disabled is a terminal branch for this section.** If the preflight prints
|
||||
`CODEX_MODE: disabled`, persist `outside_status: disabled` with the guarded
|
||||
command below, then continue directly to the workflow's required outputs after this section. Do not construct a challenge,
|
||||
@@ -401,10 +398,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: under_codex`, 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 Claude Code v2.1.198; 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 Codex: cap the dispatch at a 5-minute timeout so "never blocking"
|
||||
|
||||
@@ -736,16 +736,16 @@ missing work — do NOT call ExitPlanMode:
|
||||
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 —
|
||||
|
||||
@@ -391,15 +391,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip this section entirely; do NOT fall back to a Claude subagent — disabled means no extra review step. Print: "Codex review skipped (codex_reviews disabled). Re-enable: `gstack-config set codex_reviews enabled`."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
**Disabled is a terminal branch for this section.** If the preflight prints
|
||||
`CODEX_MODE: disabled`, persist `outside_status: disabled` with the guarded
|
||||
command below, then continue directly to the workflow's required outputs after this section. Do not construct a challenge,
|
||||
@@ -506,10 +503,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: under_codex`, 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 Claude Code v2.1.198; 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 Codex: cap the dispatch at a 5-minute timeout so "never blocking"
|
||||
|
||||
@@ -53,15 +53,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip the Codex passes only; the Claude adversarial subagent below STILL runs (it is free and fast). Print: "Codex passes skipped (codex_reviews disabled) — running Claude adversarial only."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
For this diff-review path, `CODEX_MODE: disabled` means skip the Codex passes ONLY — the
|
||||
Claude adversarial subagent below still runs (it's free and fast). `ready` runs the Codex
|
||||
passes; `not_installed` / `not_authed` skip them with the printed note and continue with
|
||||
|
||||
@@ -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\`.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -53,15 +53,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip the Codex passes only; the Claude adversarial subagent below STILL runs (it is free and fast). Print: "Codex passes skipped (codex_reviews disabled) — running Claude adversarial only."
|
||||
- **`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`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
For this diff-review path, `CODEX_MODE: disabled` means skip the Codex passes ONLY — the
|
||||
Claude adversarial subagent below still runs (it's free and fast). `ready` runs the Codex
|
||||
passes; `not_installed` / `not_authed` skip them with the printed note and continue with
|
||||
|
||||
@@ -84,7 +84,7 @@ test('only an explicit user selection or enabled successful mode check bypasses
|
||||
expect(q).toContain('`ASK_NORMALLY` means ask.');
|
||||
expect(s).toContain('This settles only the mode, not approach or scope approval.');
|
||||
expect(document).toContain('Do NOT proceed to mode selection (0F) without user approval of the chosen approach.');
|
||||
expect(s).toContain('Every mode requires your explicit approval for added scope.');
|
||||
expect(s).toContain('Every mode requires explicit user approval for scope changes.');
|
||||
expect(s).toContain('Keep the approved 0C-bis approach; explain and obtain approval for any mode-required change.');
|
||||
expect(s).toContain('offer all four modes in one AskUserQuestion');
|
||||
expect(s).toContain('context defaults for RECOMMENDATION');
|
||||
|
||||
+1
-4
@@ -2308,15 +2308,12 @@ echo "CODEX_MODE: $_CODEX_MODE"
|
||||
Branch on the echoed `CODEX_MODE`:
|
||||
- **`disabled`** — the user turned Codex reviews off (`codex_reviews=disabled`). Skip the Codex passes only; the factory (in-host) adversarial subagent below STILL runs (it is free and fast). Print: "Codex passes skipped (codex_reviews disabled) — running factory (in-host) adversarial only."
|
||||
- **`not_installed`** — Codex CLI absent. Print: "Codex not installed — falling back to a factory (in-host) 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 factory (in-host) 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 factory (in-host) subagent (same harness; model identity is unknown). Run `codex login` or set `$CODEX_API_KEY`." Fall back to the factory (in-host) 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 factory (in-host) 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 factory (in-host) subagent path. The ~10s round trip is cached for 1h; timeouts fail open to `ready`.
|
||||
- **`ready`** — run the Codex pass below.
|
||||
|
||||
A 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.
|
||||
|
||||
|
||||
For this diff-review path, `CODEX_MODE: disabled` means skip the Codex passes ONLY — the
|
||||
factory (in-host) adversarial subagent below still runs (it's free and fast). `ready` runs the Codex
|
||||
passes; `not_installed` / `not_authed` skip them with the printed note and continue with
|
||||
|
||||
@@ -5,12 +5,41 @@ import * as os from 'node:os';
|
||||
import * as path from 'node:path';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { outsideVoiceCommand, outsideVoicePreflight } from '../scripts/resolvers/outside-voice';
|
||||
import { generateCodexDocReview, generateCodexPlanReview } from '../scripts/resolvers/review';
|
||||
import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types';
|
||||
import { ALL_HOST_CONFIGS } from '../hosts';
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, '..');
|
||||
const TEMP = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-outside-preflight-'));
|
||||
afterAll(() => fs.rmSync(TEMP, { recursive: true, force: true }));
|
||||
|
||||
describe('own-harness review fallback instructions', () => {
|
||||
for (const host of ALL_HOST_CONFIGS) {
|
||||
for (const [name, render] of [['plan', generateCodexPlanReview], ['documentation', generateCodexDocReview]] as const) {
|
||||
test(`${host.name}: ${name} fallback names only the mode its preflight emits`, () => {
|
||||
const ctx: TemplateContext = { host: host.name, skillName: 'review', tmplPath: 'review/SKILL.md.tmpl', paths: HOST_PATHS[host.name] };
|
||||
const text = render(ctx);
|
||||
const mode = host.name === 'codex' ? 'under_current_harness' : 'under_codex';
|
||||
const preflight = text.match(/```bash\n([\s\S]*?)\n```/)![1];
|
||||
expect(preflight).toContain(mode);
|
||||
expect([...new Set(text.match(/under_codex|under_current_harness/g))]).toEqual([mode]);
|
||||
expect(text.includes("retain the section's native pass if defined")).toBe(false);
|
||||
|
||||
const fallback = text.slice(text.indexOf('**Native fallback'), text.indexOf('Dispatch via the Agent tool'));
|
||||
const ownHarnessBranch = `On \`CODEX_MODE: ${mode}\``;
|
||||
expect(text.split(ownHarnessBranch)).toHaveLength(2);
|
||||
expect(fallback).toContain(ownHarnessBranch);
|
||||
expect(fallback).toContain('`outside_status: unavailable`');
|
||||
expect(fallback).toContain('run no outside CLI');
|
||||
expect(fallback).toContain('use the native subagent below');
|
||||
expect(fallback).toContain('A native result never supplies outside coverage.');
|
||||
expect(fallback).toContain('The disabled branch never reaches this fallback.');
|
||||
expect(fallback).toContain('`CODEX_MODE: disabled`, finish this section with `outside_status: disabled`;');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function fixture() {
|
||||
const dir = fs.mkdtempSync(path.join(TEMP, 'case-'));
|
||||
const repo = path.join(dir, "repo ' $(touch NEVER)");
|
||||
|
||||
Reference in new issue
Block a user