Skip to content

feat(pnpm-policy-graphile): publish the Graphile allowlist as data - #117

Merged
pyramation merged 2 commits into
mainfrom
feat/graphile-inventory
Aug 6, 2026
Merged

feat(pnpm-policy-graphile): publish the Graphile allowlist as data#117
pyramation merged 2 commits into
mainfrom
feat/graphile-inventory

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

A second inventory package — @constructive-io/pnpm-policy-graphile — so a workspace that consumes Graphile can pair it with @constructive-io/pnpm-policy instead of naming an npm account anywhere.

The bug this closes

constructive currently lists an upstream npm account under maintainers. That account publishes the Graphile stack — and also co-maintains graphql, the reference implementation, plus graphiql, monaco-graphql and graphql-language-service.

All of them were swept into the exemption list. constructive/pnpm-workspace.yaml line 51 reads:

minimumReleaseAgeExclude:
  - graphql

So the most depended-upon package in the JavaScript ecosystem is skipping our quarantine today. And graphql has six maintainers — a compromise of any one of those accounts publishes a release we install immediately, with no wait.

maintainers is a delegation as wide as everything that account will ever touch. That is fine for accounts we control and wrong for anyone who also maintains popular upstream software. The tool's own README warns about exactly this.

Derivation — reproducible, not curated by taste

  1. Every package the workspaces resolve, read from lockfiles, so transitive dependencies count rather than just direct ones.
  2. Keep those whose npm repository is Graphile-owned — github.com/graphile/* or github.com/graphile-contrib/*. Checkable with npm view <pkg> repository.url.
  3. Drop the rest.

constructive and constructive-db independently resolve the same 16 packages:

@dataplan/json      @dataplan/pg          @graphile-contrib/pg-many-to-many
@graphile/lru       grafast               grafserv
graphile-build      graphile-build-pg     graphile-config
graphile-utils      pg-introspection      pg-sql2
postgraphile        ruru                  ruru-types
tamedevil

Failing step 2 and therefore now waiting like any other third-party dependency: graphql, graphiql, monaco-graphql, graphql-language-service, @graphiql/*, graphql-tag, graphql-upload, graphql-ws.

Worth noting a name-pattern sweep would have missed @graphile-contrib/pg-many-to-many and wrongly kept the GraphiQL packages. Deriving from lockfile + repository is what got this right.

No scope globs

@graphile/* or @dataplan/* would exempt whatever is published into those scopes next — the same open-ended delegation as a maintainer entry, just smaller. Names cost a line each and say exactly what was decided. npm's scope: search is also unreliable, so "is this scope exclusively theirs?" is not a question I could answer, let alone keep answered.

Guard

test.js — plain node asserts, no framework, runs with no install — fails if a forbidden name appears, if scopes or maintainers stop being empty, or if the list is unsorted or contains duplicates.

$ node test.js
ok — 16 Graphile packages, no forbidden names

Also verified end-to-end against the real tool: pointing a config at this inventory emits grafast and postgraphile into minimumReleaseAgeExclude and leaves graphql and graphiql out.

Order

Pairing this with @constructive-io/pnpm-policy needs the multi-inventory support in #116, so land that first. This package is usable on its own before then.

Once both are published I will send the constructive PR: list both inventories, delete the 1024-entry local pnpm-policy.inventory.json, and remove the account name entirely — which also closes the graphql exposure.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CEswUi4ANuB58rva48aHge

A second inventory package, so a workspace consuming Graphile can pair it
with @constructive-io/pnpm-policy instead of naming an npm account.

Why not an account: `maintainers` exempts everything an account ever
publishes, and the account behind the Graphile stack also co-maintains
`graphql` — the reference implementation — plus graphiql,
monaco-graphql and graphql-language-service. Those were swept into our
exemption list, so the most depended-upon package in the ecosystem was
skipping the quarantine, and `graphql` has six maintainers, meaning a
compromise of any one of them shipped a release we installed instantly.

An account is a delegation as wide as everything that account will ever
touch. Fine for accounts we control; wrong for anyone who also maintains
popular upstream software. So this enumerates names.

Derivation, reproducible rather than curated by taste:

  1. every package the workspaces resolve, read from lockfiles, so
     transitive dependencies count, not just direct ones
  2. keep those whose npm `repository` is Graphile-owned
     (github.com/graphile/*, github.com/graphile-contrib/*)
  3. drop the rest

`constructive` and `constructive-db` independently resolve the same 16.
graphql, graphiql, monaco-graphql, graphql-language-service, @graphiql/*,
graphql-tag, graphql-upload and graphql-ws all fail step 2 and now wait
like any other third-party dependency.

No scope globs: `@graphile/*` would exempt whatever is published into
that scope next, which is the same open-ended delegation as a maintainer
entry, only smaller.

test.js guards the boundary with plain node asserts — no framework, runs
anywhere — failing if a forbidden name appears, if scopes or maintainers
stop being empty, or if the list is unsorted or has duplicates.

Needs the multi-inventory support in the tool (#116) to be paired with
@constructive-io/pnpm-policy; usable on its own before that.
CI installs with --frozen-lockfile, so adding a workspace package without
its lockfile entry fails the build before anything runs:

  ERR_PNPM_OUTDATED_LOCKFILE  pnpm-lock.yaml is not up to date with
  <ROOT>/packages/graphile-pnpm-policy/package.json

Adds the importer stanza by hand rather than regenerating. Regenerating
rewrites 7897 lines: the committed lockfile was written by a different
pnpm major, so any write reformats the whole file, which would bury a
data-only PR in unrelated churn and risk dropping entries.

Verified with the version CI uses — `pnpm@10.12.2 install
--frozen-lockfile --lockfile-only` resolves all 40 workspace projects
with no outdated-lockfile error. That command reformats the file as a
side effect, so the reformat is discarded and only the 7-line stanza is
committed.
@pyramation
pyramation force-pushed the feat/graphile-inventory branch from 2802918 to 0d82589 Compare August 6, 2026 09:33
@pyramation
pyramation merged commit 2973325 into main Aug 6, 2026
59 checks passed
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