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

@ -105,6 +105,7 @@ class WorkOrderManager {
const sessionToken = randomToken();
this.sessions.set(hash(sessionToken), {
workorderId: id,
persona: order.persona,
target: order.target,
scope: order.scope,
@ -115,12 +116,19 @@ class WorkOrderManager {
expiresAt: now + this.sessionTtl,
maxExpiresAt: now + this.maxSessionLifetime,
renewals: 0,
lastReceipt: {
schema: "guanghu.operation-receipt/v1",
state: "session_issued",
diagnostic_code: "session_issued",
occurred_at: now,
next_step: "读取并确认该目标节点的实时导航图,然后才可执行已登记动作。",
},
});
order.claimed = true;
order.state = "claimed";
order.claimHash = "";
this.persist();
return { ok: true, sessionToken, expiresIn: this.sessionTtl, target: order.target, scope: order.scope, action: order.action, resource: order.resource || "" };
return { ok: true, sessionToken, expiresIn: this.sessionTtl, target: order.target, scope: order.scope, action: order.action, resource: order.resource || "", workorderId: id, receipt: { ...this.sessions.get(hash(sessionToken)).lastReceipt } };
}
verifySession(sessionToken, persona, target, scope, action, now = Date.now() / 1000, resource = undefined) {
@ -168,6 +176,14 @@ class WorkOrderManager {
return { ok: true, expiresAt, renewals: session.renewals, session: { ...session } };
}
recordReceipt(sessionToken, receipt) {
const session = this.sessions.get(hash(sessionToken || ""));
if (!session) return { ok: false, reason: "session_not_found" };
session.lastReceipt = { ...receipt };
this.persist();
return { ok: true, receipt: { ...session.lastReceipt } };
}
findByApproval(token) {
const needle = hash(token || "");
for (const order of this.workorders.values()) {