@ixo/flow-work 0.1.1 → 0.3.0

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.
@@ -1,4 +1,47 @@
1
1
  import type { z } from 'zod';
2
+ /**
3
+ * What the listener hands a capability handler alongside its validated inputs:
4
+ * the invocation's identity and the UCAN delegation that authorized it. The
5
+ * listener has already verified the delegation (audience, capability, caveats)
6
+ * before the handler runs — this context is for handlers that need to *act* on
7
+ * it, not re-check it.
8
+ *
9
+ * A handler that calls a downstream UCAN-guarded service (e.g. the Composio
10
+ * worker) uses `delegation` to re-mint a fresh, service-targeted invocation
11
+ * from the same authorization chain, or mints a self-signed one when it acts
12
+ * as the oracle itself. `invocationId` / `nodeId` are the natural idempotency
13
+ * key for writes bound to a single flow node.
14
+ */
15
+ export interface FlowWorkInvocationContext {
16
+ /** Unique id of this invocation — stable across redelivery. */
17
+ invocationId: string;
18
+ /** DID of the manager authenticated by the exact UCAN invoker binding. */
19
+ managerDid: string;
20
+ /** The capability ability invoked (equals the handler's `can`). */
21
+ capability: string;
22
+ /** The work discriminator invoked (equals the handler's `actionType`). */
23
+ actionType: string;
24
+ /** The flow node this work is bound to. */
25
+ nodeId: string;
26
+ /** Exact UCAN `with` resource. */
27
+ resource: string;
28
+ /** Stable commitment to the validated inputs. */
29
+ inputHash: string;
30
+ attempt: number;
31
+ /** Absolute Unix epoch deadline in milliseconds. */
32
+ deadline: number;
33
+ /** Additional contract caveats included exactly in the UCAN nb grant. */
34
+ contractCaveats: Record<string, unknown>;
35
+ /** This oracle's DID — the delegation audience. */
36
+ audience: string;
37
+ /**
38
+ * The serialized UCAN delegation (base64 CAR) that authorized this
39
+ * invocation, already validated by the listener. Pass it to
40
+ * `ucan.createInvocationFromDelegation(...)` to act on the delegator's
41
+ * behalf against a downstream service.
42
+ */
43
+ delegation: string;
44
+ }
2
45
  /**
3
46
  * A contractable capability: the unit of work this oracle accepts from
4
47
  * flow-manager. `can` is what flow-manager discovers and delegates
@@ -9,7 +52,7 @@ import type { z } from 'zod';
9
52
  export interface FlowWorkCapability<Schema extends z.ZodType = z.ZodType> {
10
53
  /** Capability ability, e.g. 'flow/diagnose'. Must match the UCAN grant. */
11
54
  can: string;
12
- /** Work discriminator within the capability, e.g. 'diagnose_http_request'. */
55
+ /** Work discriminator within the capability, e.g. 'diagnose_action'. */
13
56
  actionType: string;
14
57
  description: string;
15
58
  /**
@@ -20,7 +63,18 @@ export interface FlowWorkCapability<Schema extends z.ZodType = z.ZodType> {
20
63
  claimSchemas?: string[];
21
64
  /** Validates the invocation's `inputs` before the handler runs. */
22
65
  inputSchema: Schema;
23
- handler: (inputs: z.infer<Schema>) => Promise<unknown>;
66
+ /**
67
+ * Optional trust-boundary validation for the handler result before a
68
+ * success receipt is posted. Invalid output becomes an `output_invalid`
69
+ * failure receipt and never reaches flow-manager as advisory state.
70
+ */
71
+ outputSchema?: z.ZodType;
72
+ /**
73
+ * Runs the work. Receives the validated inputs and the invocation context.
74
+ * Pure, self-contained handlers (no downstream auth) may ignore the second
75
+ * argument; handlers that call UCAN-guarded services use its `delegation`.
76
+ */
77
+ handler: (inputs: z.infer<Schema>, context: FlowWorkInvocationContext) => Promise<unknown>;
24
78
  }
25
79
  export declare function findCapability(capabilities: readonly FlowWorkCapability[], can: string, actionType: string): FlowWorkCapability | undefined;
