mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-21 16:27:18 +02:00
Clarify native Runner completion tool guidance
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
5837aa4442
commit
26c0e552a0
17 files changed
+131
-17
No files matched your search
@@ -131,6 +131,30 @@ and existing-test update.
|
||||
`paperclip_finish`/`paperclip_block` guidance must not leak into legacy
|
||||
completion paths, which use the operational skill and API.
|
||||
|
||||
Dotta approved the six proposed 2.3 changes and clarified that native tool
|
||||
guidance must stay separate from legacy runners on 2026-10-02. Legacy adapters
|
||||
use their existing Paperclip skill/API and adapter completion paths; they must
|
||||
not inherit instructions to call unavailable native finish/block tools.
|
||||
|
||||
- [ ] **2.3.1 Share native finish/block tool documentation.** First slice:
|
||||
one canonical description per tool for Codex and native MCP bridges; refresh
|
||||
retained provider threads through the native tool-contract fingerprint.
|
||||
Executable coverage: SH-4-tools checks actual wire/catalog delivery across
|
||||
all five native provider kinds; SH-4-resume checks v13 checkpoint rotation
|
||||
without changing the Paperclip task or prior history. Live qualification is
|
||||
pending; use native profile comparisons, with legacy results kept separate.
|
||||
- [ ] **2.3.2 Move document/file delivery procedures into native tool docs.**
|
||||
Include the live server override and preserve prepared versus delivered receipts.
|
||||
- [ ] **2.3.3 Move hiring/dependency recipes into native discovery/tool docs.**
|
||||
Preserve existing blocker IDs and workspace-release behavior.
|
||||
- [ ] **2.3.4 Reduce the fixed native prompt.** Retain the pre-choice connection
|
||||
cue and the one-accepted-result boundary.
|
||||
- [ ] **2.3.5 Remove repeated native task/backend procedures.** Preserve runtime
|
||||
facts and specialized mode, answer, and recovery constraints.
|
||||
- [ ] **2.3.6 Qualify the combined native reduction.** Record prompt/tool
|
||||
revisions, exact source fingerprints, fresh/resumed sessions, and matched
|
||||
GitHub behavior results before claiming improvement.
|
||||
|
||||
### Follow-up 2.1 implementation and verification
|
||||
|
||||
The common task and conversation defaults now share the same identity sentence
|
||||
|
||||
@@ -3,8 +3,10 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
PRP_BLOCK_RESULT_OUTPUT_SCHEMA,
|
||||
PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_RESULT_OUTPUT_SCHEMA,
|
||||
PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
} from "./completion-result.js";
|
||||
import { codexSemanticToolSpecs } from "../drivers/codex/codex-driver-values.js";
|
||||
|
||||
@@ -83,6 +85,8 @@ describe("provider-neutral completion result schema", () => {
|
||||
);
|
||||
expect(finish.inputSchema).toEqual(PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA);
|
||||
expect(block.inputSchema).toEqual(PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA);
|
||||
expect(finish.description).toBe(PRP_COMPLETION_TOOL_DESCRIPTION);
|
||||
expect(block.description).toBe(PRP_BLOCK_TOOL_DESCRIPTION);
|
||||
});
|
||||
|
||||
it("allows only a response-wake continuation when completion explicitly yields", () => {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
/** Provider-neutral semantic completion tools and their strict model-facing schemas. */
|
||||
export const PRP_COMPLETION_TOOL_NAME = "paperclip_finish" as const;
|
||||
export const PRP_BLOCK_TOOL_NAME = "paperclip_block" as const;
|
||||
/** Native Runner guidance; legacy adapters use their own skill/API completion paths. */
|
||||
export const PRP_COMPLETION_TOOL_DESCRIPTION =
|
||||
"Report completed work (done), work requiring review (needs_review), or an explicit wait for the next response (yielded with response_wake). Use the current completion contract and supporting evidence. If rejected, correct the report and retry. After acceptance, read the returned outcome; do not claim completion while gated. Explain any required approval with its supplied link and action, then write the final response and end the turn without further tool calls.";
|
||||
export const PRP_BLOCK_TOOL_DESCRIPTION =
|
||||
"Report work that cannot continue because of a concrete blocker. Identify the blocker, its owner, and the action needed to unblock it; use the current completion contract and supporting evidence. If rejected, correct the report and retry. After acceptance, read the returned outcome, explain the blocker and any required action in the final response, and end the turn without further tool calls.";
|
||||
export const PRP_SEMANTIC_TOOL_NAMES = [
|
||||
PRP_COMPLETION_TOOL_NAME,
|
||||
PRP_BLOCK_TOOL_NAME,
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import {
|
||||
PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
} from "../../contracts/completion-result.js";
|
||||
import {
|
||||
CODEX_BLOCK_RESULT_OUTPUT_SCHEMA,
|
||||
CODEX_INVALID_REQUEST,
|
||||
@@ -540,6 +546,10 @@ describe("Codex app-server Codex driver", () => {
|
||||
expect(started.developerInstructions).toBe(conversationMode === "direct" ? undefined : baseInstructions);
|
||||
expect(resumed.developerInstructions).toBe(conversationMode === "direct" ? "" : baseInstructions);
|
||||
expect(resumed.dynamicTools).toEqual(started.dynamicTools);
|
||||
expect(started.dynamicTools).toEqual(conversationMode === "direct" ? [] : [
|
||||
{ name: "paperclip_finish", description: PRP_COMPLETION_TOOL_DESCRIPTION, inputSchema: PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
{ name: "paperclip_block", description: PRP_BLOCK_TOOL_DESCRIPTION, inputSchema: PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
]);
|
||||
expect(resumed.config).toEqual(started.config);
|
||||
await recovered.session?.close({ reason: "verified additive recovery" });
|
||||
});
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { PersistedHarnessProviderIdentity } from "../../contracts/harness-driver.js";
|
||||
import type { NativeUserMessage } from "../../contracts/types.js";
|
||||
import {
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
} from "../../contracts/completion-result.js";
|
||||
import {
|
||||
CODEX_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
CODEX_BLOCK_TOOL_NAME,
|
||||
@@ -232,8 +236,7 @@ export function differingJsonPaths(
|
||||
function finishToolSpec(): Record<string, unknown> {
|
||||
return {
|
||||
name: CODEX_COMPLETION_TOOL_NAME,
|
||||
description:
|
||||
"Return the one semantic completion result for this task, including an explicit response_wake yield when waiting for the next response.",
|
||||
description: PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
inputSchema: CODEX_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
};
|
||||
}
|
||||
@@ -241,8 +244,7 @@ function finishToolSpec(): Record<string, unknown> {
|
||||
function blockToolSpec(): Record<string, unknown> {
|
||||
return {
|
||||
name: CODEX_BLOCK_TOOL_NAME,
|
||||
description:
|
||||
"Return the one semantic result when the task cannot continue.",
|
||||
description: PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
inputSchema: CODEX_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
} from "../../contracts/completion-result.js";
|
||||
|
||||
import { canonicalOpenCodeMcpToolName, startOpenCodeMcpBridge, type OpenCodeMcpBridge } from "./mcp-bridge.js";
|
||||
|
||||
@@ -38,8 +44,8 @@ describe("OpenCode MCP bridge", () => {
|
||||
expect(await listed.json()).toMatchObject({
|
||||
result: { tools: [
|
||||
{ name: "documents.read" },
|
||||
{ name: "paperclip_finish" },
|
||||
{ name: "paperclip_block" },
|
||||
{ name: "paperclip_finish", description: PRP_COMPLETION_TOOL_DESCRIPTION, inputSchema: PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
{ name: "paperclip_block", description: PRP_BLOCK_TOOL_DESCRIPTION, inputSchema: PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
] },
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,8 +4,10 @@ import { Ajv2020, type ValidateFunction } from "ajv/dist/2020.js";
|
||||
|
||||
import {
|
||||
PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_BLOCK_TOOL_NAME,
|
||||
PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_TOOL_NAME,
|
||||
} from "../../contracts/completion-result.js";
|
||||
|
||||
@@ -117,8 +119,8 @@ function normalizeTools(
|
||||
seen.add(name);
|
||||
}
|
||||
if (includeTerminalTools) for (const terminal of [
|
||||
{ name: PRP_COMPLETION_TOOL_NAME, description: "Return the semantic completion result.", inputSchema: PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
{ name: PRP_BLOCK_TOOL_NAME, description: "Return the semantic blocked result.", inputSchema: PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
{ name: PRP_COMPLETION_TOOL_NAME, description: PRP_COMPLETION_TOOL_DESCRIPTION, inputSchema: PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
{ name: PRP_BLOCK_TOOL_NAME, description: PRP_BLOCK_TOOL_DESCRIPTION, inputSchema: PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
]) {
|
||||
if (!seen.has(terminal.name)) tools.push(terminal);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { connect } from "node:net";
|
||||
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
} from "../contracts/completion-result.js";
|
||||
|
||||
import {
|
||||
canonicalRunnerToolName,
|
||||
@@ -48,8 +54,8 @@ describe("runner semantic MCP bridge", () => {
|
||||
result: {
|
||||
tools: [
|
||||
{ name: "documents.read" },
|
||||
{ name: "paperclip_finish" },
|
||||
{ name: "paperclip_block" },
|
||||
{ name: "paperclip_finish", description: PRP_COMPLETION_TOOL_DESCRIPTION, inputSchema: PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
{ name: "paperclip_block", description: PRP_BLOCK_TOOL_DESCRIPTION, inputSchema: PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -10,8 +10,10 @@ import { Ajv2020, type ValidateFunction } from "ajv/dist/2020.js";
|
||||
|
||||
import {
|
||||
PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_BLOCK_TOOL_NAME,
|
||||
PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_TOOL_NAME,
|
||||
} from "../contracts/completion-result.js";
|
||||
|
||||
@@ -70,12 +72,12 @@ const MAX_RESULT_CHUNK_BYTES = 64 * 1024;
|
||||
const RESERVED_TOOLS: readonly RunnerToolDefinition[] = [
|
||||
{
|
||||
name: PRP_COMPLETION_TOOL_NAME,
|
||||
description: "Return the semantic completion result.",
|
||||
description: PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
inputSchema: PRP_COMPLETION_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
},
|
||||
{
|
||||
name: PRP_BLOCK_TOOL_NAME,
|
||||
description: "Return the semantic blocked result.",
|
||||
description: PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
inputSchema: PRP_BLOCK_RESULT_PROVIDER_INPUT_SCHEMA,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -54,6 +54,10 @@ import {
|
||||
CODEX_SKILLLESS_BASE_INSTRUCTIONS,
|
||||
createCodexTaskEnvelope,
|
||||
} from "../contracts/codex.js";
|
||||
import {
|
||||
PRP_BLOCK_TOOL_DESCRIPTION,
|
||||
PRP_COMPLETION_TOOL_DESCRIPTION,
|
||||
} from "../contracts/completion-result.js";
|
||||
import {
|
||||
CodexAppServerDriver,
|
||||
codexSemanticToolSpecs,
|
||||
@@ -1336,14 +1340,19 @@ it("includes ACPX terminal tools in the authenticated bridge catalog", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves answer and internal wait descriptions in the serialized native tool catalog", () => {
|
||||
it.each(["codex", "opencode", "claude_managed", "aws_agentcore", "acpx"] as const)("preserves answer and internal wait descriptions in the serialized native %s tool catalog", (provider) => {
|
||||
const catalog = JSON.parse(
|
||||
JSON.stringify(authorizedToolSetForProvider("codex", codexSemanticToolSpecs())),
|
||||
JSON.stringify(authorizedToolSetForProvider(provider, codexSemanticToolSpecs())),
|
||||
);
|
||||
const finish = catalog.operations.find(
|
||||
(operation: { operationId: string }) =>
|
||||
operation.operationId === "paperclip_finish",
|
||||
);
|
||||
const block = catalog.operations.find(
|
||||
(operation: { operationId: string }) => operation.operationId === "paperclip_block",
|
||||
);
|
||||
expect(finish.description).toBe(PRP_COMPLETION_TOOL_DESCRIPTION);
|
||||
expect(block.description).toBe(PRP_BLOCK_TOOL_DESCRIPTION);
|
||||
expect(finish.inputSchema.properties.summary.description).toContain(
|
||||
"complete user-facing answer",
|
||||
);
|
||||
|
||||
@@ -1840,6 +1840,12 @@ describe("rebindNativeSessionCheckpoint", () => {
|
||||
retainedFingerprint:
|
||||
"sha256:5b7b302db36f7ed6686f9ea1ba70bbf79ebd7fabf86953b548d966a2bc38b648",
|
||||
},
|
||||
{
|
||||
contract: "native completion tool guidance",
|
||||
// Deployed v13 local catalog before canonical finish/block descriptions.
|
||||
retainedFingerprint:
|
||||
"sha256:68a51d34e091c55ee5d0d2b563153454dd727d72db16e6a27c358d342ae489c9",
|
||||
},
|
||||
{
|
||||
contract: "task-bound human-input description",
|
||||
// Deployed v9 still advertises the generic mock-task question description.
|
||||
|
||||
@@ -23,7 +23,7 @@ export function nativeToolContractFingerprintForTarget(
|
||||
return `sha256:${createHash("sha256")
|
||||
.update(
|
||||
JSON.stringify({
|
||||
schema: "paperclip.native-tool-contract.v13",
|
||||
schema: "paperclip.native-tool-contract.v14",
|
||||
executionTargetKind,
|
||||
advertisementPolicy: {
|
||||
// Direct provider threads retain declarations from thread/start.
|
||||
|
||||
@@ -14,6 +14,13 @@ agent-creation route materialize the shipped default.
|
||||
| SH-1: native Codex preserves vendor base instructions | Serialized start/resume requests from the TypeScript driver, recovery paths, runnerd transport, Runner Lab/live sessions, and Rust provider use additive developer instructions. | Real new native Codex hires execute the three journeys below. Task success alone cannot prove vendor base preservation. |
|
||||
| SH-2: identity-only default hire manual | Existing public agent-creation and onboarding-asset tests cover default, custom, and CEO exceptions. | The public bundle is exactly one `AGENTS.md` containing the eight-word shipped identity, checked before provider execution and again during cleanup. |
|
||||
| SH-3: reduced shared legacy task/chat defaults and resume delta | Shared prompt tests and ACPX, Codex, OpenCode, Pi, Hermes, and Cursor Cloud adapter regressions retain runtime context and exclude removed generic procedures. | Actual legacy `adapter.invoke` prompts retain fresh identity/connection guidance, omit the removed procedures, and have complete receipts for every observed run. |
|
||||
| SH-4: shared native finish/block tool guidance | Actual authenticated MCP catalogs, Codex start/resume frames, serialized daemon catalogs for all five native provider kinds, and rotation of a retained v13 thread to the new tool contract. | The three native profiles run the existing skill, continuation, and chat journeys. Configured coverage is not a live qualification result. |
|
||||
|
||||
SH-4 changes native Runner tools only. Legacy adapters do not receive
|
||||
`paperclip_finish` or `paperclip_block` from this change. Their skill/API
|
||||
completion paths remain separate. The shared legacy prompt tests in SH-3
|
||||
continue to check their exact minimal defaults. The fixed native prompt and
|
||||
task constraints are not reduced in this first tool-documentation slice.
|
||||
|
||||
`pnpm test:e2e:runner:stock-harness` runs these credential-free prerequisites,
|
||||
including the Rust test. It writes JSON reports, the source SHA, a working-source
|
||||
|
||||
@@ -38,6 +38,20 @@ export const stockHarnessGates = [
|
||||
{ id: "SH-3-hermes", name: "Hermes shared-prompt delivery", cwd: "packages/adapters/hermes",
|
||||
files: ["src/server/prompt-rendering.test.ts"],
|
||||
required: ["renders standard assignment wake with task authority", "renders scoped planning wake authority"] },
|
||||
{ id: "SH-4-tools", name: "Native completion tool delivery", cwd: "packages/paperclip-runner", files: [
|
||||
"src/contracts/completion-result.test.ts", "src/drivers/runner-tool-bridge.test.ts",
|
||||
"src/drivers/opencode/mcp-bridge.test.ts", "src/drivers/codex/codex-app-server-driver.lifecycle.test.ts",
|
||||
"src/live/runnerd-codex-transport.test.ts",
|
||||
], testPattern: "propagates answer and wait descriptions|binds to loopback|preserves stock Codex instructions on|preserves answer and internal wait descriptions",
|
||||
required: ["propagates answer and wait descriptions", "runner semantic MCP bridge binds to loopback",
|
||||
"OpenCode MCP bridge binds to loopback", "preserves stock Codex instructions on task recovery",
|
||||
"preserves stock Codex instructions on prepared recovery", "preserves stock Codex instructions on direct recovery",
|
||||
...["codex", "opencode", "claude_managed", "aws_agentcore", "acpx"].map(provider =>
|
||||
`preserves answer and internal wait descriptions in the serialized native ${provider} tool catalog`)] },
|
||||
{ id: "SH-4-resume", name: "Refresh retained native completion guidance", cwd: ".", files: [
|
||||
"server/src/services/native-runtime/native-session-resume.test.ts",
|
||||
], testPattern: "refreshes retained",
|
||||
required: ["native completion tool guidance"] },
|
||||
{ id: "SH-eval", name: "Independent oracle and qualification admission", cwd: ".",
|
||||
config: "tests/runner-e2e/vitest.config.ts",
|
||||
files: ["tests/runner-e2e/stock-harness.test.ts", "tests/runner-e2e/stock-harness-checks.test.mjs",
|
||||
@@ -73,6 +87,11 @@ export function sourceFingerprint() {
|
||||
"packages/adapter-utils/src/server-utils.ts", "packages/shared/src/connection-intent-guidance.ts",
|
||||
"server/src/onboarding-assets/default/AGENTS.md", "server/src/routes/agents.ts", "scripts/ensure-plugin-build-deps.mjs",
|
||||
"packages/paperclip-runner/src/drivers/codex/codex-app-server-driver-impl.ts",
|
||||
"packages/paperclip-runner/src/contracts/completion-result.ts",
|
||||
"packages/paperclip-runner/src/drivers/codex/codex-driver-values.ts",
|
||||
"packages/paperclip-runner/src/drivers/runner-tool-bridge.ts",
|
||||
"packages/paperclip-runner/src/drivers/opencode/mcp-bridge.ts",
|
||||
"server/src/services/native-runtime/native-session-resume.ts",
|
||||
"packages/paperclip-runner/src/live/runnerd-codex-transport.ts",
|
||||
"packages/paperclip-runner/src/live/live-session.ts",
|
||||
"packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs",
|
||||
|
||||
@@ -7,7 +7,7 @@ const report = () => ({ testResults: [{ name: "/repo/boundary.test.ts", status:
|
||||
numTotalTests: 1, numPassedTests: 1, numFailedTests: 0, numPendingTests: 0 });
|
||||
describe("stock harness prerequisite coverage", () => {
|
||||
it("maps every implemented change to an executable gate", () => {
|
||||
expect(stockHarnessGates.map(gate => gate.id)).toEqual(["SH-1", "SH-2", "SH-3", "SH-3-hermes", "SH-eval"]);
|
||||
expect(stockHarnessGates.map(gate => gate.id)).toEqual(["SH-1", "SH-2", "SH-3", "SH-3-hermes", "SH-4-tools", "SH-4-resume", "SH-eval"]);
|
||||
expect(stockHarnessGates.every(gate => gate.files.length > 0 && gate.required.length > 0)).toBe(true);
|
||||
});
|
||||
it("accepts an executed passing boundary", () => expect(gradeGate(gate, report(), 0).passed).toBe(true));
|
||||
|
||||
@@ -5,7 +5,14 @@ import { stockHarnessSourceDigest } from "./stock-harness.js";
|
||||
vi.mock("node:fs", async importOriginal => ({ ...await importOriginal<typeof import("node:fs")>(), readFileSync: vi.fn() }));
|
||||
|
||||
describe("stock harness instruction revision", () => {
|
||||
it.each(["server/src/onboarding-assets/default/AGENTS.md", "packages/adapter-utils/src/server-utils.ts", "packages/shared/src/connection-intent-guidance.ts"])(
|
||||
it.each([
|
||||
"server/src/onboarding-assets/default/AGENTS.md", "packages/adapter-utils/src/server-utils.ts",
|
||||
"packages/shared/src/connection-intent-guidance.ts", "packages/paperclip-runner/src/contracts/completion-result.ts",
|
||||
"packages/paperclip-runner/src/drivers/codex/codex-driver-values.ts",
|
||||
"packages/paperclip-runner/src/drivers/runner-tool-bridge.ts",
|
||||
"packages/paperclip-runner/src/drivers/opencode/mcp-bridge.ts",
|
||||
"server/src/services/native-runtime/native-session-resume.ts",
|
||||
])(
|
||||
"changes when the evaluated %s changes", source => {
|
||||
vi.mocked(readFileSync).mockImplementation(() => Buffer.from("unchanged"));
|
||||
const original = stockHarnessSourceDigest();
|
||||
|
||||
@@ -114,6 +114,11 @@ export function stockHarnessSourceDigest() {
|
||||
"../../server/src/onboarding-assets/default/AGENTS.md",
|
||||
"../../packages/adapter-utils/src/server-utils.ts",
|
||||
"../../packages/shared/src/connection-intent-guidance.ts",
|
||||
"../../packages/paperclip-runner/src/contracts/completion-result.ts",
|
||||
"../../packages/paperclip-runner/src/drivers/codex/codex-driver-values.ts",
|
||||
"../../packages/paperclip-runner/src/drivers/runner-tool-bridge.ts",
|
||||
"../../packages/paperclip-runner/src/drivers/opencode/mcp-bridge.ts",
|
||||
"../../server/src/services/native-runtime/native-session-resume.ts",
|
||||
]) hash.update(source).update(readFileSync(new URL(source, import.meta.url)));
|
||||
return hash.digest("hex");
|
||||
}
|
||||
Reference in new issue
Block a user