@agenticprimitives/fabric 0.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +67 -0
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/case-machine.d.ts +76 -0
- package/dist/case-machine.d.ts.map +1 -0
- package/dist/case-machine.js +83 -0
- package/dist/case-machine.js.map +1 -0
- package/dist/client/index.d.ts +114 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +76 -0
- package/dist/client/index.js.map +1 -0
- package/dist/cloudflare/authority-verdict-cache.d.ts +27 -0
- package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -0
- package/dist/cloudflare/authority-verdict-cache.js +66 -0
- package/dist/cloudflare/authority-verdict-cache.js.map +1 -0
- package/dist/cloudflare/channel-store.d.ts +61 -0
- package/dist/cloudflare/channel-store.d.ts.map +1 -0
- package/dist/cloudflare/channel-store.js +124 -0
- package/dist/cloudflare/channel-store.js.map +1 -0
- package/dist/cloudflare/exchange-store.d.ts +16 -0
- package/dist/cloudflare/exchange-store.d.ts.map +1 -0
- package/dist/cloudflare/exchange-store.js +45 -0
- package/dist/cloudflare/exchange-store.js.map +1 -0
- package/dist/cloudflare/gateway-tools.d.ts +28 -0
- package/dist/cloudflare/gateway-tools.d.ts.map +1 -0
- package/dist/cloudflare/gateway-tools.js +45 -0
- package/dist/cloudflare/gateway-tools.js.map +1 -0
- package/dist/cloudflare/index.d.ts +13 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +20 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/cloudflare/orchestration-runtime.d.ts +28 -0
- package/dist/cloudflare/orchestration-runtime.d.ts.map +1 -0
- package/dist/cloudflare/orchestration-runtime.js +35 -0
- package/dist/cloudflare/orchestration-runtime.js.map +1 -0
- package/dist/cloudflare/outbox-store.d.ts +24 -0
- package/dist/cloudflare/outbox-store.d.ts.map +1 -0
- package/dist/cloudflare/outbox-store.js +42 -0
- package/dist/cloudflare/outbox-store.js.map +1 -0
- package/dist/cloudflare/principal-gateway-do.d.ts +234 -0
- package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -0
- package/dist/cloudflare/principal-gateway-do.js +369 -0
- package/dist/cloudflare/principal-gateway-do.js.map +1 -0
- package/dist/cloudflare/provenance-store.d.ts +9 -0
- package/dist/cloudflare/provenance-store.d.ts.map +1 -0
- package/dist/cloudflare/provenance-store.js +36 -0
- package/dist/cloudflare/provenance-store.js.map +1 -0
- package/dist/cloudflare/receipt-signer.d.ts +26 -0
- package/dist/cloudflare/receipt-signer.d.ts.map +1 -0
- package/dist/cloudflare/receipt-signer.js +69 -0
- package/dist/cloudflare/receipt-signer.js.map +1 -0
- package/dist/cloudflare/request-id-ledger.d.ts +13 -0
- package/dist/cloudflare/request-id-ledger.d.ts.map +1 -0
- package/dist/cloudflare/request-id-ledger.js +38 -0
- package/dist/cloudflare/request-id-ledger.js.map +1 -0
- package/dist/cloudflare/sql-vault.d.ts +10 -0
- package/dist/cloudflare/sql-vault.d.ts.map +1 -0
- package/dist/cloudflare/sql-vault.js +98 -0
- package/dist/cloudflare/sql-vault.js.map +1 -0
- package/dist/communicative-act.d.ts +47 -0
- package/dist/communicative-act.d.ts.map +1 -0
- package/dist/communicative-act.js +36 -0
- package/dist/communicative-act.js.map +1 -0
- package/dist/delivery-envelope.d.ts +38 -0
- package/dist/delivery-envelope.d.ts.map +1 -0
- package/dist/delivery-envelope.js +43 -0
- package/dist/delivery-envelope.js.map +1 -0
- package/dist/exchange-record.d.ts +131 -0
- package/dist/exchange-record.d.ts.map +1 -0
- package/dist/exchange-record.js +25 -0
- package/dist/exchange-record.js.map +1 -0
- package/dist/exchange-reducer.d.ts +25 -0
- package/dist/exchange-reducer.d.ts.map +1 -0
- package/dist/exchange-reducer.js +108 -0
- package/dist/exchange-reducer.js.map +1 -0
- package/dist/exchange-state.d.ts +56 -0
- package/dist/exchange-state.d.ts.map +1 -0
- package/dist/exchange-state.js +81 -0
- package/dist/exchange-state.js.map +1 -0
- package/dist/gateway-surface.d.ts +24 -0
- package/dist/gateway-surface.d.ts.map +1 -0
- package/dist/gateway-surface.js +33 -0
- package/dist/gateway-surface.js.map +1 -0
- package/dist/inbox-doc.d.ts +32 -0
- package/dist/inbox-doc.d.ts.map +1 -0
- package/dist/inbox-doc.js +57 -0
- package/dist/inbox-doc.js.map +1 -0
- package/dist/inbox-projection.d.ts +15 -0
- package/dist/inbox-projection.d.ts.map +1 -0
- package/dist/inbox-projection.js +28 -0
- package/dist/inbox-projection.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions/audited.d.ts +12 -0
- package/dist/interactions/audited.d.ts.map +1 -0
- package/dist/interactions/audited.js +67 -0
- package/dist/interactions/audited.js.map +1 -0
- package/dist/interactions/builders.d.ts +24 -0
- package/dist/interactions/builders.d.ts.map +1 -0
- package/dist/interactions/builders.js +48 -0
- package/dist/interactions/builders.js.map +1 -0
- package/dist/interactions/cards.d.ts +32 -0
- package/dist/interactions/cards.d.ts.map +1 -0
- package/dist/interactions/cards.js +20 -0
- package/dist/interactions/cards.js.map +1 -0
- package/dist/interactions/index.d.ts +15 -0
- package/dist/interactions/index.d.ts.map +1 -0
- package/dist/interactions/index.js +23 -0
- package/dist/interactions/index.js.map +1 -0
- package/dist/interactions/machine.d.ts +19 -0
- package/dist/interactions/machine.d.ts.map +1 -0
- package/dist/interactions/machine.js +31 -0
- package/dist/interactions/machine.js.map +1 -0
- package/dist/interactions/mandates.d.ts +64 -0
- package/dist/interactions/mandates.d.ts.map +1 -0
- package/dist/interactions/mandates.js +62 -0
- package/dist/interactions/mandates.js.map +1 -0
- package/dist/interactions/relationship.d.ts +29 -0
- package/dist/interactions/relationship.d.ts.map +1 -0
- package/dist/interactions/relationship.js +31 -0
- package/dist/interactions/relationship.js.map +1 -0
- package/dist/interactions/risk.d.ts +39 -0
- package/dist/interactions/risk.d.ts.map +1 -0
- package/dist/interactions/risk.js +49 -0
- package/dist/interactions/risk.js.map +1 -0
- package/dist/interactions/runs.d.ts +26 -0
- package/dist/interactions/runs.d.ts.map +1 -0
- package/dist/interactions/runs.js +80 -0
- package/dist/interactions/runs.js.map +1 -0
- package/dist/interactions/store.d.ts +20 -0
- package/dist/interactions/store.d.ts.map +1 -0
- package/dist/interactions/store.js +68 -0
- package/dist/interactions/store.js.map +1 -0
- package/dist/interactions/tickets.d.ts +68 -0
- package/dist/interactions/tickets.d.ts.map +1 -0
- package/dist/interactions/tickets.js +49 -0
- package/dist/interactions/tickets.js.map +1 -0
- package/dist/interactions/types.d.ts +160 -0
- package/dist/interactions/types.d.ts.map +1 -0
- package/dist/interactions/types.js +7 -0
- package/dist/interactions/types.js.map +1 -0
- package/dist/messaging/board.d.ts +54 -0
- package/dist/messaging/board.d.ts.map +1 -0
- package/dist/messaging/board.js +90 -0
- package/dist/messaging/board.js.map +1 -0
- package/dist/messaging/conversation.d.ts +35 -0
- package/dist/messaging/conversation.d.ts.map +1 -0
- package/dist/messaging/conversation.js +72 -0
- package/dist/messaging/conversation.js.map +1 -0
- package/dist/messaging/delivery.d.ts +19 -0
- package/dist/messaging/delivery.d.ts.map +1 -0
- package/dist/messaging/delivery.js +56 -0
- package/dist/messaging/delivery.js.map +1 -0
- package/dist/messaging/directory.d.ts +32 -0
- package/dist/messaging/directory.d.ts.map +1 -0
- package/dist/messaging/directory.js +35 -0
- package/dist/messaging/directory.js.map +1 -0
- package/dist/messaging/envelope.d.ts +14 -0
- package/dist/messaging/envelope.d.ts.map +1 -0
- package/dist/messaging/envelope.js +71 -0
- package/dist/messaging/envelope.js.map +1 -0
- package/dist/messaging/hash.d.ts +19 -0
- package/dist/messaging/hash.d.ts.map +1 -0
- package/dist/messaging/hash.js +36 -0
- package/dist/messaging/hash.js.map +1 -0
- package/dist/messaging/index.d.ts +16 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/index.js +29 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/messaging/projector.d.ts +58 -0
- package/dist/messaging/projector.d.ts.map +1 -0
- package/dist/messaging/projector.js +103 -0
- package/dist/messaging/projector.js.map +1 -0
- package/dist/messaging/receipts.d.ts +5 -0
- package/dist/messaging/receipts.d.ts.map +1 -0
- package/dist/messaging/receipts.js +19 -0
- package/dist/messaging/receipts.js.map +1 -0
- package/dist/messaging/rules.d.ts +84 -0
- package/dist/messaging/rules.d.ts.map +1 -0
- package/dist/messaging/rules.js +109 -0
- package/dist/messaging/rules.js.map +1 -0
- package/dist/messaging/store.d.ts +24 -0
- package/dist/messaging/store.d.ts.map +1 -0
- package/dist/messaging/store.js +120 -0
- package/dist/messaging/store.js.map +1 -0
- package/dist/messaging/types.d.ts +166 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/messaging/types.js +7 -0
- package/dist/messaging/types.js.map +1 -0
- package/dist/messaging/vault-store.d.ts +37 -0
- package/dist/messaging/vault-store.d.ts.map +1 -0
- package/dist/messaging/vault-store.js +62 -0
- package/dist/messaging/vault-store.js.map +1 -0
- package/dist/record-catalog.d.ts +22 -0
- package/dist/record-catalog.d.ts.map +1 -0
- package/dist/record-catalog.js +35 -0
- package/dist/record-catalog.js.map +1 -0
- package/package.json +82 -0
- package/spec.md +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mandates.js","sourceRoot":"","sources":["../../src/interactions/mandates.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,wDAAwD;AACxD,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAC9E,uEAAuE;AAmDvE;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAA6B,EAC7B,OAA6E,EAC7E,WAA6B,EAC7B,KAAa;IAEb,IAAI,WAAW,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC;QACxC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC1D,CAAC;IACD,IACE,OAAO,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS;QAC3C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,EAC9D,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IACvD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC1D,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QACxD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACzD,CAAC;IACD,0EAA0E;IAC1E,wEAAwE;IACxE,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,uEAAuE;YACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,IACE,OAAO,CAAC,aAAa,CAAC,OAAO,KAAK,SAAS;QAC3C,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO,EACjD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC9C,CAAC;AAyBD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAA6B;IACpE,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC5F,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;QACnD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC7D,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { Hex32 } from '../messaging/index.js';
|
|
3
|
+
import type { InteractionCaseV1, InteractionTransitionEventV1 } from './types.js';
|
|
4
|
+
export interface InteractionExchangeRecordV1 {
|
|
5
|
+
version: 'ap.interaction.exchange.v1';
|
|
6
|
+
interactionId: InteractionCaseV1['id'];
|
|
7
|
+
kind: InteractionCaseV1['kind'];
|
|
8
|
+
/** The relationship pair, ordered requester → responder. */
|
|
9
|
+
requester: CanonicalAgentId;
|
|
10
|
+
responder: CanonicalAgentId;
|
|
11
|
+
transition: InteractionTransitionEventV1['transition'];
|
|
12
|
+
actor: CanonicalAgentId;
|
|
13
|
+
at: string;
|
|
14
|
+
/** State AFTER the transition. */
|
|
15
|
+
resultingState: InteractionCaseV1['state'];
|
|
16
|
+
/** Hash of the resulting case snapshot — the witness's anchor. */
|
|
17
|
+
caseHash: Hex32;
|
|
18
|
+
/** Authority the exchange referenced, when any (kind + hash only). */
|
|
19
|
+
authorityKind?: string;
|
|
20
|
+
authorityHash?: Hex32;
|
|
21
|
+
}
|
|
22
|
+
/** Build the exchange record for a transition that was ACCEPTED (pass the
|
|
23
|
+
* case AFTER the transition). Hashes/ids only — no subjects, no payloads. */
|
|
24
|
+
export declare function buildExchangeRecord(caseAfter: InteractionCaseV1, event: InteractionTransitionEventV1): Promise<InteractionExchangeRecordV1>;
|
|
25
|
+
/** Port the consumer wires over the spec 306 relationship record store. */
|
|
26
|
+
export interface RelationshipExchangePort {
|
|
27
|
+
appendExchange(record: InteractionExchangeRecordV1): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=relationship.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship.d.ts","sourceRoot":"","sources":["../../src/interactions/relationship.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,4BAA4B,CAAC;IACtC,aAAa,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAChC,4DAA4D;IAC5D,SAAS,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,UAAU,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC;IACvD,KAAK,EAAE,gBAAgB,CAAC;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,cAAc,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3C,kEAAkE;IAClE,QAAQ,EAAE,KAAK,CAAC;IAChB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,KAAK,CAAC;CACvB;AAED;8EAC8E;AAC9E,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,2BAA2B,CAAC,CAkBtC;AAED,2EAA2E;AAC3E,MAAM,WAAW,wBAAwB;IACvC,cAAc,CAAC,MAAM,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Relationship-exchange seam (spec 309 W5 ← specs 306/307): every meaningful
|
|
2
|
+
// interaction exchange is appended to the requester↔responder RELATIONSHIP
|
|
3
|
+
// RECORD so the witness can later adjudicate ("what was asked, decided, and
|
|
4
|
+
// delivered between these two agents?").
|
|
5
|
+
//
|
|
6
|
+
// This package cannot import the relationships/witness packages (facet
|
|
7
|
+
// firewall), so it owns the record SHAPE + a builder + the append PORT; the
|
|
8
|
+
// consuming app/runtime implements the port over spec 306 storage.
|
|
9
|
+
import { hashInteractionCase } from './builders.js';
|
|
10
|
+
/** Build the exchange record for a transition that was ACCEPTED (pass the
|
|
11
|
+
* case AFTER the transition). Hashes/ids only — no subjects, no payloads. */
|
|
12
|
+
export async function buildExchangeRecord(caseAfter, event) {
|
|
13
|
+
if (event.interactionId !== caseAfter.id) {
|
|
14
|
+
throw new Error(`event ${event.interactionId} does not belong to case ${caseAfter.id}`);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
version: 'ap.interaction.exchange.v1',
|
|
18
|
+
interactionId: caseAfter.id,
|
|
19
|
+
kind: caseAfter.kind,
|
|
20
|
+
requester: caseAfter.requester,
|
|
21
|
+
responder: caseAfter.responder,
|
|
22
|
+
transition: event.transition,
|
|
23
|
+
actor: event.actor,
|
|
24
|
+
at: event.at,
|
|
25
|
+
resultingState: caseAfter.state,
|
|
26
|
+
caseHash: await hashInteractionCase(caseAfter),
|
|
27
|
+
authorityKind: event.authorityRef?.kind,
|
|
28
|
+
authorityHash: event.authorityRef?.hash,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=relationship.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship.js","sourceRoot":"","sources":["../../src/interactions/relationship.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,yCAAyC;AACzC,EAAE;AACF,uEAAuE;AACvE,4EAA4E;AAC5E,mEAAmE;AAInE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAsBpD;8EAC8E;AAC9E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAA4B,EAC5B,KAAmC;IAEnC,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,aAAa,4BAA4B,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO;QACL,OAAO,EAAE,4BAA4B;QACrC,aAAa,EAAE,SAAS,CAAC,EAAE;QAC3B,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,cAAc,EAAE,SAAS,CAAC,KAAK;QAC/B,QAAQ,EAAE,MAAM,mBAAmB,CAAC,SAAS,CAAC;QAC9C,aAAa,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI;QACvC,aAAa,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { SignatureProof } from '../messaging/index.js';
|
|
3
|
+
export type DataSensitivity = 'public' | 'internal' | 'confidential' | 'regulated' | 'vault-secret';
|
|
4
|
+
export interface ActionRiskMetadataV1 {
|
|
5
|
+
version: 'ap.interaction.action-risk.v1';
|
|
6
|
+
action: string;
|
|
7
|
+
readOnly: boolean;
|
|
8
|
+
destructive: boolean;
|
|
9
|
+
idempotent: boolean;
|
|
10
|
+
openWorld: boolean;
|
|
11
|
+
dataSensitivity: DataSensitivity;
|
|
12
|
+
requiresHumanApproval: boolean;
|
|
13
|
+
requiresMandate: boolean;
|
|
14
|
+
requiresCredentialPresentation?: boolean;
|
|
15
|
+
policyRefs?: string[];
|
|
16
|
+
signedBy?: CanonicalAgentId;
|
|
17
|
+
signature?: SignatureProof;
|
|
18
|
+
}
|
|
19
|
+
export type RiskDisposition = 'auto-ok' | 'requires-approval' | 'escalate' | 'block';
|
|
20
|
+
export interface RiskEvaluationOpts {
|
|
21
|
+
/** SAs whose signed risk metadata the evaluator trusts. */
|
|
22
|
+
trustedSigners: readonly CanonicalAgentId[];
|
|
23
|
+
/** Sensitivities above this level always require approval. Default 'internal'. */
|
|
24
|
+
autoOkMaxSensitivity?: DataSensitivity;
|
|
25
|
+
/** Block (instead of escalate) destructive actions from untrusted signers. */
|
|
26
|
+
blockUntrustedDestructive?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface RiskEvaluation {
|
|
29
|
+
trusted: boolean;
|
|
30
|
+
disposition: RiskDisposition;
|
|
31
|
+
reason: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Pure, fail-closed disposition. Only TRUSTED metadata can yield `auto-ok`;
|
|
35
|
+
* self-declared/unsigned/unknown-signer metadata escalates (or blocks, for
|
|
36
|
+
* destructive claims when configured) — it never relaxes handling.
|
|
37
|
+
*/
|
|
38
|
+
export declare function evaluateActionRisk(risk: ActionRiskMetadataV1, opts: RiskEvaluationOpts): RiskEvaluation;
|
|
39
|
+
//# sourceMappingURL=risk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk.d.ts","sourceRoot":"","sources":["../../src/interactions/risk.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,cAAc,GAAG,WAAW,GAAG,cAAc,CAAC;AAEpG,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,+BAA+B,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,eAAe,CAAC;IACjC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,eAAe,EAAE,OAAO,CAAC;IACzB,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,mBAAmB,GAAG,UAAU,GAAG,OAAO,CAAC;AAErF,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,cAAc,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC5C,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,eAAe,CAAC;IACvC,8EAA8E;IAC9E,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAcD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,eAAe,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,oBAAoB,EAC1B,IAAI,EAAE,kBAAkB,GACvB,cAAc,CA4BhB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// ActionRiskMetadataV1 (spec 309 §6.2) — the MCP tool-annotation pattern, but
|
|
2
|
+
// SIGNED and policy-checked, never self-declared. Consumed by inbox rules +
|
|
3
|
+
// Home approval policy to decide auto-file / auto-approve / escalate / block.
|
|
4
|
+
//
|
|
5
|
+
// Trust rule (spec 309 §8.11): risk metadata is only trusted when signed by an
|
|
6
|
+
// accountable SA the evaluator trusts. Untrusted metadata is advisory — the
|
|
7
|
+
// disposition can only get MORE conservative, never less.
|
|
8
|
+
const SENSITIVITY_ORDER = [
|
|
9
|
+
'public',
|
|
10
|
+
'internal',
|
|
11
|
+
'confidential',
|
|
12
|
+
'regulated',
|
|
13
|
+
'vault-secret',
|
|
14
|
+
];
|
|
15
|
+
function sensitivityAbove(s, ceiling) {
|
|
16
|
+
return SENSITIVITY_ORDER.indexOf(s) > SENSITIVITY_ORDER.indexOf(ceiling);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pure, fail-closed disposition. Only TRUSTED metadata can yield `auto-ok`;
|
|
20
|
+
* self-declared/unsigned/unknown-signer metadata escalates (or blocks, for
|
|
21
|
+
* destructive claims when configured) — it never relaxes handling.
|
|
22
|
+
*/
|
|
23
|
+
export function evaluateActionRisk(risk, opts) {
|
|
24
|
+
const signerOk = risk.signature !== undefined &&
|
|
25
|
+
risk.signedBy !== undefined &&
|
|
26
|
+
risk.signature.signer === risk.signedBy &&
|
|
27
|
+
opts.trustedSigners.includes(risk.signedBy);
|
|
28
|
+
if (!signerOk) {
|
|
29
|
+
if (risk.destructive && (opts.blockUntrustedDestructive ?? false)) {
|
|
30
|
+
return { trusted: false, disposition: 'block', reason: 'untrusted-destructive' };
|
|
31
|
+
}
|
|
32
|
+
return { trusted: false, disposition: 'escalate', reason: 'untrusted-signer' };
|
|
33
|
+
}
|
|
34
|
+
if (risk.destructive || risk.requiresHumanApproval) {
|
|
35
|
+
return { trusted: true, disposition: 'requires-approval', reason: 'high-impact-action' };
|
|
36
|
+
}
|
|
37
|
+
if (risk.requiresMandate || risk.requiresCredentialPresentation === true) {
|
|
38
|
+
return { trusted: true, disposition: 'requires-approval', reason: 'authority-evidence-required' };
|
|
39
|
+
}
|
|
40
|
+
const ceiling = opts.autoOkMaxSensitivity ?? 'internal';
|
|
41
|
+
if (sensitivityAbove(risk.dataSensitivity, ceiling)) {
|
|
42
|
+
return { trusted: true, disposition: 'requires-approval', reason: 'sensitivity-above-ceiling' };
|
|
43
|
+
}
|
|
44
|
+
if (!risk.readOnly && !risk.idempotent) {
|
|
45
|
+
return { trusted: true, disposition: 'requires-approval', reason: 'non-idempotent-write' };
|
|
46
|
+
}
|
|
47
|
+
return { trusted: true, disposition: 'auto-ok', reason: 'within-policy' };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=risk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk.js","sourceRoot":"","sources":["../../src/interactions/risk.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,0DAA0D;AAkC1D,MAAM,iBAAiB,GAA+B;IACpD,QAAQ;IACR,UAAU;IACV,cAAc;IACd,WAAW;IACX,cAAc;CACf,CAAC;AAEF,SAAS,gBAAgB,CAAC,CAAkB,EAAE,OAAwB;IACpE,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3E,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAA0B,EAC1B,IAAwB;IAExB,MAAM,QAAQ,GACZ,IAAI,CAAC,SAAS,KAAK,SAAS;QAC5B,IAAI,CAAC,QAAQ,KAAK,SAAS;QAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ;QACvC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAE9C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,yBAAyB,IAAI,KAAK,CAAC,EAAE,CAAC;YAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QACnF,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACjF,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC3F,CAAC;IACD,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,8BAA8B,KAAK,IAAI,EAAE,CAAC;QACzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;IACpG,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,IAAI,UAAU,CAAC;IACxD,IAAI,gBAAgB,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAClG,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC7F,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { InteractionInterruptV1, InteractionResumeV1, InteractionRunEventV1, InteractionRunV1 } from './types.js';
|
|
2
|
+
export type RunRejection = 'run-not-running' | 'run-not-paused' | 'wrong-run' | 'wrong-interrupt' | 'interrupt-expired' | 'unauthorized-responder' | 'duplicate-resume';
|
|
3
|
+
export type RunStepResult = {
|
|
4
|
+
ok: true;
|
|
5
|
+
run: InteractionRunV1;
|
|
6
|
+
event: InteractionRunEventV1;
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
reason: RunRejection;
|
|
10
|
+
};
|
|
11
|
+
export declare function startRun(runId: InteractionRunV1['runId'], interactionId: InteractionRunV1['interactionId'], at: string): {
|
|
12
|
+
run: InteractionRunV1;
|
|
13
|
+
event: InteractionRunEventV1;
|
|
14
|
+
};
|
|
15
|
+
/** Raise an interrupt on a running run: pauses it until a valid resume. */
|
|
16
|
+
export declare function raiseInterrupt(run: InteractionRunV1, interrupt: InteractionInterruptV1, seq: number, at: string): RunStepResult;
|
|
17
|
+
/**
|
|
18
|
+
* Apply a resume to a paused run. Fail-closed: wrong interrupt, expired
|
|
19
|
+
* interrupt, or a responder outside `allowedResponders` rejects; a replayed
|
|
20
|
+
* idempotency key is reported as `duplicate-resume` so callers dedupe instead
|
|
21
|
+
* of double-applying.
|
|
22
|
+
*/
|
|
23
|
+
export declare function applyResume(run: InteractionRunV1, interrupt: InteractionInterruptV1, resume: InteractionResumeV1, seq: number, seenIdempotencyKeys: ReadonlySet<string>): RunStepResult;
|
|
24
|
+
export declare function completeRun(run: InteractionRunV1, seq: number, at: string): RunStepResult;
|
|
25
|
+
export declare function failRun(run: InteractionRunV1, seq: number, at: string, reason?: string): RunStepResult;
|
|
26
|
+
//# sourceMappingURL=runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/interactions/runs.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EAEnB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,YAAY,GACpB,iBAAiB,GACjB,gBAAgB,GAChB,WAAW,GACX,iBAAiB,GACjB,mBAAmB,GACnB,wBAAwB,GACxB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAA;CAAE,GACjE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AAYxC,wBAAgB,QAAQ,CACtB,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC,EAChD,EAAE,EAAE,MAAM,GACT;IAAE,GAAG,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAA;CAAE,CAUzD;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAC5B,GAAG,EAAE,gBAAgB,EACrB,SAAS,EAAE,sBAAsB,EACjC,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,GACT,aAAa,CAYf;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,SAAS,EAAE,sBAAsB,EACjC,MAAM,EAAE,mBAAmB,EAC3B,GAAG,EAAE,MAAM,EACX,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,GACvC,aAAa,CA6Bf;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,CAIzF;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAMtG"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Durable interaction runs: pause on interrupt, resume on a signed answer
|
|
2
|
+
// (LangGraph / OpenAI-Agents-SDK / AG-UI pattern, spec 309 §6.2).
|
|
3
|
+
// A resume NEVER itself grants authority — it only un-pauses the run.
|
|
4
|
+
function runEvent(run, seq, eventType, at, payload) {
|
|
5
|
+
return { version: 'ap.interaction.run-event.v1', runId: run.runId, seq, eventType, at, payload };
|
|
6
|
+
}
|
|
7
|
+
export function startRun(runId, interactionId, at) {
|
|
8
|
+
const run = {
|
|
9
|
+
version: 'ap.interaction.run.v1',
|
|
10
|
+
runId,
|
|
11
|
+
interactionId,
|
|
12
|
+
state: 'running',
|
|
13
|
+
startedAt: at,
|
|
14
|
+
updatedAt: at,
|
|
15
|
+
};
|
|
16
|
+
return { run, event: runEvent(run, 1, 'run-started', at) };
|
|
17
|
+
}
|
|
18
|
+
/** Raise an interrupt on a running run: pauses it until a valid resume. */
|
|
19
|
+
export function raiseInterrupt(run, interrupt, seq, at) {
|
|
20
|
+
if (run.state !== 'running')
|
|
21
|
+
return { ok: false, reason: 'run-not-running' };
|
|
22
|
+
if (interrupt.runId !== run.runId)
|
|
23
|
+
return { ok: false, reason: 'wrong-run' };
|
|
24
|
+
const paused = {
|
|
25
|
+
...run,
|
|
26
|
+
state: 'paused',
|
|
27
|
+
updatedAt: at,
|
|
28
|
+
pendingInterruptId: interrupt.interruptId,
|
|
29
|
+
};
|
|
30
|
+
const eventType = interrupt.raisedBy === 'human' ? 'human-interrupt-raised' : 'agent-interrupt-raised';
|
|
31
|
+
return { ok: true, run: paused, event: runEvent(paused, seq, eventType, at, interrupt) };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Apply a resume to a paused run. Fail-closed: wrong interrupt, expired
|
|
35
|
+
* interrupt, or a responder outside `allowedResponders` rejects; a replayed
|
|
36
|
+
* idempotency key is reported as `duplicate-resume` so callers dedupe instead
|
|
37
|
+
* of double-applying.
|
|
38
|
+
*/
|
|
39
|
+
export function applyResume(run, interrupt, resume, seq, seenIdempotencyKeys) {
|
|
40
|
+
if (run.state !== 'paused')
|
|
41
|
+
return { ok: false, reason: 'run-not-paused' };
|
|
42
|
+
if (interrupt.runId !== run.runId)
|
|
43
|
+
return { ok: false, reason: 'wrong-run' };
|
|
44
|
+
if (resume.interruptId !== interrupt.interruptId ||
|
|
45
|
+
run.pendingInterruptId !== interrupt.interruptId) {
|
|
46
|
+
return { ok: false, reason: 'wrong-interrupt' };
|
|
47
|
+
}
|
|
48
|
+
if (interrupt.expiresAt !== undefined && Date.parse(resume.at) >= Date.parse(interrupt.expiresAt)) {
|
|
49
|
+
return { ok: false, reason: 'interrupt-expired' };
|
|
50
|
+
}
|
|
51
|
+
if (interrupt.allowedResponders !== undefined &&
|
|
52
|
+
interrupt.allowedResponders.length > 0 &&
|
|
53
|
+
!interrupt.allowedResponders.includes(resume.responder)) {
|
|
54
|
+
return { ok: false, reason: 'unauthorized-responder' };
|
|
55
|
+
}
|
|
56
|
+
if (seenIdempotencyKeys.has(resume.idempotencyKey)) {
|
|
57
|
+
return { ok: false, reason: 'duplicate-resume' };
|
|
58
|
+
}
|
|
59
|
+
const resumed = {
|
|
60
|
+
...run,
|
|
61
|
+
state: 'running',
|
|
62
|
+
updatedAt: resume.at,
|
|
63
|
+
pendingInterruptId: undefined,
|
|
64
|
+
};
|
|
65
|
+
return { ok: true, run: resumed, event: runEvent(resumed, seq, 'resume-submitted', resume.at, resume) };
|
|
66
|
+
}
|
|
67
|
+
export function completeRun(run, seq, at) {
|
|
68
|
+
if (run.state !== 'running')
|
|
69
|
+
return { ok: false, reason: 'run-not-running' };
|
|
70
|
+
const done = { ...run, state: 'completed', updatedAt: at };
|
|
71
|
+
return { ok: true, run: done, event: runEvent(done, seq, 'run-completed', at) };
|
|
72
|
+
}
|
|
73
|
+
export function failRun(run, seq, at, reason) {
|
|
74
|
+
if (run.state === 'completed' || run.state === 'failed') {
|
|
75
|
+
return { ok: false, reason: 'run-not-running' };
|
|
76
|
+
}
|
|
77
|
+
const failed = { ...run, state: 'failed', updatedAt: at, pendingInterruptId: undefined };
|
|
78
|
+
return { ok: true, run: failed, event: runEvent(failed, seq, 'run-failed', at, reason) };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/interactions/runs.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,kEAAkE;AAClE,sEAAsE;AAuBtE,SAAS,QAAQ,CACf,GAAqB,EACrB,GAAW,EACX,SAAkC,EAClC,EAAU,EACV,OAAiB;IAEjB,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,KAAgC,EAChC,aAAgD,EAChD,EAAU;IAEV,MAAM,GAAG,GAAqB;QAC5B,OAAO,EAAE,uBAAuB;QAChC,KAAK;QACL,aAAa;QACb,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,EAAE;KACd,CAAC;IACF,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAC5B,GAAqB,EACrB,SAAiC,EACjC,GAAW,EACX,EAAU;IAEV,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC7E,IAAI,SAAS,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC7E,MAAM,MAAM,GAAqB;QAC/B,GAAG,GAAG;QACN,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,EAAE;QACb,kBAAkB,EAAE,SAAS,CAAC,WAAW;KAC1C,CAAC;IACF,MAAM,SAAS,GACb,SAAS,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC;IACvF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,GAAqB,EACrB,SAAiC,EACjC,MAA2B,EAC3B,GAAW,EACX,mBAAwC;IAExC,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3E,IAAI,SAAS,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC7E,IACE,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW;QAC5C,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,WAAW,EAChD,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;QAClG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACpD,CAAC;IACD,IACE,SAAS,CAAC,iBAAiB,KAAK,SAAS;QACzC,SAAS,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC;QACtC,CAAC,SAAS,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EACvD,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IACD,MAAM,OAAO,GAAqB;QAChC,GAAG,GAAG;QACN,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,kBAAkB,EAAE,SAAS;KAC9B,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAqB,EAAE,GAAW,EAAE,EAAU;IACxE,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC7E,MAAM,IAAI,GAAqB,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAC7E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAqB,EAAE,GAAW,EAAE,EAAU,EAAE,MAAe;IACrF,IAAI,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAClD,CAAC;IACD,MAAM,MAAM,GAAqB,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAC3G,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;AAC3F,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type TransitionResult } from './machine.js';
|
|
2
|
+
import type { InteractionCaseV1, InteractionId, InteractionState, InteractionTransitionEventV1 } from './types.js';
|
|
3
|
+
export interface InteractionStore {
|
|
4
|
+
/** Register a new case. Fail-closed: only `draft` cases enter; duplicate ids throw. */
|
|
5
|
+
putCase(c: InteractionCaseV1): void;
|
|
6
|
+
getCase(id: InteractionId): InteractionCaseV1 | null;
|
|
7
|
+
/**
|
|
8
|
+
* Apply a signed transition event. Idempotent: replaying an event whose
|
|
9
|
+
* `idempotencyKey` was already applied returns the current case unchanged
|
|
10
|
+
* (`ok: true`), never double-applies. Rejections do not mutate.
|
|
11
|
+
*/
|
|
12
|
+
applyEvent(event: InteractionTransitionEventV1): TransitionResult;
|
|
13
|
+
listEvents(id: InteractionId): InteractionTransitionEventV1[];
|
|
14
|
+
listCases(state?: InteractionState): InteractionCaseV1[];
|
|
15
|
+
/** Deterministic clock sweep: expire every non-terminal case past its
|
|
16
|
+
* deadline as of `nowIso`. Returns the cases it expired. */
|
|
17
|
+
processDue(nowIso: string): InteractionCaseV1[];
|
|
18
|
+
}
|
|
19
|
+
export declare function createInMemoryInteractionStore(): InteractionStore;
|
|
20
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/interactions/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAA+C,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAEnH,MAAM,WAAW,gBAAgB;IAC/B,uFAAuF;IACvF,OAAO,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,iBAAiB,GAAG,IAAI,CAAC;IACrD;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,4BAA4B,GAAG,gBAAgB,CAAC;IAClE,UAAU,CAAC,EAAE,EAAE,aAAa,GAAG,4BAA4B,EAAE,CAAC;IAC9D,SAAS,CAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;IACzD;iEAC6D;IAC7D,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAAC;CACjD;AAED,wBAAgB,8BAA8B,IAAI,gBAAgB,CA6DjE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// In-memory InteractionStore: cases + transition log with idempotent replay
|
|
2
|
+
// and deterministic expiry sweeps (spec 309 §6.1, §8.10).
|
|
3
|
+
import { applyInteractionTransition, isTerminalState } from './machine.js';
|
|
4
|
+
export function createInMemoryInteractionStore() {
|
|
5
|
+
const cases = new Map();
|
|
6
|
+
const events = new Map();
|
|
7
|
+
const appliedKeys = new Map();
|
|
8
|
+
return {
|
|
9
|
+
putCase(c) {
|
|
10
|
+
if (c.state !== 'draft') {
|
|
11
|
+
throw new Error(`case ${c.id} must enter the store in draft state, got ${c.state}`);
|
|
12
|
+
}
|
|
13
|
+
if (cases.has(c.id))
|
|
14
|
+
throw new Error(`duplicate interaction id ${c.id}`);
|
|
15
|
+
cases.set(c.id, c);
|
|
16
|
+
events.set(c.id, []);
|
|
17
|
+
appliedKeys.set(c.id, new Set());
|
|
18
|
+
},
|
|
19
|
+
getCase(id) {
|
|
20
|
+
return cases.get(id) ?? null;
|
|
21
|
+
},
|
|
22
|
+
applyEvent(event) {
|
|
23
|
+
const current = cases.get(event.interactionId);
|
|
24
|
+
if (!current)
|
|
25
|
+
return { ok: false, reason: 'wrong-case' };
|
|
26
|
+
const keys = appliedKeys.get(event.interactionId);
|
|
27
|
+
if (event.idempotencyKey !== undefined && keys.has(event.idempotencyKey)) {
|
|
28
|
+
return { ok: true, case: current };
|
|
29
|
+
}
|
|
30
|
+
const result = applyInteractionTransition(current, event);
|
|
31
|
+
if (!result.ok)
|
|
32
|
+
return result;
|
|
33
|
+
cases.set(event.interactionId, result.case);
|
|
34
|
+
events.get(event.interactionId).push(event);
|
|
35
|
+
if (event.idempotencyKey !== undefined)
|
|
36
|
+
keys.add(event.idempotencyKey);
|
|
37
|
+
return result;
|
|
38
|
+
},
|
|
39
|
+
listEvents(id) {
|
|
40
|
+
return [...(events.get(id) ?? [])];
|
|
41
|
+
},
|
|
42
|
+
listCases(state) {
|
|
43
|
+
return [...cases.values()].filter((c) => (state ? c.state === state : true));
|
|
44
|
+
},
|
|
45
|
+
processDue(nowIso) {
|
|
46
|
+
const expired = [];
|
|
47
|
+
for (const c of cases.values()) {
|
|
48
|
+
if (isTerminalState(c.state))
|
|
49
|
+
continue;
|
|
50
|
+
if (c.expiresAt === undefined || Date.parse(nowIso) < Date.parse(c.expiresAt))
|
|
51
|
+
continue;
|
|
52
|
+
const result = applyInteractionTransition(c, {
|
|
53
|
+
version: 'ap.interaction.event.v1',
|
|
54
|
+
interactionId: c.id,
|
|
55
|
+
transition: 'expire',
|
|
56
|
+
actor: c.responder, // role 'any' — deterministic sweep, not a user action
|
|
57
|
+
at: nowIso,
|
|
58
|
+
});
|
|
59
|
+
if (result.ok) {
|
|
60
|
+
cases.set(c.id, result.case);
|
|
61
|
+
expired.push(result.case);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return expired;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/interactions/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { VaultRef } from '@agenticprimitives/vault';
|
|
3
|
+
import type { Hex32, SignatureProof } from '../messaging/index.js';
|
|
4
|
+
import type { InteractionId } from './types.js';
|
|
5
|
+
/** Ref to a presentation definition (spec 305) — by id/URI, never embedded. */
|
|
6
|
+
export type PresentationDefinitionRef = string;
|
|
7
|
+
export type CredentialFormat = 'jwt-vc' | 'sd-jwt-vc' | 'w3c-vc';
|
|
8
|
+
export interface PermissionTicketV1 {
|
|
9
|
+
version: 'ap.interaction.permission-ticket.v1';
|
|
10
|
+
ticketId: string;
|
|
11
|
+
interactionId: InteractionId;
|
|
12
|
+
resource: string;
|
|
13
|
+
requestedActions: string[];
|
|
14
|
+
requestingAgent: CanonicalAgentId;
|
|
15
|
+
/** The person/org the requesting agent acts for, when disclosed. */
|
|
16
|
+
requestingParty?: CanonicalAgentId;
|
|
17
|
+
claimsRequired?: PresentationDefinitionRef[];
|
|
18
|
+
issuedAt: string;
|
|
19
|
+
expiresAt: string;
|
|
20
|
+
issuer: CanonicalAgentId;
|
|
21
|
+
signature?: SignatureProof;
|
|
22
|
+
}
|
|
23
|
+
export interface ClaimsChallengeV1 {
|
|
24
|
+
version: 'ap.interaction.claims-challenge.v1';
|
|
25
|
+
challengeId: string;
|
|
26
|
+
ticketId: string;
|
|
27
|
+
requiredClaims: PresentationDefinitionRef[];
|
|
28
|
+
acceptableCredentialFormats: CredentialFormat[];
|
|
29
|
+
expiresAt?: string;
|
|
30
|
+
}
|
|
31
|
+
/** The requester's answer: a selectively-disclosed presentation, by ref+hash. */
|
|
32
|
+
export interface ClaimsPresentationV1 {
|
|
33
|
+
version: 'ap.interaction.claims-presentation.v1';
|
|
34
|
+
challengeId: string;
|
|
35
|
+
presenter: CanonicalAgentId;
|
|
36
|
+
format: CredentialFormat;
|
|
37
|
+
presentationHash: Hex32;
|
|
38
|
+
presentationRef?: VaultRef;
|
|
39
|
+
presentedAt: string;
|
|
40
|
+
signature?: SignatureProof;
|
|
41
|
+
}
|
|
42
|
+
export interface CreatePermissionTicketInput {
|
|
43
|
+
ticketId?: string;
|
|
44
|
+
interactionId: InteractionId;
|
|
45
|
+
resource: string;
|
|
46
|
+
requestedActions: string[];
|
|
47
|
+
requestingAgent: CanonicalAgentId;
|
|
48
|
+
requestingParty?: CanonicalAgentId;
|
|
49
|
+
claimsRequired?: PresentationDefinitionRef[];
|
|
50
|
+
issuedAt: string;
|
|
51
|
+
expiresAt: string;
|
|
52
|
+
issuer: CanonicalAgentId;
|
|
53
|
+
}
|
|
54
|
+
export declare function createPermissionTicket(input: CreatePermissionTicketInput): PermissionTicketV1;
|
|
55
|
+
export declare function isTicketExpired(ticket: PermissionTicketV1, atIso: string): boolean;
|
|
56
|
+
export type ChallengeAnswerReason = 'acceptable' | 'wrong-challenge' | 'format-not-acceptable' | 'challenge-expired' | 'unsigned-presentation';
|
|
57
|
+
export interface ChallengeAnswerResult {
|
|
58
|
+
acceptable: boolean;
|
|
59
|
+
reason: ChallengeAnswerReason;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Fail-closed structural gate on a presentation BEFORE credential verification:
|
|
63
|
+
* right challenge, acceptable format, inside the window, signed by presenter.
|
|
64
|
+
* An `acceptable` result still requires the credential packages to verify the
|
|
65
|
+
* presentation itself — this never substitutes for proof verification.
|
|
66
|
+
*/
|
|
67
|
+
export declare function checkPresentationAnswersChallenge(challenge: ClaimsChallengeV1, presentation: ClaimsPresentationV1): ChallengeAnswerResult;
|
|
68
|
+
//# sourceMappingURL=tickets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickets.d.ts","sourceRoot":"","sources":["../../src/interactions/tickets.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,+EAA+E;AAC/E,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,qCAAqC,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,gBAAgB,CAAC;IAClC,oEAAoE;IACpE,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,cAAc,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,oCAAoC,CAAC;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,yBAAyB,EAAE,CAAC;IAC5C,2BAA2B,EAAE,gBAAgB,EAAE,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,uCAAuC,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,gBAAgB,EAAE,KAAK,CAAC;IACxB,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,gBAAgB,CAAC;IAClC,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,cAAc,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,kBAAkB,CAa7F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAElF;AAED,MAAM,MAAM,qBAAqB,GAC7B,YAAY,GACZ,iBAAiB,GACjB,uBAAuB,GACvB,mBAAmB,GACnB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,SAAS,EAAE,iBAAiB,EAC5B,YAAY,EAAE,oBAAoB,GACjC,qBAAqB,CAiBvB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// PermissionTicketV1 / ClaimsChallengeV1 (spec 309 §6.2 — UMA/GNAP/OID4VC
|
|
2
|
+
// pattern): "please give me access" becomes an async, policy-driven
|
|
3
|
+
// negotiation. The resource side issues a ticket + a claims challenge (a
|
|
4
|
+
// `privacy-credentials` presentation definition, spec 305); the requester
|
|
5
|
+
// answers with a selectively-disclosed presentation; approval then issues the
|
|
6
|
+
// entitlement/credential through the authority packages.
|
|
7
|
+
//
|
|
8
|
+
// This package owns the negotiation SHAPES + fail-closed matching only —
|
|
9
|
+
// presentation verification lives with the credential packages.
|
|
10
|
+
export function createPermissionTicket(input) {
|
|
11
|
+
if (Date.parse(input.expiresAt) <= Date.parse(input.issuedAt)) {
|
|
12
|
+
throw new Error(`ticket expiry ${input.expiresAt} is not after issuance ${input.issuedAt}`);
|
|
13
|
+
}
|
|
14
|
+
if (input.requestedActions.length === 0) {
|
|
15
|
+
throw new Error('a permission ticket requires at least one requested action');
|
|
16
|
+
}
|
|
17
|
+
const { ticketId, ...rest } = input;
|
|
18
|
+
return {
|
|
19
|
+
version: 'ap.interaction.permission-ticket.v1',
|
|
20
|
+
ticketId: ticketId ?? `tkt_${globalThis.crypto.randomUUID().replaceAll('-', '')}`,
|
|
21
|
+
...rest,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function isTicketExpired(ticket, atIso) {
|
|
25
|
+
return Date.parse(atIso) >= Date.parse(ticket.expiresAt);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fail-closed structural gate on a presentation BEFORE credential verification:
|
|
29
|
+
* right challenge, acceptable format, inside the window, signed by presenter.
|
|
30
|
+
* An `acceptable` result still requires the credential packages to verify the
|
|
31
|
+
* presentation itself — this never substitutes for proof verification.
|
|
32
|
+
*/
|
|
33
|
+
export function checkPresentationAnswersChallenge(challenge, presentation) {
|
|
34
|
+
if (presentation.challengeId !== challenge.challengeId) {
|
|
35
|
+
return { acceptable: false, reason: 'wrong-challenge' };
|
|
36
|
+
}
|
|
37
|
+
if (challenge.expiresAt !== undefined &&
|
|
38
|
+
Date.parse(presentation.presentedAt) >= Date.parse(challenge.expiresAt)) {
|
|
39
|
+
return { acceptable: false, reason: 'challenge-expired' };
|
|
40
|
+
}
|
|
41
|
+
if (!challenge.acceptableCredentialFormats.includes(presentation.format)) {
|
|
42
|
+
return { acceptable: false, reason: 'format-not-acceptable' };
|
|
43
|
+
}
|
|
44
|
+
if (presentation.signature === undefined) {
|
|
45
|
+
return { acceptable: false, reason: 'unsigned-presentation' };
|
|
46
|
+
}
|
|
47
|
+
return { acceptable: true, reason: 'acceptable' };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=tickets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickets.js","sourceRoot":"","sources":["../../src/interactions/tickets.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,oEAAoE;AACpE,yEAAyE;AACzE,0EAA0E;AAC1E,8EAA8E;AAC9E,yDAAyD;AACzD,EAAE;AACF,yEAAyE;AACzE,gEAAgE;AA8DhE,MAAM,UAAU,sBAAsB,CAAC,KAAkC;IACvE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,SAAS,0BAA0B,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACpC,OAAO;QACL,OAAO,EAAE,qCAAqC;QAC9C,QAAQ,EAAE,QAAQ,IAAI,OAAO,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QACjF,GAAG,IAAI;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAA0B,EAAE,KAAa;IACvE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC3D,CAAC;AAcD;;;;;GAKG;AACH,MAAM,UAAU,iCAAiC,CAC/C,SAA4B,EAC5B,YAAkC;IAElC,IAAI,YAAY,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC;QACvD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC1D,CAAC;IACD,IACE,SAAS,CAAC,SAAS,KAAK,SAAS;QACjC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,EACvE,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,2BAA2B,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAChE,CAAC;IACD,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AACpD,CAAC"}
|