26
80
  //# sourceMappingURL=capability.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IACtE,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,SAAS,kBAAkB,EAAE,EAC3C,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,kBAAkB,GAAG,SAAS,CAIhC"}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,yBAAyB;IACxC,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IACtE,2EAA2E;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACzB;;;;OAIG;IACH,OAAO,EAAE,CACP,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EACvB,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,SAAS,kBAAkB,EAAE,EAC3C,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,kBAAkB,GAAG,SAAS,CAIhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,cAAc,CAC5B,YAA2C,EAC3C,GAAW,EACX,UAAkB;IAElB,OAAO,YAAY,CAAC,IAAI,CACtB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU,CAChE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAoFA,MAAM,UAAU,cAAc,CAC5B,YAA2C,EAC3C,GAAW,EACX,UAAkB;IAElB,OAAO,YAAY,CAAC,IAAI,CACtB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU,CAChE,CAAC;AACJ,CAAC"}
@@ -12,13 +12,11 @@ export declare class FlowWorkPlugin extends OraclePlugin {
12
12
  readonly version = "0.1.0";
13
13
  readonly manifest: PluginManifest;
14
14
  readonly configSchema: z.ZodObject<{
15
- FLOW_WORK_TRUSTED_HOMESERVERS: z.ZodString;
16
15
  ORACLE_ENTITY_DID: z.ZodString;
17
16
  BLOCKSYNC_GRAPHQL_URL: z.ZodOptional<z.ZodString>;
18
17
  }, z.core.$strip>;
19
- readonly autoDetectHint = "FLOW_WORK_TRUSTED_HOMESERVERS";
20
18
  constructor(options: FlowWorkPluginOptions);
21
- autoDetect(env: NodeJS.ProcessEnv): boolean;
19
+ autoDetect(): boolean;
22
20
  getNestModules(ctx?: PluginContext): DynamicModule[];
23
21
  }
24
22
  //# sourceMappingURL=flow-work.plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"flow-work.plugin.d.ts","sourceRoot":"","sources":["../src/flow-work.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,CAAC,EACD,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,KAAK,GAAG,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AA4B1D,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC;IAC/B,YAAY,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED,qBAAa,cAAe,SAAQ,YAAY;IAWlC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,QAAQ,CAAC,IAAI,eAAe;IAE5B,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,QAAQ,iBAAY;IAE7B,SAAkB,YAAY;;;;sBAAgB;IAE9C,SAAkB,cAAc,mCAAmC;gBAEtC,OAAO,EAAE,qBAAqB;IAIlD,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO;IAI3C,cAAc,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,aAAa,EAAE;CAiD9D"}
