Skip to content

chore(deps): upgrade pi SDK to ^1.4.0 - #90

Merged
patextreme merged 1 commit into
mainfrom
chore/upgrade-pi-sdk-1.4.0
Oct 24, 2026
Merged

patextreme merged 1 commit into
mainfrom
chore/upgrade-pi-sdk-1.4.0

Conversation

@patextreme

Copy link
Copy Markdown
Owner

What

Upgrades the Pi SDK from ^1.1.0 (locked 1.1.0) to ^1.4.0 (locked 1.4.0) for both @earendil-works/pi-coding-agent and @earendil-works/pi-ai.

The repo was running against a version skew: extensions executed under the Pi 1.4.0 host while typecheck validated against the 1.1.0 type definitions, so API drift in either direction could pass CI and misbehave live.

Changes

  • package.json / package-lock.json — peer + dev ranges to ^1.4.0; all seven locked @earendil-works/* packages resolve to 1.4.0.
  • extensions/notify-me/{integration,runtime-sequences}.test.ts — the locked-runtime fixtures reached into AgentSession.prototype._runAgentPrompt, which 1.4.0 replaced with _startRun(trigger, onStarted). The fixtures now call _startRun and stub _prepareRun (preparation is not the subject), so they still exercise the real post-run → boundary → settlement loop that notify-me depends on.
  • docs/notify-me-sdk-compatibility.md — refreshed evidence for the new lock: tarball URL, registry SRI, SHA-256 of the three source files, and every line reference. Semantics are unchanged (settlement still emitted only in the finally of the run loop, abort flag still authoritative); only the entry-point name moved.
  • README.md — peer range in Requirements and the notify-me minimum version.
  • nix/modules/pi-package.nix — npmDepsHash refreshed to sha256-K028BLElpgR7dit4Ukmh7C/Ur5NnVn83zAZbSt5btQs=.

No manual integrity backfill was needed this time: the generated lock carried an integrity value for every entry, and all seven @earendil-works/* SRI values match the registry's version-specific dist.integrity.

Verification

  • npm ci — clean install of the locked 1.4.0 family
  • biome check . — clean
  • npm run typecheck — clean
  • npm test — 438 pass, 0 fail, 1 skipped (hermetic-only tier, needs PI_FACTORY_SKILLS_OUTPUT)
  • nix flake check — all checks passed (biome, tsc, node-tests, package builds)

Notes

npm audit reports two advisories (1 high, 1 moderate) against undici, which [email protected] pins as a runtime dependency. 1.4.0 is the latest published SDK and no released version pins a fixed undici, so this is upstream and tracked rather than patched here — flagged in the compatibility doc.

Bumps @earendil-works/pi-coding-agent and @earendil-works/pi-ai from
^1.1.0 to ^1.4.0, matching the Pi 1.4.0 host that loads these
extensions at runtime.

- Rename the runtime fixture entry point from _runAgentPrompt to
  _startRun in the notify-me integration and sequence tests; _startRun
  now owns prompt preparation, so the fixtures stub _prepareRun and
  keep exercising the real post-run/boundary/settlement loop.
- Refresh the locked SDK compatibility evidence with 1.4.0 tarball,
  SRI, source hashes, and line references, and record the undici
  advisories 1.4.0 inherits.
- Refresh npmDepsHash and the README peer range.

Signed-off-by: Pat Losoponkul <[email protected]>
@patextreme

Copy link
Copy Markdown
Owner Author

Review complete — limited coverage, no repair-worthy findings

Standards and Spec reviews covered the full 7-file diff at c93193cb. No blockers, no significant bugs, no unresolved investigations; the repair queue is empty. 7 findings deduplicated: 0 blockers · 0 significant bugs · 3 report-only · 4 refuted.

Report-only (recorded, deliberately not repaired):

  • F-003 — the compat doc's opening line says the notification contract requires 1.4.0, conflating the package floor (1.4.0) with the contract floor (1.1.0); the next sentence corrects it.
  • F-004 — adapter.test.ts:1026 still stubs the removed _runAgentPrompt. The stub is inert: a preflight regression still fails that test, via an incidental TypeError rather than the purpose-built message. Diagnostic quality only.
  • F-007 — two line ranges in the compat doc truncate by 4 and 1 lines (1531–1561→1565, 1566–1588→1589); both cited windows still substantiate their claims.

The other four findings were refuted against the actual files (details in the audit).

Validation at c93193cb (freshly executed, not cached): biome check . clean · tsc --noEmit clean · node tests/run.mjs 438 pass / 0 fail / 1 skipped · nix flake check all checks passed · CI green. npm audit reports 1 high + 1 moderate, both pre-existing upstream undici 8.10.2 advisories identical at base and head.

Scope limitation (explicitly authorized): no originating issue and no OpenSpec change exists for this dependency bump, so the Spec axis reviewed against the PR body's own claims plus AGENTS.md, docs/notify-me-sdk-compatibility.md, and README.md only.

Reviewed: c93193cb · Delivered: no commits — no repairs were warranted · Attempts: 0/10 · Human input: none

Full Standards and Spec reports, judge ledger, and audit details

Standards

Standards review — chore/upgrade-pi-sdk-1.4.0

Hard violations: none found. No AGENTS.md, biome, tsconfig, or ADR rule is breached. Tests pass (adapter.test.ts 74/74, the two changed suites 18/18); runs are read-only.

Judgement calls

1. Stale fixture mirrors the renamed API — extensions/notify-me/adapter.test.ts:1027 (untouched by the diff)
_runAgentPrompt: () => { throw new Error("Preflight incorrectly started a run"); }. 1.4.0 has zero occurrences of _runAgentPrompt (grep of dist/); the guard now only fires incidentally via a missing _prepareRun TypeError. Dead sentinel, misleading name. The rename forced edits in 3 fixture files; only 2 were migrated → possible Shotgun Surgery. Directly contradicts the new doc claim (docs/notify-me-sdk-compatibility.md:88-91) that the suite tracks the run entry point.

2. Duplicated Code
The RuntimeMethods type + ~60-line facade (incl. the new _startRun signature and _prepareRun: async () => []) is copied verbatim between integration.test.ts:196-276 and runtime-sequences.test.ts:26-176, with a third partial copy at adapter.test.ts:1010-1030. The diff necessarily edits the same three hunks twice. The inline { messageType: "user"; prompt: string; images: unknown[] } literal is a repeated Data Clump in both files.

3. Coverage narrowing on the new surface (not on old assertions)
_prepareRun: async () => [] bypasses _startRun's own startup phase (pending-queue flush, onStarted?.(), _recordSelection, _pendingToolNames.clear), and neither fixture ever passes onStarted, so the 1.4.0 preflight "started" signal (production call at agent-session.js:1693) is unexercised. Pre/post assertions are otherwise byte-identical to the pre-change files — the migration is faithful to what it replaced, but does not cover what was added.

4. Doc line references — verified, two off
sha256sum matches all three cited files exactly; the SRI matches the lockfile. I confirmed 1423–1473, 1464–1471, 683–707, 904, 935–940, 1679–1692/1693, 1971–1982, 199, 2680, 3028, runtime 102–113 and 141/165/211/229/246/291, types.d.ts 575–581, 637–642, 752, 796–805, 848–851, 1121–1124, 1210–1211. Wrong: _handlePostAgentRun cited "1531–1561" (ends 1565); _runBeforeSettleBoundary cited "1566–1588" (ends 1589).

5. Stale floor text — README.md:17 and AGENTS.md:71 still say notify-me requires "1.1.0"/"Pi >=1.1.0" after the pin moved to ^1.4.0.

Lockfile / Nix / package.json (all consistent)

150 packages, zero missing integrity; all seven @earendil-works/* at 1.4.0 with integrity; chord removed with no dangling references (esbuild 0.28.2 still required by tsx ~0.28.0); marked-cjk-friendly added with integrity; root dev/peer mirror package.json exactly; no unrelated churn. npmDepsHash equals the hash recorded in the doc; not independently recomputable read-only. Registry-vs-SRI comparison is unverifiable offline — internally consistent, nothing contradicts it.

Spec

Spec-axis review: chore/upgrade-pi-sdk-1.4.0

(a) Claimed requirements missing / partial

PR body: "The locked-runtime fixtures reached into AgentSession.prototype._runAgentPrompt, which 1.4.0 replaced with _startRun(trigger, onStarted). The fixtures now call _startRun."

Not complete: extensions/notify-me/adapter.test.ts:1027 (a third locked-runtime fixture, not in the diff) still carries

_runAgentPrompt: () => {
  throw new Error("Preflight incorrectly started a run");
},

In 1.4.0 prompt() reaches _startRun (line 1693), never _runAgentPrompt, so this sentinel is dead. A preflight regression now surfaces as an incidental TypeError from the unstubbed _prepareRun, not as the asserted "preflight incorrectly started a run". The compat doc's preflight evidence (agent-session.js:1679–1692, "neither failure emits a run settlement") still leans on this probe.

(b) Unrequested behaviour

None. All seven files map to a stated claim; I found no extra edits.

(c) Implemented but wrong

  1. docs/notify-me-sdk-compatibility.md:3–4: "The notification contract requires Pi 1.4.0 or newer within major version 1. The contract itself dates from 1.1.0" — self-contradictory, and contradicted by README.md:17: "notify-me requires the final-settlement abort flag added in 1.1.0". The contract minimum is unchanged at 1.1.0; only the peer/dev range moved.

  2. README.md:205 (Notify Me section): "Build and load the extension with Pi 1.4.0 or newer" vs the same file's Requirements bullet (notify-me needs the 1.1.0 abort flag). Two different notify-me minimums in one file.

  3. docs/notify-me-sdk-compatibility.md: "_handlePostAgentRun (lines 1531–1561) handles retry, compaction/recovery, and queued messages" — the queued-message handling is at lines 1562–1564 (method ends 1565); the range truncates the very behaviour claimed. Also "_runBeforeSettleBoundary (lines 1566–1588)" ends at 1589 (closing brace omitted).

Claims I verified as accurate

SHA-256 of all three cited files, registry SRI for all seven @earendil-works/* (source identity + compat-doc SRI), all 149 lock entries carry integrity (no backfill needed), npmDepsHash (built checks.x86_64-linux.tsc-check successfully), tsc --noEmit clean, npm test = 439/438 pass/1 skipped, npm audit = 1 high + 1 moderate (undici 8.10.2, pinned identically by 1.1.0–1.4.0), and 1.4.0 as latest published version. Documented ranges 1423–1473, 1464–1471, 487–490, 683–707, 1971–1982, 1693, 2680/199/3028, 102–113 and runtime 141/165/211/229/246/291 all check out.

Judge ledger

Deduplicated across both axes; each ID verified against the actual files at c93193cb.

ID Provenance Category Disposition
F-001 Standards refuted refuted
F-002 Spec refuted refuted
F-003 Spec report-only open (report-only)
F-004 Standards + Spec report-only open (report-only)
F-005 Standards + Spec refuted refuted
F-006 Standards + Spec refuted refuted
F-007 Standards + Spec report-only open (report-only)

F-001 — "README.md:17 and AGENTS.md:71 are stale at the 1.1.0 floor" — refuted. Absorbs Standards findings 5's two claims. README.md:17 at head reads Pi `^1.4.0` ... notify-me requires the final-settlement abort flag added in 1.1.0, and the diff hunk changes ^1.1.0 → ^1.4.0 on that exact line — the line is not stale. The trailing "1.1.0" is a provenance clause verified by source: dist/core/extensions/types.d.ts:801-805 declares AgentSettledEvent { type: "agent_settled"; aborted: boolean }, consumed at extensions/notify-me/adapter.ts:157-163. AGENTS.md:71 reads preserve final agent_settled semantics (Pi >=1.1.0) and AGENTS.md is not in the diff (git diff --name-only confirms), so it is not a change this PR made; the parenthetical is a true statement about when those semantics appeared. Runtime: not applicable. A reviewer acting on this would "fix" a true sentence.

F-002 — "README.md:205 contradicts README.md:17" — refuted. README.md:205 says Build and load the extension with Pi 1.4.0 or newer and README.md:17 says ^1.4.0; the pre-change file said ^1.1.0/"1.1.0 or newer" on the same two lines and the diff raises both in lockstep. package.json:16 peer dep is ^1.4.0. The asserted intra-file contradiction does not exist at head.

F-003 — the doc's opening line conflates the contract floor with the package floor — report-only. docs/notify-me-sdk-compatibility.md:5 says "The notification contract requires Pi 1.4.0 or newer within major version 1", while line 6 says "The contract itself dates from 1.1.0" and lines 10-12 say "the semantics below are unchanged". Ground truth: the contract's events need 1.1.0 (types.d.ts:796-805); the package's delivered floor is 1.4.0 (package.json:16). Line 5 conflates them and the same paragraph separates them again two lines later. No behaviour, test, or gate depends on the sentence; peerDependencies genuinely excludes 1.1.x–1.3.x so "1.4.0 or newer" describes the only installable configuration. One-sentence wording imprecision, self-corrected in place — cosmetic documentation polish, not a contract defect.

F-004 — adapter.test.ts:1026 still stubs the removed _runAgentPrompt — report-only. The stub is _runAgentPrompt: () => { throw new Error("Preflight incorrectly started a run") }. grep -rl "_runAgentPrompt" node_modules/@earendil-works/ returns no files; it existed in 1.1.0 at agent-session.js:1380 and was live because 1.1.0's prompt() called it at 1631. So the guard was load-bearing before this PR and is inert now. The test still calls the real entry point (AgentSession.prototype.prompt.call(...)) and still asserts assert.rejects(..., /No model selected|No API key found/), deepEqual(events, ["input"]), and handbacks.length === 0. In 1.4.0 both preflight failures throw at agent-session.js:1679-1692, above the _startRun call at 1693, so the dead stub is never reached. Executed reproduction against the exact facade: a regression reaching _startRun throws TypeError: this._resolveIdleWaitIfIdle is not a function (from _prepareRun's catch, agent-session.js:1430-1436), not the purpose-built message — but the test still fails, so there is no false green. Unreachable dead code in a test double; diagnostic cost only.

F-005 — fixtures stub _prepareRun and omit onStarted, narrowing coverage — refuted. Base-vs-head comparison: the diff changes exactly two hunks per file (the added _prepareRun line and the _runAgentPrompt → _startRun invocation); every assertion is byte-identical to base. 1.1.0's _runAgentPrompt body (agent-session.js:1380-1414) is line-for-line the same outer loop and finally now inside 1.4.0 _startRun (1423–1473), and 1.1.0's preparation work lived inside prompt() before the call at 1631 — so these fixtures never exercised preparation in either version. onStarted is optional (onStarted?.() at 1441) and had no 1.1.0 counterpart. Answer to (a)/(b)/(c): faithful migration of the outer-loop/settlement contract, plus untested new surface for the relocated preparation phase; no pre-existing guarantee was covered at base and uncovered at head.

F-006 — duplicated RuntimeMethods/facade across the two fixtures — refuted as a PR-introduced defect. The ~85-line facade exists identically at the base commit in integration.test.ts and runtime-sequences.test.ts (base lines 214, 220 carry _deferredSettledActions and _resolveIdleWaitIfIdle). This PR's contribution to the duplication is one added line per copy. Pre-existing smell; extracting a shared helper would be test-infrastructure refactoring with no qualifying correction attached, which the threshold does not authorize.

F-007 — compatibility-doc line ranges truncate the behaviour they cite — report-only. True line numbers: _handlePostAgentRun opens 1531, next method _runBeforeSettleBoundary opens 1566, so the first ends at 1565; the doc says "1531–1561", excluding the comment and return !this._agentRunAbortRequested && this.agent.hasQueuedMessages() at 1562–1564. _runBeforeSettleBoundary spans 1566–1589; the doc says "1566–1588", omitting only the closing brace. 18 of 20 sampled citations are exact and all three SHA-256 values match the installed tarball. The claimed behaviours (retry 1540–1548, compaction 1559–1561, queued early-return 1538–1539) are all inside the cited window, so both ranges still substantiate their claims.

Repair queue: empty. No blocker and no significant bug. Prior-ID reconciliation: no prior ledger exists — round 1, 0 comments, 0 reviews at any head; nothing to reconcile or mark recurring. Escalation questions: none.

Audit record

  • Run / round: c93193cb1127270996c43ed446b6537826f9d9b4 / round 1 · Repairs used: 0/10 · Repair-start: none (no repair was warranted) · Scope amendments: none.
  • Pinned base / merge-base: a4f6e19b86f7e66deb0e64f64aebd0f10012faa4 (= origin/main tip = PR baseRefOid) · Reviewed head: c93193cb1127270996c43ed446b6537826f9d9b4 (one commit, c93193c chore(deps): upgrade pi SDK to ^1.4.0) · Delivered head: identical — no commits were created.
  • Diff: git diff a4f6e19b...c93193cb, 7 files, +129/−100: README.md, docs/notify-me-sdk-compatibility.md, extensions/notify-me/integration.test.ts, extensions/notify-me/runtime-sequences.test.ts, nix/modules/pi-package.nix, package-lock.json, package.json.
  • Sources reviewed: AGENTS.md, biome.json, tsconfig.json, GLOSSARY.md, docs/adr/0001-semantic-evidence-stays-local.md, docs/adr/0002-opencode-usage-reads-undocumented-inference-meters.md, docs/agents/{issue-tracker,labels,domain}.md, docs/notify-me-sdk-compatibility.md, README.md, plus the PR body (treated as untrusted claim evidence). No CODING_STANDARDS.md or CONTRIBUTING.md exists.
  • Checks — freshly executed at c93193cb, none cached: nix develop --command biome check . → exit 0, "Checked 49 files, no fixes applied"; ./node_modules/.bin/tsc --noEmit → exit 0, no output; node tests/run.mjs → 439 tests, 438 pass, 0 fail, 1 skipped, 18 suites, exit 0; nix flake check → exit 0, "all checks passed". CI on the PR head (CI, 44s) is green. npm run format was not run because it writes; biome check . covers format enforcement.
  • Accepted cached/indirect evidence: npmDepsHash was not independently recomputed read-only — it is evidenced by the passing nix flake check (which fails on a stale hash); the seven @earendil-works/* registry-vs-SRI comparisons were verified against the registry by the judge (7/7 match, every entry carries integrity).
  • Skipped coverage with reasons: npm ci was not run — it deletes node_modules and violates the read-only mandate; tests/semantic/** was not run (manual-only, never a gate, per ADR 0001); formatter rewrite was not attempted (write operation).
  • Material caveats: npm audit reports 1 high + 1 moderate advisory, both from upstream [email protected] pinned identically by 1.1.0–1.4.0 and therefore pre-existing, not introduced here; the compat doc records them.
  • Orchestrator verification: independently re-checked README.md:17/:205, the absence of AGENTS.md from the diff, both package.json ranges (^1.4.0 peer and dev, lines 16 and 20), the adapter.test.ts:1026-1028 stub, the absence of _runAgentPrompt from the locked SDK, the base-commit facade duplication, and the two doc line spans — all four refutations upheld. The judge's ledger cites the two truncated ranges at doc lines 51–52; the actual lines are 40–41, a citation slip in the ledger that does not affect F-007's substance.
  • Delivery state: comment only. No commits, no push, no branch movement, worktree clean before and after.
  • User authorization for limited coverage: recorded in-session for this run ("proceed with no spec"); no originating issue or OpenSpec change exists for this dependency bump.

@patextreme
patextreme merged commit daf829f into main Oct 24, 2026
1 check passed
@patextreme
patextreme deleted the chore/upgrade-pi-sdk-1.4.0 branch October 24, 2026 04:49
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