@pegma/support-desk-application 0.1.1 → 0.2.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.
Files changed (86) hide show
  1. package/README.md +228 -7
  2. package/dist/assistant-turn-capacity.d.ts +13 -0
  3. package/dist/assistant-turn-capacity.d.ts.map +1 -0
  4. package/dist/assistant-turn-capacity.js +111 -0
  5. package/dist/assistant-turn-capacity.js.map +1 -0
  6. package/dist/assistant-turn-records.d.ts +68 -0
  7. package/dist/assistant-turn-records.d.ts.map +1 -0
  8. package/dist/assistant-turn-records.js +418 -0
  9. package/dist/assistant-turn-records.js.map +1 -0
  10. package/dist/assistant-turn-types.d.ts +133 -0
  11. package/dist/assistant-turn-types.d.ts.map +1 -0
  12. package/dist/assistant-turn-types.js +2 -0
  13. package/dist/assistant-turn-types.js.map +1 -0
  14. package/dist/assistant-turns.d.ts +42 -0
  15. package/dist/assistant-turns.d.ts.map +1 -0
  16. package/dist/assistant-turns.js +640 -0
  17. package/dist/assistant-turns.js.map +1 -0
  18. package/dist/engineering-evidence.d.ts +20 -0
  19. package/dist/engineering-evidence.d.ts.map +1 -0
  20. package/dist/engineering-evidence.js +899 -0
  21. package/dist/engineering-evidence.js.map +1 -0
  22. package/dist/engineering-followup-internal.d.ts +45 -0
  23. package/dist/engineering-followup-internal.d.ts.map +1 -0
  24. package/dist/engineering-followup-internal.js +2 -0
  25. package/dist/engineering-followup-internal.js.map +1 -0
  26. package/dist/engineering-followup-records.d.ts +209 -0
  27. package/dist/engineering-followup-records.d.ts.map +1 -0
  28. package/dist/engineering-followup-records.js +1434 -0
  29. package/dist/engineering-followup-records.js.map +1 -0
  30. package/dist/engineering-followup-source.d.ts +168 -0
  31. package/dist/engineering-followup-source.d.ts.map +1 -0
  32. package/dist/engineering-followup-source.js +1144 -0
  33. package/dist/engineering-followup-source.js.map +1 -0
  34. package/dist/engineering-followup-types.d.ts +364 -0
  35. package/dist/engineering-followup-types.d.ts.map +1 -0
  36. package/dist/engineering-followup-types.js +2 -0
  37. package/dist/engineering-followup-types.js.map +1 -0
  38. package/dist/engineering-followup-work.d.ts +70 -0
  39. package/dist/engineering-followup-work.d.ts.map +1 -0
  40. package/dist/engineering-followup-work.js +1153 -0
  41. package/dist/engineering-followup-work.js.map +1 -0
  42. package/dist/engineering-internal.d.ts +38 -0
  43. package/dist/engineering-internal.d.ts.map +1 -0
  44. package/dist/engineering-internal.js +11 -0
  45. package/dist/engineering-internal.js.map +1 -0
  46. package/dist/engineering-policy.d.ts +47 -0
  47. package/dist/engineering-policy.d.ts.map +1 -0
  48. package/dist/engineering-policy.js +579 -0
  49. package/dist/engineering-policy.js.map +1 -0
  50. package/dist/engineering-reconciliation.d.ts +6 -0
  51. package/dist/engineering-reconciliation.d.ts.map +1 -0
  52. package/dist/engineering-reconciliation.js +464 -0
  53. package/dist/engineering-reconciliation.js.map +1 -0
  54. package/dist/engineering-records.d.ts +227 -0
  55. package/dist/engineering-records.d.ts.map +1 -0
  56. package/dist/engineering-records.js +1272 -0
  57. package/dist/engineering-records.js.map +1 -0
  58. package/dist/engineering-types.d.ts +505 -0
  59. package/dist/engineering-types.d.ts.map +1 -0
  60. package/dist/engineering-types.js +2 -0
  61. package/dist/engineering-types.js.map +1 -0
  62. package/dist/engineering-work.d.ts +32 -0
  63. package/dist/engineering-work.d.ts.map +1 -0
  64. package/dist/engineering-work.js +1757 -0
  65. package/dist/engineering-work.js.map +1 -0
  66. package/dist/index.d.ts +609 -14
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +3568 -204
  69. package/dist/index.js.map +1 -1
  70. package/dist/resolution-learning-records.d.ts +154 -0
  71. package/dist/resolution-learning-records.d.ts.map +1 -0
  72. package/dist/resolution-learning-records.js +657 -0
  73. package/dist/resolution-learning-records.js.map +1 -0
  74. package/dist/resolution-learning-types.d.ts +356 -0
  75. package/dist/resolution-learning-types.d.ts.map +1 -0
  76. package/dist/resolution-learning-types.js +2 -0
  77. package/dist/resolution-learning-types.js.map +1 -0
  78. package/dist/resolution-learning-worker.d.ts +21 -0
  79. package/dist/resolution-learning-worker.d.ts.map +1 -0
  80. package/dist/resolution-learning-worker.js +1027 -0
  81. package/dist/resolution-learning-worker.js.map +1 -0
  82. package/dist/resolution-learning.d.ts +38 -0
  83. package/dist/resolution-learning.d.ts.map +1 -0
  84. package/dist/resolution-learning.js +860 -0
  85. package/dist/resolution-learning.js.map +1 -0
  86. package/package.json +6 -6
