Files
pig/docs/seed-data.md
T
karti a6167629cc
CI / verify (push) Successful in 3m23s
Move from npm to pnpm across the workspace, CI and the image
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>
2026-08-13 04:15:54 -07:00

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

  1. Every record carries a confidence grade and a source URL. confirmed means two or more independent sources; probable means one good one; unverified means 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.

  2. 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.

  3. Authorship is not employment. People named on papers or in repositories are recorded with the affiliation actually evidenced — contributor, resident, alumni — never promoted to staff to make the roster look fuller.

  4. "Not found" is recorded, not invented. Where a name was supplied but could not be sourced, it appears in UNRESOLVED_NAMES with 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 sourceUrl is 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.