@odla-ai/chapter 0.42.0 → 0.42.2

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.
@@ -185,6 +185,16 @@ interface ChapterNetworkTarget {
185
185
  * this follower. Omitted by default: a target never gains write permission
186
186
  * merely because its records are browsable. */
187
187
  sharedNotes?: readonly string[];
188
+ /** Per-record-type upper bound on profile fields this leader permits its
189
+ * admins to edit remotely. The follower must independently delegate the
190
+ * same field; readable fields never become writable implicitly. */
191
+ editableFields?: Record<string, readonly string[]>;
192
+ /** Record types on which this leader permits remote lifecycle transitions.
193
+ * The follower must independently opt in and remains pipeline authority. */
194
+ stageTransitions?: readonly string[];
195
+ /** Allow package-owned desired admission decisions for existing leader CRM
196
+ * people to be delivered to this target. Omitted means default deny. */
197
+ admissionGrants?: boolean;
188
198
  }
189
199
  /** One signed peer allowed to browse a privacy-bounded projection of this
190
200
  * site's CRM. The follower owns this allowlist; a leader target declaration
@@ -194,11 +204,21 @@ interface ChapterNetworkReader {
194
204
  id: string;
195
205
  /** Per-record-type field allowlist. Omitted types and fields never leave
196
206
  * this site. Record id, name, stage, and timestamps are bounded metadata. */
197
- fields: Record<string, readonly string[]>;
207
+ fields?: Record<string, readonly string[]>;
198
208
  /** Record types on which this reader may append an explicitly shared note.
199
209
  * Omitted by default: browse permission never silently grants write access.
200
210
  * Shared notes land in the follower CRM activity feed. */
201
211
  sharedNotes?: readonly string[];
212
+ /** Exact local CRM fields this reader may edit remotely, by record type.
213
+ * Every field must also be readable so the peer can perform an optimistic
214
+ * edit against the value and revision it actually reviewed. */
215
+ editableFields?: Record<string, readonly string[]>;
216
+ /** Local CRM record types on which this reader may request a lifecycle
217
+ * transition. Chapter still enforces the local pipeline and gates. */
218
+ stageTransitions?: readonly string[];
219
+ /** Accept signed desired admission decisions from this reader. Independent
220
+ * of record browsing; an admission-only reader may omit `fields`. */
221
+ admissionGrants?: boolean;
202
222
  }
203
223
  /** Leader/follower network configuration. A follower needs no code config to
204
224
  * receive pushed records. It must explicitly declare `readers` before any peer
@@ -241,12 +261,18 @@ interface ResolvedNetworkTarget {
241
261
  secretName: string;
242
262
  fields?: Record<string, readonly string[]>;
243
263
  sharedNotes: readonly string[];
264
+ editableFields: Record<string, readonly string[]>;
265
+ stageTransitions: readonly string[];
266
+ admissionGrants?: boolean;
244
267
  }
245
268
  /** A validated follower-owned record projection for one signed reader. */
246
269
  interface ResolvedNetworkReader {
247
270
  id: string;
248
271
  fields: Record<string, readonly string[]>;
249
272
  sharedNotes: readonly string[];
273
+ editableFields: Record<string, readonly string[]>;
274
+ stageTransitions: readonly string[];
275
+ admissionGrants?: boolean;
250
276
  }
251
277
  /** Fully-resolved leader network configuration. */
