feat: office-hours Claude subagent fallback when Codex unavailable (#464)

Updates generateCodexSecondOpinion resolver to always offer second opinion
and fall back to Claude subagent when Codex is unavailable or errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-27 00:30:02 -06:00
parent e97924c870
commit 08fc45dab9
4 changed files with 76 additions and 36 deletions
+34 -17
View File
@@ -672,21 +672,19 @@ Use AskUserQuestion to confirm. If the user disagrees with a premise, revise und
## Phase 3.5: Cross-Model Second Opinion (optional)
**Binary check first — no question if unavailable:**
**Binary check first:**
```bash
which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE"
```
If `CODEX_NOT_AVAILABLE`: skip Phase 3.5 entirely — no message, no AskUserQuestion. Proceed directly to Phase 4.
Use AskUserQuestion (regardless of codex availability):
If `CODEX_AVAILABLE`: use AskUserQuestion:
> Want a second opinion from a different AI model? Codex will independently review your problem statement, key answers, premises, and any landscape findings from this session. It hasn't seen this conversation — it gets a structured summary. Usually takes 2-5 minutes.
> Want a second opinion from an independent AI perspective? It will review your problem statement, key answers, premises, and any landscape findings from this session without having seen this conversation — it gets a structured summary. Usually takes 2-5 minutes.
> A) Yes, get a second opinion
> B) No, proceed to alternatives
If B: skip Phase 3.5 entirely. Remember that Codex did NOT run (affects design doc, founder signals, and Phase 4 below).
If B: skip Phase 3.5 entirely. Remember that the second opinion did NOT run (affects design doc, founder signals, and Phase 4 below).
**If A: Run the Codex cold read.**
@@ -723,15 +721,26 @@ cat "$TMPERR_OH"
rm -f "$TMPERR_OH" "$CODEX_PROMPT_FILE"
```
**Error handling:** All errors are non-blocking — Codex second opinion is a quality enhancement, not a prerequisite.
- **Auth failure:** If stderr contains "auth", "login", "unauthorized", or "API key": "Codex authentication failed. Run \`codex login\` to authenticate. Skipping second opinion."
- **Timeout:** "Codex timed out after 5 minutes. Skipping second opinion."
- **Empty response:** "Codex returned no response. Stderr: <paste relevant error>. Skipping second opinion."
**Error handling:** All errors are non-blocking — second opinion is a quality enhancement, not a prerequisite.
- **Auth failure:** If stderr contains "auth", "login", "unauthorized", or "API key": "Codex authentication failed. Run \`codex login\` to authenticate." Fall back to Claude subagent.
- **Timeout:** "Codex timed out after 5 minutes." Fall back to Claude subagent.
- **Empty response:** "Codex returned no response." Fall back to Claude subagent.
On any error, proceed to Phase 4 — do NOT fall back to a Claude subagent (this is brainstorming, not adversarial review).
On any Codex error, fall back to the Claude subagent below.
**If CODEX_NOT_AVAILABLE (or Codex errored):**
Dispatch via the Agent tool. The subagent has fresh context — genuine independence.
Subagent prompt: same mode-appropriate prompt as above (Startup or Builder variant).
Present findings under a `SECOND OPINION (Claude subagent):` header.
If the subagent fails or times out: "Second opinion unavailable. Continuing to Phase 4."
4. **Presentation:**
If Codex ran:
```
SECOND OPINION (Codex):
════════════════════════════════════════════════════════════
@@ -739,10 +748,18 @@ SECOND OPINION (Codex):
════════════════════════════════════════════════════════════
```
5. **Cross-model synthesis:** After presenting Codex output, provide 3-5 bullet synthesis:
- Where Claude agrees with Codex
If Claude subagent ran:
```
SECOND OPINION (Claude subagent):
════════════════════════════════════════════════════════════
<full subagent output, verbatim — do not truncate or summarize>
════════════════════════════════════════════════════════════
```
5. **Cross-model synthesis:** After presenting the second opinion output, provide 3-5 bullet synthesis:
- Where Claude agrees with the second opinion
- Where Claude disagrees and why
- Whether Codex's challenged premise changes Claude's recommendation
- Whether the challenged premise changes Claude's recommendation
6. **Premise revision check:** If Codex challenged an agreed premise, use AskUserQuestion:
@@ -780,7 +797,7 @@ Rules:
- One must be the **"minimal viable"** (fewest files, smallest diff, ships fastest).
- One must be the **"ideal architecture"** (best long-term trajectory, most elegant).
- One can be **creative/lateral** (unexpected approach, different framing of the problem).
- If Codex proposed a prototype in Phase 3.5, consider using it as a starting point for the creative/lateral approach.
- If the second opinion (Codex or Claude subagent) proposed a prototype in Phase 3.5, consider using it as a starting point for the creative/lateral approach.
**RECOMMENDATION:** Choose [X] because [one-line reason].
@@ -944,7 +961,7 @@ Supersedes: {prior filename — omit this line if first design on this branch}
{from Phase 3}
## Cross-Model Perspective
{If Codex ran in Phase 3.5: Codex's independent cold read — steelman, key insight, challenged premise, prototype suggestion. Verbatim or close paraphrase of what Codex said. If Codex did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
{If second opinion ran in Phase 3.5 (Codex or Claude subagent): independent cold read — steelman, key insight, challenged premise, prototype suggestion. Verbatim or close paraphrase. If second opinion did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
## Approaches Considered
### Approach A: {name}
@@ -1001,7 +1018,7 @@ Supersedes: {prior filename — omit this line if first design on this branch}
{from Phase 3}
## Cross-Model Perspective
{If Codex ran in Phase 3.5: Codex's independent cold read — coolest version, key insight, existing tools, prototype suggestion. Verbatim or close paraphrase of what Codex said. If Codex did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
{If second opinion ran in Phase 3.5 (Codex or Claude subagent): independent cold read — coolest version, key insight, existing tools, prototype suggestion. Verbatim or close paraphrase. If second opinion did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
## Approaches Considered
### Approach A: {name}
+3 -3
View File
@@ -380,7 +380,7 @@ Rules:
- One must be the **"minimal viable"** (fewest files, smallest diff, ships fastest).
- One must be the **"ideal architecture"** (best long-term trajectory, most elegant).
- One can be **creative/lateral** (unexpected approach, different framing of the problem).
- If Codex proposed a prototype in Phase 3.5, consider using it as a starting point for the creative/lateral approach.
- If the second opinion (Codex or Claude subagent) proposed a prototype in Phase 3.5, consider using it as a starting point for the creative/lateral approach.
**RECOMMENDATION:** Choose [X] because [one-line reason].
@@ -459,7 +459,7 @@ Supersedes: {prior filename — omit this line if first design on this branch}
{from Phase 3}
## Cross-Model Perspective
{If Codex ran in Phase 3.5: Codex's independent cold read — steelman, key insight, challenged premise, prototype suggestion. Verbatim or close paraphrase of what Codex said. If Codex did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
{If second opinion ran in Phase 3.5 (Codex or Claude subagent): independent cold read — steelman, key insight, challenged premise, prototype suggestion. Verbatim or close paraphrase. If second opinion did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
## Approaches Considered
### Approach A: {name}
@@ -516,7 +516,7 @@ Supersedes: {prior filename — omit this line if first design on this branch}
{from Phase 3}
## Cross-Model Perspective
{If Codex ran in Phase 3.5: Codex's independent cold read — coolest version, key insight, existing tools, prototype suggestion. Verbatim or close paraphrase of what Codex said. If Codex did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
{If second opinion ran in Phase 3.5 (Codex or Claude subagent): independent cold read — coolest version, key insight, existing tools, prototype suggestion. Verbatim or close paraphrase. If second opinion did NOT run (skipped or unavailable): omit this section entirely — do not include it.}
## Approaches Considered
### Approach A: {name}
+31 -14
View File
@@ -250,21 +250,19 @@ export function generateCodexSecondOpinion(ctx: TemplateContext): string {
return `## Phase 3.5: Cross-Model Second Opinion (optional)
**Binary check first no question if unavailable:**
**Binary check first:**
\`\`\`bash
which codex 2>/dev/null && echo "CODEX_AVAILABLE" || echo "CODEX_NOT_AVAILABLE"
\`\`\`
If \`CODEX_NOT_AVAILABLE\`: skip Phase 3.5 entirely — no message, no AskUserQuestion. Proceed directly to Phase 4.
Use AskUserQuestion (regardless of codex availability):
If \`CODEX_AVAILABLE\`: use AskUserQuestion:
> Want a second opinion from a different AI model? Codex will independently review your problem statement, key answers, premises, and any landscape findings from this session. It hasn't seen this conversation it gets a structured summary. Usually takes 2-5 minutes.
> Want a second opinion from an independent AI perspective? It will review your problem statement, key answers, premises, and any landscape findings from this session without having seen this conversation it gets a structured summary. Usually takes 2-5 minutes.
> A) Yes, get a second opinion
> B) No, proceed to alternatives
If B: skip Phase 3.5 entirely. Remember that Codex did NOT run (affects design doc, founder signals, and Phase 4 below).
If B: skip Phase 3.5 entirely. Remember that the second opinion did NOT run (affects design doc, founder signals, and Phase 4 below).
**If A: Run the Codex cold read.**
@@ -301,15 +299,26 @@ cat "$TMPERR_OH"
rm -f "$TMPERR_OH" "$CODEX_PROMPT_FILE"
\`\`\`
**Error handling:** All errors are non-blocking Codex second opinion is a quality enhancement, not a prerequisite.
- **Auth failure:** If stderr contains "auth", "login", "unauthorized", or "API key": "Codex authentication failed. Run \\\`codex login\\\` to authenticate. Skipping second opinion."
- **Timeout:** "Codex timed out after 5 minutes. Skipping second opinion."
- **Empty response:** "Codex returned no response. Stderr: <paste relevant error>. Skipping second opinion."
**Error handling:** All errors are non-blocking second opinion is a quality enhancement, not a prerequisite.
- **Auth failure:** If stderr contains "auth", "login", "unauthorized", or "API key": "Codex authentication failed. Run \\\`codex login\\\` to authenticate." Fall back to Claude subagent.
- **Timeout:** "Codex timed out after 5 minutes." Fall back to Claude subagent.
- **Empty response:** "Codex returned no response." Fall back to Claude subagent.
On any error, proceed to Phase 4 do NOT fall back to a Claude subagent (this is brainstorming, not adversarial review).
On any Codex error, fall back to the Claude subagent below.
**If CODEX_NOT_AVAILABLE (or Codex errored):**
Dispatch via the Agent tool. The subagent has fresh context genuine independence.
Subagent prompt: same mode-appropriate prompt as above (Startup or Builder variant).
Present findings under a \`SECOND OPINION (Claude subagent):\` header.
If the subagent fails or times out: "Second opinion unavailable. Continuing to Phase 4."
4. **Presentation:**
If Codex ran:
\`\`\`
SECOND OPINION (Codex):
@@ -317,10 +326,18 @@ SECOND OPINION (Codex):
\`\`\`
5. **Cross-model synthesis:** After presenting Codex output, provide 3-5 bullet synthesis:
- Where Claude agrees with Codex
If Claude subagent ran:
\`\`\`
SECOND OPINION (Claude subagent):
<full subagent output, verbatim do not truncate or summarize>
\`\`\`
5. **Cross-model synthesis:** After presenting the second opinion output, provide 3-5 bullet synthesis:
- Where Claude agrees with the second opinion
- Where Claude disagrees and why
- Whether Codex's challenged premise changes Claude's recommendation
- Whether the challenged premise changes Claude's recommendation
6. **Premise revision check:** If Codex challenged an agreed premise, use AskUserQuestion:
+8 -2
View File
@@ -986,12 +986,18 @@ describe('CODEX_SECOND_OPINION resolver', () => {
});
test('contains opt-in AskUserQuestion text', () => {
expect(content).toContain('second opinion from a different AI model');
expect(content).toContain('second opinion from an independent AI perspective');
});
test('contains cross-model synthesis instructions', () => {
expect(content).toMatch(/[Ss]ynthesis/);
expect(content).toContain('Where Claude agrees with Codex');
expect(content).toContain('Where Claude agrees with the second opinion');
});
test('contains Claude subagent fallback', () => {
expect(content).toContain('CODEX_NOT_AVAILABLE');
expect(content).toContain('Agent tool');
expect(content).toContain('SECOND OPINION (Claude subagent)');
});
test('contains premise revision check', () => {