Skip to content

P1: core engine + CLI - #2

Merged
CodeGovindz merged 2 commits into
mainfrom
p1-core
Oct 26, 2026
Merged

CodeGovindz merged 2 commits into
mainfrom
p1-core

Conversation

@CodeGovindz

@CodeGovindz CodeGovindz commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

P1: core engine + CLI

Receipts' whole engine now exists in src/core/ (zero Next.js imports, TypeScript strict, no any): feed it any public GitHub PR URL and it extracts the author's claims with the FAST model, verifies each one with STRONG (Kimi K3) against real diff hunks, deterministic signals, and CI check runs, guards every verdict, and prints a GitHub-comment-ready report.

What works (validated on real PRs, zero network in tests)

  • Claim extraction (extract.ts) via qwen.qwen3-coder-next, max 12 claims, plus the quote guard: any claim whose quote isn't a (whitespace-normalized, case-insensitive) substring of its declared source is dropped and counted in droppedClaims.
  • Verification (verify.ts) via callStrong() — STRONG with a 45 s AbortController timeout (the HTTP request really is cancelled; typed TimeoutError), on timeout/throttle-after-SDK-retries/5xx it fails over straight to FALLBACK (30 s); concurrency 4; per-claim modelUsed + latencyMs recorded.
  • Real cancellation + no parse-failover (plan correction 1): parse/zod failures retry once on the same model with the validation error fed back, then degrade deterministically — never switch models for them.
  • Deterministic signals (signals.ts): test files/cases, skipped/focused markers, CI state incl. pending (correction 5), removedExports vs SIGNATURE_CHANGE (correction 4), dependency major bumps, docs. Every signal has a stable key the guard validates.
  • Guards (guard.ts): citation guard (evidence must exist in the bundle), line guard (evidence line must fall inside a changed hunk's new-file range, else it degrades to a file link at head SHA), evidence URLs (blob at headSHA with #L, check-run URLs), and a tests_pass CI-pending override to UNVERIFIED "CI still running".
  • Report (report.ts): grading truth table (FAIL on any CONTRADICTED, PASS if all VERIFIED, else MIXED; 0 claims → MIXED with trust "—"), trust score, modelsUsed with friendly names and the "(2 via GPT-OSS 120B)" fallback note, markdown with the <!-- receipts:report --> marker, toJSON() that round-trips through the zod Report schema.
  • Pipeline (pipeline.ts): typed events (fetching, fetched, extracting, extracted, verifying(i/n), fallback, done, error) and the correction-7 in-memory report cache keyed owner/repo#number@headSha + model IDs (--fresh bypasses).
  • CLI (scripts/verify.ts): --json, --fresh, --dump-fixture <name>; progress to stderr, report to stdout, timing/token summary.
  • 89 unit tests in src/core/__tests__/ (hunk parsing, skip-lists/budgets, hunk selection, guards incl. a hostile-PR prompt-injection fixture, grading truth table, llm parser incl. reasoningContent + fenced/prose JSON, and callJson/callStrong retry + failover with a stubbed client). npm test, npm run lint, npm run build all green.

Real-PR validation (fixtures under fixtures/real-*.json, records in docs/PLAN.md §5)

PR Kind Grade Runtime
CapSoftware/Cap#3412 agent-authored claims + failing CI FAIL, trust 67% (8/12 verified, 2 contradicted) ~27 s
facebookincubator/dispenso#129 claims test results, adds no test files, CI running MIXED, trust 42% ~42 s
github/docs#46488 docs-only typo fix MIXED, trust 67% ~11 s

All three beat the < 60 s target. The Cap PR is the money shot: the agent's "Validation: all 41 SDK tests pass" was CONTRADICTED by the failing Format (Biome) / Vercel – cap-web checks; dispenso's "1287/1287 pass" claims were held UNVERIFIED by the CI-pending rule because its head-SHA CI was mid-run.

Known weaknesses (honest)

  • Extraction misses exist. On a template-heavy body (HDPI-3476 - CYA for Warrant and Writ hmcts/pcs-api#3121) the FAST model returned {"claims":[]} where a human would find one checkable claim. On the three recorded runs extraction was solid (12/12/3 verbatim-quoted claims); keeping qwen as FAST per plan and monitoring.
  • Problem statements can be extracted as claims. The Cap run judged the sentence describing the old buggy behavior ("the SDK stays in its recording phase...") as CONTRADICTED — technically defensible (that sentence is false of this PR's result) but semantically debatable for prose descriptions.
  • Open-PR drift: while CI runs, grades drift (dispenso moved 50% → 42% between two runs as checks completed). Fixtures pin the head-SHA snapshot; live runs re-fetch current CI.
  • 12-claim cap + long bodies: a very long audit-style PR body made the FAST call take ~23 s of the 42 s run. Fine for the target, but P2's UI must stream progress or it will feel slow.
  • no_breaking_change guarantees are heuristic: removedExports detection is regex-based (JS/TS, Python, Go, Java-style public); exotic languages or indirect public-API removals won't be caught.
  • Commits exactly at the 50-commit cap are flagged commitsTruncated even when the list is complete (can't distinguish without an extra API call).
  • Windows PowerShell quirk: npm run verify -- <url> --json drops unknown flags in npm's arg forwarding — use npx tsx scripts/verify.ts <url> --json ... (documented in PLAN.md for the P4 README).

Also in this PR: P0-review fixes (env.ts with typed getConfig() + production GITHUB_TOKEN check shared by smoke + CLI; llm.ts Promise.race → real AbortController cancellation), the PLAN.md §5 note that cacheComponents: true forces a <Suspense> boundary around anything reading searchParams in P2, and fixture-based offline test data.

Next: P2 (web UI + streaming API + Vercel) will import src/core/* unchanged.

Precision fixes (review round)

The first Cap#3412 run graded the PR FAIL on two false CONTRADICTED verdicts. Both are fixed:

  • Problem statements aren't claims. "When the encoder errors, the SDK stays in its recording phase…" described the bug before the fix, and the fix itself "contradicted" it. Extraction now only emits outcome claims.
  • A formatting or deploy failure doesn't contradict a test claim. "All 41 SDK tests pass" was contradicted by a failing Format (Biome) check and a Vercel deploy. Checks are now classified by kind, and tests_pass can only be contradicted by a failed test check.
  • Skipped/neutral checks no longer make CI look pending; bot-written PR body sections (Greptile) are stripped before extraction; CONTRADICTED below 0.75 confidence becomes UNVERIFIED.

New npm run eval runs the recorded PRs through the live models against fixtures/expectations.json: 11/11 pass. Cap#3412 is now MIXED · 4/8 verified, docs#46488 PASS, dispenso#129 MIXED, with no CONTRADICTED anywhere.

Known weakness: the extraction model sometimes still emits fragment claims ("five fail before the fix.") and the quote guard drops 1–2 paraphrased claims per long PR.

CodeGovindz and others added 2 commits October 26, 2026 23:41
Extract claims with the FAST model, verify each with STRONG (AbortController timeouts, zod retry, FALLBACK failover), backstop verdicts with quote/citation/line guards + deterministic signals, grade into a GitHub-ready report, and drive it all from a streaming CLI with fixtures from three real PRs.
- Extraction only emits outcome claims; problem statements become one
  bug_fixed outcome claim. Claims carry scope (ci | local | unspecified).
- CI checks are classified by kind; tests_pass is only contradicted by a
  failed check of the kind the claim talks about, and a VERIFIED one gets
  the passing checks of that kind attached as evidence.
- Skipped/neutral/stale checks are ignored instead of reading as pending.
- sanitizePrBody() strips bot sections, HTML comments and tags.
- Low-confidence (< 0.75) CONTRADICTED is downgraded to UNVERIFIED.
- npm run eval: live-model regression eval over fixtures/real-*.json.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@CodeGovindz
CodeGovindz merged commit 5ad6b29 into main Oct 26, 2026
CodeGovindz added a commit that referenced this pull request Oct 26, 2026
* P1: core engine + CLI

Extract claims with the FAST model, verify each with STRONG (AbortController timeouts, zod retry, FALLBACK failover), backstop verdicts with quote/citation/line guards + deterministic signals, grade into a GitHub-ready report, and drive it all from a streaming CLI with fixtures from three real PRs.

* P1 precision fixes: no false CONTRADICTED verdicts

- Extraction only emits outcome claims; problem statements become one
  bug_fixed outcome claim. Claims carry scope (ci | local | unspecified).
- CI checks are classified by kind; tests_pass is only contradicted by a
  failed check of the kind the claim talks about, and a VERIFIED one gets
  the passing checks of that kind attached as evidence.
- Skipped/neutral/stale checks are ignored instead of reading as pending.
- sanitizePrBody() strips bot sections, HTML comments and tags.
- Low-confidence (< 0.75) CONTRADICTED is downgraded to UNVERIFIED.
- npm run eval: live-model regression eval over fixtures/real-*.json.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant