Skip to content

ci: every job installs from the tracked lockfile - #405

Merged
dinndev2 merged 2 commits into
mainfrom
fix/ci-installs-from-the-tracked-lockfile
Nov 12, 2026
Merged

dinndev2 merged 2 commits into
mainfrom
fix/ci-installs-from-the-tracked-lockfile

Conversation

@dinndev2

Copy link
Copy Markdown
Contributor

What

Two of the three CI jobs installed with npm install, and the npm lockfile is gitignored — so those jobs resolved dependencies to whatever was newest on the registry, on every run.

A dependency published six hours after the last green run breaks them, and it breaks them in files the change never touched:

src/mcp/tool-search.ts(196,60): error TS18046: 'inputSchema.parseAsync' is of type 'unknown'.
src/testing/tool-harness.ts(45,16): error TS18046: 'schema.parseAsync' is of type 'unknown'.

So "CI green on main" was true as history and not as a fact: the next push to main turns the node job red, and the red has nothing to do with the change that caused it.

Every job now installs with bun install --frozen-lockfile, so the tracked lockfile is the resolution. The node and integration jobs still run under node — that is the point of those jobs; the runner is what the lockfile decides, not the tool that installs it. The bun job is frozen too, so a manifest change without a lockfile update fails instead of silently resolving to something new.

The guard

packages/aitm/test/integration/ci-install-lockfile.test.ts holds the rule:

  • no install in the workflow may resolve from the registry's latest — each one must come from a lockfile;
  • every job installs at all, so a job added later without an install cannot slip in behind the rule.

The workflow is the artifact under test: it is read, not re-implemented.

Verification

  • bin/check green — typecheck, test typecheck, lint, the import-cycle check, the compat build, the Node test run and the integration suite (51 pass, 0 fail).
  • The guard was run red against both shapes it exists to catch:
    • one job's install put back to a floating npm install → the lockfile rule fails;
    • one job's install step removed → the every-job rule fails.
  • The new test passes under both runners the repo requires: bun test and node --test.

Notes

  • This is the defect that made the next push to main red, so it blocks every other change in this repository — including the public-tree cleanup that depends on it.
  • The lockfile is the one the package publishes with, so there is still exactly one lockfile and one source of resolution.

Closes #400

🤖 Generated with Claude Code

@developerz-ai

developerz-ai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

🟡 Reviewed

1 actionable comment(s) · grounded on your code

🤖 developerz.ai — automated review, running on your model and your box.

Two of the three CI jobs installed with `npm install`, and the npm lockfile
is gitignored - so those jobs resolved dependencies to whatever was newest
on the registry, on every run. A dependency published six hours after the
last green run broke them, and the next push to main turned the node job
red on a type error in files the push never touched.

Every job now installs with `bun install --frozen-lockfile`, so the tracked
lockfile is the resolution. The node and integration jobs still RUN under
node - that is the point of those jobs; the runner is what the lockfile
decides, not the tool that installs it.

packages/aitm/test/integration/ci-install-lockfile.test.ts holds the rule:
no install in the workflow may resolve from the registry's latest, and
every job installs.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@dinndev2
dinndev2 force-pushed the fix/ci-installs-from-the-tracked-lockfile branch from e546ad7 to ea2bf58 Compare November 12, 2026 09:04

@developerz-ai developerz-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary — 2 file(s), 3 finding(s).

Critical 0 · Major 0 · Minor 3 · Nit 0

CI now installs with bun install --frozen-lockfile in all three jobs, and a new integration test guards the workflow against floating installs. The change is sound and CI is green.

🤖 developerz.ai review — automated, running on your model and your box. What is this?

…t flag, and checks each job

The guard read only single-line `run:` values, so an install written as a
`run: |` block passed; it accepted `--frozen-lockfile` on npm, which has no
such flag and resolves from the registry; and it compared the total install
count to the job count, so one job installing twice hid a job with none.

It now reads every `run:` body, single-line or block scalar, split on `&&`,
`||` and `;`, and attributes each install to its job. A lockfile install is
`npm ci` or a bun/yarn/pnpm install with `--frozen-lockfile`. Each rule is
proven against a fixture before it runs on the real workflow, and both
workflow rules were run red against a planted floating install and a job
with its install removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@developerz-ai

developerz-ai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Address review findings on #405

Queued — waiting for a free box.


🤖 developerz.ai, an automated agent, not a human — developerz-ai[bot]

@developerz-ai developerz-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary — 1 file(s), 1 finding(s).

Critical 0 · Major 0 · Minor 1 · Nit 0

Guard rewrite verifies cleanly — block scalars, chained installs, the npm-flag trap and per-job attribution are all read and fixture-proven; one residual bypass remains: a run: | # comment header hides its body, so a floating install inside still passes both rules.

1 non-blocking finding(s) below major (no thread on a re-review — only blocking findings open threads)
  • packages/aitm/test/integration/ci-install-lockfile.test.ts:82 minor · test The indicator regex requires run:'s value to end at |/>, so a legal header like run: | # install deps is parsed as an inline command, its body is skipped, and a floating npm install inside passes both rules. Accept a trailing comment: /^[|>][-+]?\d*(?:\s+#.*)?$/.

🤖 developerz.ai review — automated, running on your model and your box. What is this?

@dinndev2
dinndev2 merged commit 3675019 into main Nov 12, 2026
4 checks passed
@dinndev2
dinndev2 deleted the fix/ci-installs-from-the-tracked-lockfile branch November 12, 2026 09:34
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.

ci: the npm jobs install without a lockfile, so the next push to main goes red

2 participants