1
+ {"version":3,"file":"flow-work.plugin.d.ts","sourceRoot":"","sources":["../src/flow-work.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,CAAC,EACD,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,KAAK,GAAG,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AA0B1D,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC;IAC/B,YAAY,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED,qBAAa,cAAe,SAAQ,YAAY;IASlC,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,QAAQ,CAAC,IAAI,eAAe;IAE5B,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,QAAQ,iBAAY;IAE7B,SAAkB,YAAY;;;sBAAgB;gBAEjB,OAAO,EAAE,qBAAqB;IAMlD,UAAU,IAAI,OAAO;IAIrB,cAAc,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,aAAa,EAAE;CAsE9D"}
@@ -10,8 +10,6 @@ import { FlowWorkListener } from './listener.js';
10
10
  import { adaptMatrixClient } from './matrix-port.js';
11
11
  import { buildDelegationValidator } from './ucan.js';
12
12
  const configSchema = z.object({
13
- /** Comma-separated homeserver domains whose room invites are accepted. */
14
- FLOW_WORK_TRUSTED_HOMESERVERS: z.string().trim().min(1),
15
13
  /** This oracle's DID — the expected UCAN delegation audience. */
16
14
  ORACLE_ENTITY_DID: z.string().trim().min(1),
17
15
  /** Blocksync GraphQL endpoint for did:ixo key resolution. */
@@ -19,7 +17,7 @@ const configSchema = z.object({
19
17
  });
20
18
  const manifest = {
21
19
  title: 'Flow Work',
22
- summary: 'Accepts contracted work from flow-manager: joins trusted rooms, validates UCAN-delegated ' +
20
+ summary: 'Accepts contracted work from flow-manager: joins invited rooms, validates UCAN-delegated ' +
23
21
  'ixo.flow.work.invoke events, runs the declared capability handler, and posts receipts.',
24
22
  whenToUse: [],
25
23
  whenNotToUse: [],
@@ -35,26 +33,23 @@ export class FlowWorkPlugin extends OraclePlugin {
35
33
  version = '0.1.0';
36
34
  manifest = manifest;
37
35
  configSchema = configSchema;
38
- autoDetectHint = 'FLOW_WORK_TRUSTED_HOMESERVERS';
39
36
  constructor(options) {
40
37
  super();
41
38
  this.options = options;
42
39
  }
43
- autoDetect(env) {
44
- return Boolean(env.FLOW_WORK_TRUSTED_HOMESERVERS?.trim());
40
+ // Active whenever the oracle registers it in main.ts — the contract surface
41
+ // has no trust allowlists to gate on, so there is nothing to auto-detect.
42
+ autoDetect() {
43
+ return true;
45
44
  }
46
45
  getNestModules(ctx) {
47
46
  if (!ctx)
48
47
  throw new Error('FlowWorkPlugin requires a PluginContext');
49
48
  const config = configSchema.parse(ctx.config);
50
- const trustedHomeservers = config.FLOW_WORK_TRUSTED_HOMESERVERS.split(',')
51
- .map((value) => value.trim())
52
- .filter((value) => value.length > 0);
53
49
  const logger = ctx.logger;
54
50
  const listener = new FlowWorkListener({
55
51
  port: adaptMatrixClient(this.options.matrixClient),
56
52
  oracleDid: config.ORACLE_ENTITY_DID,
57
- trustedHomeservers,
58
53
  capabilities: this.options.capabilities,
59
54
  validateDelegation: buildDelegationValidator({
60
55
  oracleDid: config.ORACLE_ENTITY_DID,
@@ -64,15 +59,29 @@ export class FlowWorkPlugin extends OraclePlugin {
64
59
  });
65
60
  const matrixClient = this.options.matrixClient;
66
61
  class FlowWorkLifecycle {
62
+ initialStateBootstrapped = false;
63
+ syncHandler = (state) => {
64
+ if (!this.initialStateBootstrapped &&
65
+ (state === 'PREPARED' || state === 'SYNCING')) {
66
+ this.initialStateBootstrapped = true;
67
+ void listener.bootstrap().catch((error) => {
68
+ logger.error(`[flow-work] post-sync bootstrap failed: ${error instanceof Error ? error.message : String(error)}`);
69
+ });
70
+ }
71
+ };
67
72
  onModuleInit() {
73
+ // Register flow-work listeners before initial sync can emit invites,
74
+ // timeline events, or state transitions.
75
+ listener.start();
76
+ matrixClient.on('sync', this.syncHandler);
68
77
  // The shared client is also used by EditorPlugin; only start it if
69
78
  // nothing else has.
70
79
  if (!matrixClient.clientRunning) {
71
80
  void matrixClient.startClient();
72
81
  }
73
- listener.start();
74
82
  }
75
83
  onModuleDestroy() {
84
+ matrixClient.removeListener('sync', this.syncHandler);
76
85
  listener.stop();
77
86
  }
78
87
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flow-work.plugin.js","sourceRoot":"","sources":["../src/flow-work.plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flow-work.plugin.js","sourceRoot":"","sources":["../src/flow-work.plugin.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { FlowWorkPlugin, type FlowWorkPluginOptions, } from './flow-work.plugin.js';
2
- export { findCapability, type FlowWorkCapability } from './capability.js';
3
- export { FlowWorkListener, homeserverOf } from './listener.js';
4
- export { adaptMatrixClient, type FlowWorkMatrixPort } from './matrix-port.js';
5
- export { FLOW_WORK_ASSIGN_EVENT, FLOW_WORK_INVOKE_EVENT, FLOW_WORK_RECEIPT_EVENT, flowWorkInvokeSchema, type FlowWorkErrorCode, type FlowWorkInvoke, type FlowWorkReceipt, } from './protocol.js';
2
+ export { findCapability, type FlowWorkCapability, type FlowWorkInvocationContext, } from './capability.js';
3
+ export { FlowWorkListener } from './listener.js';
4
+ export { adaptMatrixClient, type FlowWorkInvite, type FlowWorkMatrixPort, type FlowWorkRoomEvent, } from './matrix-port.js';
5
+ export { FLOW_WORK_ASSIGN_EVENT, FLOW_WORK_BINDING_FIELDS, FLOW_WORK_INVOKE_EVENT, FLOW_WORK_READY_EVENT, FLOW_WORK_RECEIPT_EVENT, computeFlowWorkInputHash, flowWorkAssignSchema, flowWorkBindingSchema, flowWorkInvokeSchema, flowWorkNbFor, flowWorkReadySchema, flowWorkReceiptSchema, sameFlowWorkBinding, sameFlowWorkNb, type FlowWorkAssign, type FlowWorkBinding, type FlowWorkErrorCode, type FlowWorkInvoke, type FlowWorkNb, type FlowWorkReady, type FlowWorkReceipt, } from './protocol.js';
6
6
  export { buildDelegationValidator, type DelegationValidator } from './ucan.js';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,GAC/B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { FlowWorkPlugin, } from './flow-work.plugin.js';
2
- export { findCapability } from './capability.js';
3
- export { FlowWorkListener, homeserverOf } from './listener.js';
4
- export { adaptMatrixClient } from './matrix-port.js';
5
- export { FLOW_WORK_ASSIGN_EVENT, FLOW_WORK_INVOKE_EVENT, FLOW_WORK_RECEIPT_EVENT, flowWorkInvokeSchema, } from './protocol.js';
2
+ export { findCapability, } from './capability.js';
3
+ export { FlowWorkListener } from './listener.js';
4
+ export { adaptMatrixClient, } from './matrix-port.js';
5
+ export { FLOW_WORK_ASSIGN_EVENT, FLOW_WORK_BINDING_FIELDS, FLOW_WORK_INVOKE_EVENT, FLOW_WORK_READY_EVENT, FLOW_WORK_RECEIPT_EVENT, computeFlowWorkInputHash, flowWorkAssignSchema, flowWorkBindingSchema, flowWorkInvokeSchema, flowWorkNbFor, flowWorkReadySchema, flowWorkReceiptSchema, sameFlowWorkBinding, sameFlowWorkNb, } from './protocol.js';
6
6
  export { buildDelegationValidator } from './ucan.js';
7
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAA2B,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAA2B,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,GAIrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAA4B,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,cAAc,GAGf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,iBAAiB,GAIlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GAQf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAA4B,MAAM,WAAW,CAAC"}
@@ -8,44 +8,57 @@ export interface FlowWorkLogger {
8
8
  }
9
9
  export interface FlowWorkListenerOptions {
10
10
  port: FlowWorkMatrixPort;
11
- /** This oracle's DID — invocations addressed elsewhere are ignored. */
11
+ /** This oracle entity DID — the expected UCAN delegation audience. */
12
12
  oracleDid: string;
13
- /** Homeserver domains whose room invites are accepted. */
14
- trustedHomeservers: readonly string[];
15
13
  capabilities: readonly FlowWorkCapability[];
16
14
  validateDelegation: DelegationValidator;
17
15
  logger: FlowWorkLogger;
18
- /** How many recent room events to scan for an existing receipt. */
16
+ /** Delay before retrying an unchanged ready/receipt state publication. */
17
+ receiptRetryMs?: number;
18
+ /** Injectable wall clock for deadline tests. */
19
+ now?: () => number;
20
+ /** @deprecated v2 receipt replay uses Matrix current state, never a timeline scan. */
19
21
  receiptScanLimit?: number;
20
22
  }
21
- /** Hostname of '@user:server.tld' or a bare/prefixed server name. */
22
- export declare function homeserverOf(value: string): string | null;
23
23
  /**
24
- * The oracle side of the flow-work contract: accepts invites from trusted
25
- * homeservers, executes UCAN-authorized `ixo.flow.work.invoke` events via
26
- * the declared capability handlers, and posts `ixo.flow.work.receipt`s.
24
+ * Oracle-side flow-work v2 state machine.
25
+ *
26
+ * Assignment and ready are durable state events. Invoke remains a timeline
27
+ * command. Receipt is durable state keyed by invocationId, so restart replay
28
+ * does not depend on a recent-event window.
27
29
  */
28
30
  export declare class FlowWorkListener {
29
31
  private readonly options;
30
- private readonly trusted;
32
+ private readonly assignments;
31
33
  private readonly active;
32
34
  private readonly completed;
35
+ private readonly pendingReceipts;
36
+ private readonly publishedReceipts;
37
+ private readonly publishing;
38
+ private readonly retryTimers;
39
+ private readonly readyTimers;
33
40
  private unsubscribe;
41
+ private started;
34
42
  constructor(options: FlowWorkListenerOptions);
43
+ /** Subscribe synchronously before any Matrix initial sync is started. */
35
44
  start(): void;
36
45
  stop(): void;
46
+ /** Reconcile invitations and current assignment state after initial sync. */
47
+ bootstrap(): Promise<void>;
48
+ private now;
49
+ private retryMs;
37
50
  private handleInvite;
51
+ private bootstrapRoom;
38
52
  private handleRoomEvent;
39
- /**
40
- * Bind nb caveats to the invocation before executing. A delegation minted
41
- * for one claim schema must not be reusable with unrelated claim data:
42
- * `nb.claimSchema` requires the invocation's `inputs.claimSchemaId` to be
43
- * present and equal.
44
- */
45
- private enforceCaveats;
53
+ private handleAssignment;
54
+ private hasOwnReady;
55
+ private acknowledgeAssignment;
56
+ private handleInvocation;
46
57
  private execute;
47
- private hasExistingReceipt;
48
- private postFailure;
49
- private postReceipt;
58
+ /** Preserve service contract caveats after the full exact nb comparison. */
59
+ private enforceCaveats;
60
+ private hasOwnReceipt;
61
+ private publishReceipt;
62
+ private scheduleReceiptRetry;
50
63
  }
51
64
  //# sourceMappingURL=listener.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,kBAAkB,CAAC;IACzB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC5C,kBAAkB,EAAE,mBAAmB,CAAC;IACxC,MAAM,EAAE,cAAc,CAAC;IACvB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAYD,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBzD;AAMD;;;;GAIG;AACH,qBAAa,gBAAgB;IAMf,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAAyB;gBAEf,OAAO,EAAE,uBAAuB;IAa7D,KAAK,IAAI,IAAI;IAuBb,IAAI,IAAI,IAAI;YAKE,YAAY;YAcZ,eAAe;IAgE7B;;;;;OAKG;IACH,OAAO,CAAC,cAAc;YAiBR,OAAO;IAqDrB,OAAO,CAAC,kBAAkB;YAYZ,WAAW;YAcX,WAAW;CAQ1B"}
1
+ {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,kBAAkB,CAAC;IACzB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC5C,kBAAkB,EAAE,mBAAmB,CAAC;IACxC,MAAM,EAAE,cAAc,CAAC;IACvB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4BD;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAkBf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjBpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqC;IACvE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IACJ,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IACJ,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,OAAO,CAAS;gBAEK,OAAO,EAAE,uBAAuB;IAM7D,yEAAyE;IACzE,KAAK,IAAI,IAAI;IA8Bb,IAAI,IAAI,IAAI;IAUZ,6EAA6E;IACvE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAShC,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,OAAO;YAKD,YAAY;YAQZ,aAAa;YASb,eAAe;YAUf,gBAAgB;IAoE9B,OAAO,CAAC,WAAW;YAcL,qBAAqB;YAmCrB,gBAAgB;YAqHhB,OAAO;IA+FrB,4EAA4E;IAC5E,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,aAAa;YAcP,cAAc;IA2B5B,OAAO,CAAC,oBAAoB;CAS7B"}