Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/attest-launch-for-pod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
---

Add `room/launch-attest.ts` — the L2 launch-attestation orchestration step:
`podLaunchManifest(pod)` (the pod's resolved door grants = authority held) +
`attestLaunchForPod(pod)` which attests the manifest via the keeper door
(`runKeeperDoorAttestLaunch`) and stores the signed L2 content-addressed
(`storeLaunchAttestation`), returning the `l2LaunchDigest` the box's keeper push
links. Effects are injected seams (offline-testable). The live `playPod` flow
calls this once the keeper door is up, then projects `l2LaunchDigest` into the box
env. No release.
Binary file added packages/prx/src/room/launch-attest.ts
Binary file not shown.
48 changes: 48 additions & 0 deletions packages/prx/test/room/launch-attest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// The launch-attestation orchestration step: manifest = the pod's held doors,
// attested via the keeper door + stored; returns the l2LaunchDigest.
import { describe, test, expect } from "bun:test";

import { perRepoPod } from "../../src/room/per-repo-pod.ts";
import { attestLaunchForPod, podLaunchManifest } from "../../src/room/launch-attest.ts";

describe("podLaunchManifest", () => {
test("is the pod's resolved door grants, deterministically ordered", () => {
const m = podLaunchManifest(perRepoPod);
expect(m.pod).toBe(perRepoPod.name);
expect(Array.isArray(m.doors)).toBe(true);
// each door names the authority the box holds
for (const d of m.doors) {
expect(typeof d.door).toBe("string");
expect(typeof d.capability).toBe("string");
expect(typeof d.consumer).toBe("string");
}
// deterministic (same input → same manifest)
expect(podLaunchManifest(perRepoPod)).toEqual(m);
});
});

describe("attestLaunchForPod", () => {
test("attests the manifest via the keeper door, stores the L2, returns the digest", async () => {
let sent: { subject: string; manifest: unknown } | undefined;
let storedL2: unknown;
const digest = await attestLaunchForPod(perRepoPod, {
attestLaunch: async (opts) => {
sent = opts;
return {
subject: opts.subject,
manifestDigest: "m".repeat(64),
l2LaunchDigest: "l".repeat(64),
attestation: { statement: { x: 1 }, signature: "sig" },
};
},
store: async (l2) => {
storedL2 = l2;
return "stored-digest";
},
});
expect(sent?.subject).toBe(perRepoPod.name);
expect(sent?.manifest).toEqual(podLaunchManifest(perRepoPod));
expect(storedL2).toEqual({ statement: { x: 1 }, signature: "sig" });
expect(digest).toBe("stored-digest");
});
});
Loading