@pegma/support-desk-application 0.2.4 → 0.2.5
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 +10 -7
- package/dist/attachments.d.ts +57 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +91 -0
- package/dist/attachments.js.map +1 -0
- package/dist/index.d.ts +80 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +855 -41
- package/dist/index.js.map +1 -1
- package/dist/resolution-learning-records.d.ts +2 -0
- package/dist/resolution-learning-records.d.ts.map +1 -1
- package/dist/resolution-learning-records.js +7 -0
- package/dist/resolution-learning-records.js.map +1 -1
- package/dist/resolution-learning-review-commit.d.ts +18 -0
- package/dist/resolution-learning-review-commit.d.ts.map +1 -0
- package/dist/resolution-learning-review-commit.js +199 -0
- package/dist/resolution-learning-review-commit.js.map +1 -0
- package/dist/resolution-learning-review-identity.d.ts +28 -0
- package/dist/resolution-learning-review-identity.d.ts.map +1 -0
- package/dist/resolution-learning-review-identity.js +110 -0
- package/dist/resolution-learning-review-identity.js.map +1 -0
- package/dist/resolution-learning-staged-records.d.ts +45 -0
- package/dist/resolution-learning-staged-records.d.ts.map +1 -0
- package/dist/resolution-learning-staged-records.js +193 -0
- package/dist/resolution-learning-staged-records.js.map +1 -0
- package/dist/resolution-learning-staged-types.d.ts +88 -0
- package/dist/resolution-learning-staged-types.d.ts.map +1 -0
- package/dist/resolution-learning-staged-types.js +2 -0
- package/dist/resolution-learning-staged-types.js.map +1 -0
- package/dist/resolution-learning-staged.d.ts +12 -0
- package/dist/resolution-learning-staged.d.ts.map +1 -0
- package/dist/resolution-learning-staged.js +585 -0
- package/dist/resolution-learning-staged.js.map +1 -0
- package/dist/resolution-learning-types.d.ts +6 -0
- package/dist/resolution-learning-types.d.ts.map +1 -1
- package/dist/resolution-learning-worker.d.ts.map +1 -1
- package/dist/resolution-learning-worker.js +58 -186
- package/dist/resolution-learning-worker.js.map +1 -1
- package/dist/resolution-learning.d.ts +3 -2
- package/dist/resolution-learning.d.ts.map +1 -1
- package/dist/resolution-learning.js +29 -2
- package/dist/resolution-learning.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
import { hasPermission } from "@pegma/authorization-core";
|
|
2
|
+
import { MAX_SCAN_PAGE_SIZE } from "@pegma/storage-core";
|
|
3
|
+
import { SupportDeskAuthorizationError, SupportDeskConflictError, SupportDeskLimitError, SupportDeskNotFoundError, supportPermissions, supportTicketAuditActions, } from "./index.js";
|
|
4
|
+
import { canonical, fields, fingerprint, integer, text, timestamp, } from "./assistant-turn-records.js";
|
|
5
|
+
import { safeLearningSnapshot as snapshot, resolutionLearningWorkKey, resolutionLearningReviewKey, } from "./resolution-learning-records.js";
|
|
6
|
+
import { assertResolutionLearningReviewAttempt, assertResolutionLearningReviewReservation, maximumResolutionLearningReviewAttemptBytes, resolutionLearningReviewAttemptKey, validateStagedReviewFence, validateStagedReviewIntent, validateStagedReviewProof, } from "./resolution-learning-staged-records.js";
|
|
7
|
+
import { resolutionLearningReviewIdentity, requireResolutionLearningReviewTicket, readResolutionLearningReviewSlot, resolutionLearningReviewReceiptValue, resolutionLearningReviewReceiptAction, } from "./resolution-learning-review-identity.js";
|
|
8
|
+
import { commitResolutionLearningReview } from "./resolution-learning-review-commit.js";
|
|
9
|
+
function permission(access, process = false) {
|
|
10
|
+
text(access.principalId, "principalId");
|
|
11
|
+
const names = process
|
|
12
|
+
? [supportPermissions.learningProcess]
|
|
13
|
+
: [supportPermissions.learningReview, supportPermissions.queueRead];
|
|
14
|
+
for (const name of names)
|
|
15
|
+
if (!hasPermission(access, name))
|
|
16
|
+
throw new SupportDeskAuthorizationError(name);
|
|
17
|
+
}
|
|
18
|
+
function unclaim(row) {
|
|
19
|
+
const { claim: _claim, leaseUntil: _lease, ...rest } = row;
|
|
20
|
+
return rest;
|
|
21
|
+
}
|
|
22
|
+
function check(row) {
|
|
23
|
+
assertResolutionLearningReviewAttempt(row, {
|
|
24
|
+
partition: row.partition,
|
|
25
|
+
id: row.id,
|
|
26
|
+
});
|
|
27
|
+
if (maximumResolutionLearningReviewAttemptBytes(row) > 60_000)
|
|
28
|
+
throw new SupportDeskLimitError("serialized_record", 60_000);
|
|
29
|
+
}
|
|
30
|
+
function guardRequired(guard) {
|
|
31
|
+
if (typeof guard !== "function")
|
|
32
|
+
throw new TypeError("Staged review requires a current-authority proof guard");
|
|
33
|
+
}
|
|
34
|
+
async function checkedGuard(guard) {
|
|
35
|
+
const assertion = await guard();
|
|
36
|
+
return () => {
|
|
37
|
+
if (assertion !== undefined &&
|
|
38
|
+
(typeof assertion !== "function" || assertion() !== true))
|
|
39
|
+
throw new SupportDeskConflictError("Review guard refused commit");
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Every mutation performs one conditional transaction; uncertain/conflict callers resume in another invocation. */
|
|
43
|
+
export function createResolutionLearningStagedReviewServices(deps, load) {
|
|
44
|
+
const { records, clock, options } = deps;
|
|
45
|
+
const now = () => timestamp(clock.now(), "now");
|
|
46
|
+
async function at(ticketId, commandId) {
|
|
47
|
+
const value = await records.getVersioned(resolutionLearningReviewAttemptKey(ticketId, commandId));
|
|
48
|
+
if (value === null)
|
|
49
|
+
return null;
|
|
50
|
+
assertResolutionLearningReviewAttempt(value.value, {
|
|
51
|
+
partition: ticketId,
|
|
52
|
+
id: resolutionLearningReviewAttemptKey(ticketId, commandId).id,
|
|
53
|
+
});
|
|
54
|
+
return { value: value.value, version: value.version };
|
|
55
|
+
}
|
|
56
|
+
function owner(access, row) {
|
|
57
|
+
if (access.principalId !== row.reviewerId)
|
|
58
|
+
throw new SupportDeskAuthorizationError(supportPermissions.learningReview);
|
|
59
|
+
}
|
|
60
|
+
function exact(identity, row) {
|
|
61
|
+
if (identity.hash !== row.fingerprint)
|
|
62
|
+
throw new SupportDeskConflictError("Review command reused");
|
|
63
|
+
}
|
|
64
|
+
function held(row) {
|
|
65
|
+
return (row.state !== "pending" ||
|
|
66
|
+
timestamp(row.expiresAt, "expiresAt") <= now() ||
|
|
67
|
+
(row.phase === "commit" &&
|
|
68
|
+
(row.proof === undefined ||
|
|
69
|
+
timestamp(row.proof.validUntil, "proof.validUntil") <= now())));
|
|
70
|
+
}
|
|
71
|
+
function pending(row) {
|
|
72
|
+
return snapshot({
|
|
73
|
+
outcome: "pending",
|
|
74
|
+
ticketId: row.ticketId,
|
|
75
|
+
commandId: row.command.commandId,
|
|
76
|
+
phase: row.phase,
|
|
77
|
+
claimed: row.claim !== undefined &&
|
|
78
|
+
timestamp(row.leaseUntil, "leaseUntil") > now(),
|
|
79
|
+
held: held(row),
|
|
80
|
+
expiresAt: row.expiresAt,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function hint(row) {
|
|
84
|
+
return snapshot({
|
|
85
|
+
ticketId: row.ticketId,
|
|
86
|
+
commandId: row.command.commandId,
|
|
87
|
+
reviewerId: row.reviewerId,
|
|
88
|
+
phase: row.phase,
|
|
89
|
+
expiresAt: row.expiresAt,
|
|
90
|
+
...(row.leaseUntil === undefined ? {} : { leaseUntil: row.leaseUntil }),
|
|
91
|
+
held: held(row),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function live(row, fence, phase) {
|
|
95
|
+
validateStagedReviewFence(fence);
|
|
96
|
+
if (row.state !== "pending" ||
|
|
97
|
+
row.phase !== phase ||
|
|
98
|
+
row.claim === undefined ||
|
|
99
|
+
row.leaseUntil === undefined ||
|
|
100
|
+
canonical(row.claim) !== canonical(fence) ||
|
|
101
|
+
timestamp(row.leaseUntil, "leaseUntil") <= now() ||
|
|
102
|
+
timestamp(row.expiresAt, "expiresAt") <= now() ||
|
|
103
|
+
(phase === "commit" &&
|
|
104
|
+
(row.proof === undefined ||
|
|
105
|
+
timestamp(row.proof.validUntil, "proof.validUntil") <= now())))
|
|
106
|
+
throw new SupportDeskConflictError("Review claim or proof expired/changed");
|
|
107
|
+
}
|
|
108
|
+
async function retainedIdentity(row) {
|
|
109
|
+
const identity = await resolutionLearningReviewIdentity(row.command, row.reviewerId);
|
|
110
|
+
if (row.state === "pending" && identity.hash !== row.fingerprint)
|
|
111
|
+
throw new SupportDeskConflictError("Review attempt fingerprint differs");
|
|
112
|
+
// Privacy withdrawal may scrub reason text. Recovery uses its original
|
|
113
|
+
// retained fingerprint, never a new mutation reconstructed from redacted data.
|
|
114
|
+
return {
|
|
115
|
+
...identity,
|
|
116
|
+
hash: row.fingerprint,
|
|
117
|
+
cancellationHash: await fingerprint({
|
|
118
|
+
operation: "cancel_resolution_learning_review",
|
|
119
|
+
reviewFingerprint: row.fingerprint,
|
|
120
|
+
}),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function reviewSlot(identity) {
|
|
124
|
+
await requireResolutionLearningReviewTicket(records, identity);
|
|
125
|
+
return readResolutionLearningReviewSlot(records, identity);
|
|
126
|
+
}
|
|
127
|
+
async function currentWork(loaded, row) {
|
|
128
|
+
const work = await records.getVersioned(resolutionLearningWorkKey(row.ticketId, row.command.sourceGeneration));
|
|
129
|
+
if (work?.value.kind !== "resolution_learning_work" ||
|
|
130
|
+
loaded.source.value.state !== "eligible" ||
|
|
131
|
+
!["resolved", "closed"].includes(loaded.ticket.value.ticket.status) ||
|
|
132
|
+
loaded.ticket.value.ticket.resolvedAt !==
|
|
133
|
+
loaded.source.value.resolvedAt ||
|
|
134
|
+
loaded.source.value.sourceGeneration !== row.command.sourceGeneration ||
|
|
135
|
+
loaded.source.value.resolutionCycle !== work.value.resolutionCycle ||
|
|
136
|
+
loaded.source.value.sourceBindingHash !== work.value.sourceBindingHash ||
|
|
137
|
+
work.value.workGeneration !== row.command.expectedWorkGeneration ||
|
|
138
|
+
!loaded.source.value.destinations.some((entry) => entry.articleId === row.command.target.articleId))
|
|
139
|
+
throw new SupportDeskConflictError("Review source/work/target changed");
|
|
140
|
+
return work;
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
async admit(access, input, rawIntent, guard) {
|
|
144
|
+
permission(access);
|
|
145
|
+
guardRequired(guard);
|
|
146
|
+
const identity = await resolutionLearningReviewIdentity(input, access.principalId);
|
|
147
|
+
const intent = snapshot(rawIntent);
|
|
148
|
+
validateStagedReviewIntent(intent);
|
|
149
|
+
if (intent.reviewerId !== access.principalId ||
|
|
150
|
+
intent.ticketId !== identity.command.ticketId ||
|
|
151
|
+
intent.sourceGeneration !== identity.command.sourceGeneration ||
|
|
152
|
+
intent.expectedWorkGeneration !==
|
|
153
|
+
identity.command.expectedWorkGeneration ||
|
|
154
|
+
intent.policy.version !== identity.command.policyVersion ||
|
|
155
|
+
canonical(intent.target) !== canonical(identity.command.target) ||
|
|
156
|
+
identity.command.intentBinding !== (await fingerprint(intent)))
|
|
157
|
+
throw new SupportDeskConflictError("Review intent differs from command");
|
|
158
|
+
const slot = await reviewSlot(identity);
|
|
159
|
+
const prior = slot.receipt;
|
|
160
|
+
if (prior !== null)
|
|
161
|
+
return prior;
|
|
162
|
+
const previous = await at(identity.command.ticketId, identity.command.commandId);
|
|
163
|
+
if (previous !== null) {
|
|
164
|
+
owner(access, previous.value);
|
|
165
|
+
exact(identity, previous.value);
|
|
166
|
+
if (slot.reservation === null)
|
|
167
|
+
throw new SupportDeskConflictError("Review canonical receipt/reservation is unavailable");
|
|
168
|
+
return pending(previous.value);
|
|
169
|
+
}
|
|
170
|
+
if (slot.reservation !== null)
|
|
171
|
+
throw new SupportDeskConflictError("Review reservation has no retained attempt");
|
|
172
|
+
const row = {
|
|
173
|
+
kind: "resolution_learning_review_attempt",
|
|
174
|
+
partition: identity.command.ticketId,
|
|
175
|
+
id: resolutionLearningReviewAttemptKey(identity.command.ticketId, identity.command.commandId).id,
|
|
176
|
+
ticketId: identity.command.ticketId,
|
|
177
|
+
reviewerId: access.principalId,
|
|
178
|
+
command: identity.command,
|
|
179
|
+
intent,
|
|
180
|
+
fingerprint: identity.hash,
|
|
181
|
+
state: "pending",
|
|
182
|
+
phase: "proof",
|
|
183
|
+
claimGeneration: 0,
|
|
184
|
+
completionRows: 2,
|
|
185
|
+
createdAt: clock.now(),
|
|
186
|
+
expiresAt: intent.policy.validUntil,
|
|
187
|
+
};
|
|
188
|
+
check(row);
|
|
189
|
+
const loaded = await load(row.ticketId);
|
|
190
|
+
if (loaded.rows.filter((value) => value.kind === "resolution_learning_review_attempt").length >= options.maxStagedReviewAttempts)
|
|
191
|
+
throw new SupportDeskLimitError("staged_review_attempts", options.maxStagedReviewAttempts);
|
|
192
|
+
const work = await currentWork(loaded, row);
|
|
193
|
+
const bindingKey = await resolutionLearningReviewKey(loaded.source.value, identity.command.target, identity.command.policyVersion);
|
|
194
|
+
const existingBinding = await records.get(bindingKey);
|
|
195
|
+
if (existingBinding !== null &&
|
|
196
|
+
existingBinding.kind !== "resolution_learning_review")
|
|
197
|
+
throw new SupportDeskConflictError("Review binding key collision");
|
|
198
|
+
if (existingBinding === null &&
|
|
199
|
+
loaded.source.value.reviewBindingCount >= options.maxReviewBindings)
|
|
200
|
+
throw new SupportDeskLimitError("ticket_partition", deps.limits.maxRecordsPerTicket);
|
|
201
|
+
const reservation = {
|
|
202
|
+
kind: "resolution_learning_review_reservation",
|
|
203
|
+
partition: row.ticketId,
|
|
204
|
+
id: identity.key.id,
|
|
205
|
+
ticketId: row.ticketId,
|
|
206
|
+
commandId: row.command.commandId,
|
|
207
|
+
reviewerId: row.reviewerId,
|
|
208
|
+
fingerprint: row.fingerprint,
|
|
209
|
+
expiresAt: row.expiresAt,
|
|
210
|
+
};
|
|
211
|
+
assertResolutionLearningReviewReservation(reservation, identity.key);
|
|
212
|
+
// Attempt, admission Audit and canonical reservation plus two future rows.
|
|
213
|
+
deps.admission(loaded.ticket.value.ticket, loaded.rows, 5);
|
|
214
|
+
const assert = await checkedGuard(guard);
|
|
215
|
+
if (timestamp(intent.policy.verifiedAt, "verifiedAt") > now() ||
|
|
216
|
+
timestamp(row.expiresAt, "expiresAt") <= now())
|
|
217
|
+
throw new SupportDeskConflictError("Review intent expired");
|
|
218
|
+
assert();
|
|
219
|
+
if (!(await records.transact(row.ticketId, [
|
|
220
|
+
{
|
|
221
|
+
action: "putIfUnchanged",
|
|
222
|
+
version: loaded.ticket.version,
|
|
223
|
+
value: loaded.ticket.value,
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
action: "putIfUnchanged",
|
|
227
|
+
version: loaded.source.version,
|
|
228
|
+
value: loaded.source.value,
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
action: "putIfUnchanged",
|
|
232
|
+
version: work.version,
|
|
233
|
+
value: work.value,
|
|
234
|
+
},
|
|
235
|
+
{ action: "insert", value: row },
|
|
236
|
+
{ action: "insert", value: reservation },
|
|
237
|
+
deps.audit(identity.command, loaded.ticket.value.ticket, access.principalId, row.createdAt, supportTicketAuditActions.learningReviewRequested, "\u0000support.learning.review.requested:" +
|
|
238
|
+
identity.command.commandId),
|
|
239
|
+
])).committed)
|
|
240
|
+
throw new SupportDeskConflictError();
|
|
241
|
+
return pending(row);
|
|
242
|
+
},
|
|
243
|
+
async readStatus(access, input) {
|
|
244
|
+
permission(access);
|
|
245
|
+
const identity = await resolutionLearningReviewIdentity(input, access.principalId);
|
|
246
|
+
const slot = await reviewSlot(identity);
|
|
247
|
+
const prior = slot.receipt;
|
|
248
|
+
if (prior !== null)
|
|
249
|
+
return prior;
|
|
250
|
+
const stored = await at(identity.command.ticketId, identity.command.commandId);
|
|
251
|
+
if (stored === null) {
|
|
252
|
+
if (slot.reservation !== null)
|
|
253
|
+
throw new SupportDeskConflictError("Review reservation has no retained attempt");
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
owner(access, stored.value);
|
|
257
|
+
exact(identity, stored.value);
|
|
258
|
+
if (stored.value.state === "accepted" ||
|
|
259
|
+
stored.value.state === "cancelled")
|
|
260
|
+
throw new SupportDeskConflictError("Terminal review receipt is unavailable");
|
|
261
|
+
if (slot.reservation === null)
|
|
262
|
+
throw new SupportDeskConflictError("Review canonical receipt/reservation is unavailable");
|
|
263
|
+
return pending(stored.value);
|
|
264
|
+
},
|
|
265
|
+
async readPending(access, key) {
|
|
266
|
+
permission(access, true);
|
|
267
|
+
const value = fields(key, "review key", ["ticketId", "commandId"]);
|
|
268
|
+
const ticketId = value.ticketId;
|
|
269
|
+
const commandId = value.commandId;
|
|
270
|
+
resolutionLearningReviewAttemptKey(ticketId, commandId);
|
|
271
|
+
// Both exact keys are derived from the validated request, never decoded data.
|
|
272
|
+
// Observe every result; the same Store may coalesce these independent reads.
|
|
273
|
+
const [attemptRead, slotRead] = await Promise.allSettled([
|
|
274
|
+
at(ticketId, commandId),
|
|
275
|
+
records.getVersioned({
|
|
276
|
+
partition: ticketId,
|
|
277
|
+
id: `learning-command:${commandId}`,
|
|
278
|
+
}),
|
|
279
|
+
]);
|
|
280
|
+
if (attemptRead.status === "rejected")
|
|
281
|
+
throw attemptRead.reason;
|
|
282
|
+
if (slotRead.status === "rejected")
|
|
283
|
+
throw slotRead.reason;
|
|
284
|
+
const stored = attemptRead.value;
|
|
285
|
+
const canonical = slotRead.value;
|
|
286
|
+
if (stored === null) {
|
|
287
|
+
if (canonical?.value.kind !== "resolution_learning_review_reservation")
|
|
288
|
+
return null;
|
|
289
|
+
const reservation = canonical.value;
|
|
290
|
+
assertResolutionLearningReviewReservation(reservation, {
|
|
291
|
+
partition: ticketId,
|
|
292
|
+
id: `learning-command:${commandId}`,
|
|
293
|
+
});
|
|
294
|
+
return snapshot({
|
|
295
|
+
ticketId,
|
|
296
|
+
commandId,
|
|
297
|
+
reviewerId: reservation.reviewerId,
|
|
298
|
+
phase: "proof",
|
|
299
|
+
expiresAt: reservation.expiresAt,
|
|
300
|
+
held: true,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
const identity = await retainedIdentity(stored.value);
|
|
304
|
+
const receipt = resolutionLearningReviewReceiptValue(identity, canonical?.value ?? null);
|
|
305
|
+
if (receipt !== null)
|
|
306
|
+
return null;
|
|
307
|
+
const metadata = hint(stored.value);
|
|
308
|
+
// A retained terminal attempt without its canonical receipt is unknown,
|
|
309
|
+
// never authoritative absence and never permission to relabel acceptance.
|
|
310
|
+
return canonical === null
|
|
311
|
+
? snapshot({ ...metadata, held: true })
|
|
312
|
+
: metadata;
|
|
313
|
+
},
|
|
314
|
+
async scanPending(access, input) {
|
|
315
|
+
permission(access, true);
|
|
316
|
+
const bounds = fields(input, "review scan", ["limit"], ["cursor"]);
|
|
317
|
+
integer(bounds.limit, "limit", 1, MAX_SCAN_PAGE_SIZE);
|
|
318
|
+
if (bounds.cursor !== undefined)
|
|
319
|
+
text(bounds.cursor, "cursor", 20_000);
|
|
320
|
+
const page = await records.scan({
|
|
321
|
+
limit: bounds.limit,
|
|
322
|
+
...(bounds.cursor === undefined
|
|
323
|
+
? {}
|
|
324
|
+
: { cursor: bounds.cursor }),
|
|
325
|
+
});
|
|
326
|
+
const candidates = [];
|
|
327
|
+
for (const entry of page.records) {
|
|
328
|
+
if (entry.value.kind !== "resolution_learning_review_attempt")
|
|
329
|
+
continue;
|
|
330
|
+
assertResolutionLearningReviewAttempt(entry.value, entry.key);
|
|
331
|
+
if (entry.value.state !== "pending")
|
|
332
|
+
continue;
|
|
333
|
+
const value = hint(entry.value);
|
|
334
|
+
if (value !== null &&
|
|
335
|
+
!value.held &&
|
|
336
|
+
(value.leaseUntil === undefined ||
|
|
337
|
+
timestamp(value.leaseUntil, "leaseUntil") <= now()))
|
|
338
|
+
candidates.push(value);
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
candidates,
|
|
342
|
+
nextCursor: page.nextCursor,
|
|
343
|
+
physicalRows: page.records.length,
|
|
344
|
+
pages: 1,
|
|
345
|
+
};
|
|
346
|
+
},
|
|
347
|
+
async claim(access, input) {
|
|
348
|
+
permission(access);
|
|
349
|
+
const command = snapshot(fields(input, "claim review", [
|
|
350
|
+
"ticketId",
|
|
351
|
+
"commandId",
|
|
352
|
+
"workerId",
|
|
353
|
+
"claimId",
|
|
354
|
+
"leaseMilliseconds",
|
|
355
|
+
]));
|
|
356
|
+
for (const name of ["ticketId", "commandId", "workerId", "claimId"])
|
|
357
|
+
text(command[name], name);
|
|
358
|
+
const duration = integer(command.leaseMilliseconds, "leaseMilliseconds", 1, options.maxLeaseMilliseconds);
|
|
359
|
+
const stored = await at(command.ticketId, command.commandId);
|
|
360
|
+
if (stored === null)
|
|
361
|
+
return null;
|
|
362
|
+
const row = stored.value;
|
|
363
|
+
owner(access, row);
|
|
364
|
+
const identity = await retainedIdentity(row);
|
|
365
|
+
const slot = await reviewSlot(identity);
|
|
366
|
+
if (slot.receipt !== null)
|
|
367
|
+
return null;
|
|
368
|
+
if (slot.reservation === null)
|
|
369
|
+
throw new SupportDeskConflictError("Review canonical receipt/reservation is unavailable");
|
|
370
|
+
if (row.state !== "pending" ||
|
|
371
|
+
timestamp(row.expiresAt, "expiresAt") <= now() ||
|
|
372
|
+
(row.phase === "commit" &&
|
|
373
|
+
(row.proof === undefined ||
|
|
374
|
+
timestamp(row.proof.validUntil, "proof.validUntil") <= now())))
|
|
375
|
+
return null;
|
|
376
|
+
const result = (value) => snapshot({
|
|
377
|
+
fence: value.claim,
|
|
378
|
+
reviewerId: value.reviewerId,
|
|
379
|
+
command: value.command,
|
|
380
|
+
intent: value.intent,
|
|
381
|
+
phase: value.phase,
|
|
382
|
+
leaseUntil: value.leaseUntil,
|
|
383
|
+
expiresAt: value.expiresAt,
|
|
384
|
+
...(value.proof === undefined ? {} : { proof: value.proof }),
|
|
385
|
+
});
|
|
386
|
+
if (row.claim !== undefined &&
|
|
387
|
+
timestamp(row.leaseUntil, "leaseUntil") > now())
|
|
388
|
+
return row.claim.workerId === command.workerId &&
|
|
389
|
+
row.claim.claimId === command.claimId
|
|
390
|
+
? result(row)
|
|
391
|
+
: null;
|
|
392
|
+
const fence = {
|
|
393
|
+
ticketId: row.ticketId,
|
|
394
|
+
commandId: row.command.commandId,
|
|
395
|
+
workerId: command.workerId,
|
|
396
|
+
claimId: command.claimId,
|
|
397
|
+
claimGeneration: integer(row.claimGeneration + 1, "claimGeneration", 1),
|
|
398
|
+
};
|
|
399
|
+
const next = {
|
|
400
|
+
...row,
|
|
401
|
+
claimGeneration: fence.claimGeneration,
|
|
402
|
+
claim: fence,
|
|
403
|
+
leaseUntil: new Date(Math.min(now() + duration, timestamp(row.expiresAt, "expiresAt"), row.proof === undefined
|
|
404
|
+
? Infinity
|
|
405
|
+
: timestamp(row.proof.validUntil, "proof.validUntil"))).toISOString(),
|
|
406
|
+
};
|
|
407
|
+
check(next);
|
|
408
|
+
if (!(await records.transact(row.ticketId, [
|
|
409
|
+
{ action: "putIfUnchanged", version: stored.version, value: next },
|
|
410
|
+
{
|
|
411
|
+
action: "putIfUnchanged",
|
|
412
|
+
version: slot.reservation.version,
|
|
413
|
+
value: slot.reservation.value,
|
|
414
|
+
},
|
|
415
|
+
])).committed)
|
|
416
|
+
throw new SupportDeskConflictError();
|
|
417
|
+
return result(next);
|
|
418
|
+
},
|
|
419
|
+
async prepare(access, input, guard) {
|
|
420
|
+
permission(access);
|
|
421
|
+
guardRequired(guard);
|
|
422
|
+
const command = snapshot(fields(input, "prepare review", ["fence", "proof"]));
|
|
423
|
+
validateStagedReviewFence(command.fence);
|
|
424
|
+
validateStagedReviewProof(command.proof);
|
|
425
|
+
const fence = command.fence;
|
|
426
|
+
const proof = command.proof;
|
|
427
|
+
const stored = await at(fence.ticketId, fence.commandId);
|
|
428
|
+
if (stored === null)
|
|
429
|
+
throw new SupportDeskNotFoundError();
|
|
430
|
+
const row = stored.value;
|
|
431
|
+
owner(access, row);
|
|
432
|
+
const identity = await retainedIdentity(row);
|
|
433
|
+
const slot = await reviewSlot(identity);
|
|
434
|
+
const prior = slot.receipt;
|
|
435
|
+
if (prior !== null)
|
|
436
|
+
return prior;
|
|
437
|
+
if (slot.reservation === null)
|
|
438
|
+
throw new SupportDeskConflictError("Review canonical receipt/reservation is unavailable");
|
|
439
|
+
live(row, fence, "proof");
|
|
440
|
+
if (timestamp(proof.validUntil, "proof.validUntil") >
|
|
441
|
+
timestamp(row.expiresAt, "expiresAt"))
|
|
442
|
+
throw new SupportDeskConflictError("P1 proof exceeds original intent");
|
|
443
|
+
const loaded = await load(row.ticketId);
|
|
444
|
+
const work = await currentWork(loaded, row);
|
|
445
|
+
const next = {
|
|
446
|
+
...unclaim(row),
|
|
447
|
+
phase: "commit",
|
|
448
|
+
proof,
|
|
449
|
+
};
|
|
450
|
+
check(next);
|
|
451
|
+
const assert = await checkedGuard(guard);
|
|
452
|
+
live(row, fence, "proof");
|
|
453
|
+
if (timestamp(proof.validUntil, "proof.validUntil") <= now())
|
|
454
|
+
throw new SupportDeskConflictError("P1 proof expired");
|
|
455
|
+
assert();
|
|
456
|
+
if (!(await records.transact(row.ticketId, [
|
|
457
|
+
{
|
|
458
|
+
action: "putIfUnchanged",
|
|
459
|
+
version: loaded.ticket.version,
|
|
460
|
+
value: loaded.ticket.value,
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
action: "putIfUnchanged",
|
|
464
|
+
version: loaded.source.version,
|
|
465
|
+
value: loaded.source.value,
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
action: "putIfUnchanged",
|
|
469
|
+
version: work.version,
|
|
470
|
+
value: work.value,
|
|
471
|
+
},
|
|
472
|
+
{ action: "putIfUnchanged", version: stored.version, value: next },
|
|
473
|
+
{
|
|
474
|
+
action: "putIfUnchanged",
|
|
475
|
+
version: slot.reservation.version,
|
|
476
|
+
value: slot.reservation.value,
|
|
477
|
+
},
|
|
478
|
+
])).committed)
|
|
479
|
+
throw new SupportDeskConflictError();
|
|
480
|
+
return pending(next);
|
|
481
|
+
},
|
|
482
|
+
async complete(access, rawFence, guard) {
|
|
483
|
+
permission(access);
|
|
484
|
+
guardRequired(guard);
|
|
485
|
+
const fence = snapshot(rawFence);
|
|
486
|
+
validateStagedReviewFence(fence);
|
|
487
|
+
const stored = await at(fence.ticketId, fence.commandId);
|
|
488
|
+
if (stored === null)
|
|
489
|
+
throw new SupportDeskNotFoundError();
|
|
490
|
+
const row = stored.value;
|
|
491
|
+
owner(access, row);
|
|
492
|
+
const identity = await retainedIdentity(row);
|
|
493
|
+
const slot = await reviewSlot(identity);
|
|
494
|
+
const prior = slot.receipt;
|
|
495
|
+
if (prior !== null)
|
|
496
|
+
return prior;
|
|
497
|
+
if (slot.reservation === null)
|
|
498
|
+
throw new SupportDeskConflictError("Review canonical receipt/reservation is unavailable");
|
|
499
|
+
const next = {
|
|
500
|
+
...unclaim(row),
|
|
501
|
+
state: "accepted",
|
|
502
|
+
completionRows: 0,
|
|
503
|
+
};
|
|
504
|
+
check(next);
|
|
505
|
+
const result = await commitResolutionLearningReview(deps, load, access, row.command, guard, {
|
|
506
|
+
version: stored.version,
|
|
507
|
+
value: next,
|
|
508
|
+
ensure: () => live(row, fence, "commit"),
|
|
509
|
+
});
|
|
510
|
+
return { outcome: "accepted", result };
|
|
511
|
+
},
|
|
512
|
+
async cancel(access, input, guard) {
|
|
513
|
+
permission(access);
|
|
514
|
+
guardRequired(guard);
|
|
515
|
+
const identity = await resolutionLearningReviewIdentity(input, access.principalId);
|
|
516
|
+
const slot = await reviewSlot(identity);
|
|
517
|
+
const prior = slot.receipt;
|
|
518
|
+
if (prior !== null) {
|
|
519
|
+
(await checkedGuard(guard))();
|
|
520
|
+
return prior;
|
|
521
|
+
}
|
|
522
|
+
const stored = await at(identity.command.ticketId, identity.command.commandId);
|
|
523
|
+
if (stored !== null) {
|
|
524
|
+
owner(access, stored.value);
|
|
525
|
+
exact(identity, stored.value);
|
|
526
|
+
if (stored.value.state === "accepted" ||
|
|
527
|
+
stored.value.state === "cancelled" ||
|
|
528
|
+
slot.reservation === null)
|
|
529
|
+
throw new SupportDeskConflictError("Terminal review receipt is unavailable");
|
|
530
|
+
}
|
|
531
|
+
else if (slot.reservation !== null)
|
|
532
|
+
throw new SupportDeskConflictError("Review reservation has no retained attempt");
|
|
533
|
+
const loaded = await load(identity.command.ticketId);
|
|
534
|
+
const next = stored === null
|
|
535
|
+
? undefined
|
|
536
|
+
: { ...unclaim(stored.value), state: "cancelled", completionRows: 0 };
|
|
537
|
+
if (next !== undefined)
|
|
538
|
+
check(next);
|
|
539
|
+
deps.admission(loaded.ticket.value.ticket, next === undefined
|
|
540
|
+
? loaded.rows
|
|
541
|
+
: loaded.rows.map((row) => (row.id === next.id ? next : row)), slot.reservation === null ? 2 : 1);
|
|
542
|
+
const result = {
|
|
543
|
+
ticketId: loaded.source.value.ticketId,
|
|
544
|
+
sourceGeneration: loaded.source.value.sourceGeneration,
|
|
545
|
+
resolutionCycle: loaded.source.value.resolutionCycle,
|
|
546
|
+
state: loaded.source.value.state,
|
|
547
|
+
};
|
|
548
|
+
const audit = deps.audit(identity.command, loaded.ticket.value.ticket, access.principalId, clock.now(), "support.learning.review_cancelled");
|
|
549
|
+
const assert = await checkedGuard(guard);
|
|
550
|
+
assert();
|
|
551
|
+
if (!(await records.transact(identity.command.ticketId, [
|
|
552
|
+
{
|
|
553
|
+
action: "putIfUnchanged",
|
|
554
|
+
version: loaded.ticket.version,
|
|
555
|
+
value: loaded.ticket.value,
|
|
556
|
+
},
|
|
557
|
+
...(stored === null || next === undefined
|
|
558
|
+
? []
|
|
559
|
+
: [
|
|
560
|
+
{
|
|
561
|
+
action: "putIfUnchanged",
|
|
562
|
+
version: stored.version,
|
|
563
|
+
value: next,
|
|
564
|
+
},
|
|
565
|
+
]),
|
|
566
|
+
audit,
|
|
567
|
+
resolutionLearningReviewReceiptAction(slot, {
|
|
568
|
+
kind: "resolution_learning_receipt",
|
|
569
|
+
partition: identity.command.ticketId,
|
|
570
|
+
id: identity.key.id,
|
|
571
|
+
fingerprint: identity.cancellationHash,
|
|
572
|
+
result,
|
|
573
|
+
}),
|
|
574
|
+
])).committed)
|
|
575
|
+
throw new SupportDeskConflictError();
|
|
576
|
+
(await checkedGuard(guard))();
|
|
577
|
+
return {
|
|
578
|
+
outcome: "cancelled",
|
|
579
|
+
ticketId: identity.command.ticketId,
|
|
580
|
+
commandId: identity.command.commandId,
|
|
581
|
+
};
|
|
582
|
+
},
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
//# sourceMappingURL=resolution-learning-staged.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolution-learning-staged.js","sourceRoot":"","sources":["../src/resolution-learning-staged.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ResolutionLearningStagedReviewApplication } from "./resolution-learning-staged-types.js";
|
|
1
2
|
import type { AccessContext } from "@pegma/authorization-core";
|
|
2
3
|
import type { IsoTimestamp, PrincipalId } from "@pegma/spine";
|
|
3
4
|
import type { TicketId } from "@pegma/support-desk-contracts";
|
|
@@ -120,6 +121,10 @@ export interface ResolutionLearningChecksPort {
|
|
|
120
121
|
verify(receipt: string, binding: ResolutionLearningChecksBinding): Promise<VerifiedResolutionLearningChecks | null>;
|
|
121
122
|
}
|
|
122
123
|
export interface ResolutionLearningOptions {
|
|
124
|
+
/** Opt-in durable human-review commands. Inline review remains the default. */
|
|
125
|
+
readonly stagedReviews?: boolean;
|
|
126
|
+
/** Counts all retained pending and terminal attempts; preserves bounded privacy withdrawal. */
|
|
127
|
+
readonly maxStagedReviewAttempts?: number;
|
|
123
128
|
readonly enabled?: boolean;
|
|
124
129
|
readonly productContext?: ResolutionProductContextPort;
|
|
125
130
|
readonly testReceipts?: ResolutionTestReceiptPort;
|
|
@@ -334,6 +339,7 @@ export interface RecordResolutionLearningReconciliationCommand {
|
|
|
334
339
|
};
|
|
335
340
|
}
|
|
336
341
|
export interface ResolutionLearningApplication {
|
|
342
|
+
readonly stagedResolutionLearningReviews?: ResolutionLearningStagedReviewApplication;
|
|
337
343
|
enrollResolutionLearning(access: AccessContext, command: EnrollResolutionLearningCommand): Promise<ResolutionLearningSourceResult>;
|
|
338
344
|
submitResolutionEvidence(access: AccessContext, command: SubmitResolutionEvidenceCommand): Promise<ResolutionLearningSourceResult>;
|
|
339
345
|
readResolutionLearningSource(access: AccessContext, ticketId: TicketId): Promise<ResolutionLearningSourceRecord>;
|