@peasant-labs/schema 0.18.0 → 0.19.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.
@@ -6,6 +6,17 @@ export const zActivityEdge = z.object({
6
6
  taskCount: z.int(),
7
7
  to: z.string()
8
8
  });
9
+ /**
10
+ * Actor Origin
11
+ *
12
+ * Closed session graph value
13
+ */
14
+ export const zActorOrigin = z.enum([
15
+ 'operator',
16
+ 'agent_delegate',
17
+ 'harness',
18
+ 'unknown'
19
+ ]);
9
20
  /**
10
21
  * Annotation Axis
11
22
  *
@@ -209,6 +220,7 @@ export const zAuthoritativeSessionStats = z.object({
209
220
  cachedReadTokens: z.int().nullish(),
210
221
  cachedWriteTokens: z.int().nullish(),
211
222
  durationMs: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
223
+ inputSubmissionCount: z.int().gte(0).lte(9007199254740991).optional(),
212
224
  subagentCount: z.int(),
213
225
  thoughtTokens: z.int().nullish(),
214
226
  tokensIn: z.int(),
@@ -354,6 +366,31 @@ export const zContentCapability = z.string();
354
366
  * Payload kind carried by a transcript content envelope
355
367
  */
356
368
  export const zContentKind = z.enum(['session_detail']);
369
+ /**
370
+ * Content Origin
371
+ *
372
+ * Closed session graph value
373
+ */
374
+ export const zContentOrigin = z.enum([
375
+ 'submitted_input',
376
+ 'harness_context',
377
+ 'agent_output',
378
+ 'agent_communication',
379
+ 'tool_activity',
380
+ 'system_control',
381
+ 'generated_summary',
382
+ 'unknown'
383
+ ]);
384
+ /**
385
+ * Content Ownership
386
+ *
387
+ * Closed session graph value
388
+ */
389
+ export const zContentOwnership = z.enum([
390
+ 'local',
391
+ 'inherited',
392
+ 'uncertain'
393
+ ]);
357
394
  export const zContractVersion = z.string().nullable();
