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 <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-08 10:32:00 -05:00
1 parent 604b8d307a
commit 5194a3990d
5 files changed
+23 -5

No files matched your search

@@ -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
@@ -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"],
@@ -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 } };
@@ -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"]) {
@@ -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<Record<string, readonly HistoricalAcpxProfileVersion[]>> = {
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],
};