Skip to content

feat(ai-review): lock Claude→Cursor→free model cascade - #52

Open
Hussam Aldarwish (eduly-haldarwish) wants to merge 10 commits into
mainfrom
feat/ai-review-model-cascade-51
Open

feat(ai-review): lock Claude→Cursor→free model cascade#52
Hussam Aldarwish (eduly-haldarwish) wants to merge 10 commits into
mainfrom
feat/ai-review-model-cascade-51

Conversation

@eduly-haldarwish

@eduly-haldarwish Hussam Aldarwish (eduly-haldarwish) commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Test plan

  • node --test ai-review/lib/*.test.js ai-qa/lib/*.test.js (285 passing)
  • Self-test / consumer PR run against gateway: confirm primary Claude, fallback list in logs, footer Model line on published review
  • Confirm overload path can select Cursor then free (when reproducible)

Made with Cursor

🤖 AI Review — checklist verification

  • ❔ [x] node --test ai-review/lib/.test.js ai-qa/lib/.test.js (285 passing) — test_execution was skipped this session per rubric instruction (tests not run). Static check: test file counts (action-refs 10, aggregate 57, derive-findings 16, metrics 21, prep 21, publish 33, recompute 21, roster 80, write-manifest 25, report-footer 3 = 287 test() blocks across suites) is consistent with a ~285 passing claim, but cannot confirm pass/fail without execution.
  • ❔ [ ] Self-test / consumer PR run against gateway to confirm the cascade actually falls through on a live block — Requires a live gateway run against real credentials; cannot verify via static review.
  • ❔ [ ] Confirm overload path can select Cursor then free without manual intervention — Requires live-gateway observation of an overload scenario; cannot verify via static review.

Last updated by ai-review · verdict: pass.

mtm-bot[bot]

This comment was marked as outdated.

@eduly-haldarwish Hussam Aldarwish (eduly-haldarwish) changed the title Lock Claude→Cursor→free model cascade in ai-review and ai-qa feat(ai-review): lock Claude→Cursor→free model cascade Aug 17, 2026
@mtm-bot mtm-bot Bot removed the ✓ /ai-review label Aug 17, 2026
Prefer the execution-log model when present; otherwise use
steps.models.outputs.primary instead of a second Sonnet literal.

Refs #51
claude/cursor/claude-* hangs Claude Code CLI (aborted_streaming) even when
/v1/messages succeeds, so a Claude-off cascade never reached free. Cap the
chain at three entries to match the CLI limit.

Refs #51
@mtm-bot
mtm-bot Bot dismissed their stale review August 17, 2026 05:34

Superseded by a new ai-review run.

@mtm-bot mtm-bot Bot added the ✗ /ai-review ai-review failed label Aug 17, 2026
mtm-bot[bot]

This comment was marked as outdated.

Repair was skipped when claude-code-action failed on missing
structured_output without exporting session_id. Recover it from the
execution snapshot. Schema stages fall back to structured_output free
models only — Cursor has no SO and can retract schema mid-stream.

Refs #51
@mtm-bot mtm-bot Bot removed the ✗ /ai-review ai-review failed label Aug 17, 2026
@mtm-bot
mtm-bot Bot dismissed their stale review August 17, 2026 07:33

Superseded by a new ai-review run.

mtm-bot[bot]

This comment was marked as outdated.

@mtm-bot
mtm-bot Bot dismissed their stale review August 17, 2026 07:59

Superseded by a new ai-review run.

mtm-bot[bot]

This comment was marked as outdated.

Some structured outputs deliver comment_markdown with two-character
"\n" sequences (seen on PR #52 review 4949356509), which GitHub
renders as one smashed block under the banner.

Refs #51
@mtm-bot mtm-bot Bot removed the ✓ /ai-review label Aug 17, 2026
@mtm-bot
mtm-bot Bot dismissed their stale review August 17, 2026 09:35

Superseded by a new ai-review run.

@mtm-bot mtm-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ PASS

1 P2 / 1 P3 finding(s) noted — non-blocking.

Confidence: 95 · Merge risk: low
P0: 0 · P1: 0 · P2: 1 · P3: 1

Model: claude/claude-sonnet-5
Re-run this job if you need another review pass.

P0 — Blockers

None.

P1 — Should Fix

None.

P2 — Nice to Have

  • Duplicated locked-model/cascade strings between ai-review/action.yml and ai-qa/action.yml (ai-review/action.yml:437-440, ai-qa/action.yml:299-301). This is an explicitly accepted tradeoff per the design doc ("no shared package," with a "keep in sync" comment present in the shipped code), so it's not a defect — just a spot future edits could drift on since nothing automated enforces the two lists staying aligned.

P3 — Nits

  • The free-tier fallback lists (oc/nemotron-3.5-lightning-free,oc/deepseek-v4-flash-free,auto/best-free) are repeated as literal strings across HAIKU_FALLBACK, SONNET_FALLBACK/FREE_SO, and OPUS_FALLBACK inside the same file (ai-review/action.yml:437-440) — cosmetic only, FREE_SO is already reused for two of the three.

Strengths

  • Model-cascade lock is complete and consistent. Directly verified ai-review/action.yml's inputs: block (lines 16-231) no longer defines sonnet-model/opus-model/haiku-model, and ai-qa/action.yml no longer defines qa-model (confirmed via git diff — 3 removal points: input def, a stale comment, and the --model flag usage). No remaining workflow/README references to any of the four removed inputs.
  • Cascade ordering matches issue #51 and the design doc exactly: Claude primary → Cursor composer-2.5 (excluded from every --json-schema/structured-output stage, matching the documented "no Cursor model advertises structured_output" constraint) → pinned OpenCode free models → auto/best-free as last hedge. auto/* never appears as a primary. All fallback lists stay within the CLI's 3-entry --fallback-model cap.
  • session_id recovery bugfix is correctly wired end-to-end. retry_budget's new jq-based recovery (falling back from env, to snapshot init entries, to result entries) and review_repair's if:/--resume were both switched consistently to steps.retry_budget.outputs.session_id — no drift between the two references.
  • Model attribution ("what actually ran") is correctly threaded through Publish in both actions. resolveModelUsed (ai-review) checks retry → repair → review logs in priority order before falling back to the routed primary; modelFromExecutionLog (ai-qa) reads the review log and only falls back to the primary when QA_OUTPUT is truthy (avoiding false attribution when review never produced output). Both are covered by direct unit tests (publish.test.js, metrics.test.js, report-footer.test.js).
  • unescapeLiteralNewlines fix is narrowly scoped and tested — only triggers when the literal-\n count meets/exceeds the real-newline count, avoiding accidental mangling of legitimate backslash-n sequences in review text.
  • Docs (docs/plan.md, the cascade design doc, both READMEs) are fully scrubbed of stale model-routing/model-input descriptions and now accurately describe the locked cascade, matching the shipped code.
  • Test coverage for all new/changed logic is present: report-footer.js (new), metrics.js's resolveModelUsed, and publish.js's footer/unescape helpers all have accompanying passing-shaped unit tests; this is CI/config wiring rather than a critical runtime path, so the existing coverage is adequate.

Intent Alignment

[Intent]Aligned — All 5 tasks from linked issue #51 are directly verified in code (not just inferred from docs):

  1. Publish banner with model + re-run hint — shipped in both actions, tested.
  2. Resolve actual model from execution logs into Publish — shipped in both actions, tested.
  3. Remove sonnet-model/opus-model/haiku-model inputs, hardcode the Claude→Cursor→free cascade — confirmed via direct read of the inputs: block.
  4. Remove qa-model, apply the same cascade+footer pattern to ai-qa — confirmed via git diff.
  5. Scrub stale docs — confirmed via full diffs of docs/plan.md, the design doc, and both READMEs.

No scope creep beyond the issue's task list; no missing requirement.

Testing

Test execution was skipped per review policy (static review only). The PR's checked test-plan item (node --test ... 285 passing) is unverifiable from this session but is structurally plausible — direct counting of test() blocks across the referenced suites (including the two new ai-qa/lib/report-footer.test.js cases) is consistent with that scale. The two unchecked live-gateway verification items are inherently unverifiable via static review and correctly left unchecked by the author.

Model: claude-sonnet-5
Re-run this job if you need another review pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lock Claude→Cursor→free model cascade in ai-review and ai-qa

1 participant