252
278
  interface ResolvedNetwork {
@@ -1192,9 +1218,54 @@ interface AdmissionGrantDeliveryOptions {
1192
1218
  envelope: AdmissionGrantEnvelope;
1193
1219
  fetch?: typeof globalThis.fetch;
1194
1220
  }
1221
+ /** Structured follower rejection retained by the durable leader outbox. */
1222
+ declare class AdmissionGrantDeliveryError extends Error {
1223
+ readonly status: number;
1224
+ readonly reason: string;
1225
+ constructor(status: number, reason: string);
1226
+ }
1195
1227
  /** Deliver one signed Parent admission revision. Durable retry belongs upstream. */
1196
1228
  declare function deliverAdmissionGrants(options: AdmissionGrantDeliveryOptions): Promise<AdmissionGrantReceipt>;
1197
1229
 
1230
+ /** Durable state of the latest desired admission document for one target. */
1231
+ type LeaderAdmissionDeliveryStatus = "saved" | "pending" | "acknowledged" | "retrying" | "rejected";
1232
+ /** Leader-owned desired admission decision for one authoritative CRM person. */
1233
+ interface LeaderAdmissionAssignment {
1234
+ id: string;
1235
+ targetId: string;
1236
+ personId: string;
1237
+ grantId: string;
1238
+ decision: AdmissionDecision;
1239
+ note?: string;
1240
+ expiresAt?: number;
1241
+ active: boolean;
1242
+ lastMutationId: string;
1243
+ lastRequestDigest: string;
1244
+ createdAt: number;
1245
+ createdBy: string;
1246
+ updatedAt: number;
1247
+ updatedBy: string;
1248
+ }
1249
+ /** Persisted desired admission envelope and its latest delivery evidence. */
1250
+ interface LeaderAdmissionDelivery {
1251
+ id: string;
1252
+ targetId: string;
1253
+ environment: string;
1254
+ revision: number;
1255
+ digest: string;
1256
+ envelope: AdmissionGrantEnvelope;
1257
+ status: LeaderAdmissionDeliveryStatus;
1258
+ attempts: number;
1259
+ lastAttemptAt?: number;
1260
+ lastError?: string;
1261
+ acknowledgedAt?: number;
1262
+ updatedAt: number;
1263
+ }
1264
+
1265
+ /** Retry every non-final saved delivery. Hosts may call this from a cron using
1266
+ * the same Worker context; request retries use the packaged admin route. */
1267
+ declare function retryLeaderAdmissionDeliveries(env: ChapterEnv, ctx: WorkerContext, limit?: number): Promise<LeaderAdmissionDelivery[]>;
1268
+
1198
1269
  /** Identity shared by initial HTML, response caching, and client hydration. */
1199
1270
  interface SignupControlThemeMetadata {
1200
1271
  source: "active" | "bootstrap";
@@ -1265,4 +1336,4 @@ declare function chapterWorker(options: ChapterWorkerOptions): {
1265
1336
  fetch(req: Request, env: ChapterEnv): Promise<Response>;
1266
1337
  };
1267
1338
 
1268
- export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterWorkerOptions, type MemberContentDeliveryOptions, type Route, type SignupControlDeliveryOptions, type WorkerContext, chapterWorker, createWorkerContext, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverSignupControl, renderActiveSignupControlHtml, withActiveSignupControlTheme };
1339
+ export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, AdmissionGrantDeliveryError, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterWorkerOptions, type LeaderAdmissionAssignment, type LeaderAdmissionDelivery, type LeaderAdmissionDeliveryStatus, type MemberContentDeliveryOptions, type Route, type SignupControlDeliveryOptions, type WorkerContext, chapterWorker, createWorkerContext, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverSignupControl, renderActiveSignupControlHtml, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };
@@ -185,6 +185,16 @@ interface ChapterNetworkTarget {
185
185
  * this follower. Omitted by default: a target never gains write permission
186
186
  * merely because its records are browsable. */
187
187
  sharedNotes?: readonly string[];
188
+ /** Per-record-type upper bound on profile fields this leader permits its
189
+ * admins to edit remotely. The follower must independently delegate the
190
+ * same field; readable fields never become writable implicitly. */
191
+ editableFields?: Record<string, readonly string[]>;
192
+ /** Record types on which this leader permits remote lifecycle transitions.
193
+ * The follower must independently opt in and remains pipeline authority. */
194
+ stageTransitions?: readonly string[];
195
+ /** Allow package-owned desired admission decisions for existing leader CRM
196
+ * people to be delivered to this target. Omitted means default deny. */
197
+ admissionGrants?: boolean;
188
198
  }
189
199
  /** One signed peer allowed to browse a privacy-bounded projection of this
190
200
  * site's CRM. The follower owns this allowlist; a leader target declaration
@@ -194,11 +204,21 @@ interface ChapterNetworkReader {
194
204
  id: string;
195
205
  /** Per-record-type field allowlist. Omitted types and fields never leave
196
206
  * this site. Record id, name, stage, and timestamps are bounded metadata. */
197
- fields: Record<string, readonly string[]>;
207
+ fields?: Record<string, readonly string[]>;
198
208
  /** Record types on which this reader may append an explicitly shared note.
199
209
  * Omitted by default: browse permission never silently grants write access.
200
210
  * Shared notes land in the follower CRM activity feed. */
201
211
  sharedNotes?: readonly string[];
212
+ /** Exact local CRM fields this reader may edit remotely, by record type.
213
+ * Every field must also be readable so the peer can perform an optimistic
214
+ * edit against the value and revision it actually reviewed. */
215
+ editableFields?: Record<string, readonly string[]>;
216
+ /** Local CRM record types on which this reader may request a lifecycle
217
+ * transition. Chapter still enforces the local pipeline and gates. */
218
+ stageTransitions?: readonly string[];
219
+ /** Accept signed desired admission decisions from this reader. Independent
220
+ * of record browsing; an admission-only reader may omit `fields`. */
221
+ admissionGrants?: boolean;
202
222
  }