358
395
  export const zCreateAnnotationRequest = z.object({
359
396
  annotatorName: z.string().optional(),
@@ -397,6 +434,20 @@ export const zDecayLevel = z.enum([
397
434
  'stale',
398
435
  'unexplored'
399
436
  ]);
437
+ /**
438
+ * Delivery Origin
439
+ *
440
+ * Closed session graph value
441
+ */
442
+ export const zDeliveryOrigin = z.enum([
443
+ 'session_admission',
444
+ 'guardian_review',
445
+ 'subagent_delivery',
446
+ 'inherited_context',
447
+ 'tool_delivery',
448
+ 'system_lifecycle',
449
+ 'unknown'
450
+ ]);
400
451
  export const zDiagnosticEntry = z.object({
401
452
  errorType: z.string(),
402
453
  location: z.string(),
@@ -442,6 +493,12 @@ export const zDigestItemKind = z.enum([
442
493
  'skill',
443
494
  'commit'
444
495
  ]);
496
+ /**
497
+ * Earlier History State
498
+ *
499
+ * Closed session graph value
500
+ */
501
+ export const zEarlierHistoryState = z.enum(['uncertain_migrated', 'uncertain_unresolved']);
445
502
  /**
446
503
  * Edge Violation Kind
447
504
  *
@@ -467,6 +524,19 @@ export const zEntryType = z.enum([
467
524
  'error',
468
525
  'result'
469
526
  ]);
527
+ /**
528
+ * Evidence Kind
529
+ *
530
+ * Closed session graph value
531
+ */
532
+ export const zEvidenceKind = z.enum([
533
+ 'native_typed',
534
+ 'lifecycle_typed',
535
+ 'existing_adapter',
536
+ 'retained_last_good',
537
+ 'unknown',
538
+ 'conflict'
539
+ ]);
470
540
  export const zExchangeCodeRequest = z.object({
471
541
  code: z.string(),
472
542
  state: z.string()
@@ -546,6 +616,19 @@ export const zHealthResponse = z.object({
546
616
  * Sanitized, filesystem-safe identifier derived from git remote; contains only [a-zA-Z0-9._<>-]
547
617
  */
548
618
  export const zHostSlug = z.string().regex(/^[a-zA-Z0-9._<>-]+$/);
619
+ /**
620
+ * Input Modality
621
+ *
622
+ * Closed session graph value
623
+ */
624
+ export const zInputModality = z.enum([
625
+ 'none',
626
+ 'text',
627
+ 'media',
628
+ 'user_action',
629
+ 'mixed',
630
+ 'unknown'
631
+ ]);
549
632
  export const zInsightClassification = z.object({
550
633
  category: z.string(),
551
634
  cause: z.string(),
@@ -686,25 +769,12 @@ export const zNativeMetadataSourceType = z.enum([
686
769
  * Pi message role needed for public metadata validation
687
770
  */
688
771
  export const zNativePiMessageRole = z.enum(['toolResult']);
689
- export const zNativeSourceRef = z.object({
690
- entryRef: z.string(),
691
- messageRole: zNativePiMessageRole.optional(),
692
- sourceType: zNativeMetadataSourceType
693
- });
694
- export const zNativeMetadataRecord = z.object({
695
- attachment: zNativeAttachmentRef.nullish(),
696
- customType: z.string().optional(),
697
- data: z.unknown(),
698
- id: z.string(),
699
- kind: zNativeMetadataKind,
700
- source: zNativeSourceRef
701
- });
702
772
  /**
703
773
  * Observed Model ID
704
774
  *
705
775
  * Exact UTF-8 model identifier observed on an assistant-generated turn; producer-enforced as assistant or subagent evidence. Values are non-empty and may not have a Unicode White_Space code point at either edge; all accepted bytes, including Unicode, mixed case, slashes, and internal spaces, are preserved.
706
776
  */
707
- export const zObservedModelID = z.string().min(1).regex(/^(?:|[^\s\x85])(?:[\s\S]*(?:|[^\s\x85]))?(?![\s\S])/);
777
+ export const zObservedModelID = z.string().min(1).regex(/^(?:|[^\s])(?:[\s\S]*(?:|[^\s]))?$/).refine((value) => { const edge = (text) => text === "\uFEFF" || (!/\s/u.test(text) && text !== "\u0085"); return edge(value.charAt(0)) && edge(value.charAt(value.length - 1)); }, { error: "ObservedModelID must match pattern without edge whitespace" });
708
778
  /**
709
779
  * Omitted preserves, null requests clear, and a canonical license replaces
710
780
  */
@@ -724,6 +794,23 @@ export const zAuthoritativeProjectContext = z.object({
724
794
  hash: zProjectHash,
725
795
  name: z.string()
726
796
  }).strict();
797
+ export const zLocalSyncSummary = z.object({
798
+ durationMs: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
799
+ harness: zHarness,
800
+ hostSlug: z.string(),
801
+ id: z.string(),
802
+ inputSubmissionCount: z.int().gte(0).lte(9007199254740991).optional(),
803
+ model: z.string(),
804
+ projectHash: zProjectHash,
805
+ projectName: z.string(),
806
+ startTime: z.string(),
807
+ syncStatus: z.string(),
808
+ totalTokens: z.int(),
809
+ turnCount: z.int()
810
+ });
811
+ export const zLocalSyncSessionsPayload = z.object({
812
+ sessions: z.array(zLocalSyncSummary)
813
+ });
727
814
  export const zProjectContext = z.object({
728
815
  filePath: z.string().optional(),
729
816
  hash: zProjectHash,
@@ -764,6 +851,20 @@ export const zProvenance = z.object({
764
851
  method: z.string(),
765
852
  version: z.string().optional()
766
853
  });
854
+ /**
855
+ * Public Revision Reference
856
+ */
857
+ export const zPublicRevisionRef = z.string().min(1).max(96).refine((value) => !/[\uD800-\uDFFF]/u.test(value) && new TextEncoder().encode(value).length <= 96, { error: "PublicRevisionRef is invalid UTF-8 or exceeds 96 bytes" });
858
+ /**
859
+ * Public Source Anchor Kind
860
+ *
861
+ * Closed session graph value
862
+ */
863
+ export const zPublicSourceAnchorKind = z.enum([
864
+ 'general_source_session',
865
+ 'before_redacted_entry',
866
+ 'through_redacted_entry'
867
+ ]);
767
868
  /**
768
869
  * Publish Operation Kind
769
870
  *
@@ -936,6 +1037,39 @@ export const zRedactionInfo = z.object({
936
1037
  redacted_at_ms: z.int().nullish(),
937
1038
  rule_set_version: z.string().optional()
938
1039
  });
1040
+ /**
1041
+ * Relationship Navigation Status
1042
+ *
1043
+ * Closed session graph value
1044
+ */
1045
+ export const zRelationshipNavigationStatus = z.enum([
1046
+ 'resolved',
1047
+ 'general_link_only',
1048
+ 'known_unavailable',
1049
+ 'inaccessible',
1050
+ 'unknown',
1051
+ 'conflicting'
1052
+ ]);
1053
+ export const zHelperContextSummary = z.object({
1054
+ groupId: z.string(),
1055
+ ownerStatus: zRelationshipNavigationStatus
1056
+ }).superRefine((value, context) => {
1057
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zHelperContextSummary during grouped read validation: " + reason });
1058
+ if (value.groupId === "")
1059
+ fail("context groupId must identify its scoped group; refresh the original list");
1060
+ });
1061
+ /**
1062
+ * Relationship Target State
1063
+ *
1064
+ * Closed session graph value
1065
+ */
1066
+ export const zRelationshipTargetState = z.enum([
1067
+ 'target_known',
1068
+ 'target_known_retained',
1069
+ 'explicit_none',
1070
+ 'unknown',
1071
+ 'conflicting_current_native_evidence'
1072
+ ]);
939
1073
  export const zReviewSuggestion = z.object({
940
1074
  daysSince: z.int(),
941
1075
  lastEngaged: z.string(),
@@ -1024,11 +1158,6 @@ export const zServerMessage = z.object({
1024
1158
  * Unique session identifier (UUID, agent-{hex}, ses_{id}, sess_{id} (ACP), msg_{id}, or a Strike session ID)
1025
1159
  */
1026
1160
  export const zSessionID = z.string().regex(/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|agent-[a-f0-9]+|sess?_[a-zA-Z0-9]+|msg_[a-zA-Z0-9]+|[0-9]{8}T[0-9]{6}\.[0-9]{9}Z-[A-Z2-7]{26}|[A-Z2-7]{26})$/);
1027
- export const zAuthoritativeSessionIdentity = z.object({
1028
- parentSessionId: zSessionID.optional(),
1029
- schemaVersion: z.int(),
1030
- sessionId: zSessionID
1031
- }).strict();
1032
1161
  export const zAuthoritativeSubagentRef = z.object({
1033
1162
  parentUuid: zSessionID,
1034
1163
  sessionId: zSessionID
@@ -1122,6 +1251,12 @@ export const zSessionInsight = z.object({
1122
1251
  summary: z.string().optional(),
1123
1252
  title: z.string()
1124
1253
  });
1254
+ /**
1255
+ * Session List Item Kind
1256
+ *
1257
+ * Closed session graph value
1258
+ */
1259
+ export const zSessionListItemKind = z.enum(['transcript', 'context_container']);
1125
1260
  /**
1126
1261
  * Session Origin
1127
1262
  *
@@ -1230,6 +1365,33 @@ export const zQualityMetrics = z.object({
1230
1365
  turnCount: z.int().nullish(),
1231
1366
  withinSessionReverts: z.int().nullish()
1232
1367
  });
1368
+ /**
1369
+ * Session Purpose
1370
+ *
1371
+ * Closed session graph value
1372
+ */
1373
+ export const zSessionPurpose = z.enum([
1374
+ 'interaction',
1375
+ 'delegated_work',
1376
+ 'helper_review',
1377
+ 'unknown'
1378
+ ]);
1379
+ export const zHelperGroupSummary = z.object({
1380
+ groupId: z.string(),
1381
+ helperThreadCount: z.int().gte(0).lte(9007199254740991),
1382
+ memberScope: z.string(),
1383
+ purpose: zSessionPurpose
1384
+ }).superRefine((value, context) => {
1385
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zHelperGroupSummary during grouped read validation: " + reason });
1386
+ if (value.groupId === "" || value.memberScope === "" || value.purpose !== "helper_review")
1387
+ fail("groupId/memberScope must identify an immediate helper_review group; refresh the original scoped list");
1388
+ });
1389
+ /**
1390
+ * Session Relationship Kind
1391
+ *
1392
+ * Closed session graph value
1393
+ */
1394
+ export const zSessionRelationshipKind = z.enum(['started_by', 'context_from']);
1233
1395
  export const zSessionScorecard = z.object({
1234
1396
  costTotalUsd: z.number().nullish(),
1235
1397
  m2TokenOutcomeRatio: z.number().nullish(),
@@ -1249,6 +1411,7 @@ export const zSessionStats = z.object({
1249
1411
  cachedReadTokens: z.int().nullish(),
1250
1412
  cachedWriteTokens: z.int().nullish(),
1251
1413
  durationMs: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
1414
+ inputSubmissionCount: z.int().gte(0).lte(9007199254740991).optional(),
1252
1415
  subagentCount: z.int(),
1253
1416
  thoughtTokens: z.int().nullish(),
1254
1417
  tokensIn: z.int(),
@@ -1256,27 +1419,141 @@ export const zSessionStats = z.object({
1256
1419
  toolCallCount: z.int(),
1257
1420
  turnCount: z.int()
1258
1421
  });
1422
+ export const zShutdownResponse = z.object({
1423
+ status: z.string()
1424
+ });
1425
+ /**
1426
+ * Source Entry Reference
1427
+ */
1428
+ export const zSourceEntryRef = z.string().min(1).max(96).refine((value) => !/[\uD800-\uDFFF]/u.test(value) && new TextEncoder().encode(value).length <= 96, { error: "SourceEntryRef is invalid UTF-8 or exceeds 96 bytes" });
1429
+ export const zNativeSourceRef = z.object({
1430
+ entryRef: zSourceEntryRef,
1431
+ messageRole: zNativePiMessageRole.optional(),
1432
+ sourceType: zNativeMetadataSourceType
1433
+ });
1434
+ export const zNativeMetadataRecord = z.object({
1435
+ attachment: zNativeAttachmentRef.nullish(),
1436
+ customType: z.string().optional(),
1437
+ data: z.unknown(),
1438
+ id: z.string(),
1439
+ kind: zNativeMetadataKind,
1440
+ source: zNativeSourceRef
1441
+ });
1442
+ export const zPublicSourceAnchor = z.object({
1443
+ kind: zPublicSourceAnchorKind,
1444
+ sourceEntryRef: zSourceEntryRef.optional(),
1445
+ sourceRevisionRef: zPublicRevisionRef.optional()
1446
+ }).strict();
1447
+ export const zSessionRelationship = z.object({
1448
+ anchor: zPublicSourceAnchor.optional(),
1449
+ evidence: zEvidenceKind,
1450
+ kind: zSessionRelationshipKind,
1451
+ targetLocalId: zSessionID.optional(),
1452
+ targetState: zRelationshipTargetState
1453
+ }).strict();
1454
+ export const zAuthoritativeSessionIdentity = z.object({
1455
+ parentSessionId: zSessionID.optional(),
1456
+ purpose: zSessionPurpose.optional(),
1457
+ relationships: z.array(zSessionRelationship).optional(),
1458
+ rootSessionId: zSessionID.optional(),
1459
+ schemaVersion: z.int(),
1460
+ sessionId: zSessionID
1461
+ }).strict();
1259
1462
  export const zSessionSummary = z.object({
1260
1463
  durationMins: z.number(),
1261
1464
  harness: zHarness,
1262
1465
  id: z.string(),
1466
+ inputSubmissionCount: z.int().gte(0).lte(9007199254740991).optional(),
1263
1467
  outcome: z.string().optional(),
1264
1468
  parentSessionId: z.string().nullish(),
1265
1469
  preview: z.string().optional(),
1266
1470
  project: z.string().optional(),
1267
1471
  projectHash: zProjectHash.optional(),
1472
+ purpose: zSessionPurpose.optional(),
1473
+ relationships: z.array(zSessionRelationship).optional(),
1474
+ rootSessionId: zSessionID.nullish(),
1268
1475
  sessionOrigin: zSessionOrigin.optional(),
1269
1476
  startTime: z.iso.datetime(),
1270
1477
  toolCallCount: z.int(),
1271
1478
  totalTokens: z.int(),
1272
1479
  turnCount: z.int()
1273
1480
  });
1481
+ export const zLocalSessionRow = z.object({
1482
+ matches: z.array(zSearchResult).optional(),
1483
+ session: zSessionSummary,
1484
+ sync: zLocalSyncSummary.nullish()
1485
+ }).superRefine((value, context) => {
1486
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zLocalSessionRow during grouped read validation: " + reason });
1487
+ if (value.session.id === "")
1488
+ fail("session.id is empty; provide the saved transcript identity");
1489
+ if (value.sync && value.matches?.length)
1490
+ fail("sync and matches select incompatible route arms; retain the originating route only");
1491
+ if (value.sync) {
1492
+ const s = value.session, v = value.sync;
1493
+ if (v.id !== s.id || v.harness !== s.harness || v.projectName !== s.project || v.projectHash !== s.projectHash || v.totalTokens !== s.totalTokens || v.turnCount !== s.turnCount || v.inputSubmissionCount !== s.inputSubmissionCount)
1494
+ fail("sync identity or count mirrors disagree; derive both from the same row");
1495
+ }
1496
+ if (value.matches?.some(match => match.sessionId !== value.session.id))
1497
+ fail("search match belongs to another session; retain only this transcript's evidence");
1498
+ });
1499
+ export const zLocalSessionListItem = z.object({
1500
+ context: zHelperContextSummary.nullish(),
1501
+ helperGroups: z.array(zHelperGroupSummary).optional(),
1502
+ kind: zSessionListItemKind,
1503
+ transcript: zLocalSessionRow.nullish()
1504
+ }).superRefine((value, context) => {
1505
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zLocalSessionListItem during grouped read validation: " + reason });
1506
+ if ((value.kind === "transcript") !== (value.transcript != null) || (value.kind === "context_container") !== (value.context != null))
1507
+ fail("kind must select exactly one matching transcript/context arm; omit the other arm");
1508
+ const groups = new Set();
1509
+ for (const group of value.helperGroups ?? []) {
1510
+ if (groups.has(group.groupId))
1511
+ fail("duplicate groupId prevents independent paging; emit each immediate group once");
1512
+ groups.add(group.groupId);
1513
+ }
1514
+ });
1515
+ export const zLocalHelperMembersPayload = z.object({
1516
+ limit: z.int().gte(1).lte(9007199254740991),
1517
+ members: z.array(zLocalSessionListItem.and(z.object({
1518
+ context: z.null().optional(),
1519
+ kind: z.enum(['transcript']).optional(),
1520
+ transcript: zLocalSessionRow
1521
+ }))),
1522
+ page: z.int().gte(1).lte(9007199254740991),
1523
+ total: z.int().gte(0).lte(9007199254740991)
1524
+ }).superRefine((value, context) => {
1525
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zLocalHelperMembersPayload during grouped read validation: " + reason });
1526
+ if (value.members.length > value.limit || value.members.length > value.total)
1527
+ fail("member count exceeds page limit or direct total; count direct saved helpers before paging");
1528
+ const ids = new Set();
1529
+ const groups = new Set();
1530
+ for (const member of value.members) {
1531
+ if (member.kind !== "transcript" || member.transcript == null || member.context != null) {
1532
+ fail("members must be transcript items, never context containers; preserve nested groups on the item");
1533
+ continue;
1534
+ }
1535
+ const id = member.transcript.session.id;
1536
+ if (ids.has(id))
1537
+ fail("duplicate member identity would double count a saved helper; emit each transcript once");
1538
+ ids.add(id);
1539
+ for (const group of member.helperGroups ?? []) {
1540
+ if (groups.has(group.groupId))
1541
+ fail("groupId appears under multiple members; emit each immediate-owner group once");
1542
+ groups.add(group.groupId);
1543
+ }
1544
+ }
1545
+ });
1546
+ export const zLocalSessionListPayload = z.object({
1547
+ helperThreadTotal: z.int().gte(0).lte(9007199254740991),
1548
+ items: z.array(zLocalSessionListItem),
1549
+ limit: z.int().gte(1).lte(9007199254740991),
1550
+ ordinarySessionTotal: z.int().gte(0).lte(9007199254740991),
1551
+ page: z.int().gte(1).lte(9007199254740991),
1552
+ totalItems: z.int().gte(0).lte(9007199254740991)
1553
+ });
1274
1554
  export const zSessionsPayload = z.object({
1275
1555
  sessions: z.array(zSessionSummary).nullable()
1276
1556
  });
1277
- export const zShutdownResponse = z.object({
1278
- status: z.string()
1279
- });
1280
1557
  /**
1281
1558
  * Source Format
1282
1559
  *
@@ -1307,6 +1584,19 @@ export const zSubagentRef = z.object({
1307
1584
  parentUuid: zSessionID,
1308
1585
  sessionId: zSessionID
1309
1586
  });
1587
+ /**
1588
+ * Submission Reference
1589
+ */
1590
+ export const zSubmissionRef = z.string().min(1).max(96).refine((value) => !/[\uD800-\uDFFF]/u.test(value) && new TextEncoder().encode(value).length <= 96, { error: "SubmissionRef is invalid UTF-8 or exceeds 96 bytes" });
1591
+ export const zContentProvenance = z.object({
1592
+ actor: zActorOrigin,
1593
+ delivery: zDeliveryOrigin,
1594
+ evidence: zEvidenceKind,
1595
+ inputModality: zInputModality,
1596
+ origin: zContentOrigin,
1597
+ ownership: zContentOwnership,
1598
+ submissionRef: zSubmissionRef.optional()
1599
+ }).strict();
1310
1600
  /**
1311
1601
  * Target Kind
1312
1602
  *
@@ -1652,9 +1942,11 @@ export const zAuthoritativeSessionEntry = z.object({
1652
1942
  parentEntryId: z.string().nullish(),
1653
1943
  parentIndex: z.int().nullish(),
1654
1944
  partType: z.string().nullish(),
1945
+ provenance: zContentProvenance.optional(),
1655
1946
  rawByteLength: z.int().nullish(),
1656
1947
  role: zRole,
1657
1948
  sessionId: zSessionID,
1949
+ sourceEntryRef: zSourceEntryRef.optional(),
1658
1950
  stopReason: zStopReason.nullish(),
1659
1951
  timestampMs: z.int().nullish(),
1660
1952
  tokensIn: z.int().nullish(),
@@ -1692,9 +1984,11 @@ export const zSessionEntry = z.object({
1692
1984
  parentEntryId: z.string().nullish(),
1693
1985
  parentIndex: z.int().nullish(),
1694
1986
  partType: z.string().nullish(),
1987
+ provenance: zContentProvenance.nullish(),
1695
1988
  rawByteLength: z.int().nullish(),
1696
1989
  role: zRole,
1697
1990
  sessionId: zSessionID,
1991
+ sourceEntryRef: zSourceEntryRef.optional(),
1698
1992
  stopReason: zStopReason.nullish(),
1699
1993
  timestampMs: z.int().nullish(),
1700
1994
  tokensIn: z.int().nullish(),
@@ -1769,6 +2063,13 @@ export const zPullSkipGateResult = z.object({
1769
2063
  export const zPullSkipGateResponse = z.object({
1770
2064
  results: z.array(zPullSkipGateResult)
1771
2065
  });
2066
+ export const zSessionRelationshipNavigation = z.object({
2067
+ anchor: zPublicSourceAnchor.optional(),
2068
+ kind: zSessionRelationshipKind,
2069
+ localId: zSessionID.optional(),
2070
+ status: zRelationshipNavigationStatus,
2071
+ transcriptId: zTranscriptID.optional()
2072
+ }).strict();
1772
2073
  /**
1773
2074
  * TranscriptUpdateLicense
1774
2075
  *
@@ -1859,7 +2160,10 @@ export const zUnifiedMetadata = z.object({
1859
2160
  model: zModelID,
1860
2161
  parentUuid: zSessionID.nullable(),
1861
2162
  project: zProjectContext,
2163
+ purpose: zSessionPurpose.optional(),
1862
2164
  redaction: zRedactionInfo,
2165
+ relationships: z.array(zSessionRelationship).optional(),
2166
+ rootSessionId: zSessionID.nullish(),
1863
2167
  schemaVersion: z.int(),
1864
2168
  sessionId: zSessionID,
1865
2169
  source: zSourceInfo,
@@ -1921,12 +2225,13 @@ export const zUsageDetail = z.object({
1921
2225
  cost: zRecordedCostDetail.nullish(),
1922
2226
  ownerId: z.string(),
1923
2227
  scope: zUsageScope,
1924
- sourceEntryRef: z.string(),
2228
+ sourceEntryRef: zSourceEntryRef,
1925
2229
  tokens: zTokenUsageDetail.nullish()
1926
2230
  });
1927
2231
  export const zToolCallDetail = z.object({
1928
2232
  arguments: z.string(),
1929
- callEntryRef: z.string().optional(),
2233
+ callEntryRef: zSourceEntryRef.optional(),
2234
+ callProvenance: zContentProvenance.nullish(),
1930
2235
  durationMs: z.int().nullish(),
1931
2236
  exitCode: z.int().nullish(),
1932
2237
  filePath: z.string().optional(),
@@ -1935,7 +2240,8 @@ export const zToolCallDetail = z.object({
1935
2240
  name: z.string(),
1936
2241
  namespace: z.string().optional(),
1937
2242
  result: z.string(),
1938
- resultEntryRef: z.string().optional(),
2243
+ resultEntryRef: zSourceEntryRef.optional(),
2244
+ resultProvenance: zContentProvenance.nullish(),
1939
2245
  toolKind: zToolCallKind.optional(),
1940
2246
  usage: zUsageDetail.nullish()
1941
2247
  });
@@ -1949,8 +2255,9 @@ export const zTurnDetail = z.object({
1949
2255
  index: z.int(),
1950
2256
  observedModel: zObservedModelID.optional(),
1951
2257
  parentIndex: z.int().nullish(),
2258
+ provenance: zContentProvenance.nullish(),
1952
2259
  role: zRole,
1953
- sourceEntryRef: z.string().optional(),
2260
+ sourceEntryRef: zSourceEntryRef.optional(),
1954
2261
  stopReason: zStopReason.nullish(),
1955
2262
  timestamp: z.iso.datetime(),
1956
2263
  tokensIn: z.int().nullish(),
@@ -1958,18 +2265,29 @@ export const zTurnDetail = z.object({
1958
2265
  toolCalls: z.array(zToolCallDetail).optional(),
1959
2266
  usage: zUsageDetail.nullish()
1960
2267
  });
2268
+ export const zEarlierHistorySection = z.object({
2269
+ nativeMetadata: z.array(zNativeMetadataRecord).optional(),
2270
+ state: zEarlierHistoryState,
2271
+ turns: z.array(zTurnDetail)
2272
+ }).strict();
1961
2273
  export const zSessionDetailPayload = z.object({
1962
2274
  childSessions: z.array(zChildSessionRef).optional(),
1963
2275
  durationMins: z.number(),
2276
+ earlierHistory: z.array(zEarlierHistorySection).optional(),
1964
2277
  endTime: z.iso.datetime(),
1965
2278
  gitBranch: z.string().optional(),
1966
2279
  gitRemote: z.string().optional(),
1967
2280
  harness: zHarness,
1968
2281
  id: z.string(),
2282
+ inputSubmissionCount: z.int().gte(0).lte(9007199254740991).optional(),
1969
2283
  model: z.string().optional(),
1970
2284
  nativeMetadata: z.array(zNativeMetadataRecord).optional(),
1971
2285
  outcome: zSessionOutcome.optional(),
2286
+ parentSessionId: zSessionID.nullish(),
1972
2287
  project: z.string().optional(),
2288
+ purpose: zSessionPurpose.optional(),
2289
+ relationships: z.array(zSessionRelationship).optional(),
2290
+ rootSessionId: zSessionID.nullish(),
1973
2291
  schemaVersion: z.string().optional(),
1974
2292
  scorecard: zSessionScorecard.nullish(),
1975
2293
  sessionOrigin: zSessionOrigin.optional(),
@@ -1984,6 +2302,39 @@ export const zSessionDetailPayload = z.object({
1984
2302
  turns: z.array(zTurnDetail).nullable(),
1985
2303
  workingDirectory: z.string().optional()
1986
2304
  });
2305
+ export const zSessionDetailReadPayload = z.object({
2306
+ childSessions: z.array(zChildSessionRef).optional(),
2307
+ durationMins: z.number().optional(),
2308
+ earlierHistory: z.array(zEarlierHistorySection).optional(),
2309
+ endTime: z.iso.datetime().optional(),
2310
+ gitBranch: z.string().optional(),
2311
+ gitRemote: z.string().optional(),
2312
+ harness: zHarness.optional(),
2313
+ id: z.string().optional(),
2314
+ inputSubmissionCount: z.int().gte(0).lte(9007199254740991).optional(),
2315
+ model: z.string().optional(),
2316
+ nativeMetadata: z.array(zNativeMetadataRecord).optional(),
2317
+ outcome: zSessionOutcome.optional(),
2318
+ parentSessionId: zSessionID.optional(),
2319
+ project: z.string().optional(),
2320
+ purpose: zSessionPurpose.optional(),
2321
+ relationshipNavigation: z.array(zSessionRelationshipNavigation).optional(),
2322
+ relationships: z.array(zSessionRelationship).optional(),
2323
+ rootSessionId: zSessionID.optional(),
2324
+ schemaVersion: z.string().optional(),
2325
+ scorecard: zSessionScorecard.optional(),
2326
+ sessionOrigin: zSessionOrigin.optional(),
2327
+ source: z.string().optional(),
2328
+ startTime: z.iso.datetime().optional(),
2329
+ status: z.string().optional(),
2330
+ tokensIn: z.int().optional(),
2331
+ tokensOut: z.int().optional(),
2332
+ toolCallCount: z.int().optional(),
2333
+ totalTokens: z.int().optional(),
2334
+ turnCount: z.int().optional(),
2335
+ turns: z.array(zTurnDetail).nullish(),
2336
+ workingDirectory: z.string().optional()
2337
+ });
1987
2338
  export const zTranscriptContent = z.object({
1988
2339
  contractVersion: z.string(),
1989
2340
  kind: zContentKind,
@@ -2140,6 +2491,19 @@ export const zVillageLinkRepositoryRequest = z.object({
2140
2491
  name: z.string(),
2141
2492
  owner: z.string()
2142
2493
  });
2494
+ export const zVillageListTranscriptAttestation = z.object({
2495
+ attestation_type: z.string(),
2496
+ created_at: z.iso.datetime(),
2497
+ org_login: z.string(),
2498
+ transcript_id: zTranscriptID
2499
+ });
2500
+ export const zVillageMetadataUserOrganization = z.object({
2501
+ avatar_url: z.string().nullable(),
2502
+ fetched_at: z.iso.datetime(),
2503
+ org_id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
2504
+ org_login: z.string(),
2505
+ visible: z.boolean()
2506
+ });
2143
2507
  /**
2144
2508
  * Village Project Name Source
2145
2509
  *
@@ -2270,6 +2634,7 @@ export const zVillageContributableTranscript = z.object({
2270
2634
  already_shared: z.boolean(),
2271
2635
  git_branch: z.string().nullable(),
2272
2636
  id: zTranscriptID,
2637
+ input_submission_count: z.int().gte(0).lte(9007199254740991).optional(),
2273
2638
  local_id: zSessionID,
2274
2639
  model_provider: z.string(),
2275
2640
  parent_session_id: zSessionID.nullable(),
@@ -2277,6 +2642,9 @@ export const zVillageContributableTranscript = z.object({
2277
2642
  project_hash: zProjectHash,
2278
2643
  project_name_source: zVillageProjectNameSource,
2279
2644
  published_at: z.iso.datetime(),
2645
+ purpose: zSessionPurpose.optional(),
2646
+ relationships: z.array(zSessionRelationship).optional(),
2647
+ root_session_id: zSessionID.nullish(),
2280
2648
  session_origin: zSessionOrigin,
2281
2649
  title: z.string().nullable(),
2282
2650
  visibility: zVillageTranscriptVisibility
@@ -2330,6 +2698,14 @@ export const zVillageContributedCollective = z.object({
2330
2698
  export const zVillageContributedCollectivesResponse = z.object({
2331
2699
  collectives: z.array(zVillageContributedCollective)
2332
2700
  });
2701
+ export const zVillageEnrichedTranscriptShare = z.object({
2702
+ acceptance_mode: zVillageGroupAcceptanceMode,
2703
+ group_id: zVillageUUID,
2704
+ group_name: z.string(),
2705
+ shared_at: z.iso.datetime(),
2706
+ status: zVillageShareStatus,
2707
+ transcript_id: zTranscriptID
2708
+ });
2333
2709
  export const zVillageGroup = z.object({
2334
2710
  acceptance_mode: zVillageGroupAcceptanceMode,
2335
2711
  created_at: z.iso.datetime(),
@@ -2351,6 +2727,21 @@ export const zVillageGroupContributor = z.object({
2351
2727
  id: zVillageUUID,
2352
2728
  transcript_count: z.int().min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }).max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' })
2353
2729
  });
2730
+ export const zVillageGroupDetailRecord = z.object({
2731
+ acceptance_mode: zVillageGroupAcceptanceMode,
2732
+ created_at: z.iso.datetime(),
2733
+ created_by: zVillageUUID,
2734
+ data_access: zVillageGroupDataAccess,
2735
+ description: z.string().nullable(),
2736
+ display_members: z.boolean(),
2737
+ id: zVillageUUID,
2738
+ linked_github_org: z.string().nullable(),
2739
+ name: z.string(),
2740
+ post_prompts_check: z.boolean().nullish(),
2741
+ prompts_check_mode: zVillagePromptsCheckMode.nullish(),
2742
+ transcript_deletion_policy: zVillageTranscriptDeletionPolicy,
2743
+ updated_at: z.iso.datetime()
2744
+ });
2354
2745
  export const zVillageGroupMember = z.object({
2355
2746
  avatar_url: z.string().nullable(),
2356
2747
  display_name: z.string().nullable(),
@@ -2377,6 +2768,7 @@ export const zVillageGroupTranscript = z.object({
2377
2768
  harness_version: z.string().nullable(),
2378
2769
  id: zTranscriptID,
2379
2770
  ingested_at: z.iso.datetime().nullable(),
2771
+ input_submission_count: z.int().gte(0).lte(9007199254740991).optional(),
2380
2772
  license_id: zLicense.nullable(),
2381
2773
  lines_changed: z.int().nullable(),
2382
2774
  local_id: zSessionID,
@@ -2407,8 +2799,11 @@ export const zVillageGroupTranscript = z.object({
2407
2799
  project_name_source: zVillageProjectNameSource,
2408
2800
  project_remote_label: z.string(),
2409
2801
  published_at: z.iso.datetime(),
2802
+ purpose: zSessionPurpose.optional(),
2803
+ relationships: z.array(zSessionRelationship).optional(),
2410
2804
  retry_loops: z.int().nullable(),
2411
2805
  retry_tokens_wasted: z.int().nullable(),
2806
+ root_session_id: zSessionID.nullish(),
2412
2807
  schema_version: z.string(),
2413
2808
  scope_breadth: z.int().nullable(),
2414
2809
  session_end: z.iso.datetime().nullable(),
@@ -2433,7 +2828,7 @@ export const zVillageGroupTranscript = z.object({
2433
2828
  export const zVillageGroupDetailResponse = z.object({
2434
2829
  can_read: z.boolean(),
2435
2830
  contributors: z.array(zVillageGroupContributor),
2436
- group: zVillageGroup,
2831
+ group: zVillageGroupDetailRecord,
2437
2832
  members: z.array(zVillageGroupMember),
2438
2833
  models: z.array(zVillageGroupModelBreakdown),
2439
2834
  pending_members: z.array(zVillageGroupMember).optional(),
@@ -2455,8 +2850,14 @@ export const zVillageLinkedRepository = z.object({
2455
2850
  export const zVillageLinkedRepositoriesResponse = z.object({
2456
2851
  repositories: z.array(zVillageLinkedRepository)
2457
2852
  });
2853
+ export const zVillageListUserOrganization = z.object({
2854
+ avatar_url: z.string().nullable(),
2855
+ org_login: z.string(),
2856
+ user_id: zVillageUUID
2857
+ });
2458
2858
  export const zVillagePendingShare = z.object({
2459
2859
  branch: z.string().nullable(),
2860
+ input_submission_count: z.int().gte(0).lte(9007199254740991).optional(),
2460
2861
  local_id: zSessionID,
2461
2862
  model_provider: z.string(),
2462
2863
  owner_id: zVillageUUID,
@@ -2465,6 +2866,9 @@ export const zVillagePendingShare = z.object({
2465
2866
  parent_session_id: zSessionID.nullable(),
2466
2867
  project_hash: zProjectHash,
2467
2868
  project_name: z.string().nullable(),
2869
+ purpose: zSessionPurpose.optional(),
2870
+ relationships: z.array(zSessionRelationship).optional(),
2871
+ root_session_id: zSessionID.nullish(),
2468
2872
  shared_at: z.iso.datetime(),
2469
2873
  title: z.string().nullable(),
2470
2874
  transcript_id: zTranscriptID
@@ -2506,6 +2910,10 @@ export const zVillagePullRequestAttachmentResponse = z.object({
2506
2910
  export const zVillageShareTranscriptRequest = z.object({
2507
2911
  group_ids: z.array(zVillageUUID)
2508
2912
  });
2913
+ export const zVillageTag = z.object({
2914
+ id: zVillageUUID,
2915
+ name: z.string()
2916
+ });
2509
2917
  export const zVillageTranscript = z.object({
2510
2918
  blob_size_bytes: z.int().nullable(),
2511
2919
  compute_version: z.int().nullable(),
@@ -2523,6 +2931,7 @@ export const zVillageTranscript = z.object({
2523
2931
  harness_version: z.string().nullable(),
2524
2932
  id: zTranscriptID,
2525
2933
  ingested_at: z.iso.datetime().nullable(),
2934
+ input_submission_count: z.int().gte(0).lte(9007199254740991).optional(),
2526
2935
  license_id: zLicense.nullable(),
2527
2936
  lines_changed: z.int().nullable(),
2528
2937
  local_id: zSessionID,
@@ -2550,8 +2959,11 @@ export const zVillageTranscript = z.object({
2550
2959
  project_name_source: zVillageProjectNameSource,
2551
2960
  project_remote_label: z.string(),
2552
2961
  published_at: z.iso.datetime(),
2962
+ purpose: zSessionPurpose.optional(),
2963
+ relationships: z.array(zSessionRelationship).optional(),
2553
2964
  retry_loops: z.int().nullable(),
2554
2965
  retry_tokens_wasted: z.int().nullable(),
2966
+ root_session_id: zSessionID.nullish(),
2555
2967
  schema_version: z.string(),
2556
2968
  scope_breadth: z.int().nullable(),
2557
2969
  session_end: z.iso.datetime().nullable(),
@@ -2573,6 +2985,16 @@ export const zVillageTranscript = z.object({
2573
2985
  visibility: zVillageTranscriptVisibility,
2574
2986
  within_session_reverts: z.int().nullable()
2575
2987
  });
2988
+ export const zVillageTranscriptAttestation = z.object({
2989
+ attestation_type: z.string(),
2990
+ attester_avatar: z.string().nullable(),
2991
+ attester_username: z.string(),
2992
+ created_at: z.iso.datetime(),
2993
+ id: zVillageUUID,
2994
+ note: z.string().nullable(),
2995
+ org_login: z.string(),
2996
+ transcript_id: zTranscriptID
2997
+ });
2576
2998
  export const zVillageTranscriptCollective = z.object({
2577
2999
  description: z.string().nullable(),
2578
3000
  id: zVillageUUID,
@@ -2602,6 +3024,45 @@ export const zVillageUpdateGroupRequest = z.object({
2602
3024
  export const zVillageUpdateUserSettingsRequest = z.object({
2603
3025
  preview_before_attach: z.boolean().nullish()
2604
3026
  });
3027
+ export const zVillageUser = z.object({
3028
+ avatar_url: z.string().nullable(),
3029
+ created_at: z.iso.datetime(),
3030
+ display_name: z.string().nullable(),
3031
+ github_id: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
3032
+ github_username: z.string(),
3033
+ id: zVillageUUID,
3034
+ is_discoverable: z.boolean(),
3035
+ provider: z.string(),
3036
+ provider_user_id: z.string(),
3037
+ provider_username: z.string().nullable(),
3038
+ updated_at: z.iso.datetime(),
3039
+ username_chosen: z.boolean()
3040
+ });
3041
+ export const zVillageTranscriptListRow = z.object({
3042
+ attestations: z.array(zVillageListTranscriptAttestation).nullable(),
3043
+ owner: zVillageUser,
3044
+ owner_orgs: z.array(zVillageListUserOrganization).nullable(),
3045
+ shares: z.array(zVillageEnrichedTranscriptShare).nullable(),
3046
+ tags: z.array(zVillageTag),
3047
+ transcript: zVillageTranscript
3048
+ });
3049
+ export const zVillageTranscriptListResponse = z.object({
3050
+ agent_total: z.int(),
3051
+ limit: z.int(),
3052
+ page: z.int(),
3053
+ total: z.int(),
3054
+ transcripts: z.array(zVillageTranscriptListRow)
3055
+ });
3056
+ export const zVillageTranscriptMetadataResponse = z.object({
3057
+ attestations: z.array(zVillageTranscriptAttestation),
3058
+ enriched_shares: z.array(zVillageEnrichedTranscriptShare),
3059
+ owner: zVillageUser,
3060
+ owner_orgs: z.array(zVillageMetadataUserOrganization),
3061
+ relationshipNavigation: z.array(zSessionRelationshipNavigation).optional(),
3062
+ shares: z.array(zVillageTranscriptShare),
3063
+ tags: z.array(zVillageTag),
3064
+ transcript: zVillageTranscript
3065
+ });
2605
3066
  export const zVillageUserGroup = z.object({
2606
3067
  acceptance_mode: zVillageGroupAcceptanceMode,
2607
3068
  created_at: z.iso.datetime(),
@@ -2621,12 +3082,16 @@ export const zVillageUserGroup = z.object({
2621
3082
  });
2622
3083
  export const zVillageUserGroupShare = z.object({
2623
3084
  id: zTranscriptID,
3085
+ input_submission_count: z.int().gte(0).lte(9007199254740991).optional(),
2624
3086
  local_id: zSessionID,
2625
3087
  model_name: z.string().nullable(),
2626
3088
  model_provider: z.string(),
2627
3089
  owner_id: zVillageUUID,
2628
3090
  parent_session_id: zSessionID.nullable(),
2629
3091
  published_at: z.iso.datetime(),
3092
+ purpose: zSessionPurpose.optional(),
3093
+ relationships: z.array(zSessionRelationship).optional(),
3094
+ root_session_id: zSessionID.nullish(),
2630
3095
  shared_at: z.iso.datetime(),
2631
3096
  status: zVillageShareStatus,
2632
3097
  title: z.string().nullable(),
@@ -2635,6 +3100,110 @@ export const zVillageUserGroupShare = z.object({
2635
3100
  turn_count: z.int().nullable(),
2636
3101
  visibility: zVillageTranscriptVisibility
2637
3102
  });
3103
+ export const zVillageSessionRow = z.object({
3104
+ collective: zVillageGroupTranscript.nullish(),
3105
+ contributable: zVillageContributableTranscript.nullish(),
3106
+ myShare: zVillageUserGroupShare.nullish(),
3107
+ pending: zVillagePendingShare.nullish(),
3108
+ session: zVillageTranscript
3109
+ }).superRefine((value, context) => {
3110
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zVillageSessionRow during grouped read validation: " + reason });
3111
+ const s = value.session;
3112
+ const arms = [value.collective, value.pending, value.myShare, value.contributable].filter(v => v != null);
3113
+ if (arms.length > 1)
3114
+ fail("multiple route arms supplied; retain the originating route only");
3115
+ const equal = (a, b) => {
3116
+ if (a === b)
3117
+ return true;
3118
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object")
3119
+ return false;
3120
+ const left = a, right = b;
3121
+ return Object.keys(left).length === Object.keys(right).length && Object.keys(left).every(k => Object.hasOwn(right, k) && equal(left[k], right[k]));
3122
+ };
3123
+ const check = (v, keys, aliases = {}) => {
3124
+ if (v == null)
3125
+ return;
3126
+ const row = v, session = s;
3127
+ for (const key of keys)
3128
+ if (!equal(row[key], session[aliases[key] ?? key]))
3129
+ fail("route identity or metric mirrors disagree; derive both from the same row");
3130
+ };
3131
+ const graph = ["parent_session_id", "root_session_id", "purpose", "relationships", "input_submission_count"];
3132
+ check(value.collective, [...graph, "id", "owner_id", "local_id", "title", "description", "visibility", "model_provider", "model_name", "harness_version", "turn_count", "token_count", "tokens_in", "tokens_out", "duration_ms", "project_hash", "project_name", "project_display_name", "project_name_source", "project_remote_label", "git_branch", "session_origin"]);
3133
+ check(value.pending, [...graph, "transcript_id", "owner_id", "local_id", "title", "model_provider", "project_hash", "project_name", "branch"], { transcript_id: "id", branch: "git_branch" });
3134
+ check(value.myShare, [...graph, "id", "owner_id", "local_id", "title", "visibility", "published_at", "model_provider", "model_name", "turn_count", "tokens_in", "tokens_out"]);
3135
+ check(value.contributable, [...graph, "id", "local_id", "title", "visibility", "model_provider", "project_hash", "project_display_name", "project_name_source", "git_branch", "published_at", "session_origin"]);
3136
+ });
3137
+ export const zVillageSessionListItem = z.object({
3138
+ context: zHelperContextSummary.nullish(),
3139
+ helperGroups: z.array(zHelperGroupSummary).optional(),
3140
+ kind: zSessionListItemKind,
3141
+ transcript: zVillageSessionRow.nullish()
3142
+ }).superRefine((value, context) => {
3143
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zVillageSessionListItem during grouped read validation: " + reason });
3144
+ if ((value.kind === "transcript") !== (value.transcript != null) || (value.kind === "context_container") !== (value.context != null))
3145
+ fail("kind must select exactly one matching transcript/context arm; omit the other arm");
3146
+ const groups = new Set();
3147
+ for (const group of value.helperGroups ?? []) {
3148
+ if (groups.has(group.groupId))
3149
+ fail("duplicate groupId prevents independent paging; emit each immediate group once");
3150
+ groups.add(group.groupId);
3151
+ }
3152
+ });
3153
+ export const zVillageHelperMembersPayload = z.object({
3154
+ limit: z.int().gte(1).lte(9007199254740991),
3155
+ members: z.array(zVillageSessionListItem.and(z.object({
3156
+ context: z.null().optional(),
3157
+ kind: z.enum(['transcript']).optional(),
3158
+ transcript: zVillageSessionRow
3159
+ }))),
3160
+ page: z.int().gte(1).lte(9007199254740991),
3161
+ total: z.int().gte(0).lte(9007199254740991)
3162
+ }).superRefine((value, context) => {
3163
+ const fail = (reason) => context.addIssue({ code: "custom", message: "schema.zVillageHelperMembersPayload during grouped read validation: " + reason });
3164
+ if (value.members.length > value.limit || value.members.length > value.total)
3165
+ fail("member count exceeds page limit or direct total; count direct saved helpers before paging");
3166
+ const ids = new Set();
3167
+ const groups = new Set();
3168
+ for (const member of value.members) {
3169
+ if (member.kind !== "transcript" || member.transcript == null || member.context != null) {
3170
+ fail("members must be transcript items, never context containers; preserve nested groups on the item");
3171
+ continue;
3172
+ }
3173
+ const id = member.transcript.session.id;
3174
+ if (ids.has(id))
3175
+ fail("duplicate member identity would double count a saved helper; emit each transcript once");
3176
+ ids.add(id);
3177
+ for (const group of member.helperGroups ?? []) {
3178
+ if (groups.has(group.groupId))
3179
+ fail("groupId appears under multiple members; emit each immediate-owner group once");
3180
+ groups.add(group.groupId);
3181
+ }
3182
+ }
3183
+ });
3184
+ export const zVillageSessionListPayload = z.object({
3185
+ helperThreadTotal: z.int().gte(0).lte(9007199254740991),
3186
+ items: z.array(zVillageSessionListItem),
3187
+ limit: z.int().gte(1).lte(9007199254740991),
3188
+ ordinarySessionTotal: z.int().gte(0).lte(9007199254740991),
3189
+ page: z.int().gte(1).lte(9007199254740991),
3190
+ totalItems: z.int().gte(0).lte(9007199254740991)
3191
+ });
3192
+ export const zVillageGroupedContributableResponse = z.object({
3193
+ groupId: zVillageUUID,
3194
+ transcriptList: zVillageSessionListPayload
3195
+ });
3196
+ export const zVillageGroupedGroupDetailResponse = z.object({
3197
+ can_read: z.boolean(),
3198
+ contributors: z.array(zVillageGroupContributor),
3199
+ group: zVillageGroupDetailRecord,
3200
+ members: z.array(zVillageGroupMember),
3201
+ models: z.array(zVillageGroupModelBreakdown),
3202
+ pending_members: z.array(zVillageGroupMember).optional(),
3203
+ stats: zVillageGroupTranscriptStats,
3204
+ transcriptList: zVillageSessionListPayload,
3205
+ your_role: zVillageGroupViewerRole
3206
+ });
2638
3207
  export const zVillageUserSettings = z.object({
2639
3208
  preview_before_attach: z.boolean()
2640
3209
  });