Skip to content

fix(pi): declare the compaction extension Pi-only at the package level - #2729

Merged
mergify[bot] merged 1 commit into
mainfrom
fm/vx-atomic-compaction-pi-only
Aug 17, 2026
Merged

fix(pi): declare the compaction extension Pi-only at the package level#2729
mergify[bot] merged 1 commit into
mainfrom
fm/vx-atomic-compaction-pi-only

Conversation

@cameronraysmith

Copy link
Copy Markdown
Owner

Problem

atomic reads ~/.pi/agent/settings.json as a legacy config root, so it inherits every extension registered for pi.
One of them, pi-openai-server-compaction, imports @earendil-works/pi-coding-agent as a runtime value in src/remote-compaction.ts.
pi's jiti virtualModules map satisfies that specifier; atomic 0.9.13's does not, and the resolution failure is fatal on atomic's print and interactive paths:

Error: Failed to load extension ".../src/index.ts": Failed to load extension:
ResolveMessage: Cannot find module '@earendil-works/pi-coding-agent'

The other registered extensions survive only because their references to that specifier are import type, erased at transpile.

Fix

atomic's manifest reader is APP_NAME-first with a pi fallback (packages/coding-agent/src/core/package-manager-manifest.ts:24-27) and APP_NAME is "atomic", while pi reads only pkg.pi.
Injecting {atomic: {extensions: []}} into the package's package.json therefore short-circuits atomic to zero resources and is invisible to pi.

pkgs/by-name/pi-openai-server-compaction/package.nix becomes a stdenvNoCC.mkDerivation over the existing fetchFromGitHub, following the sibling pi-agent-extensions shape, and drops the -source suffix now that the output is no longer a bare fetch.
The ws runtime-dependency comment is preserved verbatim.

Constraints held

  • The package remains a separate enabled entry and still appears in atomic list, satisfying the OpenSpec MUST at openspec/specs/pi-agent-environment/spec.md:74.
  • Nothing is added to programs.pi-coding-agent.settings, so slowModeSettingsShape is untouched.
  • compactionRetained derives both sides of its comparison from self'.packages.pi-openai-server-compaction, so it follows the new store path.

Verification

Ran the four checks that observe this derivation or its store path — the full set that would fail if the change were wrong. All green:

nix --accept-flake-config build .#checks.aarch64-darwin.package-pi-openai-server-compaction -L
nix --accept-flake-config build .#checks.aarch64-darwin.pi-agent-environment-structural -L
nix --accept-flake-config build .#checks.aarch64-darwin.pi-agent-environment-smoke -L
nix --accept-flake-config build .#checks.aarch64-darwin.home-manager-crs58 -L

pi-agent-environment-smoke is the real regression test: its fixture uses the live packageEntries and hard-fails on any extension_error.
It reported extension_errors=0.

Runtime behaviour was confirmed in an isolated HOME against scratch copies of the old and new outputs — never the captain's live config — with a marker line appended to the extension entrypoint:

host extension output result
atomic old (negative control) Cannot find module '@earendil-works/pi-coding-agent', exit 1
atomic new no extension error; reaches No API key found for the selected model.
pi old >>> VX_COMPACTION_EXTENSION_EVALUATED
pi new >>> VX_COMPACTION_EXTENSION_EVALUATED

The marker is positive proof that pi still evaluates the extension rather than merely not erroring.
atomic list was deliberately not used as an oracle: it renders this failure as a Warning: and exits 0, while the print and interactive paths render it as Error: and exit 1.

Deliberately out of scope

No atomic regulator was added to the checks suite.
The gap is real — nothing in the repo could have caught this, since pi-agent-environment-smoke is bound to mainProgram == "pi" and atomic's own --help test runs under an empty HOME — but adding one is a separate decision.
Also untouched: ATOMIC_CODING_AGENT_DIR handling, the pi module's settings, and the deleted node_modules output assertion.

Provenance

Diagnosis, fix selection, and the end-to-end verification with negative control come from the completed investigation at data/vx-atomic-pi-config-inheritance/report.md.

