@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.
- package/README.md +228 -7
- package/dist/assistant-turn-capacity.d.ts +13 -0
- package/dist/assistant-turn-capacity.d.ts.map +1 -0
- package/dist/assistant-turn-capacity.js +111 -0
- package/dist/assistant-turn-capacity.js.map +1 -0
- package/dist/assistant-turn-records.d.ts +68 -0
- package/dist/assistant-turn-records.d.ts.map +1 -0
- package/dist/assistant-turn-records.js +418 -0
- package/dist/assistant-turn-records.js.map +1 -0
- package/dist/assistant-turn-types.d.ts +133 -0
- package/dist/assistant-turn-types.d.ts.map +1 -0
- package/dist/assistant-turn-types.js +2 -0
- package/dist/assistant-turn-types.js.map +1 -0
- package/dist/assistant-turns.d.ts +42 -0
- package/dist/assistant-turns.d.ts.map +1 -0
- package/dist/assistant-turns.js +640 -0
- package/dist/assistant-turns.js.map +1 -0
- package/dist/engineering-evidence.d.ts +20 -0
- package/dist/engineering-evidence.d.ts.map +1 -0
- package/dist/engineering-evidence.js +899 -0
- package/dist/engineering-evidence.js.map +1 -0
- package/dist/engineering-followup-internal.d.ts +45 -0
- package/dist/engineering-followup-internal.d.ts.map +1 -0
- package/dist/engineering-followup-internal.js +2 -0
- package/dist/engineering-followup-internal.js.map +1 -0
- package/dist/engineering-followup-records.d.ts +209 -0
- package/dist/engineering-followup-records.d.ts.map +1 -0
- package/dist/engineering-followup-records.js +1434 -0
- package/dist/engineering-followup-records.js.map +1 -0
- package/dist/engineering-followup-source.d.ts +168 -0
- package/dist/engineering-followup-source.d.ts.map +1 -0
- package/dist/engineering-followup-source.js +1144 -0
- package/dist/engineering-followup-source.js.map +1 -0
- package/dist/engineering-followup-types.d.ts +364 -0
- package/dist/engineering-followup-types.d.ts.map +1 -0
- package/dist/engineering-followup-types.js +2 -0
- package/dist/engineering-followup-types.js.map +1 -0
- package/dist/engineering-followup-work.d.ts +70 -0
- package/dist/engineering-followup-work.d.ts.map +1 -0
- package/dist/engineering-followup-work.js +1153 -0
- package/dist/engineering-followup-work.js.map +1 -0
- package/dist/engineering-internal.d.ts +38 -0
- package/dist/engineering-internal.d.ts.map +1 -0
- package/dist/engineering-internal.js +11 -0
- package/dist/engineering-internal.js.map +1 -0
- package/dist/engineering-policy.d.ts +47 -0
- package/dist/engineering-policy.d.ts.map +1 -0
- package/dist/engineering-policy.js +579 -0
- package/dist/engineering-policy.js.map +1 -0
- package/dist/engineering-reconciliation.d.ts +6 -0
- package/dist/engineering-reconciliation.d.ts.map +1 -0
- package/dist/engineering-reconciliation.js +464 -0
- package/dist/engineering-reconciliation.js.map +1 -0
- package/dist/engineering-records.d.ts +227 -0
- package/dist/engineering-records.d.ts.map +1 -0
- package/dist/engineering-records.js +1272 -0
- package/dist/engineering-records.js.map +1 -0
- package/dist/engineering-types.d.ts +505 -0
- package/dist/engineering-types.d.ts.map +1 -0
- package/dist/engineering-types.js +2 -0
- package/dist/engineering-types.js.map +1 -0
- package/dist/engineering-work.d.ts +32 -0
- package/dist/engineering-work.d.ts.map +1 -0
- package/dist/engineering-work.js +1757 -0
- package/dist/engineering-work.js.map +1 -0
- package/dist/index.d.ts +609 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3568 -204
- package/dist/index.js.map +1 -1
- package/dist/resolution-learning-records.d.ts +154 -0
- package/dist/resolution-learning-records.d.ts.map +1 -0
- package/dist/resolution-learning-records.js +657 -0
- package/dist/resolution-learning-records.js.map +1 -0
- package/dist/resolution-learning-types.d.ts +356 -0
- package/dist/resolution-learning-types.d.ts.map +1 -0
- package/dist/resolution-learning-types.js +2 -0
- package/dist/resolution-learning-types.js.map +1 -0
- package/dist/resolution-learning-worker.d.ts +21 -0
- package/dist/resolution-learning-worker.d.ts.map +1 -0
- package/dist/resolution-learning-worker.js +1027 -0
- package/dist/resolution-learning-worker.js.map +1 -0
- package/dist/resolution-learning.d.ts +38 -0
- package/dist/resolution-learning.d.ts.map +1 -0
- package/dist/resolution-learning.js +860 -0
- package/dist/resolution-learning.js.map +1 -0
- 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.
|
|
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.
|
|
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.
|
|
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
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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":"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"}
|
|
@@ -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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"}
|