@unson/brainbase-mcp 0.43.0 → 0.44.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.
Files changed (74) hide show
  1. package/contracts/canonical-task/operation-schema.sql +58 -0
  2. package/contracts/canonical-task/search-indexes.sql +10 -0
  3. package/contracts/canonical-task/store-schema.sql +77 -0
  4. package/dist/automation-run.d.ts +213 -0
  5. package/dist/automation-run.js +479 -0
  6. package/dist/canonical-task-operations.d.ts +205 -0
  7. package/dist/canonical-task-operations.js +700 -0
  8. package/dist/canonical-task-postgres.d.ts +139 -0
  9. package/dist/canonical-task-postgres.js +554 -0
  10. package/dist/canonical-task-service.d.ts +13 -0
  11. package/dist/canonical-task-service.js +55 -3
  12. package/dist/canonical-task-store-config.d.ts +31 -0
  13. package/dist/canonical-task-store-config.js +53 -0
  14. package/dist/config-parser.d.ts +298 -0
  15. package/dist/config-parser.js +593 -0
  16. package/dist/connected-onboarding.d.ts +57 -0
  17. package/dist/connected-onboarding.js +37 -0
  18. package/dist/durable-wait-http.d.ts +3 -1
  19. package/dist/durable-wait-http.js +73 -6
  20. package/dist/durable-waits.d.ts +93 -3
  21. package/dist/durable-waits.js +320 -8
  22. package/dist/honcho.d.ts +25 -0
  23. package/dist/honcho.js +81 -0
  24. package/dist/judgment-event-adapter.d.ts +72 -0
  25. package/dist/judgment-event-adapter.js +114 -0
  26. package/dist/judgment-event-outbox.d.ts +182 -0
  27. package/dist/judgment-event-outbox.js +568 -0
  28. package/dist/judgment-execution-outcome.d.ts +46 -0
  29. package/dist/judgment-execution-outcome.js +149 -0
  30. package/dist/judgment-host.d.ts +18 -7
  31. package/dist/judgment-host.js +82 -34
  32. package/dist/judgment-lifecycle-core.d.ts +198 -0
  33. package/dist/judgment-lifecycle-core.js +464 -0
  34. package/dist/judgment-node-evidence.d.ts +57 -0
  35. package/dist/judgment-node-evidence.js +297 -0
  36. package/dist/judgment-runtime-resolution.d.ts +264 -0
  37. package/dist/judgment-runtime-resolution.js +1248 -0
  38. package/dist/judgment-runtime-resolution.public.d.ts +255 -0
  39. package/dist/knowledge-event.d.ts +28 -0
  40. package/dist/knowledge-event.js +114 -0
  41. package/dist/mcp-runtime.d.ts +75 -0
  42. package/dist/mcp-runtime.js +188 -0
  43. package/dist/meeting-automation-runtime.d.ts +102 -0
  44. package/dist/meeting-automation-runtime.js +249 -0
  45. package/dist/meeting-automation.d.ts +155 -0
  46. package/dist/meeting-automation.js +341 -0
  47. package/dist/meeting-minutes-context-receipt.d.ts +91 -0
  48. package/dist/meeting-minutes-context-receipt.js +280 -0
  49. package/dist/meeting-source-sync.d.ts +89 -0
  50. package/dist/meeting-source-sync.js +230 -0
  51. package/dist/mesh.d.ts +58 -0
  52. package/dist/mesh.js +134 -0
  53. package/dist/onboarding-runtime.d.ts +47 -0
  54. package/dist/onboarding-runtime.js +4719 -0
  55. package/dist/routine-cycle.d.ts +51 -0
  56. package/dist/routine-cycle.js +153 -0
  57. package/dist/routine-liveness.d.ts +49 -0
  58. package/dist/routine-liveness.js +227 -0
  59. package/dist/routine-runtime.d.ts +101 -0
  60. package/dist/routine-runtime.js +237 -0
  61. package/dist/routines.d.ts +3 -0
  62. package/dist/routines.js +3 -0
  63. package/dist/run-receipt.d.ts +40 -0
  64. package/dist/run-receipt.js +635 -0
  65. package/dist/runtime-host.d.ts +64 -0
  66. package/dist/runtime-host.js +70 -0
  67. package/dist/world-work.d.ts +16 -0
  68. package/package.json +115 -3
  69. package/ui/meeting-minutes.css +122 -0
  70. package/ui/meeting-minutes.js +316 -0
  71. package/ui/objective-editor.js +47 -11
  72. package/ui/world/world-district.js +18 -3
  73. package/ui/world/world-placement.js +13 -0
  74. package/ui/world/world-work-rail.js +7 -1
