The monorepo was on npm workspaces. pnpm gives it a content-addressed store shared between the eight packages, a lockfile that records the whole graph rather than a flattened view of it, and — the reason this mattered in practice — `workspace:*`, which makes an internal dependency unambiguous instead of a version range that npm may satisfy from the registry. Mechanics: - `packageManager: pnpm@11.21.0` pins the version; corepack installs it in CI and in the image, so all three environments resolve identically. - The npm `workspaces` array is replaced by `pnpm-workspace.yaml`. pnpm ignores the former, and keeping both would leave two sources of truth. - All six internal dependencies moved to `workspace:*`. - Root scripts use `pnpm -r --if-present` and `pnpm -F <pkg>`. Two findings worth recording, both from running it rather than reading it: `tsx` was a devDependency, but the server runs TypeScript directly in production — the container's command is `pnpm exec tsx apps/api/src/server.ts`. Under npm this was concealed by the runtime stage re-installing tsx by hand after pruning dev dependencies. Under `pnpm install --prod` that sleight of hand stops working and the image simply fails to start. tsx is now declared in `dependencies`, which is what it has always actually been. The first image build failed with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY. That is not a pnpm bug: it had decided the modules directory was stale and wanted confirmation before deleting it, which a non-interactive build cannot give. The trigger was the host's `node_modules` reaching the build context — there was no `.dockerignore` at all. pnpm's tree is symlinks into a content-addressed store, so copying it into an image produces dangling links and a directory pnpm rightly considers corrupt. Fixed by adding `.dockerignore` and setting `CI=true`, which is required in any non-interactive pnpm build. `esbuild` is denied install scripts via `allowBuilds`. Its platform binary arrives through the optional dependency `@esbuild/linux-x64` and the postinstall only verifies it; confirmed by running the binary directly, which reports 0.25.12. Verified under pnpm: typecheck clean, 150 tests / 0 failures, e2e passes, web builds. The image was built and booted against a real Postgres — health ok, `/api/dashboard` 401 with an issuer configured, `/` and `/capacity` serve the SPA, `/og.png` serves as image/png, and the migrator runs from the pruned runtime stage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2.2 KiB
Seed data and its provenance
PIG ships with a roster of publicly documented people so the application is legible on first run. It is public research, not an assertion of fact.
Rules applied
-
Every record carries a confidence grade and a source URL.
confirmedmeans two or more independent sources;probablemeans one good one;unverifiedmeans a single weak or self-reported source. The grade is shown in the interface wherever the record appears — a single-source claim about a real person must never look as solid as a corroborated one. -
No email addresses. None are published by the subjects. Guessing them from a name and a domain is unreliable, and when a guess lands it lands on a real person who did not ask to be contacted.
-
Authorship is not employment. People named on papers or in repositories are recorded with the affiliation actually evidenced —
contributor,resident,alumni— never promoted tostaffto make the roster look fuller. -
"Not found" is recorded, not invented. Where a name was supplied but could not be sourced, it appears in
UNRESOLVED_NAMESwith a note. Absence is weak evidence: a junior or deliberately non-public employee looks identical to a failed search.
Known limitations
- Sourced August 2026. It will go stale — that is what
sourceUrlis for. - LinkedIn, Glassdoor and several job boards refuse automated fetching, so some records rest on search-result summaries rather than a page that was read end to end. Those are graded accordingly.
- One departure is recorded explicitly (a co-author who now lists a different company) so the roster does not quietly imply current employment.
- One name in the original brief could not be tied to the company by any source and is deliberately not seeded.
Removing yourself
If you are seeded here and would rather not be, open an issue and the record will be removed. Deleting a contact in the application also removes it permanently.
Turning it off
Seeding is a separate command and is never automatic:
pnpm run db:seed # opt in
Skip it and PIG starts empty apart from a development user.