Repository navigation
Conversation
`pnpm install --frozen-lockfile` had never succeeded in this repo. CI was added in 74f12f0 on 2026-04-13 and failed at the install step on that very commit, so lint and build have never run here, not once, on any commit. Reproduced at HEAD and at 74f12f0 in throwaway checkouts before changing anything. Root cause is the rename in 16150d6, "Rename core to @attestto/identity-resolver". The package was renamed; nothing that referred to it was updated. Three different stale names were left behind: - five packages depended on `identity-resolver`, four via `workspace:*`, which resolves only inside the workspace and hard-fails when no such package exists; - packages/sns used `identity-resolver: >=0.2.0`, an ordinary registry range that would have resolved to the unscoped identity-resolver@0.2.2 on npm, which is the pre-rename core. Not a hijack risk, that package is ours, but it would have silently bound to a stale copy; - six source files imported types from `wallet-identity-resolver`, a name that has never been a package at all. All of them now point at `@attestto/identity-resolver`. The type-only imports are why this stayed hidden for four months: they compile away, so nothing at runtime ever noticed. Only tsc and the dts build care, and neither had run. Adds a root `test` script. packages/core has had `vitest run` since 0d862af, but the root had no test script to recurse into it and ci.yml has no test step, so the 15 tests added that day had no path to execution. Worth stating plainly: the commit that added those tests also added the vitest devDependency that broke --frozen-lockfile, so the change that introduced the tests is the change that guaranteed they could not run. Verified in CI's order, each of these for the first time in this repo: `pnpm install --frozen-lockfile` clean, `pnpm lint` clean across all six packages, `pnpm test` 15 passed, `pnpm build` success including the dts builds that were failing. Consumers are unaffected. CORTEX/frontend and did-method-checklist/app depend on the published @attestto/identity-resolver ^0.3.0, and the published @attestto/wir-sns@0.1.1 declares no dependencies, so none of this drift ever shipped. The breakage was entirely internal. Root package-lock.json is deleted. It was last written at v0.1.0 before the monorepo restructure and contained zero packages/ entries, describing a layout that no longer exists, while pnpm-workspace.yaml and the workspace: protocol make this a pnpm workspace that npm cannot express. Two lockfiles is also what the shared gate-self-test control refuses to run against, correctly.
The push and pull_request triggers were filtered to [main, develop], so a pull request whose base is any other branch matched no trigger and started no job at all. Stacked PRs (feature-b based on feature-a) therefore merged with zero checks having run, and the branch protection status showed as "expected" rather than failed. Widening both filters to '**' makes every branch and every PR base run the workflow, which is the only configuration where a required check is actually required. Note: this does not make CI green. `pnpm install --frozen-lockfile` fails on this repo (ERR_PNPM_OUTDATED_LOCKFILE) and has failed since the workflow was first added, so lint and build have never executed. That is tracked separately along with the two-lockfile question. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the shared gate-self-test control, byte-identical to the copy in the other Attestto repos (sha256 7e8fb2601bf5..., 344 lines, unedited), plus a Test step this workflow never had. This repo is the strongest argument for the control. Its CI had been red at the install step since the workflow was added, which is indistinguishable from having no gates at all: every step below install had simply never executed. The self-test asserts install matches the lockfile actually present, which is exactly the condition that was wrong here, and it refuses to run against two lockfiles, which is what this repo had. Two gates registered, each with a seed that genuinely violates it: lint (a real type error) and test (a really-failing assertion). build is deliberately NOT registered. tsup compiles only the entry import graph, so a seed the entry does not import cannot make it fail, and a seed that passes would assert nothing. It stays as buildScript for the test-before-build ordering check. Proven able to fail rather than assumed: pnpm gate-self-test -> OK (proven able to fail: lint, test) and, breaking it on purpose, each restored afterwards with ci.yml verified byte-identical to its backup: branches ['**'] -> [main, develop] -> RED, "would skip branches outside" delete the Gate self-test step -> RED, "never runs gate-self-test" The Test step goes before Build so a failure lands on the cheaper step.
CI failed on the first real run of this pipeline, at install, for a reason that had been hidden until now: warn: This version of pnpm requires at least Node.js v22.13 warn: The current version of Node.js is v20.20.2 Error [ERR_UNKNOWN_BUILTIN_MODULE]: No such built-in module: node:sqlite The workflow pinned Node 20 while `pnpm/action-setup` with `version: latest` resolved to pnpm 11.21.0, which requires Node >= 22.13 and loads `node:sqlite`. The two pins contradicted each other. This was invisible before. Install had never succeeded in this repo, so it never got far enough to hit the incompatibility. Fixing the lockfile did not create this failure, it exposed the next one underneath, which is what happens when a gate runs for the first time in four months. Two changes, and the second matters more than the first. Node now comes from `.nvmrc` (new, set to 22), so local and CI cannot disagree about the version. There was no `.nvmrc` at all, and nothing else made them agree. pnpm is pinned to major 10 rather than `latest`. `latest` is how a pipeline that passed yesterday breaks today with nobody touching it, and pnpm 11 dropping Node 20 support is precisely that. A version this pipeline never chose should not be able to redden it. Verified locally under Node 22 with pnpm 10, in CI's order: install --frozen-lockfile, gate-self-test, lint, test (15), build. All pass.
…st its declarations CI failed at `gate-self-test` with "`lint` fails on a clean tree, so its failure above is not evidence of anything", and it was right. The five provider packages import their types from `@attestto/identity-resolver`, which resolves to the GENERATED `dist/index.d.ts` rather than to core's source. On a fresh checkout there is no dist/, so `tsc --noEmit` cannot resolve the module and lint dies with TS2307 in four packages. My earlier local verification did not catch this and should have. I had run a build earlier in the session, so dist/ existed when lint ran, and "all five steps pass" was true only on a machine that had already built. Reproduced properly by deleting every packages/*/dist and running CI's order from scratch, which fails exactly as CI did. Adds a step that builds only core, after install and before gate-self-test. It has to precede the self-test, not just lint, because the self-test runs each gate on a clean tree and would otherwise judge lint broken for an environmental reason rather than a seeded one. This is deliberately not the full build, which still runs after the tests so a failure lands on the cheaper step first. It is a prerequisite of linting at all. Verified from a genuinely clean state: every packages/*/dist removed, then install --frozen-lockfile, build core, gate-self-test, lint, test (15), build. All pass under Node 22 with pnpm 10. Known wart, not fixed here: a developer running `pnpm lint` on a fresh clone hits the same TS2307 until they build. The durable fix is to have the providers resolve core's types from source via tsconfig paths, so the declarations stop being a build-order dependency.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
pnpm install --frozen-lockfilehad never succeeded in this repo. CI was added in74f12f0on 2026-04-13 and failed at the install step on that very commit, so lint and build have never run here, not once, on any commit. Reproduced at HEAD and at74f12f0in throwaway checkouts before changing anything.Root cause is not the lockfile
The lockfile drift is a symptom.
16150d6renamed core to@attestto/identity-resolverand nothing referring to it was updated. Three stale names were left behind:workspace:*identity-resolveridentity-resolver: >=0.2.0from 'wallet-identity-resolver'from 'identity-resolver'workspace:*resolves only inside the workspace and hard-fails when no such package exists. The>=0.2.0range would have resolved to the unscopedidentity-resolver@0.2.2on npm — the pre-rename core. Not a hijack risk, that package is ours, but it would have silently bound to a stale copy.Why it hid for four months: every stale import is
import type. Type-only imports compile away, so nothing at runtime noticed. Onlytscand the dts build care, and neither had run.Tests that could not run
packages/corehas hadvitest runsince0d862af, but the root had notestscript to recurse into it andci.ymlhad no test step, so 15 real assertions sat unrunnable. The commit that added those tests also added thevitestdevDependency that broke--frozen-lockfile— the change that introduced the tests guaranteed they could not run.Lockfile decision
Root
package-lock.jsondeleted,pnpm-lock.yamlregenerated. The npm lock was last written at v0.1.0 before the monorepo restructure and contained zeropackages/entries, describing a layout that no longer exists, whilepnpm-workspace.yamland theworkspace:protocol make this a pnpm workspace npm cannot express.The untracked
packages/core/package-lock.jsonwas left alone — a CI checkout never sees it.gate-self-test
Byte-identical shared copy (
7e8fb2601bf5, 344 lines, unedited). Two gates with genuinely violating seeds:Negative controls run by hand, restored,
ci.ymlverified byte-identical after:branches: ['**']narrowed to[main, develop]→ REDbuilddeliberately not registered:tsupcompiles only the entry import graph, so a seed the entry does not import cannot make it fail.Verified, each for the first time in this repo
Run under Node 22.
ci.ymlpins Node 20 and there is no.nvmrc, so nothing makes local and CI agree — worth closing separately.Consumers unaffected
CORTEX/frontendand the (now archived)did-method-checklist/appdepend on published@attestto/identity-resolver ^0.3.0, and published@attestto/wir-sns@0.1.1declares no dependencies. None of this drift ever shipped; the breakage was entirely internal.Tracked as ATT-1288.