@gitroll/tacitt-cli 0.1.0 → 0.3.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/dist/{agent-setup-B85GaVIz.mjs → agent-setup-CLXdKr2I.mjs} +2 -2
- package/dist/agent-setup-worker.mjs +5 -5
- package/dist/cli.mjs +165 -9
- package/dist/codex-title-worker.mjs +1 -1
- package/dist/configured-preview-worker.mjs +5 -5
- package/dist/configured-session-worker.mjs +25 -4
- package/dist/{frame-D1j9R8xX.mjs → frame-waS5FnN5.mjs} +1 -1
- package/dist/{heap-tfU61Ehy.mjs → heap-eO_uWpD1.mjs} +63 -9
- package/dist/inspection-worker.mjs +57 -0
- package/dist/job-rK-Ho9OD.mjs +613 -0
- package/dist/{locate-Bn32k2se.mjs → locate-U3-nkird.mjs} +29 -6
- package/dist/messages-D3m3bhva.mjs +40 -0
- package/dist/{model-7Nu7szNP.mjs → model-BBAnsFAx.mjs} +1 -1
- package/dist/operation-executor.mjs +3 -3
- package/dist/preview-worker.mjs +1 -1
- package/dist/privacy-validator.mjs +1 -1
- package/dist/{query-Da-KDbSV.mjs → query-DN99jiRc.mjs} +710 -630
- package/dist/{run-CCATsHS2.mjs → run-4G_CvdDj.mjs} +4 -4
- package/dist/session-process.mjs +6 -1
- package/dist/{src-CPPjOyHZ.mjs → src-B4R5XMEP.mjs} +621 -224
- package/dist/{src-BngGpFKd.mjs → src-CPbdnGrk.mjs} +130 -53
- package/dist/{src-DynBRDBc.mjs → src-qoLRvX-A.mjs} +34 -11
- package/dist/store-database-worker.mjs +1 -1
- package/dist/web/assets/index-BkuUI3Eu.js +67 -0
- package/dist/web/assets/index-Clg6Pfv_.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/skills/tacitt/SKILL.md +15 -11
- package/skills/tacitt/references/b-method.md +1 -1
- package/skills/tacitt/references/classification.md +3 -3
- package/skills/tacitt/references/commands.md +19 -14
- package/skills/tacitt/references/journey.md +17 -11
- package/skills/tacitt/references/parallel-review.md +3 -3
- package/skills/tacitt/references/send.md +5 -5
- package/skills/tacitt/scripts/INDEX.md +6 -2
- package/skills/tacitt/scripts/answer.mjs +29 -8
- package/skills/tacitt/scripts/journey-card-consolidation.d.mts +13 -4
- package/skills/tacitt/scripts/journey-card-consolidation.mjs +170 -21
- package/skills/tacitt/scripts/journey-card-values.d.mts +17 -0
- package/skills/tacitt/scripts/journey-card-values.mjs +116 -0
- package/skills/tacitt/scripts/journey-classification-progress.mjs +2 -1
- package/skills/tacitt/scripts/journey-classification-validation.mjs +49 -28
- package/skills/tacitt/scripts/journey-classification.mjs +6 -2
- package/skills/tacitt/scripts/journey-consolidation-submit.mjs +42 -5
- package/skills/tacitt/scripts/journey-consolidation.d.mts +5 -0
- package/skills/tacitt/scripts/journey-consolidation.mjs +4 -1
- package/skills/tacitt/scripts/journey-panel-host.d.mts +9 -0
- package/skills/tacitt/scripts/journey-panel-host.mjs +56 -0
- package/skills/tacitt/scripts/journey-state.d.mts +1 -0
- package/skills/tacitt/scripts/journey-state.mjs +38 -6
- package/skills/tacitt/scripts/journey-tasks.mjs +5 -3
- package/skills/tacitt/scripts/journey.d.mts +4 -0
- package/skills/tacitt/scripts/journey.mjs +249 -41
- package/skills/tacitt/scripts/privacy-validator.mjs +25 -6
- package/skills/tacitt/scripts/review-stream-client.mjs +1 -1
- package/skills/tacitt/scripts/review.mjs +24 -3
- package/dist/job--TceKk0l.mjs +0 -194
- package/dist/web/assets/index-CWQ05PFl.js +0 -67
- package/dist/web/assets/index-J-AWt_cW.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as bCountSchema, $n as scalarAfter, $t as fileIdentitySchema, A as bDuplicateMirror, B as bEvidenceReader, Bn as validatePlan, Bt as sessionPeriodSchema, C as validateBUnit, Ct as cardsSubmitSchema, D as uncoveredBObligations, Dn as entityDictionaryVersion, Dt as privacyResolveSchema, E as bLiterals, En as cleanupImplementationVersion, Et as packageConfirmActionSchema, Ft as termTypeInfo, G as subtractBRanges, Gn as detectStatic, H as codePointLength, Ht as ApplicationError, I as bIssue, It as termTypeSchema, J as bRetainedGroupSchema, Jt as reviewFamilies, Kt as familyNeedsReview, L as bOverlaps, Ln as validateProfile, Lt as termTypes, M as bLegacyBindings, Mt as reviewTermsResultSchema, N as bUnitFragments, Nt as termAssessmentSchema, O as indexBRanges, Ot as privacyTermKey, P as bAdoptedObligations, Pt as termOverrideValueSchema, Q as bAnchorSchema, Qt as sourceSnapshotId, R as unownedBObligations, Rn as orderProfile, Rt as deselectOutsidePeriod, S as validateBFields, St as cardsConfirmActionSchema, T as bLiteralTerms, Tt as emptyJourneyPrivacy, U as codePointSlice, Ut as UnfinishedJourneyError, V as bDigest, Vn as copyData, Vt as classificationTitleMaskSchema, W as createCodePointIndex, Wt as safeCode, X as bSessionDecisionSchema, Xn as createEntityMatcher, Xt as sourceKey, Y as bReviewSubmissionSchema, Yt as sourceGraph, Z as bTermSchema, Zt as observeSource, _ as semanticFindingSchema, _n as gapReasons, _t as hideConfirmSchema, a as reviewChunkSchema, at as journeyExceptionSchema, b as validateBReview, bn as staticDefaults, bt as journeyConfigurationSchema, c as textDigest, ct as journeyPreferenceScopeSchema, dt as nativeJourneySchema, en as inventorySchema, er as scalarBefore, et as bIdSchema, f as reviewAlignmentAuditSchema, ft as journeyGuidanceSchema, g as validateReviewAlignment, h as reviewFindingsDigest, hn as inspectionSemanticVersions, ht as journeyDescribeSchema, i as reviewBatchSchema, in as nativeSourceIdentitySchema, it as journeyDigestSchema, jt as reviewTermsInputSchema, l as validateReview, lt as journeyProjectTypeSchema, m as reviewAlignmentSchema, mn as currentDetectorVersion, mt as delegatedDecisionSchema, n as compileBFindings, nn as sourcePartSchema, nt as journeyAccessSchema, o as reviewDigest, ot as journeyIdSchema, p as reviewAlignmentInputSchema, pt as journeyInstructionInputSchema, q as bRepresentationSchema, qn as staticCategories, qt as familySelected, r as reviewBatchChunks, rt as journeyChoiceSchema, s as reviewSubmitSchema, st as journeyKindSchema, tr as defaultDetectionLimits, tt as bMethod, u as findingReferenceKey, ut as journeyWorkTypeSchema, vt as hidePlanInputSchema, w as bLiteralAdmitted, x as createBAnalysisUnits, xn as staticOptions, xt as cardAnswerActionSchema, y as validateBClassification, yn as createStaticProcessor, yt as hidePlanResourceSchema, z as bAnchorKey } from "./locate-
|
|
1
|
+
import { $ as bCountSchema, $n as scalarAfter, $t as fileIdentitySchema, A as bDuplicateMirror, B as bEvidenceReader, Bn as validatePlan, Bt as sessionPeriodSchema, C as validateBUnit, Ct as cardsSubmitSchema, D as uncoveredBObligations, Dn as entityDictionaryVersion, Dt as privacyResolveSchema, E as bLiterals, En as cleanupImplementationVersion, Et as packageConfirmActionSchema, Ft as termTypeInfo, G as subtractBRanges, Gn as detectStatic, H as codePointLength, Ht as ApplicationError, I as bIssue, It as termTypeSchema, J as bRetainedGroupSchema, Jt as reviewFamilies, Kt as familyNeedsReview, L as bOverlaps, Ln as validateProfile, Lt as termTypes, M as bLegacyBindings, Mt as reviewTermsResultSchema, N as bUnitFragments, Nt as termAssessmentSchema, O as indexBRanges, Ot as privacyTermKey, P as bAdoptedObligations, Pt as termOverrideValueSchema, Q as bAnchorSchema, Qt as sourceSnapshotId, R as unownedBObligations, Rn as orderProfile, Rt as deselectOutsidePeriod, S as validateBFields, St as cardsConfirmActionSchema, T as bLiteralTerms, Tt as emptyJourneyPrivacy, U as codePointSlice, Ut as UnfinishedJourneyError, V as bDigest, Vn as copyData, Vt as classificationTitleMaskSchema, W as createCodePointIndex, Wt as safeCode, X as bSessionDecisionSchema, Xn as createEntityMatcher, Xt as sourceKey, Y as bReviewSubmissionSchema, Yt as sourceGraph, Z as bTermSchema, Zt as observeSource, _ as semanticFindingSchema, _n as gapReasons, _t as hideConfirmSchema, a as reviewChunkSchema, at as journeyExceptionSchema, b as validateBReview, bn as staticDefaults, bt as journeyConfigurationSchema, c as textDigest, ct as journeyPreferenceScopeSchema, dt as nativeJourneySchema, en as inventorySchema, er as scalarBefore, et as bIdSchema, f as reviewAlignmentAuditSchema, ft as journeyGuidanceSchema, g as validateReviewAlignment, h as reviewFindingsDigest, hn as inspectionSemanticVersions, ht as journeyDescribeSchema, i as reviewBatchSchema, in as nativeSourceIdentitySchema, it as journeyDigestSchema, jt as reviewTermsInputSchema, l as validateReview, lt as journeyProjectTypeSchema, m as reviewAlignmentSchema, mn as currentDetectorVersion, mt as delegatedDecisionSchema, n as compileBFindings, nn as sourcePartSchema, nt as journeyAccessSchema, o as reviewDigest, ot as journeyIdSchema, p as reviewAlignmentInputSchema, pt as journeyInstructionInputSchema, q as bRepresentationSchema, qn as staticCategories, qt as familySelected, r as reviewBatchChunks, rt as journeyChoiceSchema, s as reviewSubmitSchema, st as journeyKindSchema, tr as defaultDetectionLimits, tt as bMethod, u as findingReferenceKey, ut as journeyWorkTypeSchema, vt as hidePlanInputSchema, w as bLiteralAdmitted, x as createBAnalysisUnits, xn as staticOptions, xt as cardAnswerActionSchema, y as validateBClassification, yn as createStaticProcessor, yt as hidePlanResourceSchema, z as bAnchorKey } from "./locate-U3-nkird.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { createHash, createHmac, createSecretKey, randomUUID } from "node:crypto";
|
|
4
4
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
@@ -1330,8 +1330,6 @@ function mergePrivacyTerms(state, incoming) {
|
|
|
1330
1330
|
return {
|
|
1331
1331
|
...state.privacy,
|
|
1332
1332
|
terms: [...terms.values()],
|
|
1333
|
-
cards: [],
|
|
1334
|
-
confirmedAnswersRevision: null,
|
|
1335
1333
|
packageApproval: null
|
|
1336
1334
|
};
|
|
1337
1335
|
}
|
|
@@ -1344,9 +1342,16 @@ function activePrivacyTerms(state) {
|
|
|
1344
1342
|
function hasCompleteWorkDescription(work) {
|
|
1345
1343
|
return work.placement === "placed" && !!work.description.trim() && work.classificationRecommendation !== null;
|
|
1346
1344
|
}
|
|
1347
|
-
/**
|
|
1345
|
+
/**
|
|
1346
|
+
* Dropped Works are not AI-read; a Work emptied by repartition has nothing left to read, and
|
|
1347
|
+
* roots classification has not grouped yet are read once they join a Work (E2).
|
|
1348
|
+
*/
|
|
1348
1349
|
function isSelectedWork(work) {
|
|
1349
|
-
return work.access !== "drop" && work.rootSessionIds.length > 0;
|
|
1350
|
+
return work.access !== "drop" && work.rootSessionIds.length > 0 && work.placement !== "classifying";
|
|
1351
|
+
}
|
|
1352
|
+
/** Classification published some Works and is still grouping the remaining roots (E2). */
|
|
1353
|
+
function isClassifying(state) {
|
|
1354
|
+
return state.works.some((work) => work.placement === "classifying");
|
|
1350
1355
|
}
|
|
1351
1356
|
function selectedWorks(state) {
|
|
1352
1357
|
return state.works.filter(isSelectedWork);
|
|
@@ -1365,7 +1370,7 @@ function hasCertifiedNoBatchReview(work, snapshotId) {
|
|
|
1365
1370
|
}
|
|
1366
1371
|
/** Reading completes over selected Works once the person has confirmed the scan scope. */
|
|
1367
1372
|
function isReadingComplete(state) {
|
|
1368
|
-
return state.scope.status === "confirmed" && state.works.length > 0 && selectedWorks(state).every((work) => work.status !== "pending" && work.status !== "blocked" && (work.totalBatches > 0 || hasCertifiedNoBatchReview(work, state.snapshotId)) && work.completedBatches === work.totalBatches);
|
|
1373
|
+
return state.scope.status === "confirmed" && state.works.length > 0 && !isClassifying(state) && selectedWorks(state).every((work) => work.status !== "pending" && work.status !== "blocked" && (work.totalBatches > 0 || hasCertifiedNoBatchReview(work, state.snapshotId)) && work.completedBatches === work.totalBatches);
|
|
1369
1374
|
}
|
|
1370
1375
|
/** Recompute completion after a selection or reading change without leaving a paused/send phase. */
|
|
1371
1376
|
function withReadingProgress(state) {
|
|
@@ -1379,12 +1384,12 @@ function withReadingProgress(state) {
|
|
|
1379
1384
|
}
|
|
1380
1385
|
//#endregion
|
|
1381
1386
|
//#region packages/application/src/journey/static-session.ts
|
|
1382
|
-
const count$
|
|
1387
|
+
const count$13 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
1383
1388
|
const staticFileSchema = z.object({
|
|
1384
1389
|
path: z.string().min(1),
|
|
1385
1390
|
identity: fileIdentitySchema,
|
|
1386
1391
|
sha256: journeyDigestSchema,
|
|
1387
|
-
byteLength: count$
|
|
1392
|
+
byteLength: count$13
|
|
1388
1393
|
}).strict();
|
|
1389
1394
|
/**
|
|
1390
1395
|
* Track B (ADR 0172): one admitted session of the private packaging base, with every built-in
|
|
@@ -1396,7 +1401,7 @@ const staticSessionResourceSchema = z.object({
|
|
|
1396
1401
|
kind: z.literal("static-session"),
|
|
1397
1402
|
journeyId: journeyIdSchema,
|
|
1398
1403
|
workId: journeyIdSchema,
|
|
1399
|
-
inputRevision: count$
|
|
1404
|
+
inputRevision: count$13.min(1),
|
|
1400
1405
|
snapshotId: journeyDigestSchema,
|
|
1401
1406
|
sessionId: z.string().min(1).max(128),
|
|
1402
1407
|
jobDigest: journeyDigestSchema,
|
|
@@ -1404,7 +1409,9 @@ const staticSessionResourceSchema = z.object({
|
|
|
1404
1409
|
result: staticFileSchema,
|
|
1405
1410
|
primary: staticFileSchema,
|
|
1406
1411
|
companion: staticFileSchema,
|
|
1407
|
-
masks: staticFileSchema
|
|
1412
|
+
masks: staticFileSchema,
|
|
1413
|
+
/** Model-facing image blocks this session's output leaves out; absent on older receipts. */
|
|
1414
|
+
imagesOmitted: count$13.optional()
|
|
1408
1415
|
}).strict();
|
|
1409
1416
|
const staticSessionId = (resource) => `${resource.workId}:${resource.inputRevision}:${resource.sessionId}`;
|
|
1410
1417
|
/** Binds one Work's complete static base to the exact session results it was sealed from. */
|
|
@@ -1473,7 +1480,7 @@ const journeyPropagateActionSchema = z.object({
|
|
|
1473
1480
|
}).strict();
|
|
1474
1481
|
//#endregion
|
|
1475
1482
|
//#region packages/application/src/journey/scope/model.ts
|
|
1476
|
-
const count$
|
|
1483
|
+
const count$12 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
1477
1484
|
const safeText = z.string().trim().min(1).max(240);
|
|
1478
1485
|
const journeyScopeConfirmActionSchema = z.object({ kind: z.literal("scope-confirm") }).strict();
|
|
1479
1486
|
const journeyWorkTypeActionSchema = z.object({
|
|
@@ -1489,7 +1496,7 @@ const journeyWorksAccessActionSchema = z.object({
|
|
|
1489
1496
|
/** Static-only Work facts for proposing project types and scan scope; no source bodies. */
|
|
1490
1497
|
const journeyCatalogQuerySchema = z.object({
|
|
1491
1498
|
journeyId: journeyIdSchema,
|
|
1492
|
-
after: count$
|
|
1499
|
+
after: count$12.default(0),
|
|
1493
1500
|
limit: z.number().int().min(1).max(100).default(50),
|
|
1494
1501
|
/** Bounded frozen root routing metadata for classification helpers. */
|
|
1495
1502
|
includeClassificationRouting: z.boolean().optional(),
|
|
@@ -1500,23 +1507,27 @@ const journeyCatalogQuerySchema = z.object({
|
|
|
1500
1507
|
path: ["includeProjectEvidence"]
|
|
1501
1508
|
});
|
|
1502
1509
|
const workspaceKinds = z.object({
|
|
1503
|
-
checkout: count$
|
|
1504
|
-
worktree: count$
|
|
1505
|
-
folder: count$
|
|
1506
|
-
scratch: count$
|
|
1507
|
-
temp: count$
|
|
1508
|
-
home: count$
|
|
1509
|
-
unresolved: count$
|
|
1510
|
+
checkout: count$12,
|
|
1511
|
+
worktree: count$12,
|
|
1512
|
+
folder: count$12,
|
|
1513
|
+
scratch: count$12,
|
|
1514
|
+
temp: count$12,
|
|
1515
|
+
home: count$12,
|
|
1516
|
+
unresolved: count$12
|
|
1510
1517
|
}).strict();
|
|
1511
1518
|
const day = z.string().regex(/^\d{4}-\d{2}-\d{2}$/u);
|
|
1512
1519
|
const journeyCatalogWorkSchema = z.object({
|
|
1513
1520
|
id: journeyIdSchema,
|
|
1514
1521
|
projectName: safeText,
|
|
1515
|
-
placement: z.enum([
|
|
1522
|
+
placement: z.enum([
|
|
1523
|
+
"placed",
|
|
1524
|
+
"unsorted",
|
|
1525
|
+
"classifying"
|
|
1526
|
+
]),
|
|
1516
1527
|
access: journeyAccessSchema,
|
|
1517
1528
|
projectType: journeyWorkTypeSchema.nullable(),
|
|
1518
|
-
roots: count$
|
|
1519
|
-
children: count$
|
|
1529
|
+
roots: count$12,
|
|
1530
|
+
children: count$12,
|
|
1520
1531
|
firstActivity: day.nullable(),
|
|
1521
1532
|
lastActivity: day.nullable(),
|
|
1522
1533
|
workspaces: workspaceKinds,
|
|
@@ -1530,7 +1541,7 @@ const classificationRootSchema = z.object({
|
|
|
1530
1541
|
workspaceKind: z.string().min(1).max(40),
|
|
1531
1542
|
harness: z.enum(["claude", "codex"]),
|
|
1532
1543
|
titleAvailable: z.boolean(),
|
|
1533
|
-
memberCount: count$
|
|
1544
|
+
memberCount: count$12,
|
|
1534
1545
|
titles: z.array(safeText).max(3),
|
|
1535
1546
|
projectEvidence: z.object({
|
|
1536
1547
|
status: z.enum([
|
|
@@ -1539,7 +1550,7 @@ const classificationRootSchema = z.object({
|
|
|
1539
1550
|
"insufficient"
|
|
1540
1551
|
]),
|
|
1541
1552
|
incomplete: z.boolean(),
|
|
1542
|
-
ignored: count$
|
|
1553
|
+
ignored: count$12,
|
|
1543
1554
|
workspace: z.object({
|
|
1544
1555
|
kind: safeText,
|
|
1545
1556
|
name: safeText.nullable()
|
|
@@ -1547,10 +1558,10 @@ const classificationRootSchema = z.object({
|
|
|
1547
1558
|
repositories: z.array(z.object({
|
|
1548
1559
|
id: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
1549
1560
|
name: safeText,
|
|
1550
|
-
references: count$
|
|
1551
|
-
reads: count$
|
|
1552
|
-
changes: count$
|
|
1553
|
-
commands: count$
|
|
1561
|
+
references: count$12,
|
|
1562
|
+
reads: count$12,
|
|
1563
|
+
changes: count$12,
|
|
1564
|
+
commands: count$12
|
|
1554
1565
|
}).strict()).max(8)
|
|
1555
1566
|
}).strict().optional()
|
|
1556
1567
|
}).strict();
|
|
@@ -1575,11 +1586,11 @@ const classificationAssignmentSchema = z.object({
|
|
|
1575
1586
|
}).strict();
|
|
1576
1587
|
const journeyCatalogSchema = z.object({
|
|
1577
1588
|
journeyId: journeyIdSchema,
|
|
1578
|
-
revision: count$
|
|
1589
|
+
revision: count$12,
|
|
1579
1590
|
scope: z.enum(["pending", "confirmed"]),
|
|
1580
|
-
total: count$
|
|
1591
|
+
total: count$12,
|
|
1581
1592
|
works: z.array(journeyCatalogWorkSchema).max(100),
|
|
1582
|
-
next: count$
|
|
1593
|
+
next: count$12.nullable(),
|
|
1583
1594
|
classificationRouting: z.object({
|
|
1584
1595
|
knownProjects: z.array(classificationKnownProjectSchema),
|
|
1585
1596
|
unresolvedRoots: z.array(classificationRootSchema),
|
|
@@ -1589,7 +1600,7 @@ const journeyCatalogSchema = z.object({
|
|
|
1589
1600
|
/** Model project-type suggestions; explicit and delegated types are never overwritten. */
|
|
1590
1601
|
const journeyClassifySchema = z.object({
|
|
1591
1602
|
journeyId: journeyIdSchema,
|
|
1592
|
-
expectedRevision: count$
|
|
1603
|
+
expectedRevision: count$12,
|
|
1593
1604
|
idempotencyKey: journeyIdSchema,
|
|
1594
1605
|
items: z.array(z.object({
|
|
1595
1606
|
workId: journeyIdSchema,
|
|
@@ -1808,7 +1819,45 @@ function assertJourneyPrivacyReady(state, packaging = false) {
|
|
|
1808
1819
|
assertJourneyStaticReady(state);
|
|
1809
1820
|
if (packaging && state.privacy.packageApproval !== privacyDecisionDigest(state)) throw new ApplicationError("CONFIRMATION_REQUIRED");
|
|
1810
1821
|
}
|
|
1822
|
+
/** Card batches start once the scan scope is confirmed (D3); they need not wait for reading. */
|
|
1823
|
+
function assertCardsAllowed(state) {
|
|
1824
|
+
if (!state.consent || state.scope.status !== "confirmed") throw new ApplicationError("SCOPE_NOT_READY");
|
|
1825
|
+
}
|
|
1826
|
+
/**
|
|
1827
|
+
* D3: a batch covers only Pending values no card covers yet. Values added to an existing card
|
|
1828
|
+
* take its answer at once when the person already answered it.
|
|
1829
|
+
*/
|
|
1830
|
+
function appendDecisionCards(state, input) {
|
|
1831
|
+
assertCardsAllowed(state);
|
|
1832
|
+
const existing = new Set(state.privacy.cards.map((card) => card.id));
|
|
1833
|
+
const coveredBefore = new Set(state.privacy.cards.flatMap((card) => card.termKeys));
|
|
1834
|
+
const open = new Set(activePrivacyTerms(state).filter((term) => term.disposition === "pending").map(privacyTermKey).filter((key) => !coveredBefore.has(key)));
|
|
1835
|
+
const extend = input.extend ?? [];
|
|
1836
|
+
const covered = [...input.cards.flatMap((card) => card.termKeys), ...extend.flatMap((item) => item.termKeys)];
|
|
1837
|
+
if (!covered.length || state.privacy.cards.length + input.cards.length > 20 || new Set(input.cards.map((card) => card.id)).size !== input.cards.length || input.cards.some((card) => existing.has(card.id)) || new Set(extend.map((item) => item.cardId)).size !== extend.length || extend.some((item) => !existing.has(item.cardId)) || new Set(covered).size !== covered.length || covered.some((key) => !open.has(key))) throw new ApplicationError("INVALID_SELECTION");
|
|
1838
|
+
const additions = new Map(extend.map((item) => [item.cardId, item.termKeys]));
|
|
1839
|
+
return applyCardAnswers({
|
|
1840
|
+
...retirePrivacyArtifacts(state),
|
|
1841
|
+
privacy: {
|
|
1842
|
+
...state.privacy,
|
|
1843
|
+
cards: [...state.privacy.cards.map((card) => {
|
|
1844
|
+
const added = additions.get(card.id);
|
|
1845
|
+
return added ? {
|
|
1846
|
+
...card,
|
|
1847
|
+
termKeys: [...card.termKeys, ...added]
|
|
1848
|
+
} : card;
|
|
1849
|
+
}), ...input.cards.map((card) => ({
|
|
1850
|
+
...card,
|
|
1851
|
+
answer: null
|
|
1852
|
+
}))],
|
|
1853
|
+
confirmedAnswersRevision: input.cards.length ? null : state.privacy.confirmedAnswersRevision,
|
|
1854
|
+
packageApproval: null
|
|
1855
|
+
}
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1811
1858
|
function publishDecisionCards(state, input) {
|
|
1859
|
+
if (input.mode === "append") return appendDecisionCards(state, input);
|
|
1860
|
+
if (input.extend?.length) throw new ApplicationError("INVALID_SELECTION");
|
|
1812
1861
|
assertJourneyScanned(state);
|
|
1813
1862
|
const pending = new Set(activePrivacyTerms(state).filter((term) => term.disposition === "pending").map(privacyTermKey));
|
|
1814
1863
|
const covered = input.cards.flatMap((card) => card.termKeys);
|
|
@@ -1838,19 +1887,45 @@ function resolvePrivacyTerms(state, input) {
|
|
|
1838
1887
|
const resolutions = new Map(input.resolutions.map((term) => [privacyTermKey(term), term]));
|
|
1839
1888
|
const pending = new Set(activePrivacyTerms(state).filter((term) => term.disposition === "pending").map(privacyTermKey));
|
|
1840
1889
|
if (resolutions.size !== input.resolutions.length || [...resolutions.keys()].some((key) => !pending.has(key))) throw new ApplicationError("INVALID_SELECTION");
|
|
1841
|
-
|
|
1890
|
+
const terms = state.privacy.terms.map((term) => {
|
|
1842
1891
|
const resolution = resolutions.get(privacyTermKey(term));
|
|
1843
1892
|
return resolution ? {
|
|
1844
1893
|
...term,
|
|
1845
1894
|
...resolution
|
|
1846
1895
|
} : term;
|
|
1847
1896
|
});
|
|
1848
|
-
const
|
|
1897
|
+
for (const same of Map.groupBy(activePrivacyTerms({
|
|
1849
1898
|
...state,
|
|
1850
1899
|
privacy: {
|
|
1851
1900
|
...state.privacy,
|
|
1852
1901
|
terms
|
|
1853
1902
|
}
|
|
1903
|
+
}), (term) => term.value.normalize("NFC")).values()) if (same.some((term) => term.disposition === "pending") && input.resolutions.some((item) => item.value.normalize("NFC") === same[0]?.value.normalize("NFC"))) throw new ApplicationError("INVALID_SELECTION");
|
|
1904
|
+
return {
|
|
1905
|
+
...retirePrivacyArtifacts(state),
|
|
1906
|
+
privacy: {
|
|
1907
|
+
...state.privacy,
|
|
1908
|
+
terms: normalizeValues(state, terms),
|
|
1909
|
+
packageApproval: null
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
/** Keys of answered cards that took one option, leaving out values the person unticked. */
|
|
1914
|
+
function answeredKeys(state, optionId) {
|
|
1915
|
+
return new Set(state.privacy.cards.flatMap((card) => {
|
|
1916
|
+
if (!card.answer) return [];
|
|
1917
|
+
const excluded = new Set(card.answer.excludedTermKeys ?? []);
|
|
1918
|
+
return card.answer.optionId === optionId ? card.termKeys.filter((key) => !excluded.has(key)) : [...excluded];
|
|
1919
|
+
}));
|
|
1920
|
+
}
|
|
1921
|
+
/** One NFC value has one outcome across term types, cards and per-value rules. */
|
|
1922
|
+
function normalizeValues(state, input) {
|
|
1923
|
+
const active = activePrivacyTerms({
|
|
1924
|
+
...state,
|
|
1925
|
+
privacy: {
|
|
1926
|
+
...state.privacy,
|
|
1927
|
+
terms: input
|
|
1928
|
+
}
|
|
1854
1929
|
});
|
|
1855
1930
|
const overrides = /* @__PURE__ */ new Map();
|
|
1856
1931
|
for (const item of state.valueOverrides ?? []) {
|
|
@@ -1858,7 +1933,7 @@ function resolvePrivacyTerms(state, input) {
|
|
|
1858
1933
|
if (!overrides.has(value)) overrides.set(value, item);
|
|
1859
1934
|
}
|
|
1860
1935
|
const cardValues = (optionId) => {
|
|
1861
|
-
const keys =
|
|
1936
|
+
const keys = answeredKeys(state, optionId);
|
|
1862
1937
|
return new Set(state.privacy.terms.filter((term) => keys.has(privacyTermKey(term))).map((term) => term.value.normalize("NFC")));
|
|
1863
1938
|
};
|
|
1864
1939
|
const hideCardValues = cardValues("hide");
|
|
@@ -1866,7 +1941,6 @@ function resolvePrivacyTerms(state, input) {
|
|
|
1866
1941
|
const ownNames = workProjectNames(state);
|
|
1867
1942
|
const normalized = /* @__PURE__ */ new Map();
|
|
1868
1943
|
for (const same of Map.groupBy(active, (term) => term.value.normalize("NFC")).values()) {
|
|
1869
|
-
if (same.some((term) => term.disposition === "pending") && input.resolutions.some((item) => item.value.normalize("NFC") === same[0]?.value.normalize("NFC"))) throw new ApplicationError("INVALID_SELECTION");
|
|
1870
1944
|
if (same.some((term) => term.disposition === "pending")) continue;
|
|
1871
1945
|
const forcedHidden = same.some((term) => !termTypeInfo[term.type].asked);
|
|
1872
1946
|
const override = overrides.get(same[0]?.value.normalize("NFC") ?? "");
|
|
@@ -1879,51 +1953,79 @@ function resolvePrivacyTerms(state, input) {
|
|
|
1879
1953
|
reason: disposition === "hidden" && term.disposition !== "hidden" ? hideCard && !same.some((item) => item.disposition === "hidden") ? "A Hide card answer covering this value takes precedence over Keep." : "A Hidden judgment for this NFC keyword takes precedence across term types." : ownKeep && term.disposition !== "keep" ? OWN_PROJECT_KEEP_REASON : term.reason
|
|
1880
1954
|
});
|
|
1881
1955
|
}
|
|
1882
|
-
|
|
1956
|
+
return input.map((term) => {
|
|
1883
1957
|
const result = normalized.get(privacyTermKey(term));
|
|
1884
1958
|
return result ? {
|
|
1885
1959
|
...term,
|
|
1886
1960
|
...result
|
|
1887
1961
|
} : term;
|
|
1888
1962
|
});
|
|
1963
|
+
}
|
|
1964
|
+
/**
|
|
1965
|
+
* The CLI applies card answers itself (D3): Hide makes every covered value Hidden and Keep keeps
|
|
1966
|
+
* it, an unticked value takes the other option, then one value gets one outcome.
|
|
1967
|
+
*/
|
|
1968
|
+
function applyCardAnswers(state) {
|
|
1969
|
+
if (!state.privacy.cards.some((card) => card.answer)) return state;
|
|
1970
|
+
const hide = answeredKeys(state, "hide");
|
|
1971
|
+
const keep = answeredKeys(state, "keep");
|
|
1972
|
+
const terms = state.privacy.terms.map((term) => {
|
|
1973
|
+
const key = privacyTermKey(term);
|
|
1974
|
+
if (hide.has(key) && term.disposition !== "hidden") return {
|
|
1975
|
+
...term,
|
|
1976
|
+
disposition: "hidden",
|
|
1977
|
+
reason: "Hidden by your decision card answer."
|
|
1978
|
+
};
|
|
1979
|
+
if (keep.has(key) && !hide.has(key) && term.disposition !== "keep") return {
|
|
1980
|
+
...term,
|
|
1981
|
+
disposition: "keep",
|
|
1982
|
+
reason: "Kept by your decision card answer."
|
|
1983
|
+
};
|
|
1984
|
+
return term;
|
|
1985
|
+
});
|
|
1889
1986
|
return {
|
|
1890
|
-
...
|
|
1987
|
+
...state,
|
|
1891
1988
|
privacy: {
|
|
1892
1989
|
...state.privacy,
|
|
1893
|
-
terms,
|
|
1894
|
-
packageApproval: null
|
|
1990
|
+
terms: normalizeValues(state, terms)
|
|
1895
1991
|
}
|
|
1896
1992
|
};
|
|
1897
1993
|
}
|
|
1898
1994
|
function respondPrivacy(state, action, source) {
|
|
1899
1995
|
if (action.kind === "card-answer") {
|
|
1900
|
-
|
|
1996
|
+
assertCardsAllowed(state);
|
|
1997
|
+
if (state.phase === "sending" || state.phase === "completed") throw new ApplicationError("INVALID_TRANSITION");
|
|
1901
1998
|
const card = state.privacy.cards.find((item) => item.id === action.cardId);
|
|
1902
1999
|
const option = card?.options.find((item) => item.id === action.optionId);
|
|
1903
2000
|
if (!card || !option) throw new ApplicationError("UNKNOWN_ITEM");
|
|
2001
|
+
const excluded = action.excludedTermKeys ?? [];
|
|
1904
2002
|
const keys = new Set(card.termKeys);
|
|
1905
|
-
|
|
2003
|
+
if (new Set(excluded).size !== excluded.length || excluded.some((key) => !keys.has(key))) throw new ApplicationError("INVALID_SELECTION");
|
|
2004
|
+
const cards = state.privacy.cards.map((item) => item.id !== card.id ? item : {
|
|
2005
|
+
...item,
|
|
2006
|
+
answer: {
|
|
2007
|
+
optionId: option.id,
|
|
2008
|
+
rule: [option.rule, action.rule?.trim()].filter(Boolean).join("\n"),
|
|
2009
|
+
additionalRule: action.rule?.trim() ?? "",
|
|
2010
|
+
remember: action.remember,
|
|
2011
|
+
...excluded.length ? { excludedTermKeys: excluded } : {}
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
2014
|
+
const answersRevision = state.privacy.answersRevision + 1;
|
|
2015
|
+
return applyCardAnswers({
|
|
1906
2016
|
...retirePrivacyArtifacts(state),
|
|
1907
2017
|
privacy: {
|
|
1908
2018
|
...state.privacy,
|
|
1909
|
-
cards
|
|
1910
|
-
...item,
|
|
1911
|
-
answer: {
|
|
1912
|
-
optionId: option.id,
|
|
1913
|
-
rule: [option.rule, action.rule?.trim()].filter(Boolean).join("\n"),
|
|
1914
|
-
additionalRule: action.rule?.trim() ?? "",
|
|
1915
|
-
remember: action.remember
|
|
1916
|
-
}
|
|
1917
|
-
}),
|
|
2019
|
+
cards,
|
|
1918
2020
|
terms: state.privacy.terms.map((term) => keys.has(privacyTermKey(term)) ? {
|
|
1919
2021
|
...term,
|
|
1920
2022
|
disposition: "pending"
|
|
1921
2023
|
} : term),
|
|
1922
|
-
answersRevision
|
|
1923
|
-
confirmedAnswersRevision: null,
|
|
2024
|
+
answersRevision,
|
|
2025
|
+
confirmedAnswersRevision: cards.every((item) => item.answer) ? answersRevision : null,
|
|
1924
2026
|
packageApproval: null
|
|
1925
2027
|
}
|
|
1926
|
-
};
|
|
2028
|
+
});
|
|
1927
2029
|
}
|
|
1928
2030
|
if (action.kind === "cards-confirm") {
|
|
1929
2031
|
assertJourneyScanned(state);
|
|
@@ -1951,12 +2053,12 @@ function respondPrivacy(state, action, source) {
|
|
|
1951
2053
|
}
|
|
1952
2054
|
//#endregion
|
|
1953
2055
|
//#region packages/application/src/journey/scope/classification.ts
|
|
1954
|
-
const count$
|
|
2056
|
+
const count$11 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
1955
2057
|
const classificationCursorSchema = z.object({
|
|
1956
2058
|
snapshotId: journeyDigestSchema,
|
|
1957
|
-
inputRevision: count$
|
|
2059
|
+
inputRevision: count$11,
|
|
1958
2060
|
rootSessionId: z.string().min(1).max(128).optional(),
|
|
1959
|
-
partIndex: count$
|
|
2061
|
+
partIndex: count$11,
|
|
1960
2062
|
afterOrdinal: z.number().int().min(-1)
|
|
1961
2063
|
}).strict();
|
|
1962
2064
|
/** Private frozen content; reading it never records privacy-review coverage. */
|
|
@@ -1968,7 +2070,7 @@ const journeyClassificationReadSchema = z.object({
|
|
|
1968
2070
|
}).strict();
|
|
1969
2071
|
const journeyClassificationSubmitSchema = z.object({
|
|
1970
2072
|
journeyId: journeyIdSchema,
|
|
1971
|
-
expectedRevision: count$
|
|
2073
|
+
expectedRevision: count$11,
|
|
1972
2074
|
idempotencyKey: journeyIdSchema,
|
|
1973
2075
|
items: z.array(z.object({
|
|
1974
2076
|
projectName: z.string().trim().min(1).max(240),
|
|
@@ -1979,7 +2081,17 @@ const journeyClassificationSubmitSchema = z.object({
|
|
|
1979
2081
|
access: journeyAccessSchema,
|
|
1980
2082
|
reason: z.string().trim().min(1).max(200)
|
|
1981
2083
|
}).strict()
|
|
1982
|
-
}).strict()).min(1).max(1e3)
|
|
2084
|
+
}).strict()).min(1).max(1e3),
|
|
2085
|
+
/**
|
|
2086
|
+
* E2: roots classification has not grouped yet. They wait in one unread Work while the
|
|
2087
|
+
* listed Works are confirmed and read; a later submission without them completes it.
|
|
2088
|
+
*/
|
|
2089
|
+
pendingRootSessionIds: z.array(z.string().min(1).max(128)).max(1e4).optional(),
|
|
2090
|
+
/**
|
|
2091
|
+
* While roots are still being grouped, scan writes keep moving the revision: a later
|
|
2092
|
+
* submission is bound to the classification it replaces instead (E2).
|
|
2093
|
+
*/
|
|
2094
|
+
expectedClassificationRevision: count$11.optional()
|
|
1983
2095
|
}).strict();
|
|
1984
2096
|
const journeyClassificationSessionsSchema = z.object({
|
|
1985
2097
|
journeyId: journeyIdSchema,
|
|
@@ -1987,7 +2099,7 @@ const journeyClassificationSessionsSchema = z.object({
|
|
|
1987
2099
|
rootsOnly: z.boolean().optional(),
|
|
1988
2100
|
includeProjectEvidence: z.boolean().optional(),
|
|
1989
2101
|
projectEvidenceRootSessionIds: z.array(z.string().min(1).max(128)).min(1).max(100).optional(),
|
|
1990
|
-
after: count$
|
|
2102
|
+
after: count$11.default(0),
|
|
1991
2103
|
limit: z.number().int().min(1).max(100).default(50)
|
|
1992
2104
|
}).strict();
|
|
1993
2105
|
//#endregion
|
|
@@ -2392,12 +2504,12 @@ function verifiedScanGitSeeds(resource, snapshotId, roots) {
|
|
|
2392
2504
|
}
|
|
2393
2505
|
//#endregion
|
|
2394
2506
|
//#region packages/application/src/journey/scan-session.ts
|
|
2395
|
-
const count$
|
|
2507
|
+
const count$10 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
2396
2508
|
const scanFileSchema = z.object({
|
|
2397
2509
|
path: z.string().min(1),
|
|
2398
2510
|
identity: fileIdentitySchema,
|
|
2399
2511
|
sha256: journeyDigestSchema,
|
|
2400
|
-
byteLength: count$
|
|
2512
|
+
byteLength: count$10
|
|
2401
2513
|
}).strict();
|
|
2402
2514
|
/**
|
|
2403
2515
|
* Track A source-bound prose (`file`) with built-in static protection spans; no delivery archive
|
|
@@ -2413,13 +2525,13 @@ const sessionScanInputSchema = z.object({
|
|
|
2413
2525
|
native: nativeSourceIdentitySchema,
|
|
2414
2526
|
facts: z.object({
|
|
2415
2527
|
representation: z.enum(["jsonl", "jsonl.zst"]),
|
|
2416
|
-
byteLength: count$
|
|
2528
|
+
byteLength: count$10,
|
|
2417
2529
|
sha256: journeyDigestSchema
|
|
2418
2530
|
}).strict()
|
|
2419
2531
|
}).strict()),
|
|
2420
|
-
recordCount: count$
|
|
2421
|
-
fieldCount: count$
|
|
2422
|
-
inputUtf16: count$
|
|
2532
|
+
recordCount: count$10,
|
|
2533
|
+
fieldCount: count$10,
|
|
2534
|
+
inputUtf16: count$10,
|
|
2423
2535
|
mainReviewVerified: z.literal(true),
|
|
2424
2536
|
emptyReviewVerified: z.boolean()
|
|
2425
2537
|
}).strict().refine((input) => new Set(input.sources.map((source) => source.sourceId)).size === input.sources.length);
|
|
@@ -2427,7 +2539,7 @@ const scanSessionResourceSchema = z.object({
|
|
|
2427
2539
|
kind: z.literal("scan-session"),
|
|
2428
2540
|
journeyId: journeyIdSchema,
|
|
2429
2541
|
workId: journeyIdSchema,
|
|
2430
|
-
inputRevision: count$
|
|
2542
|
+
inputRevision: count$10.min(1),
|
|
2431
2543
|
snapshotId: journeyDigestSchema,
|
|
2432
2544
|
configurationDigest: journeyDigestSchema,
|
|
2433
2545
|
rootSessionId: z.string().min(1),
|
|
@@ -2446,7 +2558,7 @@ function scanPreparationDigest(resources) {
|
|
|
2446
2558
|
const scanBatchBinding = {
|
|
2447
2559
|
journeyId: journeyIdSchema,
|
|
2448
2560
|
workId: journeyIdSchema,
|
|
2449
|
-
inputRevision: count$
|
|
2561
|
+
inputRevision: count$10.min(1),
|
|
2450
2562
|
snapshotId: journeyDigestSchema,
|
|
2451
2563
|
configurationDigest: journeyDigestSchema
|
|
2452
2564
|
};
|
|
@@ -3461,7 +3573,7 @@ const reviewProgressSchema = z.array(z.object({
|
|
|
3461
3573
|
}).strict());
|
|
3462
3574
|
//#endregion
|
|
3463
3575
|
//#region packages/application/src/journey/review/session-schema.ts
|
|
3464
|
-
const count$
|
|
3576
|
+
const count$9 = z.number().int().nonnegative();
|
|
3465
3577
|
const sessionReviewInputSchema = z.object({
|
|
3466
3578
|
journeyId: journeyIdSchema,
|
|
3467
3579
|
workId: journeyIdSchema,
|
|
@@ -3482,7 +3594,7 @@ const sessionReviewResourceSchema = z.object({
|
|
|
3482
3594
|
workId: journeyIdSchema,
|
|
3483
3595
|
sessionId: z.string().min(1).max(128),
|
|
3484
3596
|
snapshotId: journeyDigestSchema,
|
|
3485
|
-
inputRevision: count$
|
|
3597
|
+
inputRevision: count$9.positive(),
|
|
3486
3598
|
requestHash: journeyDigestSchema,
|
|
3487
3599
|
bindingDigest: journeyDigestSchema,
|
|
3488
3600
|
at: z.iso.datetime(),
|
|
@@ -3496,8 +3608,8 @@ const sessionReviewResourceSchema = z.object({
|
|
|
3496
3608
|
issues: z.array(reviewIssueSchema),
|
|
3497
3609
|
requiresSemantic: z.boolean(),
|
|
3498
3610
|
usefulness: sessionUsefulnessSchema,
|
|
3499
|
-
totalCodePoints: count$
|
|
3500
|
-
reviewedCodePoints: count$
|
|
3611
|
+
totalCodePoints: count$9,
|
|
3612
|
+
reviewedCodePoints: count$9
|
|
3501
3613
|
}).strict();
|
|
3502
3614
|
const sessionRereadInputSchema = z.object({
|
|
3503
3615
|
journeyId: journeyIdSchema,
|
|
@@ -3506,8 +3618,8 @@ const sessionRereadInputSchema = z.object({
|
|
|
3506
3618
|
anchors: z.array(z.object({
|
|
3507
3619
|
fieldId: z.string().min(1),
|
|
3508
3620
|
fieldHash: journeyDigestSchema,
|
|
3509
|
-
start: count$
|
|
3510
|
-
end: count$
|
|
3621
|
+
start: count$9,
|
|
3622
|
+
end: count$9
|
|
3511
3623
|
}).strict()).min(1).max(128)
|
|
3512
3624
|
}).strict();
|
|
3513
3625
|
const sessionRereadResourceSchema = z.object({
|
|
@@ -3516,7 +3628,7 @@ const sessionRereadResourceSchema = z.object({
|
|
|
3516
3628
|
journeyId: journeyIdSchema,
|
|
3517
3629
|
workId: journeyIdSchema,
|
|
3518
3630
|
sessionId: z.string().min(1).max(128),
|
|
3519
|
-
inputRevision: count$
|
|
3631
|
+
inputRevision: count$9.positive(),
|
|
3520
3632
|
snapshotId: journeyDigestSchema,
|
|
3521
3633
|
sessionReviewId: journeyIdSchema,
|
|
3522
3634
|
bindingDigest: journeyDigestSchema,
|
|
@@ -3534,8 +3646,8 @@ const sessionReconcileInputSchema = z.object({
|
|
|
3534
3646
|
alignment: reviewAlignmentSchema
|
|
3535
3647
|
}).strict();
|
|
3536
3648
|
const retainedReviewAnchorSchema = bAnchorSchema.extend({
|
|
3537
|
-
utf16Start: count$
|
|
3538
|
-
utf16End: count$
|
|
3649
|
+
utf16Start: count$9,
|
|
3650
|
+
utf16End: count$9,
|
|
3539
3651
|
owned: z.boolean()
|
|
3540
3652
|
}).strict();
|
|
3541
3653
|
const sessionOverlaySchema = z.object({
|
|
@@ -3549,7 +3661,7 @@ const sessionReconciliationResourceSchema = z.object({
|
|
|
3549
3661
|
journeyId: journeyIdSchema,
|
|
3550
3662
|
workId: journeyIdSchema,
|
|
3551
3663
|
sessionId: z.string().min(1).max(128),
|
|
3552
|
-
inputRevision: count$
|
|
3664
|
+
inputRevision: count$9.positive(),
|
|
3553
3665
|
snapshotId: journeyDigestSchema,
|
|
3554
3666
|
sessionReviewId: journeyIdSchema,
|
|
3555
3667
|
bindingDigest: journeyDigestSchema,
|
|
@@ -3577,8 +3689,8 @@ const sessionReviewQuerySchema = z.object({
|
|
|
3577
3689
|
workId: journeyIdSchema.optional(),
|
|
3578
3690
|
sessionId: z.string().min(1).max(128).optional(),
|
|
3579
3691
|
sessionReviewId: journeyIdSchema.optional(),
|
|
3580
|
-
afterHit: count$
|
|
3581
|
-
limit: count$
|
|
3692
|
+
afterHit: count$9.default(0),
|
|
3693
|
+
limit: count$9.positive().max(500).default(100)
|
|
3582
3694
|
}).strict();
|
|
3583
3695
|
const sessionReviewStatusSchema = z.object({
|
|
3584
3696
|
complete: z.boolean(),
|
|
@@ -3594,8 +3706,8 @@ const sessionReviewStatusSchema = z.object({
|
|
|
3594
3706
|
requiresHumanDecision: z.boolean(),
|
|
3595
3707
|
requiresSemantic: z.boolean(),
|
|
3596
3708
|
issues: z.array(reviewIssueSchema),
|
|
3597
|
-
totalCodePoints: count$
|
|
3598
|
-
reviewedCodePoints: count$
|
|
3709
|
+
totalCodePoints: count$9,
|
|
3710
|
+
reviewedCodePoints: count$9,
|
|
3599
3711
|
reconciliationId: journeyIdSchema.nullable(),
|
|
3600
3712
|
/** ADR 0086: a read unit of the session suggests excluding it; advice, never a gate. */
|
|
3601
3713
|
suggestExclude: z.boolean(),
|
|
@@ -3603,8 +3715,8 @@ const sessionReviewStatusSchema = z.object({
|
|
|
3603
3715
|
reason: z.string().min(1).max(2e3).nullable()
|
|
3604
3716
|
}).strict()),
|
|
3605
3717
|
hits: z.array(sessionReviewHitSchema),
|
|
3606
|
-
nextHit: count$
|
|
3607
|
-
totalHits: count$
|
|
3718
|
+
nextHit: count$9.nullable(),
|
|
3719
|
+
totalHits: count$9
|
|
3608
3720
|
}).strict();
|
|
3609
3721
|
const sessionReviewResultSchema = z.object({
|
|
3610
3722
|
preparation: sessionReviewResourceSchema,
|
|
@@ -3688,13 +3800,13 @@ const metadataFieldsSchema = z.object({
|
|
|
3688
3800
|
}).strict();
|
|
3689
3801
|
//#endregion
|
|
3690
3802
|
//#region packages/application/src/journey/placement/routing-schema.ts
|
|
3691
|
-
const count$
|
|
3803
|
+
const count$8 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
3692
3804
|
const bucket = z.object({
|
|
3693
3805
|
complete: z.boolean(),
|
|
3694
|
-
total: count$
|
|
3806
|
+
total: count$8,
|
|
3695
3807
|
repositories: z.array(z.object({
|
|
3696
3808
|
id: z.string().min(1),
|
|
3697
|
-
count: count$
|
|
3809
|
+
count: count$8.min(1)
|
|
3698
3810
|
}).strict())
|
|
3699
3811
|
}).strict();
|
|
3700
3812
|
const placementSignalsSchema = z.object({
|
|
@@ -3712,8 +3824,8 @@ const cheapPlacementSchema = z.object({
|
|
|
3712
3824
|
"name"
|
|
3713
3825
|
]),
|
|
3714
3826
|
confidence: z.enum(["high", "medium"]),
|
|
3715
|
-
matched: count$
|
|
3716
|
-
total: count$
|
|
3827
|
+
matched: count$8.min(1),
|
|
3828
|
+
total: count$8.min(1),
|
|
3717
3829
|
otherRepositoryIds: z.array(z.string())
|
|
3718
3830
|
}).strict();
|
|
3719
3831
|
const sortingResourceSchema = z.object({
|
|
@@ -3734,26 +3846,26 @@ const sortingResourceSchema = z.object({
|
|
|
3734
3846
|
const sortingApplySchema = z.object({
|
|
3735
3847
|
journeyId: z.uuid(),
|
|
3736
3848
|
sessionId: z.string().min(1).max(128),
|
|
3737
|
-
expectedRevision: count$
|
|
3849
|
+
expectedRevision: count$8,
|
|
3738
3850
|
idempotencyKey: z.uuid()
|
|
3739
3851
|
}).strict();
|
|
3740
3852
|
/** Preparation moves identified failing roots of one pending Work into its blocked Work. */
|
|
3741
3853
|
const journeyIsolateSchema = z.object({
|
|
3742
3854
|
journeyId: z.uuid(),
|
|
3743
3855
|
workId: z.uuid(),
|
|
3744
|
-
inputRevision: count$
|
|
3856
|
+
inputRevision: count$8.min(1),
|
|
3745
3857
|
roots: z.array(z.object({
|
|
3746
3858
|
sessionId: z.string().min(1).max(128),
|
|
3747
3859
|
code: z.string().regex(/^[A-Z_]{3,80}$/u)
|
|
3748
3860
|
}).strict()).min(1).max(1e5),
|
|
3749
|
-
expectedRevision: count$
|
|
3861
|
+
expectedRevision: count$8,
|
|
3750
3862
|
idempotencyKey: z.uuid()
|
|
3751
3863
|
}).strict();
|
|
3752
3864
|
const placement = z.object({
|
|
3753
3865
|
workId: z.uuid(),
|
|
3754
3866
|
sessionId: z.string().min(1).max(128),
|
|
3755
|
-
inputRevision: count$
|
|
3756
|
-
throughEvent: count$
|
|
3867
|
+
inputRevision: count$8.min(1),
|
|
3868
|
+
throughEvent: count$8,
|
|
3757
3869
|
contextDigest: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
3758
3870
|
decision: z.enum([
|
|
3759
3871
|
"join",
|
|
@@ -3769,13 +3881,13 @@ const placement = z.object({
|
|
|
3769
3881
|
}).strict();
|
|
3770
3882
|
const journeyPlaceSchema = z.object({
|
|
3771
3883
|
journeyId: z.uuid(),
|
|
3772
|
-
expectedRevision: count$
|
|
3884
|
+
expectedRevision: count$8,
|
|
3773
3885
|
idempotencyKey: z.uuid(),
|
|
3774
3886
|
placements: z.array(placement).min(1).max(1e3)
|
|
3775
3887
|
}).strict();
|
|
3776
3888
|
//#endregion
|
|
3777
3889
|
//#region packages/application/src/journey/scope/progress.ts
|
|
3778
|
-
const count$
|
|
3890
|
+
const count$7 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
3779
3891
|
const ids = z.array(z.string().min(1).max(128)).max(1e5).refine((values) => new Set(values).size === values.length);
|
|
3780
3892
|
const journeyClassificationProgressSchema = z.object({
|
|
3781
3893
|
journeyId: journeyIdSchema,
|
|
@@ -3783,8 +3895,8 @@ const journeyClassificationProgressSchema = z.object({
|
|
|
3783
3895
|
id: z.literal("current"),
|
|
3784
3896
|
snapshotId: journeyDigestSchema,
|
|
3785
3897
|
inputFingerprint: journeyDigestSchema,
|
|
3786
|
-
baselineRevision: count$
|
|
3787
|
-
proposalRevision: count$
|
|
3898
|
+
baselineRevision: count$7,
|
|
3899
|
+
proposalRevision: count$7.nullable(),
|
|
3788
3900
|
stage: z.enum(["classification", "proposal"]),
|
|
3789
3901
|
status: z.enum([
|
|
3790
3902
|
"running",
|
|
@@ -3794,7 +3906,7 @@ const journeyClassificationProgressSchema = z.object({
|
|
|
3794
3906
|
]),
|
|
3795
3907
|
startedAt: z.iso.datetime(),
|
|
3796
3908
|
updatedAt: z.iso.datetime(),
|
|
3797
|
-
elapsedMs: count$
|
|
3909
|
+
elapsedMs: count$7,
|
|
3798
3910
|
rootIds: ids,
|
|
3799
3911
|
completedRootIds: ids,
|
|
3800
3912
|
groupedRootIds: ids,
|
|
@@ -4057,7 +4169,7 @@ const journeyPolicyRespondSchema = z.object({
|
|
|
4057
4169
|
}).strict();
|
|
4058
4170
|
//#endregion
|
|
4059
4171
|
//#region packages/application/src/journey/search.ts
|
|
4060
|
-
const count$
|
|
4172
|
+
const count$6 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
4061
4173
|
const term = z.string().min(1).max(1024).refine((value) => Buffer.byteLength(value) <= 1024 && !/[\0\r\n]/u.test(value));
|
|
4062
4174
|
const journeySearchSchema = z.object({
|
|
4063
4175
|
journeyId: journeyIdSchema,
|
|
@@ -4071,11 +4183,11 @@ const journeySearchResultSchema = z.object({
|
|
|
4071
4183
|
binding: z.object({
|
|
4072
4184
|
journeyId: journeyIdSchema,
|
|
4073
4185
|
snapshotId: journeyDigestSchema,
|
|
4074
|
-
revision: count$
|
|
4186
|
+
revision: count$6,
|
|
4075
4187
|
scopeDigest: journeyDigestSchema,
|
|
4076
4188
|
outputs: z.array(z.object({
|
|
4077
4189
|
workId: journeyIdSchema,
|
|
4078
|
-
outputRevision: count$
|
|
4190
|
+
outputRevision: count$6,
|
|
4079
4191
|
sha256: journeyDigestSchema
|
|
4080
4192
|
}).strict())
|
|
4081
4193
|
}).strict(),
|
|
@@ -4092,10 +4204,10 @@ const journeySearchResultSchema = z.object({
|
|
|
4092
4204
|
terms: z.array(z.object({
|
|
4093
4205
|
id: z.string(),
|
|
4094
4206
|
tried: z.array(z.string()),
|
|
4095
|
-
sentMatches: count$
|
|
4096
|
-
originalMatches: count$
|
|
4097
|
-
sentSessions: count$
|
|
4098
|
-
originalSessions: count$
|
|
4207
|
+
sentMatches: count$6.nullable(),
|
|
4208
|
+
originalMatches: count$6.nullable(),
|
|
4209
|
+
sentSessions: count$6.nullable(),
|
|
4210
|
+
originalSessions: count$6.nullable()
|
|
4099
4211
|
}).strict()),
|
|
4100
4212
|
hits: z.array(z.object({
|
|
4101
4213
|
termId: z.string(),
|
|
@@ -4111,16 +4223,16 @@ const journeySearchResultSchema = z.object({
|
|
|
4111
4223
|
archiveSessionId: z.string().optional(),
|
|
4112
4224
|
sessionId: z.string().optional(),
|
|
4113
4225
|
sourcePartId: z.string().optional(),
|
|
4114
|
-
recordIndex: count$
|
|
4226
|
+
recordIndex: count$6,
|
|
4115
4227
|
fieldId: z.string(),
|
|
4116
|
-
line: count$
|
|
4228
|
+
line: count$6
|
|
4117
4229
|
}).strict(),
|
|
4118
|
-
occurrences: count$
|
|
4230
|
+
occurrences: count$6,
|
|
4119
4231
|
modelContext: z.string().max(4096).optional(),
|
|
4120
4232
|
match: z.object({
|
|
4121
|
-
variantIndex: count$
|
|
4122
|
-
start: count$
|
|
4123
|
-
end: count$
|
|
4233
|
+
variantIndex: count$6.max(7),
|
|
4234
|
+
start: count$6,
|
|
4235
|
+
end: count$6
|
|
4124
4236
|
}).strict().optional()
|
|
4125
4237
|
}).strict()),
|
|
4126
4238
|
failures: z.array(z.object({
|
|
@@ -4143,7 +4255,7 @@ const journeySearchResultSchema = z.object({
|
|
|
4143
4255
|
}));
|
|
4144
4256
|
const journeySearchSaveSchema = z.object({
|
|
4145
4257
|
journeyId: journeyIdSchema,
|
|
4146
|
-
expectedRevision: count$
|
|
4258
|
+
expectedRevision: count$6,
|
|
4147
4259
|
idempotencyKey: journeyIdSchema,
|
|
4148
4260
|
result: journeySearchResultSchema
|
|
4149
4261
|
}).strict();
|
|
@@ -4180,10 +4292,10 @@ const hideFinishSchema = z.object({
|
|
|
4180
4292
|
}).strict();
|
|
4181
4293
|
//#endregion
|
|
4182
4294
|
//#region packages/application/src/journey/placement/context-schema.ts
|
|
4183
|
-
const count$
|
|
4295
|
+
const count$5 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
4184
4296
|
const cursor = z.object({
|
|
4185
|
-
inputRevision: count$
|
|
4186
|
-
throughEvent: count$
|
|
4297
|
+
inputRevision: count$5.min(1),
|
|
4298
|
+
throughEvent: count$5,
|
|
4187
4299
|
afterOrdinal: z.number().int().min(-1)
|
|
4188
4300
|
}).strict();
|
|
4189
4301
|
const journeyContextQuerySchema = z.object({
|
|
@@ -4196,14 +4308,14 @@ const journeyContextSchema = z.object({
|
|
|
4196
4308
|
journeyId: z.uuid(),
|
|
4197
4309
|
workId: z.uuid(),
|
|
4198
4310
|
sessionId: z.string().min(1).max(128).nullable(),
|
|
4199
|
-
inputRevision: count$
|
|
4311
|
+
inputRevision: count$5.min(1),
|
|
4200
4312
|
explicitTitleId: z.uuid().nullable(),
|
|
4201
4313
|
titleReview: z.object({
|
|
4202
4314
|
id: z.uuid(),
|
|
4203
4315
|
text: z.string().min(1).max(240),
|
|
4204
4316
|
sha256: z.string().regex(/^[a-f0-9]{64}$/u)
|
|
4205
4317
|
}).strict().nullable(),
|
|
4206
|
-
throughEvent: count$
|
|
4318
|
+
throughEvent: count$5,
|
|
4207
4319
|
digest: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
4208
4320
|
decisionDigest: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
4209
4321
|
decisions: z.array(z.object({
|
|
@@ -4221,13 +4333,13 @@ const journeyContextSchema = z.object({
|
|
|
4221
4333
|
confirmed: z.boolean()
|
|
4222
4334
|
}).strict()),
|
|
4223
4335
|
describedCheckpoints: z.array(z.enum(["initial", "complete"])).max(2),
|
|
4224
|
-
totalBatches: count$
|
|
4225
|
-
reviewedBatches: count$
|
|
4336
|
+
totalBatches: count$5,
|
|
4337
|
+
reviewedBatches: count$5,
|
|
4226
4338
|
complete: z.boolean(),
|
|
4227
4339
|
placementReviewed: z.boolean(),
|
|
4228
4340
|
fragments: z.array(z.object({
|
|
4229
4341
|
batchId: z.uuid(),
|
|
4230
|
-
ordinal: count$
|
|
4342
|
+
ordinal: count$5
|
|
4231
4343
|
}).strict()).max(16),
|
|
4232
4344
|
cursor: cursor.nullable()
|
|
4233
4345
|
}).strict();
|
|
@@ -4255,6 +4367,268 @@ z.discriminatedUnion("kind", [z.object({
|
|
|
4255
4367
|
submission: sessionReconcileInputSchema
|
|
4256
4368
|
}).strict()]);
|
|
4257
4369
|
//#endregion
|
|
4370
|
+
//#region packages/application/src/journey/placement/work.ts
|
|
4371
|
+
/** The processed project name is both the initial title and the retired-description fallback. */
|
|
4372
|
+
function newJourneyWork(id, projectName, rootSessionIds, sourceWorkspaceIds, placement = "placed") {
|
|
4373
|
+
return {
|
|
4374
|
+
id,
|
|
4375
|
+
title: projectName,
|
|
4376
|
+
projectName,
|
|
4377
|
+
projectType: null,
|
|
4378
|
+
description: "",
|
|
4379
|
+
titleOrigin: "model",
|
|
4380
|
+
explicitTitleId: null,
|
|
4381
|
+
accessOrigin: "default",
|
|
4382
|
+
placement,
|
|
4383
|
+
suggestion: null,
|
|
4384
|
+
classificationRecommendation: null,
|
|
4385
|
+
sourceWorkspaceIds,
|
|
4386
|
+
rootSessionIds,
|
|
4387
|
+
grouping: sourceWorkspaceIds.length === 1 ? "workspace" : "regrouped",
|
|
4388
|
+
access: "private",
|
|
4389
|
+
accessConfirmed: false,
|
|
4390
|
+
reason: "Awaiting content review.",
|
|
4391
|
+
revision: 1,
|
|
4392
|
+
inputRevision: 1,
|
|
4393
|
+
status: "pending",
|
|
4394
|
+
totalBatches: 0,
|
|
4395
|
+
completedBatches: 0,
|
|
4396
|
+
groupIds: [],
|
|
4397
|
+
blockedCodes: [],
|
|
4398
|
+
artifact: null,
|
|
4399
|
+
binding: null
|
|
4400
|
+
};
|
|
4401
|
+
}
|
|
4402
|
+
//#endregion
|
|
4403
|
+
//#region packages/application/src/journey/scan-generation.ts
|
|
4404
|
+
/** Retire one scan generation while preserving the person's confirmed classification. */
|
|
4405
|
+
function retireScanGeneration(state, workId) {
|
|
4406
|
+
if (!state.works.some((work) => work.id === workId)) throw new ApplicationError("UNKNOWN_ITEM");
|
|
4407
|
+
const changedKeys = /* @__PURE__ */ new Set();
|
|
4408
|
+
const terms = state.privacy.terms.flatMap((term) => {
|
|
4409
|
+
if (!term.sources.some((source) => source.workId === workId)) return [term];
|
|
4410
|
+
changedKeys.add(privacyTermKey(term));
|
|
4411
|
+
const sources = term.sources.filter((source) => source.workId !== workId);
|
|
4412
|
+
return sources.length ? [{
|
|
4413
|
+
...term,
|
|
4414
|
+
sources,
|
|
4415
|
+
disposition: term.disposition === "keep" ? "pending" : term.disposition
|
|
4416
|
+
}] : [];
|
|
4417
|
+
});
|
|
4418
|
+
return {
|
|
4419
|
+
...state,
|
|
4420
|
+
readingComplete: false,
|
|
4421
|
+
phase: state.phase === "paused" ? "paused" : "processing",
|
|
4422
|
+
privacy: {
|
|
4423
|
+
...state.privacy,
|
|
4424
|
+
terms,
|
|
4425
|
+
cards: state.privacy.cards.filter((card) => card.termKeys.every((key) => !changedKeys.has(key))),
|
|
4426
|
+
confirmedAnswersRevision: null,
|
|
4427
|
+
packageApproval: null
|
|
4428
|
+
},
|
|
4429
|
+
works: state.works.map((work) => work.id === workId ? resetWorkScan(work) : work)
|
|
4430
|
+
};
|
|
4431
|
+
}
|
|
4432
|
+
/** The same Work with a new scan generation: it is read again from its first session. */
|
|
4433
|
+
function resetWorkScan(work) {
|
|
4434
|
+
const { emptyReview: _empty, excludedReview: _excluded, staticReview: _static, metadataReviewedDigest: _metadata, reviewReuseFrom: _reuse, renderFailure: _failure, ...retained } = work;
|
|
4435
|
+
return {
|
|
4436
|
+
...retained,
|
|
4437
|
+
revision: work.revision + 1,
|
|
4438
|
+
inputRevision: work.inputRevision + 1,
|
|
4439
|
+
status: "pending",
|
|
4440
|
+
suggestion: null,
|
|
4441
|
+
totalBatches: 0,
|
|
4442
|
+
completedBatches: 0,
|
|
4443
|
+
groupIds: [],
|
|
4444
|
+
blockedCodes: [],
|
|
4445
|
+
artifact: null
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4448
|
+
//#endregion
|
|
4449
|
+
//#region packages/application/src/journey/scope/proposal.ts
|
|
4450
|
+
const count$4 = z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
4451
|
+
const workspaces = z.array(z.string().min(1).max(128));
|
|
4452
|
+
/**
|
|
4453
|
+
* A complete classification proposal prepared outside the store and applied inside one store
|
|
4454
|
+
* transaction against the current state (BL-216). New Work IDs and the session of every finding
|
|
4455
|
+
* chunk the regrouping moves are resolved beforehand, so applying it needs no I/O.
|
|
4456
|
+
*/
|
|
4457
|
+
const classificationCommitSchema = z.object({
|
|
4458
|
+
journeyId: journeyIdSchema,
|
|
4459
|
+
requestKey: journeyIdSchema,
|
|
4460
|
+
requestHash: journeyDigestSchema,
|
|
4461
|
+
at: z.iso.datetime(),
|
|
4462
|
+
/** Unbound proposals keep the exact journey revision fence. */
|
|
4463
|
+
expectedRevision: count$4,
|
|
4464
|
+
/** Bound proposals (E2) are fenced on the classification they replace instead. */
|
|
4465
|
+
expectedClassificationRevision: count$4.nullable(),
|
|
4466
|
+
snapshotId: journeyDigestSchema,
|
|
4467
|
+
/** `classificationPartition` of the state the proposal was prepared against. */
|
|
4468
|
+
partition: journeyDigestSchema,
|
|
4469
|
+
late: z.boolean(),
|
|
4470
|
+
items: z.array(journeyClassificationSubmitSchema.shape.items.element.extend({
|
|
4471
|
+
workId: journeyIdSchema,
|
|
4472
|
+
workspaceIds: workspaces
|
|
4473
|
+
})).min(1).max(1e3),
|
|
4474
|
+
pending: z.object({
|
|
4475
|
+
workId: journeyIdSchema,
|
|
4476
|
+
rootSessionIds: z.array(z.string().min(1).max(128)).min(1).max(1e4),
|
|
4477
|
+
workspaceIds: workspaces
|
|
4478
|
+
}).strict().nullable(),
|
|
4479
|
+
chunkSessions: z.array(z.object({
|
|
4480
|
+
batchId: z.uuid(),
|
|
4481
|
+
chunkId: z.uuid(),
|
|
4482
|
+
sessionId: z.string().min(1).max(128)
|
|
4483
|
+
}).strict()).max(1e6)
|
|
4484
|
+
}).strict();
|
|
4485
|
+
/** The Works and roots a proposal regroups; scan progress and access never change it. */
|
|
4486
|
+
function classificationPartition(state) {
|
|
4487
|
+
return createHash("sha256").update(JSON.stringify(state.works.map((work) => [
|
|
4488
|
+
work.id,
|
|
4489
|
+
work.placement,
|
|
4490
|
+
work.rootSessionIds.toSorted()
|
|
4491
|
+
]))).digest("hex");
|
|
4492
|
+
}
|
|
4493
|
+
/** The proposal's Works built from the given state's current Works (E2). */
|
|
4494
|
+
function classificationWorks(state, plan) {
|
|
4495
|
+
const late = plan.late;
|
|
4496
|
+
const works = [];
|
|
4497
|
+
for (const item of plan.items) {
|
|
4498
|
+
const existing = state.works.find((work) => work.placement !== "classifying" && work.rootSessionIds.length === item.rootSessionIds.length && work.rootSessionIds.every((root) => item.rootSessionIds.includes(root)));
|
|
4499
|
+
const extended = late ? state.works.find((work) => work.placement === "placed" && work.rootSessionIds.every((root) => item.rootSessionIds.includes(root))) : void 0;
|
|
4500
|
+
if (late && existing) {
|
|
4501
|
+
works.push(existing);
|
|
4502
|
+
continue;
|
|
4503
|
+
}
|
|
4504
|
+
const base = existing ?? (extended ? {
|
|
4505
|
+
...resetWorkScan(extended),
|
|
4506
|
+
rootSessionIds: item.rootSessionIds,
|
|
4507
|
+
sourceWorkspaceIds: [.../* @__PURE__ */ new Set([...extended.sourceWorkspaceIds, ...item.workspaceIds])]
|
|
4508
|
+
} : newJourneyWork(item.workId, item.projectName, item.rootSessionIds, item.workspaceIds, "placed"));
|
|
4509
|
+
const { classificationMetadata: _display, ...original } = base;
|
|
4510
|
+
works.push({
|
|
4511
|
+
...original,
|
|
4512
|
+
projectName: item.projectName,
|
|
4513
|
+
title: base.titleOrigin === "explicit" ? base.title : item.projectName,
|
|
4514
|
+
description: item.description,
|
|
4515
|
+
projectType: {
|
|
4516
|
+
type: item.projectType,
|
|
4517
|
+
reason: item.recommendation.reason,
|
|
4518
|
+
origin: "model"
|
|
4519
|
+
},
|
|
4520
|
+
placement: "placed",
|
|
4521
|
+
...late && !extended ? {
|
|
4522
|
+
access: item.recommendation.access,
|
|
4523
|
+
accessOrigin: "model",
|
|
4524
|
+
accessConfirmed: true
|
|
4525
|
+
} : {},
|
|
4526
|
+
classificationRecommendation: item.recommendation,
|
|
4527
|
+
suggestion: null,
|
|
4528
|
+
artifact: null,
|
|
4529
|
+
revision: base.revision + 1
|
|
4530
|
+
});
|
|
4531
|
+
}
|
|
4532
|
+
const pending = plan.pending;
|
|
4533
|
+
if (pending) {
|
|
4534
|
+
const prior = state.works.find((work) => work.placement === "classifying" && work.rootSessionIds.length === pending.rootSessionIds.length && work.rootSessionIds.every((root) => pending.rootSessionIds.includes(root)));
|
|
4535
|
+
works.push(prior ?? newJourneyWork(pending.workId, "Still being grouped", pending.rootSessionIds, pending.workspaceIds, "classifying"));
|
|
4536
|
+
}
|
|
4537
|
+
const fields = (work) => JSON.stringify([
|
|
4538
|
+
work?.title,
|
|
4539
|
+
work?.projectName,
|
|
4540
|
+
work?.description,
|
|
4541
|
+
work?.classificationRecommendation?.reason
|
|
4542
|
+
]);
|
|
4543
|
+
return {
|
|
4544
|
+
works,
|
|
4545
|
+
changedMetadata: new Set(works.filter((work) => {
|
|
4546
|
+
const old = state.works.find((item) => item.id === work.id);
|
|
4547
|
+
return !old || fields(work) !== fields(old);
|
|
4548
|
+
}).map((work) => work.id))
|
|
4549
|
+
};
|
|
4550
|
+
}
|
|
4551
|
+
/**
|
|
4552
|
+
* Rebind accepted frozen evidence; original batch/chunk IDs remain its audit provenance. Null
|
|
4553
|
+
* when a finding in a moved Work was not resolved beforehand, so the proposal is stale.
|
|
4554
|
+
*/
|
|
4555
|
+
function regroupTerms(terms, works, changedMetadata, chunkSessions) {
|
|
4556
|
+
const owners = new Map(works.flatMap((work) => work.rootSessionIds.map((id) => [id, work.id])));
|
|
4557
|
+
const retained = new Set(works.map((work) => work.id));
|
|
4558
|
+
const sessions = new Map(chunkSessions.map((item) => [`${item.batchId}:${item.chunkId}`, item.sessionId]));
|
|
4559
|
+
const regrouped = [];
|
|
4560
|
+
for (const term of terms) {
|
|
4561
|
+
const sources = [];
|
|
4562
|
+
for (const source of term.sources) {
|
|
4563
|
+
if (source.kind === "metadata") {
|
|
4564
|
+
if (retained.has(source.workId) && !changedMetadata.has(source.workId)) sources.push(source);
|
|
4565
|
+
continue;
|
|
4566
|
+
}
|
|
4567
|
+
if (retained.has(source.workId)) {
|
|
4568
|
+
sources.push(source);
|
|
4569
|
+
continue;
|
|
4570
|
+
}
|
|
4571
|
+
const session = sessions.get(`${source.batchId}:${source.chunkId}`);
|
|
4572
|
+
if (session === void 0) return null;
|
|
4573
|
+
const workId = owners.get(session);
|
|
4574
|
+
if (!workId) throw new ApplicationError("CORRUPTED_STATE");
|
|
4575
|
+
sources.push({
|
|
4576
|
+
...source,
|
|
4577
|
+
workId
|
|
4578
|
+
});
|
|
4579
|
+
}
|
|
4580
|
+
regrouped.push({
|
|
4581
|
+
...term,
|
|
4582
|
+
sources
|
|
4583
|
+
});
|
|
4584
|
+
}
|
|
4585
|
+
return regrouped;
|
|
4586
|
+
}
|
|
4587
|
+
/**
|
|
4588
|
+
* The proposal applied to the current state, or null when it is stale: the classification, the
|
|
4589
|
+
* frozen snapshot, the regrouped Works and roots, or the scope changed since it was prepared.
|
|
4590
|
+
* Scan progress, Work input revisions and the person's visibility choices do not make it stale;
|
|
4591
|
+
* they are kept as the current state has them.
|
|
4592
|
+
*/
|
|
4593
|
+
function applyClassificationProposal(state, plan) {
|
|
4594
|
+
const classifying = isClassifying(state);
|
|
4595
|
+
if (!state.consent || state.journeyId !== plan.journeyId || (plan.expectedClassificationRevision === null ? state.revision !== plan.expectedRevision : !classifying || state.classificationRevision !== plan.expectedClassificationRevision) || state.snapshotId !== plan.snapshotId || state.scope.status === "confirmed" !== plan.late || plan.late && !classifying || state.phase === "paused" || state.pendingHideId || classificationPartition(state) !== plan.partition) return null;
|
|
4596
|
+
const { works, changedMetadata } = classificationWorks(state, plan);
|
|
4597
|
+
const retained = new Set(works.map((work) => work.id));
|
|
4598
|
+
const regrouped = !plan.late && (state.works.some((work) => !retained.has(work.id)) || changedMetadata.size > 0);
|
|
4599
|
+
const cardTerms = new Set(state.privacy.cards.flatMap((card) => card.termKeys));
|
|
4600
|
+
const preserved = regroupTerms(state.privacy.terms, works, changedMetadata, plan.chunkSessions);
|
|
4601
|
+
if (!preserved) return null;
|
|
4602
|
+
const forced = new Set(preserved.filter((term) => !termTypeInfo[term.type].asked).map((term) => term.value));
|
|
4603
|
+
const overrides = new Map(state.valueOverrides?.map((item) => [item.value, item.choice]) ?? []);
|
|
4604
|
+
const terms = preserved.map((term) => ({
|
|
4605
|
+
...term,
|
|
4606
|
+
disposition: forced.has(term.value) ? "hidden" : overrides.has(term.value) ? overrides.get(term.value) === "hide" ? "hidden" : "keep" : regrouped && cardTerms.has(privacyTermKey(term)) ? "pending" : term.disposition
|
|
4607
|
+
}));
|
|
4608
|
+
return {
|
|
4609
|
+
...state,
|
|
4610
|
+
works,
|
|
4611
|
+
classificationRevision: state.revision + 1,
|
|
4612
|
+
scope: plan.late ? state.scope : {
|
|
4613
|
+
status: "pending",
|
|
4614
|
+
actor: null,
|
|
4615
|
+
at: null
|
|
4616
|
+
},
|
|
4617
|
+
privacy: {
|
|
4618
|
+
...state.privacy,
|
|
4619
|
+
terms,
|
|
4620
|
+
packageApproval: null,
|
|
4621
|
+
...regrouped ? {
|
|
4622
|
+
cards: [],
|
|
4623
|
+
answersRevision: state.privacy.answersRevision + 1,
|
|
4624
|
+
confirmedAnswersRevision: null
|
|
4625
|
+
} : {}
|
|
4626
|
+
},
|
|
4627
|
+
readingComplete: !plan.pending && works.filter((work) => work.access !== "drop").every((work) => work.totalBatches > 0 && work.completedBatches === work.totalBatches),
|
|
4628
|
+
phase: "processing"
|
|
4629
|
+
};
|
|
4630
|
+
}
|
|
4631
|
+
//#endregion
|
|
4258
4632
|
//#region packages/application/src/journey/review/port.ts
|
|
4259
4633
|
/** Batches are served in publication order; only a Drop or un-Drop invalidates a cursor. */
|
|
4260
4634
|
const journeyReadCursorSchema = z.object({
|
|
@@ -4505,7 +4879,7 @@ function propagateGroups(state, action) {
|
|
|
4505
4879
|
/** Classification confirmation fixes visibility and scan membership for this journey. */
|
|
4506
4880
|
function confirmScope(state, now, decision) {
|
|
4507
4881
|
if (state.scope.status === "confirmed") return state;
|
|
4508
|
-
if (state.classificationRevision === null || !state.works.length || state.works.some((work) => work.placement !== "placed" || !(work.status === "blocked" && work.access === "drop" && work.accessConfirmed) && (!work.description.trim() || !work.projectType))) throw new ApplicationError("SCOPE_NOT_READY");
|
|
4882
|
+
if (state.classificationRevision === null || !state.works.length || state.works.some((work) => work.placement !== "placed" && work.placement !== "classifying" || work.placement === "placed" && !(work.status === "blocked" && work.access === "drop" && work.accessConfirmed) && (!work.description.trim() || !work.projectType))) throw new ApplicationError("SCOPE_NOT_READY");
|
|
4509
4883
|
return withReadingProgress({
|
|
4510
4884
|
...state,
|
|
4511
4885
|
scope: {
|
|
@@ -4513,7 +4887,7 @@ function confirmScope(state, now, decision) {
|
|
|
4513
4887
|
actor: decision ? "delegate" : "human",
|
|
4514
4888
|
at: now
|
|
4515
4889
|
},
|
|
4516
|
-
works: state.works.map((work) => work.accessConfirmed || !work.classificationRecommendation ? {
|
|
4890
|
+
works: state.works.map((work) => work.placement === "classifying" ? work : work.accessConfirmed || !work.classificationRecommendation ? {
|
|
4517
4891
|
...work,
|
|
4518
4892
|
accessConfirmed: true
|
|
4519
4893
|
} : {
|
|
@@ -4558,7 +4932,7 @@ function setWorkType(state, workId, type, decision) {
|
|
|
4558
4932
|
function setWorksAccess(state, workIds, access, decision) {
|
|
4559
4933
|
if (new Set(workIds).size !== workIds.length) throw new ApplicationError("INVALID_SELECTION");
|
|
4560
4934
|
if (workIds.some((id) => !state.works.some((work) => work.id === id))) throw new ApplicationError("UNKNOWN_WORKSPACE");
|
|
4561
|
-
if (state.scope.status === "confirmed") return
|
|
4935
|
+
if (state.scope.status === "confirmed") return changeConfirmedAccess(state, workIds, access, decision);
|
|
4562
4936
|
return withReadingProgress({
|
|
4563
4937
|
...state,
|
|
4564
4938
|
scope: {
|
|
@@ -4584,11 +4958,12 @@ function setWorksAccess(state, workIds, access, decision) {
|
|
|
4584
4958
|
});
|
|
4585
4959
|
}
|
|
4586
4960
|
/**
|
|
4587
|
-
*
|
|
4588
|
-
*
|
|
4961
|
+
* After confirmation the person, never a delegate, may still change any Work's visibility
|
|
4962
|
+
* (D2, superseding ADR 0162's lock and ADR 0188's blocked-only Drop). Drop stops that Work's
|
|
4963
|
+
* scan; a Work moved out of Drop is read again; reading progress is recomputed.
|
|
4589
4964
|
*/
|
|
4590
|
-
function
|
|
4591
|
-
if (decision ||
|
|
4965
|
+
function changeConfirmedAccess(state, workIds, access, decision) {
|
|
4966
|
+
if (decision || state.phase === "sending" || state.phase === "completed" || state.works.some((work) => workIds.includes(work.id) && work.access === access)) throw new ApplicationError("INVALID_TRANSITION");
|
|
4592
4967
|
return withReadingProgress({
|
|
4593
4968
|
...state,
|
|
4594
4969
|
privacy: {
|
|
@@ -4598,7 +4973,9 @@ function dropBlockedWorks(state, workIds, access, decision) {
|
|
|
4598
4973
|
works: state.works.map((work) => workIds.includes(work.id) ? {
|
|
4599
4974
|
...work,
|
|
4600
4975
|
revision: work.revision + 1,
|
|
4601
|
-
|
|
4976
|
+
artifact: null,
|
|
4977
|
+
status: work.status === "ready" ? "review" : work.status,
|
|
4978
|
+
access,
|
|
4602
4979
|
accessConfirmed: true,
|
|
4603
4980
|
accessOrigin: "explicit"
|
|
4604
4981
|
} : work)
|
|
@@ -4687,7 +5064,7 @@ function respondToJourney(state, action, source, now, decision, preferenceScope)
|
|
|
4687
5064
|
};
|
|
4688
5065
|
}
|
|
4689
5066
|
if (action.kind === "consent") {
|
|
4690
|
-
if (
|
|
5067
|
+
if (decision) throw new ApplicationError("CONFIRMATION_REQUIRED");
|
|
4691
5068
|
if (state.consent) return state;
|
|
4692
5069
|
if (!action.allow) return {
|
|
4693
5070
|
...state,
|
|
@@ -4801,7 +5178,7 @@ function pendingGroups(state) {
|
|
|
4801
5178
|
* It is never filtered by Work or relevance, so its digest proves which guidance was current.
|
|
4802
5179
|
*/
|
|
4803
5180
|
function journeyGuidance(state) {
|
|
4804
|
-
const rules = [...state.privacy.rememberedRules, ...state.privacy.cards.flatMap((card) => card.answer ? [card
|
|
5181
|
+
const rules = [...state.privacy.rememberedRules, ...state.privacy.cards.flatMap((card) => card.answer ? [answeredRule(card)] : [])];
|
|
4805
5182
|
const conditions = state.groups.map(({ id, kind, key, label, condition, choice, confirmed, origin }) => ({
|
|
4806
5183
|
groupId: id,
|
|
4807
5184
|
kind,
|
|
@@ -4841,6 +5218,17 @@ function journeyGuidance(state) {
|
|
|
4841
5218
|
rules
|
|
4842
5219
|
};
|
|
4843
5220
|
}
|
|
5221
|
+
/**
|
|
5222
|
+
* An answered card as scan children read it: the question with the answer, so a value that fits
|
|
5223
|
+
* the question takes that answer instead of staying Pending (E3).
|
|
5224
|
+
*/
|
|
5225
|
+
function answeredRule(card) {
|
|
5226
|
+
const answer = card.answer;
|
|
5227
|
+
if (!answer) return "";
|
|
5228
|
+
const label = card.options.find((option) => option.id === answer.optionId)?.label;
|
|
5229
|
+
const rule = `Answered question “${card.question}”: ${answer.optionId === "hide" ? "Hide" : "Keep"}${label ? ` (“${label}”)` : ""}. ${answer.rule}`;
|
|
5230
|
+
return rule.length <= 4001 ? rule : answer.rule;
|
|
5231
|
+
}
|
|
4844
5232
|
//#endregion
|
|
4845
5233
|
//#region packages/application/src/journey/review/agents.ts
|
|
4846
5234
|
/** A dispatch without a pack ID is its own analysis agent. */
|
|
@@ -5513,9 +5901,11 @@ function journeyView(state, now) {
|
|
|
5513
5901
|
},
|
|
5514
5902
|
works: state.works.map((work) => {
|
|
5515
5903
|
const localTitle = work.suggestion || work.explicitTitleId ? work.title : work.classificationMetadata?.title ?? work.title;
|
|
5904
|
+
const imagesOmitted = hasCurrentStaticReview(state, work) ? work.staticReview?.imagesOmitted ?? 0 : 0;
|
|
5516
5905
|
if (!work.classificationMetadata) return {
|
|
5517
5906
|
...work,
|
|
5518
|
-
localTitle
|
|
5907
|
+
localTitle,
|
|
5908
|
+
imagesOmitted
|
|
5519
5909
|
};
|
|
5520
5910
|
const metadata = work.classificationMetadata;
|
|
5521
5911
|
const displayed = {
|
|
@@ -5528,6 +5918,7 @@ function journeyView(state, now) {
|
|
|
5528
5918
|
...work,
|
|
5529
5919
|
...displayed,
|
|
5530
5920
|
localTitle,
|
|
5921
|
+
imagesOmitted,
|
|
5531
5922
|
projectType: work.projectType ? {
|
|
5532
5923
|
...work.projectType,
|
|
5533
5924
|
reason: work.projectType.origin === "model" ? displayed.reason : work.projectType.reason
|
|
@@ -5668,10 +6059,30 @@ function createNativeJourney(storage, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
5668
6059
|
id: "current"
|
|
5669
6060
|
})).find((resource) => resource.kind === "classification-progress");
|
|
5670
6061
|
if (previous) {
|
|
5671
|
-
const contains = (next, prior) => prior.every((id) => next.includes(id));
|
|
5672
6062
|
const replacesObsoleteAttempt = previous.baselineRevision !== progress.baselineRevision && progress.baselineRevision === state.revision && progress.status === "running" && progress.stage === "classification" && progress.completedRootIds.length === 0 && progress.groupedRootIds.length === 0 && progress.aiCompletedRootIds.length === 0 && Date.parse(progress.startedAt) > Date.parse(previous.startedAt);
|
|
5673
6063
|
const restartsFailedAttempt = previous.status === "failed" && previous.baselineRevision === progress.baselineRevision && progress.baselineRevision === state.revision && progress.status === "running" && progress.stage === "classification" && progress.completedRootIds.length === 0 && progress.groupedRootIds.length === 0 && progress.aiCompletedRootIds.length === 0 && Date.parse(progress.startedAt) > Date.parse(previous.startedAt);
|
|
5674
|
-
if (!replacesObsoleteAttempt && !restartsFailedAttempt
|
|
6064
|
+
if (!replacesObsoleteAttempt && !restartsFailedAttempt) {
|
|
6065
|
+
if (previous.inputFingerprint !== progress.inputFingerprint || previous.baselineRevision !== progress.baselineRevision || previous.proposalRevision !== null && previous.proposalRevision !== progress.proposalRevision || previous.startedAt !== progress.startedAt) throw new ApplicationError("REVISION_CONFLICT");
|
|
6066
|
+
const union = (left, right) => [.../* @__PURE__ */ new Set([...left, ...right])].toSorted();
|
|
6067
|
+
const rank = {
|
|
6068
|
+
running: 0,
|
|
6069
|
+
paused: 0,
|
|
6070
|
+
failed: 1,
|
|
6071
|
+
complete: 2
|
|
6072
|
+
};
|
|
6073
|
+
await storage.saveResource({
|
|
6074
|
+
...progress,
|
|
6075
|
+
stage: previous.stage === "proposal" ? "proposal" : progress.stage,
|
|
6076
|
+
status: rank[previous.status] > rank[progress.status] ? previous.status : progress.status,
|
|
6077
|
+
proposalRevision: progress.proposalRevision ?? previous.proposalRevision,
|
|
6078
|
+
updatedAt: Date.parse(previous.updatedAt) > Date.parse(progress.updatedAt) ? previous.updatedAt : progress.updatedAt,
|
|
6079
|
+
elapsedMs: Math.max(previous.elapsedMs, progress.elapsedMs),
|
|
6080
|
+
completedRootIds: union(previous.completedRootIds, progress.completedRootIds),
|
|
6081
|
+
groupedRootIds: union(previous.groupedRootIds, progress.groupedRootIds),
|
|
6082
|
+
aiCompletedRootIds: union(previous.aiCompletedRootIds, progress.aiCompletedRootIds)
|
|
6083
|
+
});
|
|
6084
|
+
return { accepted: true };
|
|
6085
|
+
}
|
|
5675
6086
|
}
|
|
5676
6087
|
await storage.saveResource(progress);
|
|
5677
6088
|
return { accepted: true };
|
|
@@ -5806,16 +6217,29 @@ function createNativeJourney(storage, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
5806
6217
|
state: await present(result.state)
|
|
5807
6218
|
};
|
|
5808
6219
|
}
|
|
6220
|
+
const rebase = source === "panel" && !input.decision && [
|
|
6221
|
+
"consent",
|
|
6222
|
+
"work-access",
|
|
6223
|
+
"works-access",
|
|
6224
|
+
"card-answer"
|
|
6225
|
+
].includes(input.action.kind);
|
|
6226
|
+
for (let attempt = 0;; attempt++) {
|
|
6227
|
+
const result = await commitResponse(input, source, rebase);
|
|
6228
|
+
if (result.status !== "stale" || !rebase || attempt >= 4) return result;
|
|
6229
|
+
}
|
|
6230
|
+
}
|
|
6231
|
+
async function commitResponse(input, source, rebase) {
|
|
5809
6232
|
const current = await storage.current(input.journeyId);
|
|
5810
6233
|
if (!current) throw new ApplicationError("UNKNOWN_ITEM");
|
|
5811
|
-
const
|
|
6234
|
+
const expectedRevision = rebase ? current.revision : input.expectedRevision;
|
|
6235
|
+
const state = current.revision === expectedRevision ? respondToJourney(current, input.action, source, now(), input.decision, input.preferenceScope) : current;
|
|
5812
6236
|
const groupIds = input.action.kind === "group" ? [input.action.groupId] : input.action.kind === "groups-hide" ? input.action.groupIds : [];
|
|
5813
6237
|
const preferenceScopes = input.decision ? [] : state.groups.flatMap((group) => groupIds.includes(group.id) && group.preferenceScope ? [{
|
|
5814
6238
|
groupId: group.id,
|
|
5815
6239
|
preferenceScope: group.preferenceScope
|
|
5816
6240
|
}] : []);
|
|
5817
6241
|
const result = await storage.commit({
|
|
5818
|
-
expectedRevision
|
|
6242
|
+
expectedRevision,
|
|
5819
6243
|
requestKey: input.idempotencyKey,
|
|
5820
6244
|
requestHash: digest$1(input),
|
|
5821
6245
|
state,
|
|
@@ -5845,7 +6269,7 @@ function createNativeJourney(storage, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
5845
6269
|
events: rows,
|
|
5846
6270
|
state: await get({ journeyId: input.journeyId })
|
|
5847
6271
|
};
|
|
5848
|
-
await setTimeout$1(Math.min(
|
|
6272
|
+
await setTimeout$1(Math.min(1e3, Math.max(0, deadline - Date.now())), void 0, { signal });
|
|
5849
6273
|
}
|
|
5850
6274
|
}
|
|
5851
6275
|
async function prepare(value, signal) {
|
|
@@ -5948,7 +6372,7 @@ function createNativeJourney(storage, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
5948
6372
|
const scope = await port.renderScope?.(journeyId, workIds.length, signal);
|
|
5949
6373
|
const renderWork = scope ? (workId) => scope.render(workId) : (workId) => port.render(journeyId, workId, signal);
|
|
5950
6374
|
try {
|
|
5951
|
-
await Promise.
|
|
6375
|
+
const failure = (await Promise.allSettled(Array.from({ length: Math.min(scope?.concurrency ?? renderConcurrency, workIds.length) }, async () => {
|
|
5952
6376
|
for (let workId = workIds[next++]; workId !== void 0; workId = workIds[next++]) {
|
|
5953
6377
|
try {
|
|
5954
6378
|
await renderWork(workId);
|
|
@@ -5967,7 +6391,8 @@ function createNativeJourney(storage, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
5967
6391
|
}
|
|
5968
6392
|
await new Promise((resolve) => setImmediate(resolve));
|
|
5969
6393
|
}
|
|
5970
|
-
}));
|
|
6394
|
+
}))).find((item) => item.status === "rejected");
|
|
6395
|
+
if (failure) throw failure.reason;
|
|
5971
6396
|
} finally {
|
|
5972
6397
|
await scope?.close();
|
|
5973
6398
|
}
|
|
@@ -6051,11 +6476,19 @@ function createNativeJourney(storage, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
6051
6476
|
}
|
|
6052
6477
|
async function privacyWrite(value, resolve) {
|
|
6053
6478
|
const input = resolve ? privacyResolveSchema.parse(value) : cardsSubmitSchema.parse(value);
|
|
6479
|
+
const rebase = "mode" in input && input.mode === "append";
|
|
6480
|
+
for (let attempt = 0;; attempt++) {
|
|
6481
|
+
const result = await commitPrivacy(input, rebase);
|
|
6482
|
+
if (result.status !== "stale" || !rebase || attempt >= 4) return result;
|
|
6483
|
+
}
|
|
6484
|
+
}
|
|
6485
|
+
async function commitPrivacy(input, rebase) {
|
|
6054
6486
|
const current = await storage.current(input.journeyId);
|
|
6055
6487
|
if (!current) throw new ApplicationError("UNKNOWN_ITEM");
|
|
6056
|
-
const
|
|
6488
|
+
const expectedRevision = rebase ? current.revision : input.expectedRevision;
|
|
6489
|
+
const state = current.revision !== expectedRevision ? current : "resolutions" in input ? resolvePrivacyTerms(current, input) : publishDecisionCards(current, input);
|
|
6057
6490
|
const result = await storage.commit({
|
|
6058
|
-
expectedRevision
|
|
6491
|
+
expectedRevision,
|
|
6059
6492
|
requestKey: input.idempotencyKey,
|
|
6060
6493
|
requestHash: digest$1(input),
|
|
6061
6494
|
state,
|
|
@@ -6252,7 +6685,12 @@ const sendReceiptSchema = z.object({
|
|
|
6252
6685
|
passportIncluded: z.boolean(),
|
|
6253
6686
|
upload: z.object({
|
|
6254
6687
|
uploadUrl: z.url(),
|
|
6255
|
-
expiresAt: z.iso.datetime()
|
|
6688
|
+
expiresAt: z.iso.datetime(),
|
|
6689
|
+
/**
|
|
6690
|
+
* Headers the signed URL requires besides type and length: Passport answers them only
|
|
6691
|
+
* for a checksum upload, whose PUT writes the immutable object directly (ADR 0230).
|
|
6692
|
+
*/
|
|
6693
|
+
headers: z.object({ "x-amz-checksum-sha256": z.base64().length(44) }).strict().optional()
|
|
6256
6694
|
}).strict().nullable()
|
|
6257
6695
|
}).strict();
|
|
6258
6696
|
/** `POST /me/works/replace`: the owner's other Works are retired (ADR 0204). */
|
|
@@ -6298,6 +6736,13 @@ const sendItemSchema = z.object({
|
|
|
6298
6736
|
reservation: sendUploadInputSchema.nullable(),
|
|
6299
6737
|
receipt: savedSendReceiptSchema.nullable(),
|
|
6300
6738
|
previousReceipts: z.array(savedSendReceiptSchema),
|
|
6739
|
+
/** The receipt whose bytes were PUT but not yet completed: the next step completes it (BL-210). */
|
|
6740
|
+
uploadedReceiptId: journeyIdSchema.nullable().optional(),
|
|
6741
|
+
/**
|
|
6742
|
+
* Passport answered `bundle_mismatch` to this Work's checksum upload: the rest of this Send
|
|
6743
|
+
* uploads through staging (ADR 0231).
|
|
6744
|
+
*/
|
|
6745
|
+
checksumUploadRefused: z.literal(true).optional(),
|
|
6301
6746
|
status: z.enum([
|
|
6302
6747
|
"ready",
|
|
6303
6748
|
"target",
|
|
@@ -6417,6 +6862,9 @@ function safeJourneySender(sender, now) {
|
|
|
6417
6862
|
async resume(input) {
|
|
6418
6863
|
return safe(await sender.resume(input));
|
|
6419
6864
|
},
|
|
6865
|
+
async withdraw(input) {
|
|
6866
|
+
return safe(await sender.withdraw(input));
|
|
6867
|
+
},
|
|
6420
6868
|
async advance(input, signal = new AbortController().signal) {
|
|
6421
6869
|
return safe(await sender.advance(input, signal));
|
|
6422
6870
|
}
|
|
@@ -10009,6 +10457,28 @@ const validateInspectionClaim = (input) => decode(inspectionClaimSchema, input);
|
|
|
10009
10457
|
const validateInspectionHead = (input) => decode(inspectionHeadSchema, input);
|
|
10010
10458
|
const validateInspectionQuery = (input) => decode(inspectionQuerySchema, input);
|
|
10011
10459
|
//#endregion
|
|
10460
|
+
//#region packages/application/src/inspection/validation/request.ts
|
|
10461
|
+
/**
|
|
10462
|
+
* The inspection Worker receives its request across a thread boundary. A real inventory can exceed
|
|
10463
|
+
* the persisted-evidence decoding bounds, so this parses the host's own request unbounded.
|
|
10464
|
+
*/
|
|
10465
|
+
const inspectionRequestSchema = z.object({
|
|
10466
|
+
customTerms: z.object({
|
|
10467
|
+
revision: z.string().min(1).max(64),
|
|
10468
|
+
terms: z.array(z.string().max(1024)).max(1e5)
|
|
10469
|
+
}).optional(),
|
|
10470
|
+
inputs: inspectionInputsSchema,
|
|
10471
|
+
inventory: inventorySchema,
|
|
10472
|
+
cleanupBySession: z.record(z.string(), cleanupSelectionSchema)
|
|
10473
|
+
});
|
|
10474
|
+
const validateInspectionRequest = (input) => {
|
|
10475
|
+
const { customTerms, ...request } = inspectionRequestSchema.parse(input);
|
|
10476
|
+
return customTerms ? {
|
|
10477
|
+
...request,
|
|
10478
|
+
customTerms
|
|
10479
|
+
} : request;
|
|
10480
|
+
};
|
|
10481
|
+
//#endregion
|
|
10012
10482
|
//#region packages/application/src/inspection/validation/index.ts
|
|
10013
10483
|
const inspectionBatchSchema = z.object({
|
|
10014
10484
|
contributions: z.array(inspectionContributionSchema).max(128),
|
|
@@ -11025,7 +11495,7 @@ function profileUrlMatchesIdentity(profileUrl, identityUrl) {
|
|
|
11025
11495
|
}
|
|
11026
11496
|
const deviceProfileScopeSchema = z.string().max(256).refine((scope) => {
|
|
11027
11497
|
const scopes = new Set(scope.trim().split(/\s+/u));
|
|
11028
|
-
return scopes.size === 2 && scopes.has("openid") && scopes.has("profile");
|
|
11498
|
+
return scopes.size === (scopes.has("offline_access") ? 3 : 2) && scopes.has("openid") && scopes.has("profile");
|
|
11029
11499
|
});
|
|
11030
11500
|
/** Display data resolved together from the issued token's UserInfo response. */
|
|
11031
11501
|
const accountProfileSchema = z.object({
|
|
@@ -11052,6 +11522,8 @@ const storedCredentialSchema = accountProfileSchema.extend({
|
|
|
11052
11522
|
identityUrl: z.string().min(1).max(2048),
|
|
11053
11523
|
clientId: z.string().min(1).max(256),
|
|
11054
11524
|
accessToken: z.string().min(1).max(4096),
|
|
11525
|
+
/** Renews the access token without a new device approval (BL-210); absent when not issued. */
|
|
11526
|
+
refreshToken: z.string().min(1).max(4096).optional(),
|
|
11055
11527
|
tokenType: z.literal("Bearer"),
|
|
11056
11528
|
scope: deviceProfileScopeSchema,
|
|
11057
11529
|
issuedAt: z.string().min(1).max(64),
|
|
@@ -11113,7 +11585,7 @@ function createSharedAccount(ports) {
|
|
|
11113
11585
|
async function read() {
|
|
11114
11586
|
return update((state) => {
|
|
11115
11587
|
const saved = state.credential;
|
|
11116
|
-
if (saved && expired(saved.expiresAt, ports.now())) {
|
|
11588
|
+
if (saved && !saved.refreshToken && expired(saved.expiresAt, ports.now())) {
|
|
11117
11589
|
state.credential = null;
|
|
11118
11590
|
state.connection = null;
|
|
11119
11591
|
state.lastError = "SIGN_IN_EXPIRED";
|
|
@@ -11168,6 +11640,7 @@ function createSharedAccount(ports) {
|
|
|
11168
11640
|
avatarUrl: state.credential.avatarUrl,
|
|
11169
11641
|
profileUrl: state.credential.profileUrl,
|
|
11170
11642
|
expiresAt: state.credential.expiresAt,
|
|
11643
|
+
renews: Boolean(state.credential.refreshToken),
|
|
11171
11644
|
connection: state.connection ?? null
|
|
11172
11645
|
};
|
|
11173
11646
|
return {
|
|
@@ -11227,6 +11700,7 @@ function createSharedAccount(ports) {
|
|
|
11227
11700
|
avatarUrl: identity.avatarUrl,
|
|
11228
11701
|
profileUrl: identity.profileUrl,
|
|
11229
11702
|
accessToken: result.accessToken,
|
|
11703
|
+
...result.refreshToken ? { refreshToken: result.refreshToken } : {},
|
|
11230
11704
|
tokenType: "Bearer",
|
|
11231
11705
|
scope: result.scope,
|
|
11232
11706
|
issuedAt: ports.now(),
|
|
@@ -11287,7 +11761,8 @@ function createSharedAccount(ports) {
|
|
|
11287
11761
|
})).authorization?.id === id) await poll(id, signal, clientId);
|
|
11288
11762
|
} catch (error) {
|
|
11289
11763
|
if (signal.aborted) return;
|
|
11290
|
-
|
|
11764
|
+
const detail = typeof error === "object" && error !== null && "detail" in error ? ` (${String(error.detail)})` : "";
|
|
11765
|
+
console.error(`Account authorization failed: ${safeCode(error)}${detail}`);
|
|
11291
11766
|
await finish(id, safeCode(error));
|
|
11292
11767
|
throw error;
|
|
11293
11768
|
} finally {
|
|
@@ -12085,39 +12560,6 @@ function reviseGroupMembership(state, action, members, preferenceScope) {
|
|
|
12085
12560
|
};
|
|
12086
12561
|
}
|
|
12087
12562
|
//#endregion
|
|
12088
|
-
//#region packages/application/src/journey/placement/work.ts
|
|
12089
|
-
/** The processed project name is both the initial title and the retired-description fallback. */
|
|
12090
|
-
function newJourneyWork(id, projectName, rootSessionIds, sourceWorkspaceIds, placement = "placed") {
|
|
12091
|
-
return {
|
|
12092
|
-
id,
|
|
12093
|
-
title: projectName,
|
|
12094
|
-
projectName,
|
|
12095
|
-
projectType: null,
|
|
12096
|
-
description: "",
|
|
12097
|
-
titleOrigin: "model",
|
|
12098
|
-
explicitTitleId: null,
|
|
12099
|
-
accessOrigin: "default",
|
|
12100
|
-
placement,
|
|
12101
|
-
suggestion: null,
|
|
12102
|
-
classificationRecommendation: null,
|
|
12103
|
-
sourceWorkspaceIds,
|
|
12104
|
-
rootSessionIds,
|
|
12105
|
-
grouping: sourceWorkspaceIds.length === 1 ? "workspace" : "regrouped",
|
|
12106
|
-
access: "private",
|
|
12107
|
-
accessConfirmed: false,
|
|
12108
|
-
reason: "Awaiting content review.",
|
|
12109
|
-
revision: 1,
|
|
12110
|
-
inputRevision: 1,
|
|
12111
|
-
status: "pending",
|
|
12112
|
-
totalBatches: 0,
|
|
12113
|
-
completedBatches: 0,
|
|
12114
|
-
groupIds: [],
|
|
12115
|
-
blockedCodes: [],
|
|
12116
|
-
artifact: null,
|
|
12117
|
-
binding: null
|
|
12118
|
-
};
|
|
12119
|
-
}
|
|
12120
|
-
//#endregion
|
|
12121
12563
|
//#region packages/application/src/journey/b/reconstruct.ts
|
|
12122
12564
|
function reconstructBFields(inputs) {
|
|
12123
12565
|
const units = inputs.map(validateBUnit).sort((left, right) => left.ordinal - right.ordinal);
|
|
@@ -12734,49 +13176,4 @@ function equivalenceDuplicates(batch) {
|
|
|
12734
13176
|
return bindings.sort();
|
|
12735
13177
|
}
|
|
12736
13178
|
//#endregion
|
|
12737
|
-
|
|
12738
|
-
/** Retire one scan generation while preserving the person's confirmed classification. */
|
|
12739
|
-
function retireScanGeneration(state, workId) {
|
|
12740
|
-
if (!state.works.some((work) => work.id === workId)) throw new ApplicationError("UNKNOWN_ITEM");
|
|
12741
|
-
const changedKeys = /* @__PURE__ */ new Set();
|
|
12742
|
-
const terms = state.privacy.terms.flatMap((term) => {
|
|
12743
|
-
if (!term.sources.some((source) => source.workId === workId)) return [term];
|
|
12744
|
-
changedKeys.add(privacyTermKey(term));
|
|
12745
|
-
const sources = term.sources.filter((source) => source.workId !== workId);
|
|
12746
|
-
return sources.length ? [{
|
|
12747
|
-
...term,
|
|
12748
|
-
sources,
|
|
12749
|
-
disposition: term.disposition === "keep" ? "pending" : term.disposition
|
|
12750
|
-
}] : [];
|
|
12751
|
-
});
|
|
12752
|
-
return {
|
|
12753
|
-
...state,
|
|
12754
|
-
readingComplete: false,
|
|
12755
|
-
phase: state.phase === "paused" ? "paused" : "processing",
|
|
12756
|
-
privacy: {
|
|
12757
|
-
...state.privacy,
|
|
12758
|
-
terms,
|
|
12759
|
-
cards: state.privacy.cards.filter((card) => card.termKeys.every((key) => !changedKeys.has(key))),
|
|
12760
|
-
confirmedAnswersRevision: null,
|
|
12761
|
-
packageApproval: null
|
|
12762
|
-
},
|
|
12763
|
-
works: state.works.map((work) => {
|
|
12764
|
-
if (work.id !== workId) return work;
|
|
12765
|
-
const { emptyReview: _empty, excludedReview: _excluded, staticReview: _static, metadataReviewedDigest: _metadata, reviewReuseFrom: _reuse, renderFailure: _failure, ...retained } = work;
|
|
12766
|
-
return {
|
|
12767
|
-
...retained,
|
|
12768
|
-
revision: work.revision + 1,
|
|
12769
|
-
inputRevision: work.inputRevision + 1,
|
|
12770
|
-
status: "pending",
|
|
12771
|
-
suggestion: null,
|
|
12772
|
-
totalBatches: 0,
|
|
12773
|
-
completedBatches: 0,
|
|
12774
|
-
groupIds: [],
|
|
12775
|
-
blockedCodes: [],
|
|
12776
|
-
artifact: null
|
|
12777
|
-
};
|
|
12778
|
-
})
|
|
12779
|
-
};
|
|
12780
|
-
}
|
|
12781
|
-
//#endregion
|
|
12782
|
-
export { settingsBatchSchema as $, bReviewDigest as $n, defaultScopedSettings as $r, journeyResourceQuerySchema as $t, accountProfileSchema as A, packHideIndex as An, staticSessionResourceSchema as Ar, sendSettingsSchema as At, inspectionCancelSchema as B, dictionaryHides as Bn, journeyRenderInputSchema as Br, journeyBatchReadSchema as Bt, rebindReviewAlignment as C, readConfirmedHideChange as Cn, privacyDecisionDigest as Cr, sendPrepareSchema as Ct, guardedFindingText as D, addHideIndexTokens as Dn, hasCurrentStaticReview as Dr, sendReceiptSchema as Dt, reviewBatchReuse as E, termHideAdditions as En, nativeRespondSchema as Er, sendArtifactSchema as Et, storedCredentialSchema as F, bWordBounded as Fn, withReadingProgress as Fr, nativeAdapterVersions as Ft, validateInspectionClaim as G, workDecisionDigest as Gn, selectionSchema as Gr, hideBeginSchema as Gt, validateInspectionBatch as H, maskedHitsStale as Hn, commandSchema as Hr, reviewCompileSchema as Ht, sourceIdentityEvidence as I, confirmedHideGroupIds as In, mergePrivacyTerms as Ir, attemptBudgetCodePoints as It, validateInspectionInputs as J, reviewCandidateInputSchema as Jn, stateSchema as Jr, journeySearchResultSchema as Jt, validateInspectionFence as K, workPrivacyDecisions as Kn, gitMetadataBudgetBytes as Kr, hideFinishSchema as Kt, withSourceEvidence as L, confirmedHideKey as Ln, journeyFindingImpactSchema as Lr, validateAttemptAppend as Lt, deviceProfileScopeSchema as M, bExceptionRanges as Mn, isReadingComplete as Mr, currentJourneyAdapters as Mt, profileUrlMatchesIdentity as N, bMaskedHits as Nn, isSelectedWork as Nr, obsoleteJourney as Nt, staticallyHiddenFindings as O, hideKeyId as On, staticReviewDigest as Or, sendReplaceResultSchema as Ot, readAccountAvatarUrl as P, bTermMatcher as Pn, selectedWorks as Pr, metadataProcessingVersion as Pt, inspectionInputs as Q, reviewTransportBytes as Qn, effectiveTreatmentSchema as Qr, projectPreparationProgress as Qt, agentSetupKey as R, confirmedHideKinds as Rn, journeyFindingsSchema as Rr, journeyGuidance as Rt, bReviewScope as S, confirmedHideDeltaSchema as Sn, assertJourneyPrivacyReady as Sr, sendChoiceSchema as St, rebindReviewSubmit as T, settleConfirmedHides as Tn, nativeGetSchema as Tr, journeySendSchema as Tt, validateInspectionBatches as U, syncTermGroups as Un, packageCommandSchema as Ur, journeyContextQuerySchema as Ut, inspectionStartSchema as V, journeyConfirmedHides as Vn, journeyRenderSchema as Vr, journeyReviewStorageQuerySchema as Vt, inspectionQuerySchema as W, retireWorkDescription as Wn, selectionBatchSchema as Wr, journeyContextSchema as Wt, validateInspectionContribution as X, reviewRepairInputSchema as Xn, recommendParallelism as Xr, searchScopeDigest as Xt, validateInspectionQuery as Y, reviewCandidateResourceSchema as Yn, sourceChangePolicy as Yr, journeySearchSaveSchema as Yt, validateDetectionSummary as Z, reviewRepairResourceSchema as Zn, approvedTreatmentSchema as Zr, journeyPolicyRespondSchema as Zt, semanticGroupKey as _, sessionUsefulnessResourceSchema as _n, preparationBeginSchema as _r, emptyTermsRevision as _t, validateBCrossSegmentReview as a, reviewAttemptsQuerySchema as an, scanSessionResourceSchema as ar, defaultAgentSetupInclusion as at, preparationScope as b, journeyEventSchema as bn, validatePreparationFacts as br, replaceSensitiveTermsSchema as bt, reconcileBSession as c, sessionReconcileResultSchema as cn, verifiedScanGitSeeds as cr, resolveFailureLocation as ct, reviseGroupMembership as d, sessionRereadResourceSchema as dn, resolveSourceSelection as dr, manualUploadBindingSchema as dt, freezeConfiguration as ei, journeyResourceSchema as en, mergeBRepair as er, settingsQuerySchema as et, resolveGroupSplit as f, sessionReviewInputSchema as fn, journeyInventoryQuerySchema as fr, manualUploadChoiceSchema as ft, hideScopeDigest as g, sessionUsefulnessInputSchema as gn, emptyPreparationFacts as gr, candidateSortAvailable as gt, activeJourneyTerms as h, sessionReviewStatusSchema as hn, journeyPreparationProgressSchema as hr, manualUploadStartSchema as ht, locateTermEvidence as i, reviewAttemptResourceSchema as in, scanPreparationDigest as ir, classifyAgentSetup as it, deviceAuthorizationSchema as j, bContainment as jn, hasCompleteWorkDescription as jr, settleCorrections as jt, createAccount as k, maximumHideIndexTokens as kn, staticSessionId as kr, sendResolutionSchema as kt, reconstructBFields as l, sessionReconciliationResourceSchema as ln, scanExclusionResourceSchema as lr, validateFailureLocation as lt, splitSelectorValues as m, sessionReviewResourceSchema as mn, journeyInventorySchema as mr, manualUploadSchema as mt, scanBatchContextDigest as n, staticCatalogRef as ni, journeyPlaceSchema as nn, scanAliasResourceSchema as nr, reviewInventory as nt, bCrossSegmentReviewSchema as o, reviewAttemptsResultSchema as on, scanGitSeedsId as or, maximumAgentSetupSessions as ot, selectedValueMembers as p, sessionReviewQuerySchema as pn, journeyInventoryReadSchema as pr, manualUploadPrepareSchema as pt, validateInspectionHead as q, workCorrectionBinding as qn, producerVersion as qr, hidePublishSchema as qt, scanBatchEquivalenceDigest as r, sortingApplySchema as rn, scanCanonicalResourceSchema as rr, appendSensitiveTerms as rt, bRereadDigest as s, sessionReconcileInputSchema as sn, scanGitSeedsResource as sr, artifactFailureDetailSchema as st, retireScanGeneration as t, selectFrozenConfiguration as ti, journeyIsolateSchema as tn, planBRepair as tr, readWorkspaceOutcomes as tt, newJourneyWork as u, sessionRereadInputSchema as un, validateScanExclusion as ur, manualUploadActionSchema as ut, changeJourney as v, journeyCommitResultSchema as vn, preparationSettlementSchema as vr, maximumTermsFileBytes as vt, rebindReviewOverlay as w, renderedHideValue as wn, nativeEventsSchema as wr, sendStartSchema as wt, isGenericPublicTerm as x, confirmedHideAdditions as xn, journeyClassificationSessionsSchema as xr, sendActionSchema as xt, projectJourneyInventory as y, journeyCommitSchema as yn, preparationStartSchema as yr, normalizeSensitiveTerms as yt, createApplication as z, confirmedHideTerms as zn, journeyPreviewSchema as zr, applyClassification as zt };
|
|
13179
|
+
export { settingsQuerySchema as $, reviewCandidateInputSchema as $n, gitMetadataBudgetBytes as $r, journeySearchResultSchema as $t, deviceProfileScopeSchema as A, settleConfirmedHides as An, nativeEventsSchema as Ar, settleCorrections as At, validateInspectionBatch as B, bWordBounded as Bn, isSelectedWork as Br, journeyReviewStorageQuerySchema as Bt, rebindReviewSubmit as C, journeyCommitResultSchema as Cn, preparationSettlementSchema as Cr, sendStartSchema as Ct, createAccount as D, confirmedHideDeltaSchema as Dn, applyCardAnswers as Dr, sendReplaceResultSchema as Dt, staticallyHiddenFindings as E, confirmedHideAdditions as En, journeyClassificationSessionsSchema as Er, sendReceiptSchema as Et, withSourceEvidence as F, packHideIndex as Fn, staticSessionId as Fr, attemptBudgetCodePoints as Ft, validateInspectionFence as G, dictionaryHides as Gn, journeyFindingsSchema as Gr, retireScanGeneration as Gt, validateInspectionRequest as H, confirmedHideKey as Hn, withReadingProgress as Hr, classificationCommitSchema as Ht, agentSetupKey as I, bContainment as In, staticSessionResourceSchema as Ir, validateAttemptAppend as It, validateInspectionQuery as J, syncTermGroups as Jn, journeyRenderSchema as Jr, journeyContextQuerySchema as Jt, validateInspectionHead as K, journeyConfirmedHides as Kn, journeyPreviewSchema as Kr, newJourneyWork as Kt, createApplication as L, bExceptionRanges as Ln, hasCompleteWorkDescription as Lr, journeyGuidance as Lt, readAccountAvatarUrl as M, addHideIndexTokens as Mn, nativeRespondSchema as Mr, obsoleteJourney as Mt, storedCredentialSchema as N, hideKeyId as Nn, hasCurrentStaticReview as Nr, metadataProcessingVersion as Nt, accountProfileSchema as O, readConfirmedHideChange as On, assertJourneyPrivacyReady as Or, sendResolutionSchema as Ot, sourceIdentityEvidence as P, maximumHideIndexTokens as Pn, staticReviewDigest as Pr, nativeAdapterVersions as Pt, settingsBatchSchema as Q, workCorrectionBinding as Qn, selectionSchema as Qr, hidePublishSchema as Qt, inspectionCancelSchema as R, bMaskedHits as Rn, isClassifying as Rr, applyClassification as Rt, rebindReviewOverlay as S, sessionUsefulnessResourceSchema as Sn, preparationBeginSchema as Sr, sendPrepareSchema as St, guardedFindingText as T, journeyEventSchema as Tn, validatePreparationFacts as Tr, sendArtifactSchema as Tt, inspectionQuerySchema as U, confirmedHideKinds as Un, mergePrivacyTerms as Ur, classificationPartition as Ut, validateInspectionBatches as V, confirmedHideGroupIds as Vn, selectedWorks as Vr, applyClassificationProposal as Vt, validateInspectionClaim as W, confirmedHideTerms as Wn, journeyFindingImpactSchema as Wr, classificationWorks as Wt, validateDetectionSummary as X, workDecisionDigest as Xn, packageCommandSchema as Xr, hideBeginSchema as Xt, validateInspectionContribution as Y, retireWorkDescription as Yn, commandSchema as Yr, journeyContextSchema as Yt, inspectionInputs as Z, workPrivacyDecisions as Zn, selectionBatchSchema as Zr, hideFinishSchema as Zt, projectJourneyInventory as _, sessionReviewInputSchema as _n, journeyInventoryQuerySchema as _r, maximumTermsFileBytes as _t, bCrossSegmentReviewSchema as a, effectiveTreatmentSchema as ai, journeyResourceSchema as an, mergeBRepair as ar, maximumAgentSetupSessions as at, bReviewScope as b, sessionReviewStatusSchema as bn, journeyPreparationProgressSchema as br, sendActionSchema as bt, reconstructBFields as c, selectFrozenConfiguration as ci, sortingApplySchema as cn, scanCanonicalResourceSchema as cr, validateFailureLocation as ct, selectedValueMembers as d, reviewAttemptsResultSchema as dn, scanGitSeedsId as dr, manualUploadChoiceSchema as dt, producerVersion as ei, journeySearchSaveSchema as en, reviewCandidateResourceSchema as er, readWorkspaceOutcomes as et, splitSelectorValues as f, sessionReconcileInputSchema as fn, scanGitSeedsResource as fr, manualUploadPrepareSchema as ft, changeJourney as g, sessionRereadResourceSchema as gn, resolveSourceSelection as gr, emptyTermsRevision as gt, semanticGroupKey as h, sessionRereadInputSchema as hn, validateScanExclusion as hr, candidateSortAvailable as ht, validateBCrossSegmentReview as i, approvedTreatmentSchema as ii, journeyResourceQuerySchema as in, bReviewDigest as ir, defaultAgentSetupInclusion as it, profileUrlMatchesIdentity as j, termHideAdditions as jn, nativeGetSchema as jr, currentJourneyAdapters as jt, deviceAuthorizationSchema as k, renderedHideValue as kn, privacyDecisionDigest as kr, sendSettingsSchema as kt, reviseGroupMembership as l, staticCatalogRef as li, reviewAttemptResourceSchema as ln, scanPreparationDigest as lr, manualUploadActionSchema as lt, hideScopeDigest as m, sessionReconciliationResourceSchema as mn, scanExclusionResourceSchema as mr, manualUploadStartSchema as mt, scanBatchEquivalenceDigest as n, sourceChangePolicy as ni, journeyPolicyRespondSchema as nn, reviewRepairResourceSchema as nr, appendSensitiveTerms as nt, bRereadDigest as o, defaultScopedSettings as oi, journeyIsolateSchema as on, planBRepair as or, artifactFailureDetailSchema as ot, activeJourneyTerms as p, sessionReconcileResultSchema as pn, verifiedScanGitSeeds as pr, manualUploadSchema as pt, validateInspectionInputs as q, maskedHitsStale as qn, journeyRenderInputSchema as qr, reviewCompileSchema as qt, locateTermEvidence as r, recommendParallelism as ri, projectPreparationProgress as rn, reviewTransportBytes as rr, classifyAgentSetup as rt, reconcileBSession as s, freezeConfiguration as si, journeyPlaceSchema as sn, scanAliasResourceSchema as sr, resolveFailureLocation as st, scanBatchContextDigest as t, stateSchema as ti, searchScopeDigest as tn, reviewRepairInputSchema as tr, reviewInventory as tt, resolveGroupSplit as u, reviewAttemptsQuerySchema as un, scanSessionResourceSchema as ur, manualUploadBindingSchema as ut, preparationScope as v, sessionReviewQuerySchema as vn, journeyInventoryReadSchema as vr, normalizeSensitiveTerms as vt, reviewBatchReuse as w, journeyCommitSchema as wn, preparationStartSchema as wr, journeySendSchema as wt, rebindReviewAlignment as x, sessionUsefulnessInputSchema as xn, emptyPreparationFacts as xr, sendChoiceSchema as xt, isGenericPublicTerm as y, sessionReviewResourceSchema as yn, journeyInventorySchema as yr, replaceSensitiveTermsSchema as yt, inspectionStartSchema as z, bTermMatcher as zn, isReadingComplete as zr, journeyBatchReadSchema as zt };
|