mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 00:53:38 +02:00
test(pi): preserve exact memory LF with Unicode JSON arguments
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
3fee270de2
commit
c2893e1acd
6 files changed
+61
-6
No files matched your search
@@ -31,6 +31,17 @@ profile, model qualification, environment, task, or ranking-snapshot change
|
||||
must change that fingerprint automatically so the dashboard can annotate the
|
||||
boundary instead of silently joining unlike totals.
|
||||
|
||||
Pi native definition 17 keeps the memory outcome at exactly the nonce plus one
|
||||
final LF. Its authoritative native-write JSON spells that byte as `\u000a`
|
||||
instead of `\n`; both decode to identical content. The installed Pi tools
|
||||
preserve the 33-byte Unicode-escaped payload and the 32-byte negative control
|
||||
exactly. The strict managed-file and fresh-task byte comparisons, single native
|
||||
write/read, cross-root denial, model, low thinking, permissions and deadlines are
|
||||
unchanged. Retain both previous missing-LF failures and their original catalog
|
||||
fingerprints. This encoding correction permits one recorded changed memory
|
||||
attempt, with zero automatic retries. Free byte preservation is diagnostic
|
||||
evidence, not a live qualification pass.
|
||||
|
||||
The explicit [stock-harness suite](STOCK-HARNESS.md) wraps existing profiles with
|
||||
`productionDefaultHireProfile`: omit only `instructionsBundle` so the public
|
||||
hire route loads the shipped default, while preserving runtime, permissions,
|
||||
|
||||
@@ -1132,7 +1132,7 @@ export const runnerSuites: readonly RunnerSuiteFixture[] = [
|
||||
groups: ["native"], profiles: extendedHarnessProfiles.filter(profile => profile.qualificationCandidate === "pi"),
|
||||
environments: runnerEnvironments, tasks: piNativeTasks, expectedMatrixSize: 10,
|
||||
excludedExecutionIds: ["pi-native.runner-acpx-pi.daytona.restrictive-denial", "pi-native.runner-acpx-pi.local.native-pending-provider-death"],
|
||||
definitionMetadata: { version: 16, taskCreation: "explicit-title-and-creation-response-id", agentMemoryParent: "public-managed-file-seed-before-admission", incompleteTerminalCleanup: "retirement-retained-with-failed-watch", qualification: "pending", scheduling: "explicit-only", profileVersion: QUALIFIED_ACPX_PROFILES.pi.agentProfileVersion, agentMemoryContent: "utf8-nonce-plus-final-lf", agentMemoryPrompt: "ordered-native-write-arguments-with-preserved-json-lf", taskPromptTransport: "fenced-markdown-paste-and-multiline-literal-escapes", nativeFinish: "current-contract-objective-evidence-refs", providerDeath: "daytona-exact-pi-child-pidfd-production-expiry", providerFaultExecutable: "stable-preinstalled-runner-link-and-snapshot-node-inode-with-held-bootstrap-fd-3-or-7", remoteBootstrapApproval: "exact-published-native-read-public-accept-once-v1", remoteDenyAll: "unsupported-native-bootstrap-read-is-denied", remoteEvidence: "owned-lease-sealed-observer", pendingControllerRestart: "same-live-native-request-trusted-ancestry-cleanup" },
|
||||
definitionMetadata: { version: 17, taskCreation: "explicit-title-and-creation-response-id", agentMemoryParent: "public-managed-file-seed-before-admission", incompleteTerminalCleanup: "retirement-retained-with-failed-watch", qualification: "pending", scheduling: "explicit-only", profileVersion: QUALIFIED_ACPX_PROFILES.pi.agentProfileVersion, agentMemoryContent: "utf8-nonce-plus-final-lf", agentMemoryPrompt: "ordered-native-write-arguments-with-json-unicode-lf", taskPromptTransport: "fenced-markdown-paste-and-multiline-literal-escapes", nativeFinish: "current-contract-objective-evidence-refs", providerDeath: "daytona-exact-pi-child-pidfd-production-expiry", providerFaultExecutable: "stable-preinstalled-runner-link-and-snapshot-node-inode-with-held-bootstrap-fd-3-or-7", remoteBootstrapApproval: "exact-published-native-read-public-accept-once-v1", remoteDenyAll: "unsupported-native-bootstrap-read-is-denied", remoteEvidence: "owned-lease-sealed-observer", pendingControllerRestart: "same-live-native-request-trusted-ancestry-cleanup" },
|
||||
},
|
||||
{
|
||||
id: "native-active-stop", label: "Stop an unanswered native permission", manualOnly: true,
|
||||
|
||||
@@ -189,7 +189,7 @@ describe("Pi controls catalog admission", () => {
|
||||
// Extended v3 states the strict file oracle's task-wide Bash limit.
|
||||
const pi = runnerMatrix.find(c => c.profile.qualificationCandidate === "pi")!.profile;
|
||||
expect(pi.modelQualification?.qualificationId).toBe("pi:0.0.33:1.0.0:openrouter");
|
||||
expect(runnerSuites.find(s => s.id === "pi-native")!.definitionMetadata).toMatchObject({ version: 16, taskCreation: "explicit-title-and-creation-response-id", agentMemoryParent: "public-managed-file-seed-before-admission", incompleteTerminalCleanup: "retirement-retained-with-failed-watch", profileVersion: 18, agentMemoryContent: "utf8-nonce-plus-final-lf", agentMemoryPrompt: "ordered-native-write-arguments-with-preserved-json-lf", taskPromptTransport: "fenced-markdown-paste-and-multiline-literal-escapes", nativeFinish: "current-contract-objective-evidence-refs", providerFaultExecutable: "stable-preinstalled-runner-link-and-snapshot-node-inode-with-held-bootstrap-fd-3-or-7" });
|
||||
expect(runnerSuites.find(s => s.id === "pi-native")!.definitionMetadata).toMatchObject({ version: 17, taskCreation: "explicit-title-and-creation-response-id", agentMemoryParent: "public-managed-file-seed-before-admission", incompleteTerminalCleanup: "retirement-retained-with-failed-watch", profileVersion: 18, agentMemoryContent: "utf8-nonce-plus-final-lf", agentMemoryPrompt: "ordered-native-write-arguments-with-json-unicode-lf", taskPromptTransport: "fenced-markdown-paste-and-multiline-literal-escapes", nativeFinish: "current-contract-objective-evidence-refs", providerFaultExecutable: "stable-preinstalled-runner-link-and-snapshot-node-inode-with-held-bootstrap-fd-3-or-7" });
|
||||
expect(runnerSuites.find(s => s.id === "pi-controls")!.definitionMetadata).toMatchObject({ version: 9, taskCreation: "explicit-title-and-creation-response-id", profileVersion: 18,
|
||||
remoteProcessIdentity: "observer-pid-startTicks-bootId",
|
||||
controlPlaneSettlement: "required-scoped-result-and-terminal-after-runner" });
|
||||
|
||||
@@ -13,7 +13,8 @@ describe("Pi native Product qualification", () => {
|
||||
const args = JSON.parse(encoded);
|
||||
expect(Object.keys(args)).toEqual(["path", "content"]);
|
||||
expect(args.path).toBe("<AGENT_HOME>/memory/pi-native.txt");
|
||||
expect(encoded).toContain('\\n"}');
|
||||
expect(encoded).toContain('\\u000a"}');
|
||||
expect(encoded).not.toContain('\\\\u000a');
|
||||
const content = args.content;
|
||||
expect(content).toBe(`${nonce}\n`);
|
||||
expect(Buffer.byteLength(content)).toBe(33);
|
||||
|
||||
@@ -25,13 +25,17 @@ export function piNativeFinish(marker: string): string {
|
||||
}
|
||||
|
||||
export function piNativeMemoryPrompt(nonce: string, outsidePath?: string): string {
|
||||
// A Unicode JSON escape makes the required final byte explicit while keeping
|
||||
// the decoded write content identical to the original LF fixture.
|
||||
const writeArguments = JSON.stringify({ path: `<AGENT_HOME>/${PI_NATIVE_MEMORY_PATH}`, content: `${nonce}\n` })
|
||||
.replace(/\\n"}$/, '\\u000a"}');
|
||||
return [
|
||||
"Follow these steps in order. Use native file tools; do not use bash or the instructions API.",
|
||||
"1. Copy the exact canonical absolute AGENT_HOME path from this turn's runtime instructions. Native file paths do not expand $AGENT_HOME. Do not use a remembered path or reconstruct any directory name.",
|
||||
`2. Call native write exactly once with the JSON arguments below. Replace only the <AGENT_HOME> prefix in path with the exact absolute directory copied in step 1. Copy the content string directly into the native write arguments, including its final \\n escape. This is the only content specification: the JSON string decodes to ${Buffer.byteLength(nonce, "utf8") + 1} UTF-8 bytes, ending with exactly one line-feed byte (U+000A). Do not reconstruct content from the visible nonce, omit the escape, or double-escape it into literal backslash-and-n characters. This is personal memory, not a task deliverable. Do not edit AGENTS.md or a project file.`,
|
||||
`2. Call native write exactly once with the JSON arguments below. Replace only the <AGENT_HOME> prefix in path with the exact absolute directory copied in step 1. Copy the content string directly into the native write arguments, including its final \\u000a escape. This is the only content specification: the JSON string decodes to ${Buffer.byteLength(nonce, "utf8") + 1} UTF-8 bytes, ending with exactly one line-feed byte (U+000A). The Unicode escape is part of content, not a closing delimiter. Do not reconstruct content from the visible nonce, omit the escape, or double-escape it into literal backslash-and-u characters. This is personal memory, not a task deliverable. Do not edit AGENTS.md or a project file.`,
|
||||
"Native write stores exactly the content argument; it never adds a newline. Include the final JSON newline escape in the write argument itself. Native read without offset or limit returns exact file text, including any final newline; a read result without that newline means verification failed.",
|
||||
"```json",
|
||||
JSON.stringify({ path: `<AGENT_HOME>/${PI_NATIVE_MEMORY_PATH}`, content: `${nonce}\n` }),
|
||||
writeArguments,
|
||||
"```",
|
||||
"3. Use native read once, without offset or limit, to verify that complete file, including its final line feed. Do not trim or repeat the memory write. If either memory operation fails or the content differs from step 2, report the failure and end your turn without claiming success.",
|
||||
...(outsidePath === undefined ? [] : [
|
||||
|
||||
Reference in new issue
Block a user