@brightbeamai/chap-coordinator 0.2.13 → 0.3.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/README.md CHANGED
@@ -220,7 +220,10 @@ const coord = new Coordinator({
220
220
 
221
221
  Every call to `task.route`, `review.depth`, and `escalate.auto`
222
222
  emits a `route_decision` artefact. `task.route` also updates the
223
- task's `assignee`.
223
+ task's `assignee`. The caller must be a workspace member. The default
224
+ policy takes the first candidate that is a member and is not paused; a
225
+ `routingPolicy` selection that is not a member is refused with
226
+ `-32510`, and one that is paused with `-32063`.
224
227
 
225
228
  ## Audit and SCITT (audit-scitt/1.0)
226
229
 
@@ -269,9 +272,9 @@ and response shapes. The full audit notes are in the parent repo's
269
272
  the original TypeScript expansion and 0.2.3 / 0.2.4 covering the MCP
270
273
  and A2A transport additions.
271
274
 
272
- ## License
275
+ ## Licence
273
276
 
274
- Apache 2.0. See the parent repository's [LICENSE](./LICENSE).
277
+ Apache 2.0. This package ships the licence in its own [LICENSE](./LICENSE) file.
275
278
 
276
279
  ## Specification
277
280
 
@@ -79,6 +79,10 @@ interface CoordinatorOptions {
79
79
  maxEnvelopeBytes?: number;
80
80
  onAudit?: AuditListener;
81
81
  onAutoEscalate?: (task: Task, to: ParticipantUri) => void;
82
+ onStoreError?: (err: unknown, record: {
83
+ id: string;
84
+ version: number;
85
+ }) => void;
82
86
  verifyOidcToken?: TokenVerifier;
83
87
  verifyVc?: CredentialVerifier;
84
88
  scittSubmitter?: ScittSubmitter;
@@ -110,8 +114,16 @@ declare class Coordinator {
110
114
  readonly ids: IdFactory;
111
115
  readonly store: Store;
112
116
  private wsVersions;
117
+ private saveChains;
113
118
  private clockMs?;
119
+ private frozenNow?;
114
120
  private auditListeners;
121
+ /**
122
+ * The signed calls on each workspace's log, by what their senders signed:
123
+ * recorded refusals with their seq and code, and accepted calls. Rebuilt
124
+ * from the log when missing, so a snapshot never carries it.
125
+ */
126
+ private signedIndexes;
115
127
  /** Method handler registry; profiles plug into this. */
116
128
  readonly handlers: Map<string, Handler>;
117
129
  /** Custom lapse-check function (whisper/1.0). Set by the whisper profile. */
@@ -129,6 +141,10 @@ declare class Coordinator {
129
141
  private applyRecords;
130
142
  /** Persist the current snapshot of one workspace to the store. */
131
143
  private persist;
144
+ private trackSave;
145
+ private reportStoreError;
146
+ drainSaves(): Promise<void>;
147
+ private advanceClock;
132
148
  now(): string;
133
149
  onAudit(listener: AuditListener): () => void;
134
150
  /** Convenience: get a workspace by id, or undefined. */
@@ -160,10 +176,34 @@ declare class Coordinator {
160
176
  * any existing in-memory workspaces. */
161
177
  restore(data: unknown): void;
162
178
  dispatch(envelope: Envelope): Envelope;
179
+ private _dispatch;
163
180
  recordAudit(ws: Workspace, envelope: Envelope): void;
181
+ /**
182
+ * SPECIFICATION 10.1: record a refused call when it is a governed attempt.
183
+ * The caller must be a member of an existing workspace, the call must be a
184
+ * JSON-RPC call for a method that is not a read, and the refusal must be one
185
+ * `refusalIsRecorded` names. The request is kept as it arrived, so a
186
+ * signature on it still verifies. Every call that reaches a recorded refusal
187
+ * has passed the canonical check, so it can be hashed into the chain.
188
+ */
189
+ private recordRefusal;
190
+ /** The signed calls on this workspace's log, built from the log when missing. */
191
+ private signedIndex;
192
+ private appendEntry;
164
193
  private verifySignature;
165
194
  /** Lookup the key valid for a given participant at a given time. */
166
195
  lookupKey(member: Member, kid: string, ts: string): KeyRecord | null;
196
+ /**
197
+ * The SPECIFICATION 15.4 check, per method rather than per namespace.
198
+ *
199
+ * Core is always present, so a core method is never gated. The reads in
200
+ * ALWAYS_AVAILABLE are never gated either: a workspace must be able to ask
201
+ * what it is and to check its own chain, and `audit.verify_chain` belongs to
202
+ * `audit-scitt/1.0` while chaining also turns on through an option, so
203
+ * gating it would let a workspace write a hash-linked chain it is refused
204
+ * permission to verify.
205
+ */
206
+ private profileGate;
167
207
  private checkStepUp;
168
208
  private registerCoreHandlers;
169
209
  private registerProfileHandlers;
@@ -79,6 +79,10 @@ interface CoordinatorOptions {
79
79
  maxEnvelopeBytes?: number;
80
80
  onAudit?: AuditListener;
81
81
  onAutoEscalate?: (task: Task, to: ParticipantUri) => void;
82
+ onStoreError?: (err: unknown, record: {
83
+ id: string;
84
+ version: number;
85
+ }) => void;
82
86
  verifyOidcToken?: TokenVerifier;
83
87
  verifyVc?: CredentialVerifier;
84
88
  scittSubmitter?: ScittSubmitter;
@@ -110,8 +114,16 @@ declare class Coordinator {
110
114
  readonly ids: IdFactory;
111
115
  readonly store: Store;
112
116
  private wsVersions;
117
+ private saveChains;
113
118
  private clockMs?;
119
+ private frozenNow?;
114
120
  private auditListeners;
121
+ /**
122
+ * The signed calls on each workspace's log, by what their senders signed:
123
+ * recorded refusals with their seq and code, and accepted calls. Rebuilt
124
+ * from the log when missing, so a snapshot never carries it.
125
+ */
126
+ private signedIndexes;
115
127
  /** Method handler registry; profiles plug into this. */
116
128
  readonly handlers: Map<string, Handler>;
117
129
  /** Custom lapse-check function (whisper/1.0). Set by the whisper profile. */
@@ -129,6 +141,10 @@ declare class Coordinator {
129
141
  private applyRecords;
130
142
  /** Persist the current snapshot of one workspace to the store. */
131
143
  private persist;
144
+ private trackSave;
145
+ private reportStoreError;
146
+ drainSaves(): Promise<void>;
147
+ private advanceClock;
132
148
  now(): string;
133
149
  onAudit(listener: AuditListener): () => void;
134
150
  /** Convenience: get a workspace by id, or undefined. */
@@ -160,10 +176,34 @@ declare class Coordinator {
160
176
  * any existing in-memory workspaces. */
161
177
  restore(data: unknown): void;
162
178
  dispatch(envelope: Envelope): Envelope;
179
+ private _dispatch;
163
180
  recordAudit(ws: Workspace, envelope: Envelope): void;
181
+ /**
182
+ * SPECIFICATION 10.1: record a refused call when it is a governed attempt.
183
+ * The caller must be a member of an existing workspace, the call must be a
184
+ * JSON-RPC call for a method that is not a read, and the refusal must be one
185
+ * `refusalIsRecorded` names. The request is kept as it arrived, so a
186
+ * signature on it still verifies. Every call that reaches a recorded refusal
187
+ * has passed the canonical check, so it can be hashed into the chain.
188
+ */
189
+ private recordRefusal;
190
+ /** The signed calls on this workspace's log, built from the log when missing. */
191
+ private signedIndex;
192
+ private appendEntry;
164
193
  private verifySignature;
165
194
  /** Lookup the key valid for a given participant at a given time. */
166
195
  lookupKey(member: Member, kid: string, ts: string): KeyRecord | null;
196
+ /**
197
+ * The SPECIFICATION 15.4 check, per method rather than per namespace.
198
+ *
199
+ * Core is always present, so a core method is never gated. The reads in
200
+ * ALWAYS_AVAILABLE are never gated either: a workspace must be able to ask
201
+ * what it is and to check its own chain, and `audit.verify_chain` belongs to
202
+ * `audit-scitt/1.0` while chaining also turns on through an option, so
203
+ * gating it would let a workspace write a hash-linked chain it is refused
204
+ * permission to verify.
205
+ */
206
+ private profileGate;
167
207
  private checkStepUp;
168
208
  private registerCoreHandlers;
169
209
  private registerProfileHandlers;
package/dist/api.d.cts CHANGED
@@ -1,4 +1,4 @@
1
1
  import './methods.cjs';
2
- export { b as CoordinatorApi, c as CoordinatorError, g as call, m as makeApi } from './api-DiiL0sil.cjs';
2
+ export { b as CoordinatorApi, c as CoordinatorError, g as call, m as makeApi } from './api-BkvwN42r.cjs';
3
3
  import './types.cjs';
4
4
  import './storage/store.cjs';
package/dist/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import './methods.js';
2
- export { b as CoordinatorApi, c as CoordinatorError, g as call, m as makeApi } from './api-BOGEBNmX.js';
2
+ export { b as CoordinatorApi, c as CoordinatorError, g as call, m as makeApi } from './api-Ddy9fqkY.js';
3
3
  import './types.js';
4
4
  import './storage/store.js';