@@ -0,0 +1,341 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ const EXTERNAL_RUNTIME_CANDIDATE_SOURCE = 'external_meeting_runtime';
3
+ const EXTERNAL_RUNTIME_CANDIDATE_MAX_COUNT = 5;
4
+ const EXTERNAL_RUNTIME_CANDIDATE_FIELD_MAX_LENGTHS = Object.freeze({
5
+ title: 500,
6
+ owner_hint: 200,
7
+ ownerHint: 200,
8
+ due_hint: 200,
9
+ dueHint: 200,
10
+ source_excerpt: 2_000,
11
+ sourceExcerpt: 2_000,
12
+ decision_type: 100,
13
+ decisionType: 100
14
+ });
15
+ const EXTERNAL_RUNTIME_FOLLOW_UP_BODY_MAX_LENGTH = 10_000;
16
+ export class MeetingAutomationContractError extends Error {
17
+ code = 'validation_error';
18
+ statusCode = 400;
19
+ status = 400;
20
+ timestamp;
21
+ details;
22
+ constructor(message, details = {}) {
23
+ super(message);
24
+ this.name = 'MeetingAutomationContractError';
25
+ this.timestamp = new Date().toISOString();
26
+ this.details = details;
27
+ }
28
+ toJSON() {
29
+ return {
30
+ error: {
31
+ code: this.code,
32
+ message: this.message,
33
+ timestamp: this.timestamp
34
+ }
35
+ };
36
+ }
37
+ }
38
+ function validationError(message, stateTransition, details = {}) {
39
+ return new MeetingAutomationContractError(message, {
40
+ state_transition: stateTransition,
41
+ ...details
42
+ });
43
+ }
44
+ function asRecord(value) {
45
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
46
+ ? value
47
+ : null;
48
+ }
49
+ function readOptionalString(input, snakeKey, camelKey = snakeKey) {
50
+ const record = asRecord(input);
51
+ const value = record?.[snakeKey] ?? record?.[camelKey];
52
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
53
+ }
54
+ function stableId(prefix, ...parts) {
55
+ const base = parts
56
+ .map((part) => String(part || '').trim())
57
+ .filter(Boolean)
58
+ .join('_')
59
+ .toLowerCase()
60
+ .replace(/[^a-z0-9]+/g, '_')
61
+ .replace(/^_+|_+$/g, '');
62
+ if (!base)
63
+ return `${prefix}_${randomUUID()}`;
64
+ if (base.length <= 96)
65
+ return `${prefix}_${base}`;
66
+ const hash = createHash('sha256').update(base).digest('hex').slice(0, 12);
67
+ return `${prefix}_${base.slice(0, 83).replace(/_+$/g, '')}_${hash}`;
68
+ }
69
+ function taskCandidateOwnerHint(candidate) {
70
+ return readOptionalString(candidate, 'owner_hint', 'ownerHint')
71
+ || readOptionalString(candidate, 'assignee_hint', 'assigneeHint')
72
+ || readOptionalString(candidate, 'owner')
73
+ || readOptionalString(candidate, 'assignee')
74
+ || null;
75
+ }
76
+ function assertOptionalCandidateString(candidate, fieldName, index, collectionName) {
77
+ const value = candidate[fieldName];
78
+ // Normalized candidates deliberately use null for absent optional values.
79
+ // Keep that representation valid when a host owner resolver returns the
80
+ // normalized package for post-resolution contract verification.
81
+ if (value !== undefined && value !== null && typeof value !== 'string') {
82
+ throw validationError(`${collectionName}[${index}].${fieldName} must be a string`, 'blocked_invalid_candidates');
83
+ }
84
+ const maxLength = EXTERNAL_RUNTIME_CANDIDATE_FIELD_MAX_LENGTHS[fieldName];
85
+ if (typeof value === 'string' && maxLength && value.length > maxLength) {
86
+ throw validationError(`${collectionName}[${index}].${fieldName} must be at most ${maxLength} characters`, 'blocked_invalid_candidates');
87
+ }
88
+ }
89
+ function assertCandidateList(value, collectionName, optionalStringFields) {
90
+ if (!Array.isArray(value)) {
91
+ throw validationError(`${collectionName} must be an array`, 'blocked_invalid_candidates');
92
+ }
93
+ if (value.length > EXTERNAL_RUNTIME_CANDIDATE_MAX_COUNT) {
94
+ throw validationError(`${collectionName} must contain at most ${EXTERNAL_RUNTIME_CANDIDATE_MAX_COUNT} candidates`, 'blocked_invalid_candidates');
95
+ }
96
+ value.forEach((candidateValue, index) => {
97
+ const candidate = asRecord(candidateValue);
98
+ if (!candidate) {
99
+ throw validationError(`${collectionName}[${index}] must be a JSON object`, 'blocked_invalid_candidates');
100
+ }
101
+ if (typeof candidate.title !== 'string' || candidate.title.trim().length === 0) {
102
+ throw validationError(`${collectionName}[${index}].title must be a non-empty string`, 'blocked_invalid_candidates');
103
+ }
104
+ if (candidate.title.length > EXTERNAL_RUNTIME_CANDIDATE_FIELD_MAX_LENGTHS.title) {
105
+ throw validationError(`${collectionName}[${index}].title must be at most ${EXTERNAL_RUNTIME_CANDIDATE_FIELD_MAX_LENGTHS.title} characters`, 'blocked_invalid_candidates');
106
+ }
107
+ optionalStringFields.forEach((fieldName) => {
108
+ assertOptionalCandidateString(candidate, fieldName, index, collectionName);
109
+ });
110
+ });
111
+ }
112
+ export function assertMeetingCandidatesInput(input) {
113
+ const record = asRecord(input) ?? {};
114
+ assertCandidateList(record.task_candidates, 'task_candidates', [
115
+ 'owner_hint',
116
+ 'ownerHint',
117
+ 'due_hint',
118
+ 'dueHint',
119
+ 'source_excerpt',
120
+ 'sourceExcerpt'
121
+ ]);
122
+ assertCandidateList(record.decision_candidates, 'decision_candidates', [
123
+ 'decision_type',
124
+ 'decisionType',
125
+ 'source_excerpt',
126
+ 'sourceExcerpt'
127
+ ]);
128
+ const followUpDraft = asRecord(record.follow_up_draft);
129
+ if (!followUpDraft) {
130
+ throw validationError('follow_up_draft must be a JSON object', 'blocked_invalid_candidates');
131
+ }
132
+ if (typeof followUpDraft.body !== 'string') {
133
+ throw validationError('follow_up_draft.body must be a string', 'blocked_invalid_candidates');
134
+ }
135
+ if (followUpDraft.body.length > EXTERNAL_RUNTIME_FOLLOW_UP_BODY_MAX_LENGTH) {
136
+ throw validationError(`follow_up_draft.body must be at most ${EXTERNAL_RUNTIME_FOLLOW_UP_BODY_MAX_LENGTH} characters`, 'blocked_invalid_candidates');
137
+ }
138
+ }
139
+ export function normalizeTaskCandidates(rawCandidates, { caseScope = null, evidenceRefs = [] } = {}) {
140
+ if (!Array.isArray(rawCandidates))
141
+ return [];
142
+ return rawCandidates
143
+ .map((candidate) => asRecord(candidate))
144
+ .filter((candidate) => Boolean(candidate))
145
+ .map((candidate, index) => {
146
+ const title = readOptionalString(candidate, 'title') || '';
147
+ if (!title)
148
+ return null;
149
+ return {
150
+ id: stableId('task_candidate', caseScope || '', 'task', title, index),
151
+ title,
152
+ status: 'candidate',
153
+ source: EXTERNAL_RUNTIME_CANDIDATE_SOURCE,
154
+ case_scope: caseScope,
155
+ owner_hint: taskCandidateOwnerHint(candidate),
156
+ due_hint: readOptionalString(candidate, 'due_hint', 'dueHint'),
157
+ source_excerpt: readOptionalString(candidate, 'source_excerpt', 'sourceExcerpt'),
158
+ evidence_refs: evidenceRefs
159
+ };
160
+ })
161
+ .filter((candidate) => Boolean(candidate));
162
+ }
163
+ export function normalizeDecisionCandidates(rawCandidates, { caseScope = null, evidenceRefs = [] } = {}) {
164
+ if (!Array.isArray(rawCandidates))
165
+ return [];
166
+ return rawCandidates
167
+ .map((candidate) => asRecord(candidate))
168
+ .filter((candidate) => Boolean(candidate))
169
+ .map((candidate, index) => {
170
+ const title = readOptionalString(candidate, 'title') || '';
171
+ if (!title)
172
+ return null;
173
+ return {
174
+ id: stableId('decision_candidate', caseScope || '', 'decision', title, index),
175
+ title,
176
+ status: 'candidate',
177
+ source: EXTERNAL_RUNTIME_CANDIDATE_SOURCE,
178
+ case_scope: caseScope,
179
+ decision_type: readOptionalString(candidate, 'decision_type', 'decisionType') || 'meeting_decision',
180
+ source_excerpt: readOptionalString(candidate, 'source_excerpt', 'sourceExcerpt'),
181
+ evidence_refs: evidenceRefs
182
+ };
183
+ })
184
+ .filter((candidate) => Boolean(candidate));
185
+ }
186
+ export function normalizeFollowUpDraft(rawDraft) {
187
+ const record = asRecord(rawDraft);
188
+ return {
189
+ status: 'draft_only',
190
+ external_send_required_approval: true,
191
+ body: typeof record?.body === 'string' ? record.body : ''
192
+ };
193
+ }
194
+ export const MEETING_REVIEW_OUTPUT_DEFINITIONS = [
195
+ {
196
+ id: 'meeting_note_draft',
197
+ title: '議事録ドラフト',
198
+ type: 'meeting_note_draft',
199
+ package_key: 'meeting_note_summary',
200
+ loop_intent_key: 'transcript_to_meeting_note',
201
+ write_back_target: 'meeting_note_draft'
202
+ },
203
+ {
204
+ id: 'task_candidates',
205
+ title: 'Task候補',
206
+ type: 'task_candidates',
207
+ package_key: 'task_candidates',
208
+ loop_intent_key: 'meeting_note_to_tasks',
209
+ write_back_target: 'task_store'
210
+ },
211
+ {
212
+ id: 'decision_candidates',
213
+ title: 'Decision候補',
214
+ type: 'decision_candidates',
215
+ package_key: 'decision_candidates',
216
+ loop_intent_key: 'meeting_note_to_decisions',
217
+ write_back_target: 'graph_ssot_decision'
218
+ },
219
+ {
220
+ id: 'follow_up_draft',
221
+ title: 'フォローアップ文面ドラフト',
222
+ type: 'message_draft',
223
+ package_key: 'follow_up_draft',
224
+ loop_intent_key: 'post_meeting_follow_up_message',
225
+ write_back_target: 'external_message_draft'
226
+ },
227
+ {
228
+ id: 'promotion_candidates',
229
+ title: 'Graph / Learning昇格候補',
230
+ type: 'promotion_candidates',
231
+ package_key: 'promotion_candidates',
232
+ loop_intent_key: 'meeting_note_to_decisions',
233
+ write_back_target: 'candidate_store'
234
+ }
235
+ ];
236
+ export const MEETING_REVIEW_HUMAN_STEP_DEFINITIONS = [
237
+ {
238
+ id: 'approve_meeting_note_publish',
239
+ step_type: 'approval',
240
+ prompt: '議事録ドラフトの公開可否を確認してください',
241
+ reason: 'required_before_publish',
242
+ protects: ['meeting_note_publish'],
243
+ write_back_target: 'meeting_note_draft',
244
+ loop_intent_key: 'transcript_to_meeting_note'
245
+ },
246
+ {
247
+ id: 'approve_task_candidates',
248
+ step_type: 'approval',
249
+ prompt: 'Task候補を作成してよいか確認してください',
250
+ reason: 'required_before_task_create',
251
+ protects: ['task_create'],
252
+ write_back_target: 'task_store',
253
+ loop_intent_key: 'meeting_note_to_tasks'
254
+ },
255
+ {
256
+ id: 'approve_decision_candidates',
257
+ step_type: 'approval',
258
+ prompt: 'Decision候補をGraph SSOTへ昇格してよいか確認してください',
259
+ reason: 'required_before_graph_promotion',
260
+ protects: ['decision_promotion', 'graph_promotion'],
261
+ write_back_target: 'graph_ssot_decision',
262
+ loop_intent_key: 'meeting_note_to_decisions'
263
+ },
264
+ {
265
+ id: 'approve_follow_up_draft',
266
+ step_type: 'approval',
267
+ prompt: 'フォローアップ文面を外部送信してよいか確認してください',
268
+ reason: 'required_before_external_send',
269
+ protects: ['external_send'],
270
+ write_back_target: 'external_message_draft',
271
+ loop_intent_key: 'post_meeting_follow_up_message'
272
+ },
273
+ {
274
+ id: 'approve_promotion_candidates',
275
+ step_type: 'approval',
276
+ prompt: 'Graph / Learning昇格候補を次の審査へ回してよいか確認してください',
277
+ reason: 'required_before_candidate_promotion',
278
+ protects: ['graph_candidate_promotion', 'learning_candidate_promotion'],
279
+ write_back_target: 'candidate_store',
280
+ loop_intent_key: 'meeting_note_to_decisions'
281
+ }
282
+ ];
283
+ const REQUIRED_LOOP_INTENT_KEYS = Array.from(new Set([
284
+ ...MEETING_REVIEW_OUTPUT_DEFINITIONS.map((definition) => definition.loop_intent_key),
285
+ ...MEETING_REVIEW_HUMAN_STEP_DEFINITIONS.map((definition) => definition.loop_intent_key)
286
+ ]));
287
+ const REQUIRED_PACKAGE_KEYS = MEETING_REVIEW_OUTPUT_DEFINITIONS.map((definition) => definition.package_key);
288
+ export function verifyMeetingReviewPackage({ repository, reviewPackage, orgId, projectId }) {
289
+ const missingPackageKeys = REQUIRED_PACKAGE_KEYS
290
+ .filter((key) => !Object.hasOwn(reviewPackage, key) || reviewPackage[key] == null);
291
+ if (missingPackageKeys.length > 0) {
292
+ throw validationError('review_package is missing required output payload key(s)', 'blocked_invalid_review_package', {
293
+ missing_package_keys: missingPackageKeys,
294
+ required_package_keys: REQUIRED_PACKAGE_KEYS
295
+ });
296
+ }
297
+ const loopIntentIds = reviewPackage.loop_intent_ids;
298
+ if (!loopIntentIds || typeof loopIntentIds !== 'object' || Array.isArray(loopIntentIds)) {
299
+ throw validationError('review_package.loop_intent_ids must be a JSON object', 'blocked_loop_intent_mismatch', {
300
+ required_loop_intent_keys: REQUIRED_LOOP_INTENT_KEYS
301
+ });
302
+ }
303
+ const loopEntries = Object.entries(loopIntentIds)
304
+ .map(([key, value]) => [key, typeof value === 'string' ? value.trim() : ''])
305
+ .filter(([, value]) => value);
306
+ if (loopEntries.length === 0) {
307
+ throw validationError('review_package.loop_intent_ids must include at least one id', 'blocked_loop_intent_mismatch', {
308
+ required_loop_intent_keys: REQUIRED_LOOP_INTENT_KEYS
309
+ });
310
+ }
311
+ const presentKeys = new Set(loopEntries.map(([key]) => key));
312
+ const missingKeys = REQUIRED_LOOP_INTENT_KEYS.filter((key) => !presentKeys.has(key));
313
+ if (missingKeys.length > 0) {
314
+ throw validationError('review_package.loop_intent_ids is missing required meeting review key(s)', 'blocked_loop_intent_mismatch', {
315
+ missing_loop_intent_keys: missingKeys,
316
+ required_loop_intent_keys: REQUIRED_LOOP_INTENT_KEYS
317
+ });
318
+ }
319
+ const loopIntents = loopEntries.map(([key, loopIntentId]) => {
320
+ const loopIntent = repository.getLoopIntent(loopIntentId);
321
+ if (!loopIntent) {
322
+ throw validationError(`loop_intent '${loopIntentId}' not found`, 'blocked_loop_intent_mismatch', {
323
+ loop_intent_key: key,
324
+ loop_intent_id: loopIntentId
325
+ });
326
+ }
327
+ if (loopIntent.org_id !== orgId || loopIntent.project_id !== projectId) {
328
+ throw validationError(`loop_intent '${loopIntentId}' belongs to '${loopIntent.org_id}/${loopIntent.project_id}'`, 'blocked_loop_intent_mismatch', {
329
+ loop_intent_key: key,
330
+ loop_intent_id: loopIntentId,
331
+ expected: { org_id: orgId, project_id: projectId },
332
+ actual: { org_id: loopIntent.org_id, project_id: loopIntent.project_id }
333
+ });
334
+ }
335
+ return { key, loop_intent: loopIntent };
336
+ });
337
+ return {
338
+ loopIntents,
339
+ loopIntentByKey: new Map(loopIntents.map((entry) => [entry.key, entry.loop_intent]))
340
+ };
341
+ }
@@ -0,0 +1,91 @@
1
+ export declare const MEETING_MINUTES_CONTEXT_RECEIPT_VERSION: "meeting_minutes_context_receipt.v1";
2
+ export declare const MEETING_MINUTES_CONTEXT_RECEIPT_MAX_BYTES: number;
3
+ type UnknownRecord = Record<string, unknown>;
4
+ type MaybePromise<T> = T | Promise<T>;
5
+ export type MeetingMinutesContextReceiptStatus = 'resolved' | 'confirmed_empty' | 'partial' | 'unavailable';
6
+ export interface MeetingMinutesContextIdentity {
7
+ readonly run_id: string;
8
+ readonly project_code: string;
9
+ readonly transcript_sha256: string;
10
+ }
11
+ export interface MeetingMinutesContextReceipt {
12
+ readonly schema_version: typeof MEETING_MINUTES_CONTEXT_RECEIPT_VERSION;
13
+ readonly receipt_id: string;
14
+ readonly identity: MeetingMinutesContextIdentity;
15
+ readonly status: MeetingMinutesContextReceiptStatus;
16
+ readonly source_status: {
17
+ readonly graph: string;
18
+ readonly tasks: string;
19
+ };
20
+ readonly resolved_at: string;
21
+ readonly context: UnknownRecord;
22
+ readonly errors: readonly UnknownRecord[];
23
+ readonly checksum: string;
24
+ readonly [key: string]: unknown;
25
+ }
26
+ export interface MeetingMinutesContextReceiptClaimRequest {
27
+ readonly receipt_id: string;
28
+ readonly fingerprint: string;
29
+ readonly scope: UnknownRecord | null;
30
+ readonly execute: () => MaybePromise<MeetingMinutesContextReceipt>;
31
+ }
32
+ export interface MeetingMinutesContextReceiptClaimResult {
33
+ readonly status: 'persisted' | 'replayed';
34
+ readonly receipt: MeetingMinutesContextReceipt;
35
+ }
36
+ export interface MeetingMinutesContextReceiptPorts {
37
+ readonly graph?: (input: {
38
+ identity: MeetingMinutesContextIdentity;
39
+ retrieval_context: UnknownRecord;
40
+ }) => MaybePromise<UnknownRecord | null>;
41
+ readonly tasks?: (input: {
42
+ identity: MeetingMinutesContextIdentity;
43
+ }) => MaybePromise<UnknownRecord | readonly UnknownRecord[] | null>;
44
+ /** Identity/authentication/tenant/project checks remain host-owned ports. */
45
+ readonly actor: {
46
+ readonly resolve: (input: {
47
+ identity: MeetingMinutesContextIdentity;
48
+ request: UnknownRecord;
49
+ }) => MaybePromise<UnknownRecord>;
50
+ };
51
+ readonly auth: {
52
+ readonly authorize: (input: {
53
+ actor: UnknownRecord;
54
+ identity: MeetingMinutesContextIdentity;
55
+ }) => MaybePromise<void>;
56
+ };
57
+ readonly tenant: {
58
+ readonly authorize: (input: {
59
+ actor: UnknownRecord;
60
+ identity: MeetingMinutesContextIdentity;
61
+ }) => MaybePromise<void>;
62
+ };
63
+ readonly project: {
64
+ readonly authorize: (input: {
65
+ actor: UnknownRecord;
66
+ identity: MeetingMinutesContextIdentity;
67
+ }) => MaybePromise<void>;
68
+ };
69
+ readonly repository: {
70
+ /** Durable claim prevents two workers from both fetching and writing. */
71
+ readonly claimOrReplay: (request: MeetingMinutesContextReceiptClaimRequest) => MaybePromise<MeetingMinutesContextReceiptClaimResult>;
72
+ put: (receipt: MeetingMinutesContextReceipt, scope?: UnknownRecord | null) => MaybePromise<MeetingMinutesContextReceipt | void>;
73
+ get: (receiptId: string, scope?: UnknownRecord | null) => MaybePromise<MeetingMinutesContextReceipt | null>;
74
+ };
75
+ readonly scope?: UnknownRecord | null;
76
+ readonly now?: () => Date;
77
+ readonly max_attempts?: number;
78
+ readonly is_retryable?: (error: unknown) => boolean;
79
+ }
80
+ export declare class MeetingMinutesContextReceiptError extends Error {
81
+ readonly code: string;
82
+ readonly statusCode: number;
83
+ readonly details: UnknownRecord;
84
+ constructor(code: string, message: string, statusCode?: number, details?: UnknownRecord);
85
+ }
86
+ export declare function digestMeetingMinutesContext(value: unknown): string;
87
+ export declare function normalizeMeetingMinutesContextIdentity(input?: UnknownRecord): MeetingMinutesContextIdentity;
88
+ export declare function normalizeMeetingMinutesRetrievalContext(input?: UnknownRecord): UnknownRecord;
89
+ export declare function createMeetingMinutesContextReceipt(input: UnknownRecord, ports: MeetingMinutesContextReceiptPorts): Promise<MeetingMinutesContextReceipt>;
90
+ export declare function readMeetingMinutesContextReceipt(receiptId: string, input: UnknownRecord, ports: MeetingMinutesContextReceiptPorts): Promise<MeetingMinutesContextReceipt>;
91
+ export {};