Fix Primary Package Selection in Monorepos
The primary package heuristic picks the package with the most files when no `apps/` directory with framework evidence exists. For library and platform monorepos, the biggest package is often the admin dashboard, test suite, i18n data, or example app — not the core product. This cascades to wrong framework detection, wrong shape, wrong UI system, and wrong version display.
verdict PASSscore 27 / 27findings 6 (0 risk · 2 debt · 4 obs)duration 1h 24mrejection cycles 0shipped May 22, 2026surface cli
Pipeline timeline
Intent to proven code in 1h 24m across Think, Plan, Build, and Verify.
Think28m
Plan18m
Build6m
Verify5m
Assertion ledger
27 claims, each independently verified. Showing 8 — show all →
| ID | Says | Matcher | |
|---|---|---|---|
| A001 | A package whose name exactly matches the repo directory is selected as primary | verified | ok |
| A002 | A scoped package whose bare name matches the repo directory is selected | verified | ok |
| A003 | A scoped package with identity word 'core' whose scope matches the directory is selected | verified | ok |
| A004 | A scoped package with identity word 'server' whose scope matches the directory is selected | verified | ok |
| A005 | A scoped self-named package whose bare name equals the scope is selected | verified | ok |
| A006 | Higher-priority tiers win over lower-priority tiers | verified | ok |
| A007 | When multiple packages match the same tier, the one with more files wins | verified | ok |
| A008 | A name-matched package with fewer than 10 files is rejected by the guard | verified | ok |
Findings 6 total
debtpackages/cli/tests/engine/census-primary.test.ts→ closed
A007 tiebreaker test uses toContain('larger') — would pass if result were 'larger-thing' or any string containing 'larger'
obspackages/cli/tests/engine/census-primary.test.ts→ closed
A026 caller test doesn't verify actual call site — it only shows selectPrimary accepts 3 args. Caller verified by source inspection (census.ts:571).
obspackages/cli/src/engine/census.ts→ monitor
Tier 4 (scoped+self-named) matches any package where bare === scope, regardless of projectDirName. @strapi/strapi matches in any repo whose packages include it, not just 'strapi' directories.
obspackages/cli/src/engine/census.ts→ closed
parsePackageName is a private helper but has no guard for empty-string input — returns { scope: '', bare: '' }. Harmless because nameMatchCandidates filters null packageName, but empty-string packageName would pass the filter and produce an empty bare match.
debtpackages/cli/tests/engine/census-primary.test.ts→ scope
No test for the Policy 1 + Policy 0 interaction: an apps/ package in a non-product path (e.g., 'examples/apps/web') — would Policy 0 filter it before Policy 1 can match?
+1more findings
Integrity seal
scopesha256:dc146d74f36b1...
contractsha256:45188d7f874f2...
plansha256:a98d577337ead...
specsha256:499b3796fd3b3...
build-reportsha256:07a49df75a5f0...
build-datasha256:958045e8ead38...
verify-reportsha256:0d41c8d37cb5d...
verify-datasha256:1d7999cb3ac0d...
audit cmd$ ana proof audit fix-primary-selection → all hashes match