diff --git a/doc/plans/2026-10-02-pi-production-readiness.md b/doc/plans/2026-10-02-pi-production-readiness.md index 297bea79a84..7f8cb7e0155 100644 --- a/doc/plans/2026-10-02-pi-production-readiness.md +++ b/doc/plans/2026-10-02-pi-production-readiness.md @@ -38,6 +38,8 @@ The following current-cloud paths pass with runtime `b696e131`, harness | File edit, one exact successful command, authenticated public download, registered deliverable, finish, Done and finalized copy-back | `pi-core-0-1791470879` | 23 files; archive SHA256 `9a1c41e2ccad75f89a069ff571a3aa9f8cb94ae80c1bd397f7c886338b9a09bd`; definition 5 | | Three browser follow-up turns retain native session/process/workspace identity and append the earlier work | `pi-core-1-1791471072` | 23 files; archive SHA256 `d10310a2720a0d6c0636ce389fc6cc5faa887cc5c95bd697cdf0172619973609`; definition 2 | | Human plan approval resumes work and completion through the public product | `pi-core-3-1791472300` | 22 files; archive SHA256 `8c069ff176cb94166429901957f80e8b22c36ddf0f2047193889c4b7059aedf3`; definition 5 | +| Same-turn browser steering and human denial stay on the original run | `pi-core-4-1791472621` | 39 files; archive SHA256 `ce1f35ceaa66e2edaed070a26d25fcb24251be72726fb4372d057ab36425e1c3`; controls definition 3 | +| Stop during pending native permission cancels work and retires the owned runtime | `pi-core-5-1791472865` | 33 files; archive SHA256 `771f132bdc192d08a106b2b35322ade1c8baafc837949770d76ea60e571770a5`; controls definition 3 | Every listed canonical result and independent cleanup check passes. All retained files are hash-verified. These are exact-source passes; a changed runtime must @@ -65,6 +67,18 @@ No model allowlist, model fallback, credential policy or question-answer coercio is added. The corrected runtime requires the normal hosted cloud build and public-install checks before another paid question attempt. +The baseline core host stops normally after retaining all six dispatched +campaigns, including the failed question attempt. No runtime process or scratch +root remains. Controller restart was not dispatched on the old question runtime. +The first profile-19 cloud build is superseded because the normal install probe +still expected profile 18. Its correction synchronizes the exact version and +digest; the original build handle remains retained. Review then identifies a +valid recovery decoder gap: stored Pi profile-18 runs must remain parseable after +the profile-19 upgrade. Add profile 18 to historical decoding and preserve its +exact persisted identity, while current launch admission still rejects it. No +question-schema, package graph or executable closure changes in this correction. +Hold the fresh qualification build until this narrow recovery fix passes review. + ## Correct cloud memory-read authority — 2026-10-08 Frozen runtime/image `b696e131ae32a82418e570b32f4727b5adb14e49` passes all diff --git a/packages/paperclip-runner/src/backends/native-backend-factory.test.ts b/packages/paperclip-runner/src/backends/native-backend-factory.test.ts index 62a35bac28d..d7f0c1c9d95 100644 --- a/packages/paperclip-runner/src/backends/native-backend-factory.test.ts +++ b/packages/paperclip-runner/src/backends/native-backend-factory.test.ts @@ -545,6 +545,7 @@ describe("native backend factory", () => { ["copilot", "../../test/fixtures/copilot-profile-v14-identity.json"], ["pi", "../../test-fixtures/pi-acp/profile-v13-identity.json"], ["pi", "../../test-fixtures/pi-acp/profile-v14-identity.json"], + ["pi", "../../test-fixtures/pi-acp/profile-v18-identity.json"], ["cursor", "../../test/fixtures/cursor-acp/profile-v9-identity.json"], ["copilot", "../../test/fixtures/copilot-profile-v7-identity.json"], ["copilot", "../../test/fixtures/copilot-profile-v9-identity.json"], diff --git a/packages/paperclip-runner/src/contracts/native-execution.test.ts b/packages/paperclip-runner/src/contracts/native-execution.test.ts index dd6f4c02929..d4a4370f188 100644 --- a/packages/paperclip-runner/src/contracts/native-execution.test.ts +++ b/packages/paperclip-runner/src/contracts/native-execution.test.ts @@ -312,10 +312,12 @@ describe("NativeExecutionInputV1", () => { })).toThrow("eventExpiryDays"); }); - it("decodes a persisted Pi profile-17 run without rewriting its identity", () => { + it.each([ + [17, "sha256:a1d976c437cb736c9cce8ebe8b8baf59e571761a8d00e8b1885e72dd906d8f21"], + [18, "sha256:9d3e7d8269f1a0af94616552dfc69671932688b81dbbd5bab9ef356b3a9cbccb"], + ] as const)("decodes a persisted Pi profile-%s run without rewriting its identity", (agentProfileVersion, commandDigest) => { const { permissionPolicy: _permissionPolicy, ...nativeProfile } = QUALIFIED_ACPX_PROFILES.pi; - const profile = { ...nativeProfile, agentProfileVersion: 17, - commandDigest: "sha256:a1d976c437cb736c9cce8ebe8b8baf59e571761a8d00e8b1885e72dd906d8f21" }; + const profile = { ...nativeProfile, agentProfileVersion, commandDigest }; const persisted = { ...input, session: { ...input.session, driverKind: "acpx_runtime" }, provider: { kind: "acpx", agent: "pi", model: "openrouter/deepseek/deepseek-v4-flash-0731", piThinkingLevel: "low", permissionPolicy: "interactive", profile } }; diff --git a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts index 51719105a4f..9ac4d51f87e 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts @@ -5,6 +5,7 @@ import { isSupportedAcpxProfileVersion } from "./profile-compatibility.js"; describe("historical ACPX profile decoding", () => { it("retains each provider's existing revision boundary", () => { expect(isSupportedAcpxProfileVersion("pi", 17)).toBe(true); + expect(isSupportedAcpxProfileVersion("pi", 18)).toBe(true); expect(isSupportedAcpxProfileVersion("cursor", 15)).toBe(true); expect(isSupportedAcpxProfileVersion("cursor", 16)).toBe(false); for (const agent of ["pi", "copilot"]) { diff --git a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts index 86dcba70229..3cf4d702a5a 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts @@ -2,12 +2,12 @@ import { QUALIFIED_ACPX_PROFILE_DATA } from "./generated-profiles.js"; /** Decodable historical profile revisions, not permission to launch them. * Exact current profile/package/digest admission is checked separately. */ -type HistoricalAcpxProfileVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17; +type HistoricalAcpxProfileVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18; type CurrentAcpxProfileVersion = typeof QUALIFIED_ACPX_PROFILE_DATA[keyof typeof QUALIFIED_ACPX_PROFILE_DATA]["agentProfileVersion"]; export type AcpxProfileVersion = HistoricalAcpxProfileVersion | CurrentAcpxProfileVersion; const historicalVersions: Readonly> = { - pi: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], claude: [1, 2, 3, 4, 5], codex: [1, 2, 3, 4, 5], + pi: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], claude: [1, 2, 3, 4, 5], codex: [1, 2, 3, 4, 5], grok: [1, 2, 3, 4, 5], copilot: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], cursor: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], };