package/README.md CHANGED
@@ -3,6 +3,84 @@
3
3
  Authorized customer ticket services and provider-neutral durable outbox
4
4
  records for Support Desk. The host supplies an `@pegma/storage-core` `Store`
5
5
  and a trusted Authorization Core access context.
6
+ The host server supplies `correlationId` on commands; the application validates
7
+ and propagates it and never generates it.
8
+
9
+ The synchronized source candidate is `0.2.0` and includes changes beyond the
10
+ published `0.1.1` artifacts. SD-01 adds handling/handoff foundations
11
+ without model generation or a KB dependency; source review/tests determine
12
+ completion. Host adoption requires the later synchronized SD-06 release and
13
+ activation gates, not a source checkout or overwritten registry version.
14
+
15
+ SD-02's merged source adds opt-in `assistantTurns` and the
16
+ `AssistantTurnApplication` methods `scanAssistantTurnCandidates`,
17
+ `claimAssistantTurn`, `prepareAssistantTurnAttempt`, `completeAssistantTurn`,
18
+ and `finishAssistantTurnAttempt`. These keep bounded causal turn work beside
19
+ the ticket and expose fixed answer/escalation completion with a read-only
20
+ validation guard. They add no KB or provider dependency to this package;
21
+ the optional `@pegma/support-desk-ai` coordinator owns those integrations.
22
+ Lease/preparation/retry metadata do not bump Ticket revision, exact receipts recover
23
+ ambiguous commits, and request-person/takeover remain provider-independent.
24
+ See the [layout checkpoint](../../docs/COLLECTIONS.md#sd-02-assistant-turn-layout-checkpoint)
25
+ and [coordination guide](../../docs/ASSISTANT_COORDINATION.md). Current-head
26
+ tests/review and future verified SD-06 publication remain required.
27
+
28
+ SD-03's merged source adds opt-in `resolutionLearning` and fixed evidence,
29
+ work, exact staff review, withdrawal, and reconciliation operations. The
30
+ [resolution learning guide](../../docs/RESOLUTION_LEARNING.md) documents the
31
+ `support.learning.*` permissions, trusted evidence ports, 13-row human reserve
32
+ plus two withdrawal rows, and source retention requirements. The public AI
33
+ learning coordinator and KB delivery integration live in the optional AI
34
+ package. This application
35
+ package still has no KB or model-provider dependency.
36
+
37
+ SD-04's merged source adds optional `engineering` evidence/work services and
38
+ bounded `engineeringPolicy` configuration. Repository policy has its own
39
+ declared collection and atomic Audit/receipts. Engineering source/work records
40
+ share the ticket partition, with independent withdrawal and terminal-result
41
+ capacity reserved before external dispatch. The optional AI package supplies
42
+ model and GitHub coordination through host ports. See the
43
+ [engineering guide](../../docs/ENGINEERING_EXPORT.md). Host adoption still
44
+ requires the synchronized SD-06 release and its activation gates.
45
+
46
+ SD-05's merged source adds optional `engineeringFollowup` services
47
+ through `EngineeringFollowupApplication`. Signed allowlisted input and current
48
+ confirmed fix-to-product/build/deployment mapping establish bounded private
49
+ follow-up work; issue closure or a release tag alone does not. Independent
50
+ issue/deployment generations and captured source/destination revocation epochs
51
+ fence stale associations. Default four, hard maximum eight semantic work sets
52
+ share the existing ticket partition; delivered work never rearms.
53
+
54
+ `prepareEngineeringFollowupBundle` requires mode `prepare` or
55
+ `staff_reassessment`. `rejectEngineeringFollowupBundle` is a local staff review
56
+ with a reason, independent of provider/export availability. The combined
57
+ `approveAndPostEngineeringFollowupWebUpdate` commits one authenticated web
58
+ notice, quota, Audit/receipt, and delivered marker while preserving status,
59
+ handling, and first-staff-response facts. No worker or email sends a notice.
60
+ Five prepaid rows and one message slot cover bundle preparation and posting;
61
+ parent engineering withdrawal scrubs children using its existing privacy reserve.
62
+ Admission checks each actual stage: exact model manifests and their completion
63
+ states before paid work, then actual bundle/request counts and later retest/post
64
+ states at bundle preparation. Retest Audit/receipts use ordinary capacity.
65
+ `recoverEngineeringFollowupPreparation` returns only an opaque accepted result
66
+ bound to the current staff actor and exact recovery intent before live work or
67
+ proof reads, preventing duplicate preparation after a lost acknowledgement.
68
+ `retryEngineeringFollowupWork` explicitly readmits held/superseded or expired
69
+ draftless model work under fresh same-semantic proof, retaining its ID and
70
+ lifetime attempt cap and reserving five rows plus a slot. Its two Audit/receipt
71
+ rows use ordinary capacity. `abandonEngineeringFollowupWork` locally holds
72
+ undelivered work without provider/proof ports, spends its own two funded rows or
73
+ ordinary capacity, and releases the remaining tail/slot while preserving history.
74
+ Both use current review and queue authority; parent withdrawal remains the
75
+ privacy-erasure operation.
76
+ The optional coordinator additionally needs follow-up read and queue grants for
77
+ new private processing/review; direct base operations retain their purpose
78
+ permissions. Metadata-only receipt replay remains available under each base
79
+ operation's current grants. Zero-row stale/unchanged/unavailable observations
80
+ are live reevaluated reads, with no persisted command receipt.
81
+ See the [release follow-up guide](../../docs/ENGINEERING_FOLLOWUP.md) for trusted
82
+ ports, explicit retry/reassessment, private KB/retest handoffs, and capacity rules.
83
+ Current-head validation/review, publication, and host acceptance remain separate.
6
84
 
7
85
  Customer create uses `support.ticket.create`; list and read both use the
8
86
  documented `support.ticket.read.own` permission and then confirm authoritative
@@ -22,8 +100,101 @@ Staff services use the same application factory and ticket partition:
22
100
  | `resolveTicket` | `support.queue.read` + `support.ticket.manage` | → `resolved` (closed tickets must reopen first) |
23
101
  | `closeTicket` | `support.queue.read` + `support.ticket.manage` | → `closed` (resolved only) |
24
102
  | `reopenTicket` | `support.queue.read` + `support.ticket.manage` | resolved/closed → `waiting_on_support` |
103
+ | `setTags` | `support.queue.read` + `support.ticket.manage` | Replace staff tags; status, customer time, and mail unchanged |
25
104
  | `readTicketAuditHistory` | `support.audit.read` | Ordered Audit history for one ticket |
26
105
 
106
+ ### Optional handling and human controls (SD-01)
107
+
108
+ The factory's `assistantHandlingEnabled` defaults to false. Explicit trusted
109
+ web create with `initialHandling: "assistant"` requires both create and
110
+ `support.ticket.assistant.start`. Legacy omission remains human handling with
111
+ no rewrite. No model or KB is configured by enabling these source commands.
112
+ Turning the flag off refuses new assistant creation/replies. Exact committed
113
+ replays remain available after current command permissions and customer
114
+ ownership checks, without new rows or reservations; receipts do not restore
115
+ revoked access.
116
+
117
+ | Method | Permission and boundary |
118
+ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
119
+ | `readAssistantConversation` | `support.ticket.assistant.read`; service-only safe messages plus revision/handling/customer-trigger fences |
120
+ | `replyAsAssistant` | `support.ticket.assistant.reply`; exact revision/handling/trigger, attributed plain-text reply, no mail |
121
+ | `escalateToHuman` | `support.ticket.assistant.escalate`; exact fences plus bounded handoff work |
122
+ | `requestPerson` | `support.ticket.request_person.own` and ownership; deterministic human request with current customer-safe result |
123
+ | `takeOverTicket` | Queue read plus `support.ticket.take_over`; exact revision/handling fences and historical staff result |
124
+ | `confirmCustomerSuccess` | `support.ticket.confirm_success.own` and ownership/current visible-message proof; always resolves |
125
+ | `readCustomerSuccessConfirmations` | Queue read plus audit read; private text-free confirmation evidence |
126
+
127
+ `readHandoffWork(access, ticketId)` requires queue read and returns bounded
128
+ staff-only work DTOs with summary/guide IDs/transcript references, separate
129
+ from historical staff replay and customer/assistant results.
130
+
131
+ Assistant reads omit internal notes and requester identity. Their extra
132
+ revision/generation metadata is service-only. Assistant commits require the
133
+ latest visible message to remain the triggering customer message; new input
134
+ or human handling defeats stale work. Only a public staff reply establishes
135
+ `firstStaffRespondedAt`. Staff reopen enters human-pending for explicit
136
+ handling; fresh inbound mail and verified email into assistant chat use humans.
137
+
138
+ Customer confirmation supplies `lastSeenVisibleMessageId`, never internal
139
+ revision/generation or free-form evidence. It always resolves (no optional
140
+ flag), requires reopening closed work, and stores proof privately. Already
141
+ human active requests and repeated accepted resolved proof add no rows.
142
+ Assistant reply/escalation return only bounded `HandlingCommandResult` fields.
143
+ Ticket change, work/evidence, Audit, and replay receipt commit together;
144
+ handoff stores bounded summary/guide IDs and transcript references, not copied
145
+ transcripts, notes, or mail jobs.
146
+
147
+ Default `listStaffQueue` uses `handling: "human"`; `"assistant"`/`"all"`
148
+ are explicit supervision views. Quota `assistantManaged` reserves 12 ordinary
149
+ rows and one human message slot until the first staff response; controls keep
150
+ a four-row/one-message tail. Legacy quotas retain their limits. Repeated
151
+ no-ops avoid churn, but finite control cycles remain subject to named capacity.
152
+ See [host composition](../../docs/HOST_COMPOSITION.md#optional-handling-and-deterministic-controls-sd-01)
153
+ and [collections](../../docs/COLLECTIONS.md#sd-01-handling-and-handoff-layout-checkpoint)
154
+ for exact admission, replay, and source/release boundaries.
155
+
156
+ Handoff summaries are limited to 2,000 UTF-16 code units with
157
+ `SupportDeskLimitError` field `handoff_summary`. Complete serialized assistant
158
+ message/handoff records, including wrappers, are limited to 60,000 UTF-16
159
+ bytes with field `serialized_record`; refusal occurs before commit.
160
+
161
+ ### Optional lifecycle extras
162
+
163
+ `setTags` requires queue read plus `support.ticket.manage`. Configure
164
+ `allowedTags` (at most 32 raw entries, normalized, deduplicated, sorted) and
165
+ `maxTagsPerTicket` (default 8, maximum 32). Tags follow the category identifier
166
+ discipline after trimming and lowercasing; each raw label is at most 64
167
+ characters with no controls. `[]` clears tags. This command updates staff time
168
+ and revision only, with an atomic `support.ticket.tags_changed` audit action
169
+ and receipt, and no messages or mail. Queue query `tag` matches one label.
170
+
171
+ Pass optional `responseTargetPolicy: { computeTargets(context) }` to both
172
+ `createSupportDeskApplication` and `createInboundMailProcessor`. The host
173
+ returns canonical ISO `firstResponseDueAt` / `resolutionDueAt` fields as a
174
+ complete replacement on create, customer follow-up (web/email), and priority
175
+ changes. Omitted result fields clear targets; absent policy preserves them.
176
+ The frozen context is content-free and hooks must tolerate retries. First
177
+ public staff reply sets `firstStaffRespondedAt` once. `resolvedAt` describes
178
+ the current resolution cycle; reopen/reply clears it and re-resolution sets
179
+ it again. Calendars, business hours, and presence remain host responsibilities.
180
+
181
+ Queue queries select `target: "first_response" | "resolution"` (resolution
182
+ by default), `targetState: "overdue" | "due_soon"`, and the latter's required
183
+ `dueSoonMilliseconds` (0 to 30 days, rejected otherwise). Sort by `due_soonest` or `due_latest`,
184
+ with completed/missing targets last and ticket ID tie-breaking. All values
185
+ come from authoritative confirmation within existing scan budgets. Tags,
186
+ targets, and milestones stay out of customer DTOs and automatic customer mail.
187
+
188
+ Every staff mutation accepts optional `expectedRevision`. A mismatch fails
189
+ before ticket changes with `SupportDeskStaleRevisionError`, exposing only
190
+ `currentRevision` and `updatedAt` for HTTP 409. Omission retains existing
191
+ conflict retries. Replay detection precedes revision checking; new receipts
192
+ return the original result using a ticket snapshot and message revision cutoff.
193
+ Legacy receipts retain current-detail replay. Run queue repair after upgrade
194
+ to enrich old rows; no automatic target or historical milestone backfill runs.
195
+ See [host composition](../../docs/HOST_COMPOSITION.md#optional-lifecycle-extras-task-13)
196
+ for complete retry, lifecycle, and HTTP semantics.
197
+
27
198
  ### Staff queue projection
28
199
 
29
200
  `support-desk.queue-index.v1` holds one projection row per ticket (partition =
@@ -46,6 +217,12 @@ still terminal beyond the shared cutoff). Both workers require an explicit
46
217
  the application so projection, repair, and sweep share one cutoff. The
47
218
  projection is never ownership or permission evidence.
48
219
 
220
+ A valid positive older active hint can discover a newer active canonical
221
+ ticket, including a human handoff, without waiting for projection repair.
222
+ Malformed, nonpositive, future-revision, and inactive hints are refused;
223
+ canonical fields alone govern handling/filter/sort. Missing or inactive hints
224
+ can still cause a temporary repair gap.
225
+
49
226
  Staff reads return `StaffTicketView` (full `Ticket` and all `TicketMessage`
50
227
  rows). Mutations that return that view also require `support.queue.read` so a
51
228
  narrow write permission cannot bypass the staff-detail boundary. They do not
@@ -87,12 +264,12 @@ When a create includes a notification, Support Desk sets the
87
264
  lifecycle changes. Internal notes, assignment, and priority changes advance
88
265
  only staff-facing `updatedAt` (in core workflow events).
89
266
 
90
- Accepted-change history is exact `@pegma/audit@0.1.0` projected into the
267
+ Accepted-change history is exact `@pegma/audit@0.2.0` projected into the
91
268
  ticket partition with `defineAudit`. Customer create/reply and every staff
92
269
  mutation drop Audit transaction actions beside the state change; history is
93
270
  read through `readTicketAuditHistory` / Audit, not a private sorter. Domain
94
271
  `TicketEvent` remains pure workflow input and is not stored as a second audit
95
- shape. Authorization Core is exact `0.1.2`.
272
+ shape. Authorization Core is exact `0.4.0`.
96
273
 
97
274
  Customer and staff commands are snapshotted from own data properties exactly
98
275
  once before validation, idempotency fingerprinting, or persistence. Accessors
@@ -109,7 +286,7 @@ Outbound `Message-ID` values must be at most 254 ASCII characters with a
109
286
  dot-atom local part, a valid DNS domain, and no controls or malformed dots.
110
287
 
111
288
  Outbound state is the application projection of published exact
112
- `@pegma/mail@0.1.0`. Support Desk keeps its `delivery:*` physical record and
289
+ `@pegma/mail@0.1.1`. Support Desk keeps its `delivery:*` physical record and
113
290
  stores immutable template, subject, and `Message-ID` content on the causal
114
291
  message in the same transaction. The generic package owns claims, provider
115
292
  idempotency, submission generations, retry/reconciliation transitions,
@@ -129,10 +306,54 @@ Reply timestamps are sampled and validated on every transaction attempt, then
129
306
  clamped to the stored ticket's `updatedAt` so clock skew cannot move a
130
307
  conversation backward.
131
308
 
132
- Inbound processing remains a future phase, but its declared receipt collection
133
- is already hard-bounded to 256 hash slots per partition. Terminal receipt
134
- retention uses trusted processing time, a 30-day deduplication horizon, and
135
- version-conditional deletion; in-flight receipts are never swept.
309
+ ### Inbound mail
310
+
311
+ `createInboundMailProcessor({ store, clock, accountMatcher, routingPolicy,
312
+ notificationPolicy?, subjectMarkerPrefix?, supportAddresses?, ... })` returns
313
+ `processInboundEmail(input)`. The host calls it only after verifying the
314
+ provider event and normalizing bounded MIME into `InboundEmailInput` (safe
315
+ text, sender address, host-evaluated `senderAuthentication`, threading headers,
316
+ candidate reply token, and loop signals). There is no permission check: the
317
+ caller is a trusted worker, and the input has no principal, role, plan,
318
+ priority, or session field.
319
+
320
+ For a ticket with `requester.email`, every reply locator requires the
321
+ case-insensitive normalized `from` address to equal that email and a passing
322
+ sender result bound to the same `from`. DMARC requires aligned DKIM or aligned
323
+ SPF; `host_identity` represents an equivalent host-authenticated identity.
324
+ Missing, failed, unaligned, or differently bound results create a new
325
+ unverified related ticket and leave the named ticket unchanged. A ticket
326
+ without a requester email retains the opaque routing-token flow; headers and
327
+ subject markers alone remain insufficient. Sender authentication never selects
328
+ a principal or grants web access.
329
+
330
+ Processing reserves the `support-desk.inbound-receipts.v1` receipt with
331
+ `insertIfAbsent` before ticket work (256 hash slots per partition), suppresses
332
+ bounce and auto-reply loops, persists one routing decision on the receipt,
333
+ and then creates or replies in one ticket-partition transaction with an Audit
334
+ event (`system` actor `support-desk.inbound-email`), a command receipt, and an
335
+ optional notification. Retries and concurrent duplicates return the first
336
+ delivery's result and identifiers. Earlier receipts without a canonical replay
337
+ fingerprint recognize only their exact prior payload shapes, bind the current
338
+ fingerprint before continuing, and retain their original ticket-command
339
+ fingerprint. Matching order is reply token,
340
+ `In-Reply-To`/`References`, then subject marker, all through
341
+ `support-desk.thread-index.v1` key lookups confirmed against authoritative
342
+ records. A repeated inbound message's own `Message-ID` is checked for duplicate
343
+ delivery first; when it does not qualify, its ticket precedes the subject
344
+ marker as the related-ticket fallback. Unsafe or ambiguous matches create a new
345
+ unverified ticket with the staff-only `Ticket.relatedTicketId`. A unique account
346
+ match creates a `matched_email` ticket that stays invisible to customer web
347
+ services.
348
+
349
+ Notifications may carry an optional `replyRoutingToken` (22 to 128 URL-safe
350
+ characters) for the host to render into the reply address. The application
351
+ indexes it by SHA-256, with each notification `Message-ID` and every ticket
352
+ number, after commit. Schedule `repairThreadIndexPage` and
353
+ `sweepThreadIndexPage` with the same `threadIndexRetentionMilliseconds` as the
354
+ processor. Terminal receipt retention uses trusted processing time, a 30-day
355
+ deduplication horizon, and version-conditional deletion; in-flight receipts
356
+ are never swept.
136
357
 
137
358
  ## Host composition
138
359
 
@@ -0,0 +1,13 @@
1
+ import { type AssistantTurnRecord } from "./assistant-turn-records.js";
2
+ /**
3
+ * Reserve a constructive upper bound before a paid request can be prepared.
4
+ * Earlier bindings and metadata remain verbatim. Only the current attempt's
5
+ * accounting/metadata can change; a later preparation must reserve again.
6
+ *
7
+ * The old 8KB gap alone was insufficient: maximum legal processing metadata
8
+ * is 10,898 encoded bytes and finish stores it twice. Count complete reply,
9
+ * escalation, retry/supersession receipts and the largest replacement claim,
10
+ * using the same processing builder and encoder as actual writes.
11
+ */
12
+ export declare function maximumPostPreparationRecordBytes(job: AssistantTurnRecord): number;
13
+ //# sourceMappingURL=assistant-turn-capacity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-turn-capacity.d.ts","sourceRoot":"","sources":["../src/assistant-turn-capacity.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAC;AAmBrC;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,mBAAmB,GACvB,MAAM,CAoFR"}
@@ -0,0 +1,111 @@
1
+ import { assistantTurnProcessingState, encodedBytes, withoutAssistantTurnLease, } from "./assistant-turn-records.js";
2
+ // Each accepted UTF-16 code unit can occupy at most six JSON characters.
3
+ // Lone surrogates reach that bound and are allowed by the text validator.
4
+ const maximumText = "\ud800".repeat(200);
5
+ const maximumProcessing = Object.freeze({
6
+ provider: maximumText,
7
+ model: maximumText,
8
+ requestId: maximumText,
9
+ currency: maximumText,
10
+ failureCategory: "\ud800".repeat(80),
11
+ inputTokens: Number.MAX_SAFE_INTEGER,
12
+ outputTokens: Number.MAX_SAFE_INTEGER,
13
+ costMicros: Number.MAX_SAFE_INTEGER,
14
+ });
15
+ // Extended ISO years have the longest canonical Date.toISOString() shape.
16
+ const maximumTimestamp = "+100000-01-01T00:00:00.000Z";
17
+ const maximumFingerprint = "f".repeat(64);
18
+ /**
19
+ * Reserve a constructive upper bound before a paid request can be prepared.
20
+ * Earlier bindings and metadata remain verbatim. Only the current attempt's
21
+ * accounting/metadata can change; a later preparation must reserve again.
22
+ *
23
+ * The old 8KB gap alone was insufficient: maximum legal processing metadata
24
+ * is 10,898 encoded bytes and finish stores it twice. Count complete reply,
25
+ * escalation, retry/supersession receipts and the largest replacement claim,
26
+ * using the same processing builder and encoder as actual writes.
27
+ */
28
+ export function maximumPostPreparationRecordBytes(job) {
29
+ const base = withoutAssistantTurnLease(job);
30
+ const processed = assistantTurnProcessingState(base, maximumProcessing, {
31
+ attemptId: `${job.turnId}:${job.attempt}`,
32
+ accounting: "not_called", // Longest supported accounting value.
33
+ });
34
+ const key = { ticketId: job.ticketId, turnId: job.turnId };
35
+ const result = {
36
+ ticketId: job.ticketId,
37
+ revision: Number.MAX_SAFE_INTEGER,
38
+ handlingGeneration: Number.MAX_SAFE_INTEGER,
39
+ };
40
+ const finishReceipt = (finishResult) => ({
41
+ fingerprint: maximumFingerprint,
42
+ result: finishResult,
43
+ });
44
+ const retry = {
45
+ ...processed,
46
+ status: "retry",
47
+ nextAttemptAt: maximumTimestamp,
48
+ lastFinish: finishReceipt({
49
+ ...key,
50
+ outcome: "retry_scheduled",
51
+ nextAttemptAt: maximumTimestamp,
52
+ }),
53
+ };
54
+ const superseded = {
55
+ ...processed,
56
+ status: "superseded",
57
+ lastFinish: finishReceipt({ ...key, outcome: "superseded" }),
58
+ };
59
+ const escalated = {
60
+ ...processed,
61
+ status: "escalated",
62
+ terminalResult: result,
63
+ lastFinish: finishReceipt({ ...key, outcome: "escalated", result }),
64
+ };
65
+ const completed = {
66
+ ...assistantTurnProcessingState(base, maximumProcessing),
67
+ status: "completed",
68
+ terminalResult: { ...result, messageId: maximumText },
69
+ };
70
+ const directEscalation = {
71
+ ...assistantTurnProcessingState(base, maximumProcessing),
72
+ status: "escalated",
73
+ terminalResult: result,
74
+ };
75
+ // Retry/expired-lease recovery must still admit the next owner before that
76
+ // owner's preparation can perform its own size reservation. In particular,
77
+ // don't assume its workerId/claimId will be as short as the current owner's.
78
+ const nextAttempt = Math.min(job.maxAttempts, job.attempt + 1);
79
+ const attemptId = `${job.turnId}:${nextAttempt}`;
80
+ const claim = {
81
+ ...key,
82
+ workerId: maximumText,
83
+ claimId: maximumText,
84
+ claimGeneration: nextAttempt,
85
+ attempt: nextAttempt,
86
+ attemptId,
87
+ commandId: `assistant-complete:${attemptId}`,
88
+ correlationId: job.correlationId,
89
+ expectedRevision: Number.MAX_SAFE_INTEGER,
90
+ expectedHandlingGeneration: job.triggerHandlingGeneration,
91
+ triggerMessageId: job.triggerMessageId,
92
+ };
93
+ const { nextAttemptAt: _retryAt, ...afterRetry } = retry;
94
+ const replacement = {
95
+ ...afterRetry,
96
+ status: "claimed",
97
+ attempt: nextAttempt,
98
+ claimGeneration: nextAttempt,
99
+ claim,
100
+ leaseUntil: maximumTimestamp,
101
+ };
102
+ return Math.max(...[
103
+ retry,
104
+ superseded,
105
+ escalated,
106
+ completed,
107
+ directEscalation,
108
+ replacement,
109
+ ].map(encodedBytes));
110
+ }
111
+ //# sourceMappingURL=assistant-turn-capacity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-turn-capacity.js","sourceRoot":"","sources":["../src/assistant-turn-capacity.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,4BAA4B,EAC5B,YAAY,EACZ,yBAAyB,GAE1B,MAAM,6BAA6B,CAAC;AAErC,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACzC,MAAM,iBAAiB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACvE,QAAQ,EAAE,WAAW;IACrB,KAAK,EAAE,WAAW;IAClB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,WAAW;IACrB,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC,gBAAgB;IACpC,YAAY,EAAE,MAAM,CAAC,gBAAgB;IACrC,UAAU,EAAE,MAAM,CAAC,gBAAgB;CACpC,CAAC,CAAC;AACH,0EAA0E;AAC1E,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AACvD,MAAM,kBAAkB,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE1C;;;;;;;;;GASG;AACH,MAAM,UAAU,iCAAiC,CAC/C,GAAwB;IAExB,MAAM,IAAI,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,4BAA4B,CAAC,IAAI,EAAE,iBAAiB,EAAE;QACtE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE;QACzC,UAAU,EAAE,YAAY,EAAE,sCAAsC;KACjE,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3D,MAAM,MAAM,GAA0B;QACpC,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,MAAM,CAAC,gBAAgB;QACjC,kBAAkB,EAAE,MAAM,CAAC,gBAAgB;KAC5C,CAAC;IACF,MAAM,aAAa,GAAG,CAAC,YAAuC,EAAE,EAAE,CAAC,CAAC;QAClE,WAAW,EAAE,kBAAkB;QAC/B,MAAM,EAAE,YAAY;KACrB,CAAC,CAAC;IACH,MAAM,KAAK,GAAwB;QACjC,GAAG,SAAS;QACZ,MAAM,EAAE,OAAO;QACf,aAAa,EAAE,gBAAgB;QAC/B,UAAU,EAAE,aAAa,CAAC;YACxB,GAAG,GAAG;YACN,OAAO,EAAE,iBAAiB;YAC1B,aAAa,EAAE,gBAAgB;SAChC,CAAC;KACH,CAAC;IACF,MAAM,UAAU,GAAwB;QACtC,GAAG,SAAS;QACZ,MAAM,EAAE,YAAY;QACpB,UAAU,EAAE,aAAa,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;KAC7D,CAAC;IACF,MAAM,SAAS,GAAwB;QACrC,GAAG,SAAS;QACZ,MAAM,EAAE,WAAW;QACnB,cAAc,EAAE,MAAM;QACtB,UAAU,EAAE,aAAa,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;KACpE,CAAC;IACF,MAAM,SAAS,GAAwB;QACrC,GAAG,4BAA4B,CAAC,IAAI,EAAE,iBAAiB,CAAC;QACxD,MAAM,EAAE,WAAW;QACnB,cAAc,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE;KACtD,CAAC;IACF,MAAM,gBAAgB,GAAwB;QAC5C,GAAG,4BAA4B,CAAC,IAAI,EAAE,iBAAiB,CAAC;QACxD,MAAM,EAAE,WAAW;QACnB,cAAc,EAAE,MAAM;KACvB,CAAC;IACF,2EAA2E;IAC3E,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;IACjD,MAAM,KAAK,GAA4B;QACrC,GAAG,GAAG;QACN,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,WAAW;QACpB,eAAe,EAAE,WAAW;QAC5B,OAAO,EAAE,WAAW;QACpB,SAAS;QACT,SAAS,EAAE,sBAAsB,SAAS,EAAE;QAC5C,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,0BAA0B,EAAE,GAAG,CAAC,yBAAyB;QACzD,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;KACvC,CAAC;IACF,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAC;IACzD,MAAM,WAAW,GAAwB;QACvC,GAAG,UAAU;QACb,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,WAAW;QACpB,eAAe,EAAE,WAAW;QAC5B,KAAK;QACL,UAAU,EAAE,gBAAgB;KAC7B,CAAC;IACF,OAAO,IAAI,CAAC,GAAG,CACb,GAAG;QACD,KAAK;QACL,UAAU;QACV,SAAS;QACT,SAAS;QACT,gBAAgB;QAChB,WAAW;KACZ,CAAC,GAAG,CAAC,YAAY,CAAC,CACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,68 @@
1
+ import type { IsoTimestamp } from "@pegma/spine";
2
+ import type { EntityKey } from "@pegma/storage-core";
3
+ import type { Ticket, TicketMessage } from "@pegma/support-desk-contracts";
4
+ import type { HandlingCommandResult } from "./index.js";
5
+ import type { AssistantAttemptBinding, AssistantPreparedAttempt, AssistantTurnClaimFence, AssistantTurnAccounting, AssistantTurnFinishResult, AssistantTurnOptions, AssistantTurnProcessingMetadata } from "./assistant-turn-types.js";
6
+ export interface ResolvedAssistantTurnOptions {
7
+ readonly maxAttempts: number;
8
+ readonly maxTurnMilliseconds: number;
9
+ readonly maxLeaseMilliseconds: number;
10
+ }
11
+ /** One bounded row per causal message; attempts never append physical rows. */
12
+ export interface AssistantTurnRecord {
13
+ readonly kind: "assistant_turn";
14
+ readonly partition: string;
15
+ readonly id: string;
16
+ readonly ticketId: string;
17
+ readonly turnId: string;
18
+ readonly triggerMessageId: string;
19
+ readonly triggerRevision: number;
20
+ readonly triggerHandlingGeneration: number;
21
+ readonly correlationId: string;
22
+ readonly createdAt: IsoTimestamp;
23
+ readonly turnDeadline: IsoTimestamp;
24
+ readonly maxAttempts: number;
25
+ readonly status: "pending" | "claimed" | "retry" | "completed" | "escalated" | "superseded";
26
+ readonly attempt: number;
27
+ readonly claimGeneration: number;
28
+ readonly claim?: AssistantTurnClaimFence;
29
+ readonly leaseUntil?: IsoTimestamp;
30
+ readonly nextAttemptAt?: IsoTimestamp;
31
+ readonly preparedAttempts: readonly AssistantPreparedAttempt[];
32
+ readonly processing?: AssistantTurnProcessingMetadata;
33
+ readonly terminalResult?: HandlingCommandResult;
34
+ readonly lastFinish?: {
35
+ readonly fingerprint: string;
36
+ readonly result: AssistantTurnFinishResult;
37
+ };
38
+ }
39
+ export declare const maximumRecordBytes = 60000;
40
+ /** Initial ceiling; preparation also reserves the largest reachable later state. */
41
+ export declare const preparedRecordBytes = 52000;
42
+ export declare const maximumBindingBytes = 12000;
43
+ export declare function dataObject(value: unknown, name: string): Record<string, unknown>;
44
+ export declare function fields(value: unknown, name: string, required: readonly string[], optional?: readonly string[]): Record<string, unknown>;
45
+ export declare function dataArray(value: unknown, name: string, maximum: number): readonly unknown[];
46
+ export declare function text(value: unknown, name: string, maximum?: number): string;
47
+ export declare function integer(value: unknown, name: string, minimum?: number, maximum?: number): number;
48
+ export declare function timestamp(value: unknown, name: string): number;
49
+ export declare function encodedBytes(value: unknown): number;
50
+ export declare function canonical(value: unknown): string;
51
+ export declare function fingerprint(value: unknown): Promise<string>;
52
+ export declare function snapshot<T>(value: T): T;
53
+ export declare function resolveAssistantTurnOptions(input: AssistantTurnOptions | undefined): ResolvedAssistantTurnOptions | undefined;
54
+ export declare function assistantTurnKey(ticketId: string, turnId: string): EntityKey;
55
+ export declare function terminalTurn(record: AssistantTurnRecord): boolean;
56
+ export declare function withoutAssistantTurnLease(job: AssistantTurnRecord): AssistantTurnRecord;
57
+ /** Shared by real state changes and the constructive preparation size bound. */
58
+ export declare function assistantTurnProcessingState(job: AssistantTurnRecord, processing: AssistantTurnProcessingMetadata | undefined, accounting?: {
59
+ readonly attemptId: string;
60
+ readonly accounting: AssistantTurnAccounting;
61
+ }): AssistantTurnRecord;
62
+ export declare function createAssistantTurnRecord(ticket: Ticket, message: TicketMessage, correlationId: string, options: ResolvedAssistantTurnOptions): Promise<AssistantTurnRecord>;
63
+ export declare const assistantTurnFenceFields: readonly string[];
64
+ export declare function validateFence(input: unknown, extraRequired?: readonly string[], extraOptional?: readonly string[]): AssistantTurnClaimFence & Record<string, unknown>;
65
+ export declare function validateProcessing(input: unknown): AssistantTurnProcessingMetadata | undefined;
66
+ export declare function validateBinding(input: unknown): AssistantAttemptBinding;
67
+ export declare function assertAssistantTurnRecord(value: AssistantTurnRecord, physical?: EntityKey): void;
68
+ //# sourceMappingURL=assistant-turn-records.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-turn-records.d.ts","sourceRoot":"","sources":["../src/assistant-turn-records.ts"],"names":[],"mappings":"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"}