From 5194a3990dcb87622288aaafce7baebe09542a4d Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 8 Oct 2026 10:32:00 -0500 Subject: [PATCH] Keep persisted Pi profile 18 decodable after the question upgrade Preserve exact stored identity while current profile and digest remain required to launch. Record scoped live controls and baseline host retirement. Co-Authored-By: Paperclip --- doc/plans/2026-10-02-pi-production-readiness.md | 14 ++++++++++++++ .../src/backends/native-backend-factory.test.ts | 1 + .../src/contracts/native-execution.test.ts | 8 +++++--- .../src/drivers/acpx/profile-compatibility.test.ts | 1 + .../src/drivers/acpx/profile-compatibility.ts | 4 ++-- 5 files changed, 23 insertions(+), 5 deletions(-) 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], };