Skip to content

feat(ai-review): model cascade + delta/OSH/Test Plan CI - #54

Merged
Hussam Aldarwish (eduly-haldarwish) merged 31 commits into
mainfrom
feat/ai-review-cascade-and-osh
Aug 18, 2026
Merged

feat(ai-review): model cascade + delta/OSH/Test Plan CI#54
Hussam Aldarwish (eduly-haldarwish) merged 31 commits into
mainfrom
feat/ai-review-cascade-and-osh

Conversation

@eduly-haldarwish

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

Copy link
Copy Markdown
Contributor

Summary

Combines closed #52 and #53 into one PR against main.

  • Model cascade (feat(ai-review): lock Claude→Cursor→free model cascade #52 / Lock Claude→Cursor→free model cascade in ai-review and ai-qa #51): lock Claude primaries in ai-review and ai-qa with Cursor → pinned OpenCode free → auto/best-free fallbacks; unescape literal \n in publish bodies.
  • Delta reviews: after last published <!-- ai-review-meta -->, re-runs review prior_head…HEAD (full on missing/inconclusive meta, rebase, base change, or force-full-review).
  • Test Plan ↔ CI: inventory CI; uncovered Test Plan items → findings; checklist tick / PR-body write-back retired.
  • OSH fan-out: route by roster K — K≤1 Sonnet collapse; K>1 Opus parent + Sonnet Task workers (osh-* agents; no Haiku Task children). Size-based sonnet-*-threshold routing deprecated.

Spec: docs/superpowers/specs/2026-08-17-ai-review-osh-delta-testplan-design.md. ADR: docs/adr/0006-test-plan-ci-findings-and-osh-routing.md.

Test plan

  • node --test ai-review/lib/*.test.js (324+ pass)
  • Selftest on combined tip: review PASS / APPROVED (gated-demo green)
  • Fresh PR: full review + meta marker on published body
  • Push follow-up: delta mode + prior-review carry-forward
  • force-full-review: true forces full range with valid prior meta
  • Test Plan items with weak/no CI → findings; PR body checkboxes unchanged
  • Small diff (K=1): Sonnet collapse; large multi-file (K>1): Opus + Task

Made with Cursor

✅ ai-qa: PASS

Deploy health: healthy · findings P0 0 · P1 0 · P2 0 · P3 0

Last updated by ai-qa · QA run

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
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
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
Slice 1 helpers for OSH redesign: parse/format ai-review-meta, resolve
full vs delta range, and stamp the marker on published review bodies.
Wire prep to resolve full vs delta from prior review meta, drive
numstat/diff from the active range, stamp publish meta, and document
force-full-review. Preserve prior-review.md on forced full for carry-forward.
Map PR Test Plan items to CI check inventory as findings; retire PR-body checklist tick write-back.
Keep mixed checkbox + bullet/numbered items; fall back to body checkboxes when the section is empty.
Route review model by roster K from assignments.json (K≤1 Sonnet collapse,
K>1 Opus fan-out). Deprecate file/churn thresholds for selection. Parent SO
remains the Publish gate; multi-role aggregate.js stays shadow-only.
…er confidence

Roster write failures now fail prep (Slice 3 routes on assignments.json).
Collapse restores Read-only allowlist; fanout adds Task only (no Write).
Fan-out SO confidence/severity_confirmed come from the Haiku scorer.
Column-0 heredoc bodies inside `run: |` terminate the block scalar, so
GitHub Actions failed to load action.yml (line 532: expected ':'). Copy
checked-in fanout/collapse policy files instead.
Haiku Task children inherit Opus adaptive thinking and 400 on this
gateway. Pre-register osh-* Sonnet --agents and spawn them in one wave.
Stop printing Model: on published review bodies.
Claude stages abort when GET .../collaborators/.../permission returns
503, before any model work. Pass allowed_non_write_users through and
scope selftest to the PR author so Context/Review can run; Publish still
uses the App token.
Opt out of CCA subprocess env scrub (invalid package.json broke Publish),
stop silencing testplan-ci failures, tighten Task tools, and align docs with
Sonnet-only workers plus the two-axis K formula.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fan-out review regularly burns ~27m before SO; the 30m job ceiling was
cancelling mid-Opus and publishing inconclusive.

Co-authored-by: Cursor <cursoragent@cursor.com>
…kiness

Remove allowed-non-write-users (selftest + action wiring) and the CCA
subprocess scrub opt-out that only existed to make that bypass safe.
Keep the 55m selftest timeout for real Opus fan-out wall-clock.

Co-authored-by: Cursor <cursoragent@cursor.com>
mtm-bot[bot]

This comment was marked as outdated.

@mtm-bot mtm-bot Bot added the ✗ /ai-review ai-review failed label Aug 18, 2026
Documented 25m / issues: read would cancel Opus fan-out before Publish or
403 addLabels before verdict is set. Match selftest (55m, issues: write),
keep labels from swallowing the gate, and prefer completed CI rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mtm-bot mtm-bot Bot removed the ✗ /ai-review ai-review failed label Aug 18, 2026
@mtm-bot
mtm-bot Bot dismissed their stale review August 18, 2026 03:45

Superseded by a new ai-review run.

mtm-bot[bot]

This comment was marked as outdated.

They were deprecated no-ops; delete them so callers cannot imply in-review
suite execution. ai-qa test-hint is unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mtm-bot mtm-bot Bot removed the ✓ /ai-review label Aug 18, 2026
Prove prior_head…HEAD selection against a real git history (including
force-push fallback), and assert selftest Publish stamps parseable
ai-review-meta without a recursive follow-up push.

Co-authored-by: Cursor <cursoragent@cursor.com>
@eduly-haldarwish

Copy link
Copy Markdown
Contributor Author

Added delta coverage for the incremental-review ask:

  • Unit: write-delta.test.js now uses a real git history — delta only includes the follow-up commit’s files; rewritten history → full; CLI main() emits prep KEY=value lines.
  • Selftest: after a non-empty verdict, asserts the published review has parseable <!-- ai-review-meta head_sha=… base_sha=… mode=full|delta|inconclusive --> (and tip match for full/delta).

A live second-push delta run still isn’t in CI (would re-enter the workflow / cancel-in-progress); the unit tests cover that range math.

Avoid ${{ }} expansion inside the run script so template-injection
audit passes; bind VERDICT in env like the other step inputs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mtm-bot
mtm-bot Bot dismissed their stale review August 18, 2026 04:40

Superseded by a new ai-review run.

mtm-bot[bot]

This comment was marked as outdated.

Prep always writes a factual context.md from the manifest/roster so Review
keeps handoff when Haiku stalls. Auto-skip the Haiku Context stage on
delta + K≤1 (must-read gate unchanged); full/large reviews still enrich.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mtm-bot mtm-bot Bot removed the ✓ /ai-review label Aug 18, 2026
@mtm-bot
mtm-bot Bot dismissed their stale review August 18, 2026 05:21

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

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

Confidence: 65 · Merge risk: medium
P0: 0 · P1: 0 · P2: 7 · P3: 11

Re-run this job if you need another review pass.

This delta makes context.md deterministic — prep always writes it — and auto-skips the Haiku enrichment stage on delta + roster K≤1. Reviewed as a delta against 73aba88 (7 files, 340 lines churn) with an OSH fan-out: two coverage reviewers, a cross-file tracer, a history pass, and an independent scorer.

Intent (Angle H, framed before the diff): linked-issues.json is empty, so the contract is the PR body. This delta's performance work is not one of the four stated workstreams there — but it is a coherent, well-scoped extension of the delta-review workstream rather than a deviation, and the README and input documentation were updated in the same commit. Judged aligned.

P0 — Blockers

None.

P1 — Should Fix

None.

P2 — Nice-to-Have

  • ai-review/action.yml:509 — the new auto-skip branch has no test coverage of any kind. grep -rn "run-context-stage|RUN_CONTEXT_STAGE|ENABLE_CONTEXT_STAGE" ai-review/lib/ .github/workflows/ returns nothing. This is the central behavioral change of the delta, and it lives entirely in shell inside a composite action — the one layer with no harness. selftest.yml deliberately passes no enable-context-stage (correct, so the default path stays exercised), but nothing asserts which branch was taken. A future edit that inverts the condition would skip Haiku on every review, or run it on every review, with a fully green suite. The logic itself is sound: REVIEW_MODE is defaulted at :462 before the :511 comparison, K is guarded as ${K:-0}, and the run-context-stage key is spelled consistently at :558, :608, and :700.
  • ai-review/action.yml:1062RETRY_BUDGET_MS still justifies itself with a 25-minute timeout that no longer exists. (Carried forward, re-verified.) The budget is 15 minutes while README.md:327 recommends timeout-minutes: 55. A first attempt running 16 minutes skips the retry with ~39 minutes of headroom left.
  • ai-review/README.md:130 — per-role findings/<role>.json artifacts the roster path does not produce. (Carried forward, narrowed on fresh evidence.) The scorer partially refuted the original framing: action.yml:1564-1566 does write .ai-review/findings/review-serial.json in shadow-aggregation mode, so the directory is not wholly fictional. The multi-role framing at :130 remains aspirational.
  • ai-review/lib/testplan-ci.js:140 — same-rank duplicate check rows resolve to last-in-array. (Carried forward.) Two completed rows for one check name tie on rank, and the Checks API does not guarantee order, so a stale failure can overwrite a newer success. Bounded: this feeds the advisory inventory, not the deterministic CI_SIGNAL.
  • ai-review/action.yml:1871 — the happy-path createReview is still unwrapped while addLabels/removeLabel directly below it are hardened. Fail-safe in direction, but it fails by job death rather than by the deterministic non-pass verdict the design intends. (Carried forward.)
  • ai-review/action.yml:710SIGNAL reads the raw check-runs array while ci-checks.json is deduped. (Carried forward.) The two views can disagree on precisely the duplicate case checkRowRank exists to handle. Direction is fail-safe.
  • ai-review/lib/action-refs.js:13 — the reference linter validates step IDs but not output keys. STEP_REF_RE = /steps\.([\w-]+)\./g captures the step id only. A typo in run-context-stage on either the producer or a consumer side would evaluate to the empty string, making == 'true' false and disabling the Haiku stage permanently and silently. A pre-existing limitation, but this delta's new wiring is what falls into it.

P3 — Nits

  • ai-review/action.yml:10 — the action's own top-level description: still says the Haiku stage always summarizes the diff first. The README was updated correctly; this in-file description was not, so the marketplace listing now contradicts the behavior.
  • ai-review/lib/write-context.test.js:55 — the full-mode else if (m.base_sha) branch is never asserted. Test 1 has no base_sha, test 2 is delta mode, test 3 omits it — so the "active diff base (merge-base)" line is dead code in the suite. One line added to test 3 closes it.
  • ADR 0006 and the workstream design spec don't mention the auto-skip. grep -rn "context" docs/adr/0006-…md returns nothing; the spec references the context stage only as a model-ID table row. The decision trail no longer explains why Haiku became conditional. (ADR 0003's "best-effort, read if present" claim still holds — this change strengthens it.)
  • ai-review/lib/write-context.js — no byte or count budget on the changed-file and symbol lists. Marginal: roster.js already bounds per-reviewer file and byte budgets upstream.
  • ai-review/rubric.md:412, README.md:219, action.yml:92 — all three still claim P3 findings lower the reported confidence, but recompute.js:90 has no P3 term. (Carried forward, re-verified in all three locations.)
  • ai-review/lib/write-delta.test.js:109,150,190,228 — bare fs.rmSync while :285,328,390 use try/finally. (Carried forward.)
  • ai-review/lib/publish.js:82modelFooter(_modelUsed) still discards its parameter while resolveModelUsed parses three logs on every publish. (Carried forward.)
  • ai-review/README.md:243 — no blank line before the ## Test Plan ↔ CI heading. The file was edited again in this delta without fixing it. (Carried forward.)
  • .github/workflows/selftest.yml:19 — the K=1 Sonnet collapse path still has no CI coverage; this run is K=2. Newly relevant: the auto-skip fires only on delta + K≤1, so the untested collapse lane is now the only lane where the new skip triggers end-to-end.
  • .github/workflows/selftest.yml:57force-full-review still has no CI lane that sets it. (Carried forward, narrowed — the prior delta added genuine unit coverage; only the wiring is unasserted.)
  • .github/workflows/selftest.yml:72 — Test Plan item 4 has no end-to-end assertion. The comment's reason for declining a second push (racing cancel-in-progress) is sound; recorded as a residual gap rather than counted as coverage.

Prior review — carry-forward status

The prior review at 73aba88 was PASS with 0 P0 / 0 P1 / 8 P2 / 9 P3. This delta touches none of the files those findings live in except README.md and action.yml, and none of the open findings were closed by it. All are restated above, each re-verified this session with a fresh command rather than copied forward. Two were revised on new evidence: the findings/<role>.json claim is narrower than stated (shadow mode does write one file), and force-full-review drops to P3 now that real unit coverage exists.

Also carried at prior severity but outside the active range, listed so they are not dropped silently: testplan-ci.test.js:149's ordering-pinned dedupe test, delta.js:17's permissive \S+ SHA pattern, publish.js:38's literal < real newline heuristic, testplan-ci.js:139's callerless findObviousUncoveredItems, osh-agents.json:41's scorer tool grant, and rubric.md:178's commitlint P0/P2 split.

Test Plan ↔ CI mapping

CI inventory: Lint workflow and action files ✅, Static analysis of GitHub Actions workflows ✅, duplicated-snippets ✅, node-test ✅, review (this run, in progress).

  • Covered: items 1–2 — node --test maps to node-test, whose glob picks up the new write-context.test.js; the selftest verdict lane is green. Item 3 (meta marker) is asserted by the step added in a prior commit. Item 6 (Test Plan gaps → findings, checkboxes untouched) is exercised by this review itself.
  • Partially covered: item 4 — unit-tested against a real git history and demonstrated live by this run, but not asserted end-to-end.
  • Uncovered: item 5 (force-full-review, wiring only) and item 7 (K=1 collapse). Both filed as findings above rather than assumed covered. Item 7 is the notable one for this delta — the new auto-skip fires only on the K≤1 path that no CI lane exercises.

PR-body checkboxes were not modified; CI, not ticks, is the coverage source here.

Strengths

  • The skip removes exposure to a known failure mode, not just wall-clock. action.yml:825-827 records that three of four historical gateway stalls hit the Context stage, and that removing the stage is "the only measure so far shown to avoid the failure, as opposed to bounding it." Skipping it on small deltas applies that evidence where the enrichment is worth least. That reasoning is written down at the site rather than left in a commit message.
  • The deterministic write lands before the optional stage, so Review never loses handoff. The ordering is the whole point of the design and it's implemented correctly: writeRoster writes context.md at prep time, and the Haiku stage only ever enriches. A stalled or skipped Haiku now degrades to a factual context file instead of no context at all — which is what makes skipping it safe in the first place.
  • The failure path is genuinely fail-open. The new block in write-manifest.js wraps the context write in try/catch and downgrades any error to a ::warning::, so a broken context write cannot sink a review. The Verify context.md handoff step branches on RAN_HAIKU_CONTEXT to give an accurate diagnostic either way, and a missing output degrades to the generic warning rather than erroring.
  • Telemetry was updated to match, so the skip cannot masquerade as a stall. metrics.js has NOT_RUN.ran = false, isStalled requires ran === true, collectMetrics maps a null log to NOT_RUN, and renderSummary prints _skipped_. metrics.test.js:219 ("a skipped stage is not a stall") pins it. Extending an observability contract alongside the behavior change is the part most easily forgotten.
  • The test-only no-op branch does not weaken the production path. writeRoster's io seam skips the real write unless a test supplies writeContext, avoiding cwd pollution — and main() calls writeRoster(manifest, sizes) with no io at :151, so production always resolves the real writer. write-manifest.test.js:427-428 backs this with a real-disk main() assertion under a proper chdir/try/finally, so the injection seam cannot silently become the shipped behavior.
  • The self-test comment argues for what it deliberately does not configure. selftest.yml:61-65 explains that omitting enable-context-stage is intentional, so the self-test exercises the same default consumers get, and warns against forcing false because that would leave the default path untested. That is a real trade-off recorded at the decision point.
  • Documentation was updated at every layer a consumer actually reads. README item 9, the enable-context-stage input row at :222, and the input description at action.yml:113-120 all describe the deterministic write and the delta + K≤1 auto-skip consistently with the implementation. The gap is confined to the ADR trail.

Verification notes

Per instruction, the project's tests were not run and no toolchain was probed — test_execution: "skipped". Every claim above rests on a command run this session; the commands and their output are recorded in verification_evidence. The cross-file tracer found no coherence breakage in the new write-manifest.jswrite-context.js wiring. Confidence and severity were assigned by an independent scorer, not by the reviewers who raised the findings — the scorer returned several values off the 0/25/50/75/100 scale (90, 85, 60, 40), which were snapped to the nearest allowed step rather than re-derived.

One gap worth stating plainly: OSH_MODE and PR_NUMBER could not be read from the environment (the shell allowlist rejected every attempt). Fan-out mode was inferred from .ai-review/osh-policy.md being the fan-out policy document, corroborated by assignments.json's k: 2; the PR number came from the history worker's gh pr view. The inference is well-supported but it is an inference.

context.md is untracked and not gitignored, so it shows in git status after a local prep run. No workflow gates on a clean tree (grep for porcelain and git diff --exit-code across .github/workflows/ and action.yml returns nothing), so this is cosmetic — but adding it to .gitignore would keep local git status clean.

@eduly-haldarwish
Hussam Aldarwish (eduly-haldarwish) merged commit a65ff19 into main Aug 18, 2026
6 checks passed
@eduly-haldarwish
Hussam Aldarwish (eduly-haldarwish) deleted the feat/ai-review-cascade-and-osh branch August 18, 2026 05:27
@mtm-bot

mtm-bot Bot commented Aug 18, 2026

Copy link
Copy Markdown

✅ ai-qa: PASS

Merge commit a65ff192c75a

Signal Result
Deploy health (https://raw.githubusercontent.com/EdulyCom/github-actions/main/README.md) ✅ healthy
QA review ⚠️ did not run — reporting deploy-health signal only

Posted by mtm-bot[bot] · workflow run

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.

1 participant