203
223
  /** Leader/follower network configuration. A follower needs no code config to
204
224
  * receive pushed records. It must explicitly declare `readers` before any peer
@@ -241,12 +261,18 @@ interface ResolvedNetworkTarget {
241
261
  secretName: string;
242
262
  fields?: Record<string, readonly string[]>;
243
263
  sharedNotes: readonly string[];
264
+ editableFields: Record<string, readonly string[]>;
265
+ stageTransitions: readonly string[];
266
+ admissionGrants?: boolean;
244
267
  }
245
268
  /** A validated follower-owned record projection for one signed reader. */
246
269
  interface ResolvedNetworkReader {
247
270
  id: string;
248
271
  fields: Record<string, readonly string[]>;
249
272
  sharedNotes: readonly string[];
273
+ editableFields: Record<string, readonly string[]>;
274
+ stageTransitions: readonly string[];
275
+ admissionGrants?: boolean;
250
276
  }
251
277
  /** Fully-resolved leader network configuration. */
252
278
  interface ResolvedNetwork {
@@ -1192,9 +1218,54 @@ interface AdmissionGrantDeliveryOptions {
1192
1218
  envelope: AdmissionGrantEnvelope;
1193
1219
  fetch?: typeof globalThis.fetch;
1194
1220
  }
1221
+ /** Structured follower rejection retained by the durable leader outbox. */
1222
+ declare class AdmissionGrantDeliveryError extends Error {
1223
+ readonly status: number;
1224
+ readonly reason: string;
1225
+ constructor(status: number, reason: string);
1226
+ }
1195
1227
  /** Deliver one signed Parent admission revision. Durable retry belongs upstream. */
1196
1228
  declare function deliverAdmissionGrants(options: AdmissionGrantDeliveryOptions): Promise<AdmissionGrantReceipt>;
1197
1229
 
1230
+ /** Durable state of the latest desired admission document for one target. */
1231
+ type LeaderAdmissionDeliveryStatus = "saved" | "pending" | "acknowledged" | "retrying" | "rejected";
1232
+ /** Leader-owned desired admission decision for one authoritative CRM person. */
1233
+ interface LeaderAdmissionAssignment {
1234
+ id: string;
1235
+ targetId: string;
1236
+ personId: string;
1237
+ grantId: string;
1238
+ decision: AdmissionDecision;
1239
+ note?: string;
1240
+ expiresAt?: number;
1241
+ active: boolean;
1242
+ lastMutationId: string;
1243
+ lastRequestDigest: string;
1244
+ createdAt: number;
1245
+ createdBy: string;
1246
+ updatedAt: number;
1247
+ updatedBy: string;
1248
+ }
1249
+ /** Persisted desired admission envelope and its latest delivery evidence. */
1250
+ interface LeaderAdmissionDelivery {
1251
+ id: string;
1252
+ targetId: string;
1253
+ environment: string;
1254
+ revision: number;
1255
+ digest: string;
1256
+ envelope: AdmissionGrantEnvelope;
1257
+ status: LeaderAdmissionDeliveryStatus;
1258
+ attempts: number;
1259
+ lastAttemptAt?: number;
1260
+ lastError?: string;
1261
+ acknowledgedAt?: number;
1262
+ updatedAt: number;
1263
+ }
1264
+
1265
+ /** Retry every non-final saved delivery. Hosts may call this from a cron using
1266
+ * the same Worker context; request retries use the packaged admin route. */
1267
+ declare function retryLeaderAdmissionDeliveries(env: ChapterEnv, ctx: WorkerContext, limit?: number): Promise<LeaderAdmissionDelivery[]>;
1268
+
1198
1269
  /** Identity shared by initial HTML, response caching, and client hydration. */
1199
1270
  interface SignupControlThemeMetadata {
1200
1271
  source: "active" | "bootstrap";
@@ -1265,4 +1336,4 @@ declare function chapterWorker(options: ChapterWorkerOptions): {
1265
1336
  fetch(req: Request, env: ChapterEnv): Promise<Response>;
1266
1337
  };
1267
1338
 
1268
- export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterWorkerOptions, type MemberContentDeliveryOptions, type Route, type SignupControlDeliveryOptions, type WorkerContext, chapterWorker, createWorkerContext, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverSignupControl, renderActiveSignupControlHtml, withActiveSignupControlTheme };
1339
+ export { type ActiveSignupControlHtml, type ActiveSignupControlThemeOptions, AdmissionGrantDeliveryError, type AdmissionGrantDeliveryOptions, type BuilderLibraryDeliveryOptions, type ChapterEnv, type ChapterWorkerOptions, type LeaderAdmissionAssignment, type LeaderAdmissionDelivery, type LeaderAdmissionDeliveryStatus, type MemberContentDeliveryOptions, type Route, type SignupControlDeliveryOptions, type WorkerContext, chapterWorker, createWorkerContext, deliverAdmissionGrants, deliverBuilderLibrary, deliverMemberContent, deliverSignupControl, renderActiveSignupControlHtml, retryLeaderAdmissionDeliveries, withActiveSignupControlTheme };