mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-28 12:04:41 +01:00
fix(runner): label credential validation before configuration
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
cb8f9025e4
commit
654bc5aa21
7 files changed
+30
-6
No files matched your search
@@ -37,7 +37,7 @@
|
||||
"agentServerVersion": "1.0.88",
|
||||
"agentRuntimePackage": null,
|
||||
"agentRuntimeVersion": null,
|
||||
"commandDigest": "sha256:754e74c58bc9b22b49d38e0b9ff0a4708caff46abf6ac531975ea2d91c27de41",
|
||||
"commandDigest": "sha256:618c3b69bc98b9a7e3c1b3411700eab8b90fd9245ba35d0bc85484319247fdbc",
|
||||
"requiresProviderPolicy": true
|
||||
},
|
||||
"claude": {
|
||||
|
||||
@@ -47,7 +47,7 @@ pub(crate) fn acpx_release_profile(agent: &str) -> Option<AcpxReleaseProfile> {
|
||||
agent_runtime_package: None,
|
||||
agent_runtime_version: None,
|
||||
command_digest:
|
||||
"sha256:754e74c58bc9b22b49d38e0b9ff0a4708caff46abf6ac531975ea2d91c27de41",
|
||||
"sha256:618c3b69bc98b9a7e3c1b3411700eab8b90fd9245ba35d0bc85484319247fdbc",
|
||||
requires_provider_policy: true,
|
||||
},
|
||||
"claude" => AcpxReleaseProfile {
|
||||
|
||||
@@ -89,7 +89,7 @@ describe("Copilot build-owned installation", () => {
|
||||
it("admits the current profile with environment launch preparation", () => {
|
||||
expect(QUALIFIED_ACPX_PROFILES.copilot.agentProfileVersion).toBe(70);
|
||||
expect(QUALIFIED_ACPX_PROFILES.copilot.qualificationStatus).toBeUndefined();
|
||||
expect(QUALIFIED_ACPX_PROFILES.copilot.commandDigest).toBe("sha256:754e74c58bc9b22b49d38e0b9ff0a4708caff46abf6ac531975ea2d91c27de41");
|
||||
expect(QUALIFIED_ACPX_PROFILES.copilot.commandDigest).toBe("sha256:618c3b69bc98b9a7e3c1b3411700eab8b90fd9245ba35d0bc85484319247fdbc");
|
||||
});
|
||||
|
||||
it("preserves v69 while binding closed startup diagnostics in v70", async () => {
|
||||
|
||||
@@ -53,7 +53,7 @@ export const QUALIFIED_ACPX_PROFILE_DATA = {
|
||||
"agentServerVersion": "1.0.88",
|
||||
"agentRuntimePackage": null,
|
||||
"agentRuntimeVersion": null,
|
||||
"commandDigest": "sha256:754e74c58bc9b22b49d38e0b9ff0a4708caff46abf6ac531975ea2d91c27de41",
|
||||
"commandDigest": "sha256:618c3b69bc98b9a7e3c1b3411700eab8b90fd9245ba35d0bc85484319247fdbc",
|
||||
"permissionPolicy": "interactive"
|
||||
},
|
||||
"claude": {
|
||||
|
||||
@@ -203,6 +203,28 @@ afterEach(async () => {
|
||||
});
|
||||
|
||||
describe("ACPX runtime host", () => {
|
||||
it.each(["copilot", "cursor"] as const)("reports missing %s credentials as credential admission", async agent => {
|
||||
const fixture = await hostFixture();
|
||||
const openRuntime = vi.fn(async () => runtimePort());
|
||||
const failure = await AcpxRuntimeHost.open({ ...fixture.options, agent, model:"gpt-5.6-sol",
|
||||
permissionMode:"approve-all",environment:{} }, fixture.dependencies({openRuntime})).catch(error => error);
|
||||
expect(failure).toMatchObject({code:agent === "copilot" ? "COPILOT_AUTH_REQUIRED" : "CURSOR_CREDENTIALS_MISSING"});
|
||||
expect(acpxSidecarErrorCode(failure)).toBe("ACPX_ADMISSION_CREDENTIAL");
|
||||
expect(openRuntime).not.toHaveBeenCalled();
|
||||
expect(fixture.commandClose).not.toHaveBeenCalled();
|
||||
});
|
||||
it("retains binding admission when the selected workspace is missing", async () => {
|
||||
const fixture = await hostFixture();
|
||||
await rm(fixture.options.workingDirectory,{recursive:true});
|
||||
const openRuntime = vi.fn(async () => runtimePort());
|
||||
const dependencies = fixture.dependencies({openRuntime});
|
||||
const verifyInstallation = vi.fn(dependencies.verifyInstallation!);
|
||||
const failure = await AcpxRuntimeHost.open({ ...fixture.options,agent:"codex",model:"gpt-5.6-sol",
|
||||
permissionMode:"approve-all" }, {...dependencies,verifyInstallation}).catch(error => error);
|
||||
expect(acpxSidecarErrorCode(failure)).toBe("ACPX_ADMISSION_BINDING");
|
||||
expect(verifyInstallation).not.toHaveBeenCalled();
|
||||
expect(openRuntime).not.toHaveBeenCalled();
|
||||
});
|
||||
it("retains the admission stage when provider classification replaces the error", async () => {
|
||||
const fixture = await hostFixture();
|
||||
const openRuntime = vi.fn(async () => { throw new Error("Unauthorized private-token-canary"); });
|
||||
|
||||
@@ -526,7 +526,9 @@ export class AcpxRuntimeHost {
|
||||
},
|
||||
);
|
||||
options.signal?.throwIfAborted();
|
||||
admissionStage = "credential";
|
||||
assertAcpxProfileEnvironment(options.agent, sandbox.launchEnvironment);
|
||||
admissionStage = "configuration";
|
||||
let launchEnvironment = sandbox.launchEnvironment;
|
||||
// This copy is registered by the authenticated controller for its company,
|
||||
// agent and run. Environment/config values cannot widen the grant. Each
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"commandDigest": "sha256:754e74c58bc9b22b49d38e0b9ff0a4708caff46abf6ac531975ea2d91c27de41",
|
||||
"commandDigest": "sha256:618c3b69bc98b9a7e3c1b3411700eab8b90fd9245ba35d0bc85484319247fdbc",
|
||||
"declaration": {
|
||||
"schema": "paperclip.acpx_profile_declaration.v1",
|
||||
"agent": "copilot",
|
||||
@@ -77,7 +77,7 @@
|
||||
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
|
||||
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
|
||||
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
|
||||
"runtimeHostSourceSha256": "be14218ad4477e083cfc32f6680fcfed776056a4084615d6b0efd1e521e66232",
|
||||
"runtimeHostSourceSha256": "c779acab9ae4bbab4a13002d2e12c8c1acb208d0c4b575e7c5697fc3e7bb44c3",
|
||||
"runtimeAdapterSourceSha256": "7c47c05306ebe7d1ca6b5d046a96f5726a48adec4d27e7c16788f505f25b5db2",
|
||||
"runtimeSandboxSourceSha256": "981449a4c6d10f682ecf86d834eed07faca30a7d9b419fb8db4973a442a343ec",
|
||||
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
|
||||
|
||||
Reference in new issue
Block a user