atomic reads `~/.pi/agent/settings.json` as a legacy config root, so it
inherits every extension registered for pi. `pi-openai-server-compaction`
imports `@earendil-works/pi-coding-agent` as a runtime value in
`src/remote-compaction.ts`; pi's jiti `virtualModules` map satisfies that
specifier, atomic 0.9.13's does not, and the resolution failure is fatal on
atomic's print and interactive paths. The other registered extensions survive
only because their references to that specifier are `import type`, erased at
transpile.

atomic's manifest reader is `APP_NAME`-first with a `pi` fallback
(`packages/coding-agent/src/core/package-manager-manifest.ts:24-27`) and
`APP_NAME` is `"atomic"`, while pi reads only `pkg.pi`. Injecting
`{atomic: {extensions: []}}` therefore short-circuits atomic to zero resources
and is invisible to pi. The derivation becomes a `stdenvNoCC.mkDerivation`
over the existing fetch, following the sibling `pi-agent-extensions` shape,
and drops the `-source` suffix now that the output is no longer a bare fetch.

The package remains a separate enabled entry and still appears in
`atomic list`, satisfying the OpenSpec MUST at
`openspec/specs/pi-agent-environment/spec.md:74`. Nothing is added to
`programs.pi-coding-agent.settings`, so `slowModeSettingsShape` is untouched.

Verified with the four checks that observe this derivation or its store path,
which is the full set that would fail if the change were wrong:

- `package-pi-openai-server-compaction` builds the derivation itself.
- `pi-agent-environment-structural` covers `compactionRetained`, which derives
  both sides of its comparison from the package and so follows the new path.
- `pi-agent-environment-smoke` is the real regression test: its fixture uses
  the live `packageEntries` and hard-fails on any `extension_error`. It
  reported `extension_errors=0`.
- `home-manager-crs58` covers the consumer that embeds the store path in the
  generated settings file.

Runtime behaviour was confirmed in an isolated `HOME` against scratch copies,
never the captain's live config, with a marker line appended to the extension
entrypoint. atomic on the old output fails with the verbatim
`Cannot find module` error; atomic on the new output reaches `No API key
found`; pi prints the marker on both, proving it still evaluates the extension
rather than merely not erroring. `atomic list` was not used as an oracle: it
renders this failure as a warning and exits 0.

Deliberately left out: no atomic regulator was added to the checks suite. The
gap is real (nothing in the repo could have caught this) but adding one is a
separate decision.
@cameronraysmith
cameronraysmith marked this pull request as ready for review August 17, 2026 01:01
@cameronraysmith cameronraysmith added the author-approved Owner self-approval marker; triggers Mergify auto-approve label Aug 17, 2026
@mergify

mergify Bot commented Aug 17, 2026

Copy link
Copy Markdown

Queued — the merge queue status continues in this comment ↓.

@mergify mergify Bot added the queued label Aug 17, 2026
@mergify

mergify Bot commented Aug 17, 2026

Copy link
Copy Markdown

Merge Queue Status

  • Entered queue2026-08-17 01:02 UTC · Rule: default · triggered by rule queue human PRs
  • Checks skipped · PR is already up-to-date
  • Merged2026-08-17 01:03 UTC · at 534834c0bce14f77ba88828c2c43e6de2e27c949 · fast-forward

This pull request spent 39 seconds in the queue, including 6 seconds running CI.

Required conditions to merge
  • any of [🛡 GitHub repository ruleset rule buildbot]:
    • check-success = buildbot/nix-build
    • check-neutral = buildbot/nix-build
    • check-skipped = buildbot/nix-build

@mergify
mergify Bot merged commit 534834c into main Aug 17, 2026
7 checks passed
@mergify
mergify Bot deleted the fm/vx-atomic-compaction-pi-only branch August 17, 2026 01:03
@mergify mergify Bot removed the queued label Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author-approved Owner self-approval marker; triggers Mergify auto-approve

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant