Skip to content

Stale PR Triage — 2026-07-07

Scope: all open PRs excluding #1444–#1451 (opened today). Verified against origin/main (fetched today). “Conflicts” = GitHub mergeable state vs current main.

PRTitleAgeCIConflictsRecommendationRationale
#1348Self-sufficient EC2 spot worker (co-located sidecars + hardened boot)9dpassnone (CLEAN)DECIDESolid DR work (failover fleet currently can’t finish jobs when .4 is down), CI green, no conflicts — but it 4בs spot instance size (c6a.large→m6a.xlarge), adds 3 ECR repos to maintain, and needs push:worker-images + CDK deploy to take effect. One-sentence decision: is real failover capacity worth the added instance cost and image-maintenance burden, given the fleet intentionally sits at 0?
#1345Drop the misleading ‘Requirement sections’ heading9dpassCONFLICTINGREFRESH (trivial, ~15 min)7-line copy fix, still valid, but WorksheetEditor.tsx has changed since (worksheet paywall #1367 etc.). Cheaper to redo the edit on a fresh branch than to resolve.
#1269Fix WCAG warnings never auto-fixed in converted HTML15dno checks reportedCONFLICTINGREFRESH (medium, ~half day)Underlying bug (fixable warnings never enter the fix loop) is NOT fixed on main — but wcag-validator.ts took 4 later fixes (#1290 #1391 #1396 #1415) so the rebase is real work, and the PR body itself documents a known double-wrap bug in wrapForeignScriptRuns that must be fixed before merge.
#1268Fix PDF hyperlinks dropped in production conversion path15dpassCONFLICTINGREFRESH (medium, ~half day)Real prod bug, still unfixed: main’s struct-link-injector is untouched since #655 and chunk-assembler has no injectStructLinks wiring — prod conversions still drop source-PDF hyperlinks. chunk-assembler has since taken the region-crop geometry series (#1404/#1407/#1411), so rebase carefully. Highest-value REFRESH in the list.
#1266Record org-chart vision extraction cost to cost_ledger15dpassnone (CLEAN)LANDNot on main (no cost recording in org-chart extract path); aligns with the global cost-tracking standard; small, tested, mergeable. One fixup: migration is numbered 20260621_188 while main is at 201 — renumber to 202+ before applying so ordering stays sane.
#1231Docs: dollar-balance + deposit-bonus migration plan17dpassnone (CLEAN)DECIDEDocs-only plan for credits→dollars. Since it was written, the entitlement model shipped (migrations 195–198) and the v2 multiplier-pricing work (base×multiplier in cents) is already in progress — the plan is at least partially overtaken. Decision: is this doc still the pricing roadmap of record (merge as docs/admin reference, §8/§12 decisions still open), or has v2 pricing made it stale (close)?
#1200Fix VPAT parse 502: raise output cap + Nova→Haiku escalation19dpassCONFLICTINGCLOSESuperseded: main merged #1371 “Fix 502 on large ACRs: raise LLM output cap + salvage truncated JSON” directly on workers/vpat-parse/src/worker.ts. Also overlaps #1168. If the Nova→Haiku cost optimization for vpat-parse is still wanted, do it as a fresh branch on top of #1371 (the pattern now exists on main from the ai-fix Nova chain, #1419).
#1168Fix vpat-parse 502: raise token caps, detect truncation, align deploy target21dpassCONFLICTINGCLOSESame 502 bug, superseded by #1371 on main; overlaps #1200. The “align deploy target” concern is already captured in project memory/docs (live worker is top-level vpat-parse). The 212-line test file is the only piece worth salvaging into a fresh branch if desired.
#1141Replace per-card move buttons with accessible “Move to semester” select23dpassCONFLICTINGREFRESH (medium, ~half day)Genuine WCAG 2.5.7 / 2.1.1 improvement not on main, but course-map UI has moved a lot in 3 weeks (7 files touched). Worth redoing on current main.
#1021course-map: add app CLAUDE.md + gitignore local PDF fixtures28dpassnone (CLEAN)LANDZero-risk (docs + .gitignore), mergeable clean. Skim the CLAUDE.md for accuracy first — course-map grew catalog ingestion and the flowchart split since June 9, so a paragraph or two may need a touch-up post-merge.
#1019Fix local dev env bootstrap + speed up AWS deploys28dno checks reportedCONFLICTINGREFRESH (medium) — split itTwo unrelated halves. The local-dev fixes (docker-compose pins, init-db.sh ordering) are likely still valid and worth salvaging. The .github/workflows/deploy-aws.yml rewrite is a month stale against a workflow that has since changed (AWS is now live primary), and it deletes a course-map test wholesale. Re-cut as a local-dev-only PR.
#983admin users: add Remove Credits action30dpassnone (CLEAN)LANDSmall (1 file, +24), reuses the existing POST /api/admin/credits/adjust endpoint which is still live on main; mergeable clean, CI green. Only caveat: credits UI may be reworked by the v2 pricing effort later — fine to take now.
#980ai-fix: strip inlined images before sending to the model + 413 mapping30dpassCONFLICTINGREFRESH (medium, ~half day)Still valuable — nothing on main strips base64 payloads before the model call, and it complements the just-merged Nova chain (#1419). But ai-fix.ts has been rewritten twice since (#957 streaming, #958 structured edits, #1419 provider chain), so the ai-fix.ts half needs a real rework; strip-inline-data.ts + its tests should port cleanly.
#889Spike: Docling hybrid evaluation (draft, do not merge as-is)36dpassnoneCLOSEKnown-abandoned per project record: the June Docling evaluation ran, Marker won every test, decision was “not integrating”. Draft that was never meant to merge; the branch (worktree-docling-container) preserves the work.
#883Add delete capability to course maps37dpassCONFLICTINGCLOSESuperseded: main’s workers/course-map-api/src/routes/course-maps.ts already has full delete routes (map delete incl. R2 cleanup at lines ~209/270, per-course delete at ~898). Independently implemented after this PR stalled.
#863Reject 0-byte file uploads with a friendly message37dpassnone (CLEAN)CLOSEFully superseded: main already contains the identical changes — the file.size === 0 guard + friendly message in useUpload.ts, the same guard + improved warn in lib/pdf.ts, and even the byte-identical pdf.test.ts (same git blob). Content landed via another route; nothing left in the diff.
#851Lint cleanup: close #846, #848, #849 (split #847)38dtest FAILCONFLICTINGCLOSE58 mostly-mechanical files, conflicting and failing after 5 weeks of churn. Resolving conflicts on auto-generated eslint --fix output is more work than regenerating it: close, re-run the same three-step cleanup (--fix, catch-binding pass, no-img-element config flip) on fresh main. Keep issues #846/#848/#849 open until then.
#845Speed up CI test workflow with caching and task parallelism38dpassnone (CLEAN)LANDSingle-file .github/workflows/test.yml change, mergeable clean, CI green on the branch. Quick sanity-read against the current workflow (it merged cleanly, so drift is minimal), then take the CI-minutes win.
#821Fix wrong table name when setting images_externalized flag41dpassnone (CLEAN)CLOSESuperseded: main’s chunk-scheduler.ts already uses .from('files') at the same site — the exact one-line fix landed independently. Nothing left.
#763Fix api_keys schema drift in pdf API (revoked_at vs is_active)46dtest FAILnone (UNSTABLE)DECIDEThe PR’s premise (“table has is_active”) contradicts the migration files: 056_org_chart_tables.sql creates public.api_keys with revoked_at and no is_active, and main’s route consistently uses revoked_at. Either live prod drifted from migrations (then this PR — or a migration adding the missing column — is needed) or the PR is wrong. One-sentence decision: check the live Supabase api_keys columns; if revoked_at exists in prod, close this. CI is also failing on the branch.
#747Audit: surface axe-core failures as auditError, not fake violation (#740)47dpassCONFLICTINGREFRESH (large, ~1 day)Correct and important: infra failures currently tank customer audit scores by ~20 pts as fake critical violations — no fix on main. But 16 files across api/batch/audit-app from 7 weeks ago against heavily-churned executors. Keep issue #740 open; rebase or re-implement the typed auditError design.
#710Fix budget-killswitch sender domain + document IAM gotcha50dpassnone (CLEAN)LANDOne functional line (sender domain) + docs for GCP infra that’s still in use. Clean, green, zero blast radius.
#649api: harden admin check against missing JWT email claim55dpassnone (CLEAN)LANDBug still live on main: admin gate relies solely on the JWT email claim (auth.ts isAdminEmail(payload.email)), so sessions without the claim 403 legit admin-domain users. The profiles.email fallback keeps the same verified-email security posture. Clean and green — the oldest still-mergeable fix in the list.
#637Refactor LLM surfaces around a single tool catalog (#636)58dpassCONFLICTINGREFRESH (large, 1–2 days) or CLOSE-and-redoThe architecture (one ToolCatalog feeding MCP/OpenAI/Gemini) is still the right idea and #636 remains unaddressed, but 19 files touching MCP transports from 2 months ago means a painful rebase — MCP surfaces and index/index-aws entry points have all churned. Decide effort tolerance; if refreshing, budget for re-verifying the byte-identical openapi.yaml guarantee.

