feat(authz): add resident agent operation receipts

This commit is contained in:
冰朔 2026-07-26 15:26:21 +08:00
commit 357ac5e67a
6 changed files with 136 additions and 18 deletions

View file

@ -75,6 +75,7 @@ test("cross-device request is powerless until the owner asks for an email and ap
assert.equal(requested.status, 201);
const order = await requested.json();
assert.equal(order.status, "waiting_for_owner_handoff");
assert.equal(order.receipt.diagnostic_code, "owner_handoff_required");
assert.equal(mail.length, 0);
assert.match(order.request_url, /\/request\//);
assert.doesNotMatch(JSON.stringify(order), /approve\//);
@ -233,6 +234,8 @@ test("registered action bridge executes only after session and map checks", asyn
await fetch(`${base}${approvalPath}`, { method: "POST" });
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
const session = await claimed.json();
const initialStatus = await fetch(`${base}/api/session/status`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" }) });
assert.equal((await initialStatus.json()).state, "map_ack_required");
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "inspect-services" };
const beforeAck = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) });
assert.equal(beforeAck.status, 423);
@ -242,11 +245,40 @@ test("registered action bridge executes only after session and map checks", asyn
assert.equal(forbidden.status, 400);
const executed = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) });
assert.equal(executed.status, 200);
assert.equal((await executed.clone().json()).receipt.state, "succeeded");
const finalStatus = await fetch(`${base}/api/session/status`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" }) });
const finalPayload = await finalStatus.json();
assert.equal(finalPayload.state, "ready_to_execute");
assert.equal(finalPayload.last_receipt.diagnostic_code, "action_succeeded");
assert.deepEqual(calls, [{ action: "inspect-services", target: "JD-FD-PRIMARY" }]);
}, { mapsDir, mapStateFile: path.join(dir, "acks.json"), executeAction: async request => { calls.push(request); return { ok: true, stdout: "healthy" }; } });
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
});
test("failed server actions return a durable diagnosis instead of making a persona guess", async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-action-failure-"));
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
fs.writeFileSync(path.join(mapsDir, "JD-FD-PRIMARY.json"), JSON.stringify({ node_id: "JD-FD-PRIMARY" }));
try {
await withServer(async ({ base, mail }) => {
const requested = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map" }) });
const order = await requested.json();
await fetch(`${base}${new URL(order.request_url).pathname.replace("/authz", "")}`, { method: "POST" });
await fetch(`${base}${new URL(mail[0].approvalUrl).pathname.replace("/authz", "")}`, { method: "POST" });
const session = await (await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } })).json();
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" };
const map = await (await fetch(`${base}/api/navigation-map/read`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) })).json();
await fetch(`${base}/api/navigation-map/ack`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, map_hash: map.map_hash }) });
const failed = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, action: "inspect-services" }) });
assert.equal(failed.status, 502);
const payload = await failed.json();
assert.equal(payload.receipt.state, "failed");
assert.equal(payload.receipt.diagnostic_code, "agent_socket_unavailable");
assert.match(payload.receipt.next_step, /diagnostic_code/);
}, { mapsDir, mapStateFile: path.join(dir, "acks.json"), executeAction: async () => ({ ok: false, error: "agent_socket_unavailable", stderr: "socket offline" }) });
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
});
test("request endpoint rejects direct email target switching and unknown actions", async () => {
await withServer(async ({ base }) => {
const common = { method: "POST", headers: { authorization: "Bearer request-only-secret", "content-type": "application/json" } };