Fix deploy platform detection for monorepos

The scan shows the wrong deploy platform for monorepos where a secondary service's config file sorts alphabetically before the primary app's. inbox-zero deploys to Vercel but the scan says "Cloudflare Workers" because `apps/image-proxy/wrangler.jsonc` is discovered before `apps/web/vercel.json`. The wrong platform cascades into AGENTS.md (no Vercel serverless warnings), gotcha matching (Prisma + Vercel safety gotcha silently suppressed), deployment skill context, service dedup, and scaffold generators. The fix makes `detectDeployment` primary-aware so it prefers the primary package's deploy config.

verdict PASSscore 8 / 8findings 5 (0 risk · 1 debt · 4 obs)duration 49mrejection cycles 0shipped May 26, 2026surface cli

Pipeline timeline

Intent to proven code in 49m across Think, Plan, Build, and Verify.

Think
1m
Plan
23m
Build
3m
Verify
5m

Assertion ledger

8 claims, each independently verified.

IDSaysMatcher
A001Monorepo scan picks the primary package's deploy platform over alphabetically-firstverifiedok
A002Monorepo scan returns the primary package's config file pathverifiedok
A003When the primary package has no deploy config, the first available platform is usedverifiedok
A004Single-repo projects still detect their deploy platform correctlyverifiedok
A005Calling without a primary path preserves the original first-match behaviorverifiedok
A006Empty deployment list still returns null platformverifiedok
A007Empty deployment list with a primary path still returns nullverifiedok
A008The scan engine passes the primary source root to deployment detectionverifiedok

Findings 5 total

obsclosed
AC5 wording says AGENTS.md contains Vercel guidance — guidance actually lands in deployment skill
obsclosed
Contract A006 matcher is 'exists' but says field says 'returns null' — test correctly asserts null, matcher is imprecise
obspackages/cli/src/engine/scan-engine.tsclosed
No @ana tag for A008 — assertion verified by source inspection only
debtpackages/cli/src/engine/census.tsclosed
census.ts comment claims V8 string-key insertion order — correct per ES2015+ spec, not V8-specific
obspackages/cli/tests/engine/detectors/ci-detection.test.tsmonitor
No negative test for primaryPath matching wrong sourceRootPath substring (e.g., 'apps/we' partial match)

Integrity seal

scopesha256:03b29fa1df674...
contractsha256:8f4602c851082...
plansha256:7c1dabafbfbce...
specsha256:78623483604d9...
build-reportsha256:8ecb7905454d7...
build-datasha256:3ca3c45219427...
verify-reportsha256:f79d660d914f1...
verify-datasha256:c62bbe7099bc0...
audit cmd$ ana proof audit fix-deploy-platform-detection   → all hashes match