Suggested order of operations

  1. Quick CLOSE sweep (5 min, no risk) — #889 (abandoned spike), #863, #821, #883 (all three verified already-on-main), #1200 + #1168 (superseded by #1371), #851 (regenerate instead of rebase). Cuts the stale list by 7 immediately.
  2. LAND the clean five — #649 (real admin-403 bug, oldest first), #710, #845, #983, #1021, and #1266 (renumber its migration to 202+ before applying to prod). All are CLEAN + green; each is a small review + merge.
  3. DECIDE with Larry (three one-sentence calls) — #1348 (failover capacity vs cost), #763 (check live api_keys schema — likely close), #1231 (is the dollar-balance plan still the roadmap post-entitlements/v2 pricing?).
  4. REFRESH queue, by value — #1268 first (prod is still dropping PDF hyperlinks today), then #1269 (fix the documented double-wrap bug while rebasing), #980 (port strip-inline-data onto the new Nova-chain ai-fix), #1141 (WCAG 2.5.7), #1345 (15-minute redo), #1019 (re-cut local-dev half only), and #747 / #637 as capacity allows (both large).

Verification notes: mergeable/conflict state re-queried today after GitHub recomputed (first pass returned UNKNOWN). Supersession claims for #863/#821/#883/#1200/#1168 were confirmed by grepping origin/main file contents/history, not just titles. CI failures: only #851 and #763; #1269 and #1019 have no checks reported (branches predate current CI triggers or need a re-push).