mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-04 11:01:16 +01:00
Follow current Copilot profile identity in native installation admission
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
fa393bff17
commit
59bba28192
2 files changed
+13
-2
No files matched your search
@@ -10,6 +10,17 @@ import { QUALIFIED_ACPX_PROFILES } from "./qualified-profiles.js";
|
||||
vi.mock("./installation-integrity.js", () => ({ verifyNativeAcpxInstallation: vi.fn() }));
|
||||
|
||||
describe("Copilot build-owned installation", () => {
|
||||
it("admits the current v3 declaration and binds its source policy/patch hashes", () => {
|
||||
const identity = JSON.parse(readFileSync(new URL("../../../test/fixtures/copilot-profile-v3-identity.json", import.meta.url), "utf8"));
|
||||
expect(QUALIFIED_ACPX_PROFILES.copilot.agentProfileVersion).toBe(identity.declaration.agentProfileVersion);
|
||||
expect(QUALIFIED_ACPX_PROFILES.copilot.commandDigest).toBe(identity.commandDigest);
|
||||
const sorted = Object.fromEntries(Object.entries(identity.declaration).sort(([a], [b]) => a.localeCompare(b)));
|
||||
expect(`sha256:${createHash("sha256").update(JSON.stringify(sorted)).digest("hex")}`).toBe(identity.commandDigest);
|
||||
for (const [relative, field] of [["copilot-policy.ts", "policySha256"], ["../../../../../patches/acpx@0.13.1.patch", "acpxPatchSha256"]]) {
|
||||
expect(createHash("sha256").update(readFileSync(new URL(relative!, import.meta.url))).digest("hex")).toBe(identity.declaration[field!]);
|
||||
}
|
||||
expect(readFileSync(new URL("../../../scripts/build-copilot-distribution.mjs", import.meta.url), "utf8")).toContain(identity.commandDigest);
|
||||
});
|
||||
it("pins the materializer's complete executable closure on every target platform", () => {
|
||||
const script = readFileSync(new URL("../../../scripts/materialize-copilot-binary.mjs", import.meta.url), "utf8");
|
||||
const records = [...script.matchAll(/"(darwin-arm64|darwin-x64|linux-x64)": Object\.freeze\(\{ packageName: "[^"]+", executableDigest: "([a-f0-9]+)", size: (\d+)/g)];
|
||||
@@ -38,7 +49,7 @@ describe("Copilot build-owned installation", () => {
|
||||
});
|
||||
it("rejects changed profile identities before native file access", async () => {
|
||||
vi.mocked(verifyNativeAcpxInstallation).mockClear();
|
||||
for (const override of [{ agentServerVersion: "latest" }, { commandDigest: "sha256:untrusted" }, { agent: "cursor" }, { agentProfileVersion: 1 }]) {
|
||||
for (const override of [{ agentServerVersion: "latest" }, { commandDigest: "sha256:untrusted" }, { agent: "cursor" }, { agentProfileVersion: 1 }, { agentProfileVersion: 2 }, { agentProfileVersion: 4 }]) {
|
||||
await expect(verifyCopilotInstallation({ ...QUALIFIED_ACPX_PROFILES.copilot, ...override } as never)).rejects.toThrow("exact pinned");
|
||||
}
|
||||
expect(verifyNativeAcpxInstallation).not.toHaveBeenCalled();
|
||||
|
||||
@@ -13,7 +13,7 @@ export const COPILOT_CLOSURE_SHA256 = Object.freeze({
|
||||
/** Admission primitive only. Pending candidates remain gated by qualification. */
|
||||
export async function verifyCopilotInstallation(profile: QualifiedAcpxProfile): Promise<VerifiedAcpxInstallation> {
|
||||
const expected = QUALIFIED_ACPX_PROFILES.copilot;
|
||||
if (profile.agent !== "copilot" || profile.agentProfileVersion !== 2
|
||||
if (profile.agent !== "copilot" || profile.agentProfileVersion !== expected.agentProfileVersion
|
||||
|| profile.acpxVersion !== expected.acpxVersion || profile.agentServerPackage !== "@github/copilot"
|
||||
|| profile.agentServerVersion !== COPILOT_VERSION || profile.commandDigest !== expected.commandDigest
|
||||
|| profile.agentRuntimePackage !== null || profile.agentRuntimeVersion !== null) {
|
||||
|
||||
Reference in new issue
Block a user