@anchrd/intel-contract 0.9.0 → 0.11.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.
@@ -28,6 +28,7 @@ export declare const NodeKind: z.ZodEnum<{
28
28
  attachment: "attachment";
29
29
  table: "table";
30
30
  agent: "agent";
31
+ board: "board";
31
32
  }>;
32
33
  export type NodeKind = z.infer<typeof NodeKind>;
33
34
  export declare const ResourceVerb: z.ZodEnum<{
@@ -56,6 +57,7 @@ export declare const Node: z.ZodObject<{
56
57
  attachment: "attachment";
57
58
  table: "table";
58
59
  agent: "agent";
60
+ board: "board";
59
61
  }>;
60
62
  title: z.ZodString;
61
63
  description: z.ZodNullable<z.ZodString>;
@@ -114,6 +116,7 @@ export declare const CreateNodeInput: z.ZodObject<{
114
116
  attachment: "attachment";
115
117
  table: "table";
116
118
  agent: "agent";
119
+ board: "board";
117
120
  }>;
118
121
  title: z.ZodString;
119
122
  description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
@@ -162,6 +165,7 @@ export declare const NodeList: z.ZodObject<{
162
165
  attachment: "attachment";
163
166
  table: "table";
164
167
  agent: "agent";
168
+ board: "board";
165
169
  }>;
166
170
  title: z.ZodString;
167
171
  description: z.ZodNullable<z.ZodString>;
@@ -202,6 +206,7 @@ export declare const NodeDocument: z.ZodObject<{
202
206
  attachment: "attachment";
203
207
  table: "table";
204
208
  agent: "agent";
209
+ board: "board";
205
210
  }>;
206
211
  title: z.ZodString;
207
212
  description: z.ZodNullable<z.ZodString>;
@@ -239,6 +244,7 @@ export declare const NodeAttachment: z.ZodObject<{
239
244
  attachment: "attachment";
240
245
  table: "table";
241
246
  agent: "agent";
247
+ board: "board";
242
248
  }>;
243
249
  title: z.ZodString;
244
250
  description: z.ZodNullable<z.ZodString>;
@@ -296,6 +302,7 @@ export declare const NodeTable: z.ZodObject<{
296
302
  attachment: "attachment";
297
303
  table: "table";
298
304
  agent: "agent";
305
+ board: "board";
299
306
  }>;
300
307
  title: z.ZodString;
301
308
  description: z.ZodNullable<z.ZodString>;
@@ -320,6 +327,7 @@ export declare const AppendTableRowsResult: z.ZodObject<{
320
327
  attachment: "attachment";
321
328
  table: "table";
322
329
  agent: "agent";
330
+ board: "board";
323
331
  }>;
324
332
  title: z.ZodString;
325
333
  description: z.ZodNullable<z.ZodString>;
@@ -368,6 +376,7 @@ export declare const UpdateTableRowsResult: z.ZodObject<{
368
376
  attachment: "attachment";
369
377
  table: "table";
370
378
  agent: "agent";
379
+ board: "board";
371
380
  }>;
372
381
  title: z.ZodString;
373
382
  description: z.ZodNullable<z.ZodString>;
@@ -412,6 +421,7 @@ export declare const DeleteTableRowsResult: z.ZodObject<{
412
421
  attachment: "attachment";
413
422
  table: "table";
414
423
  agent: "agent";
424
+ board: "board";
415
425
  }>;
416
426
  title: z.ZodString;
417
427
  description: z.ZodNullable<z.ZodString>;
@@ -454,6 +464,419 @@ export declare const RedefineTableInput: z.ZodObject<{
454
464
  idempotencyKey: z.ZodString;
455
465
  }, z.core.$strict>;
456
466
  export type RedefineTableInput = z.infer<typeof RedefineTableInput>;
467
+ export declare const BoardMediaType = "application/vnd.anchrd.board+json";
468
+ export declare const ArchivedBoardStatusId = "archived";
469
+ export declare const BoardStatusId: z.ZodString;
470
+ export declare const BoardStatus: z.ZodObject<{
471
+ id: z.ZodString;
472
+ label: z.ZodString;
473
+ order: z.ZodNumber;
474
+ terminal: z.ZodBoolean;
475
+ }, z.core.$strict>;
476
+ export type BoardStatus = z.infer<typeof BoardStatus>;
477
+ export declare const BoardDefaultStatuses: readonly BoardStatus[];
478
+ /**
479
+ * Who a task is on: a person Gate knows, or an agent node in this installation (#285).
480
+ *
481
+ * ⚠️ A `user` id is deliberately NOT validated against Intel's own id shape. Identity is Gate's
482
+ * (see the product boundary), so a rule here would be Intel inventing one about somebody else's
483
+ * identifier — the same reason `GateApplicationId` is a plain bounded string.
484
+ */
485
+ export declare const BoardAssignee: z.ZodDiscriminatedUnion<[z.ZodObject<{
486
+ type: z.ZodLiteral<"user">;
487
+ id: z.ZodString;
488
+ }, z.core.$strict>, z.ZodObject<{
489
+ type: z.ZodLiteral<"agent">;
490
+ nodeId: z.ZodString;
491
+ }, z.core.$strict>], "type">;
492
+ export type BoardAssignee = z.infer<typeof BoardAssignee>;
493
+ /**
494
+ * A task's place among the others, as a fractional index (#285).
495
+ *
496
+ * ⚠️ Server-assigned, and a caller can never send one. A move names its NEIGHBOURS and the server
497
+ * mints a key between theirs, so moving one task writes one task and renumbers nothing — the whole
498
+ * reason a board is not addressed by position the way a table's rows are (`TableRowPosition`).
499
+ * A hand-written key could collide, and two tasks sharing a key have no defined order at all.
500
+ */
501
+ export declare const BoardTaskOrder: z.ZodString;
502
+ export declare const BoardTaskId: z.ZodString;
503
+ export declare const BoardTaskLabel: z.ZodString;
504
+ export declare const BoardTaskDate: z.ZodISODate;
505
+ export declare const BoardTaskDescription: z.ZodString;
506
+ /**
507
+ * The tasks one task waits for (#285), each of them at most once (anchrd/intel#318).
508
+ *
509
+ * ⚠️ Board-internal only, enforced on the write path: a dependency on a task in another board would
510
+ * hang this node on a file that can change without anyone here noticing. Across boards the link is
511
+ * `references`, which points at the board NODE and lands in the link graph.
512
+ *
513
+ * ⚠️ Refused rather than folded together, the same shape as the status ids in `ConfigureBoardInput`.
514
+ * A repeat carries no information — but that is a fact about the value, not about the answer: a
515
+ * caller handed back a shorter list than it sent is told nothing, and composes the same one again.
516
+ * The refusal names the mistake once, and the caller is holding the list it has to fix. (The one
517
+ * place a repeat is folded instead is `upgradeStoredBoard`, where there is no caller to tell.)
518
+ *
519
+ * ⚠️ It sits on the STORED task as well as on the two inputs, so a consumer may rely on it rather
520
+ * than defend against it — `createBoardGraph` mints one edge key per pair, and a second one threw
521
+ * the whole graph view off the screen for everybody looking at that board.
522
+ */
523
+ export declare const BoardTaskDependsOn: z.ZodArray<z.ZodString>;
524
+ /**
525
+ * A task's labels, each of them at most once (anchrd/intel#318).
526
+ *
527
+ * ⚠️ The same rule the detail panel has always applied to what a person types — it refuses to add a
528
+ * label the task already carries — stated where every surface meets it, because the MCP write path
529
+ * did not. A repeated label draws the same chip twice on the card, with two remove buttons of which
530
+ * either takes both away, and weights that word higher in the search text (`indexing.ts`).
531
+ */
532
+ export declare const BoardTaskLabels: z.ZodArray<z.ZodString>;
533
+ /**
534
+ * The Intel nodes a task points at, each of them at most once (anchrd/intel#318).
535
+ *
536
+ * They land in the link graph as `text` links, the same way a document's inline links do, so what a
537
+ * board points at is visible from the other side too.
538
+ *
539
+ * ⚠️ Distinct for the same reason as `labels`: the picker in the detail panel already refuses one
540
+ * the task holds, and the link graph counts a repeat once anyway (`ON CONFLICT DO NOTHING`), so a
541
+ * duplicate is a second row in the panel and nothing else — which is exactly the kind of value that
542
+ * has no reading and should not be storable.
543
+ */
544
+ export declare const BoardTaskReferences: z.ZodArray<z.ZodString>;
545
+ export declare const BoardTask: z.ZodObject<{
546
+ id: z.ZodString;
547
+ title: z.ZodString;
548
+ status: z.ZodString;
549
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
550
+ type: z.ZodLiteral<"user">;
551
+ id: z.ZodString;
552
+ }, z.core.$strict>, z.ZodObject<{
553
+ type: z.ZodLiteral<"agent">;
554
+ nodeId: z.ZodString;
555
+ }, z.core.$strict>], "type">>;
556
+ labels: z.ZodArray<z.ZodString>;
557
+ startDate: z.ZodNullable<z.ZodISODate>;
558
+ dueDate: z.ZodNullable<z.ZodISODate>;
559
+ parentId: z.ZodNullable<z.ZodString>;
560
+ dependsOn: z.ZodArray<z.ZodString>;
561
+ order: z.ZodString;
562
+ description: z.ZodString;
563
+ references: z.ZodArray<z.ZodString>;
564
+ }, z.core.$strict>;
565
+ export type BoardTask = z.infer<typeof BoardTask>;
566
+ export declare const BoardDocument: z.ZodObject<{
567
+ statuses: z.ZodArray<z.ZodObject<{
568
+ id: z.ZodString;
569
+ label: z.ZodString;
570
+ order: z.ZodNumber;
571
+ terminal: z.ZodBoolean;
572
+ }, z.core.$strict>>;
573
+ tasks: z.ZodArray<z.ZodObject<{
574
+ id: z.ZodString;
575
+ title: z.ZodString;
576
+ status: z.ZodString;
577
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
578
+ type: z.ZodLiteral<"user">;
579
+ id: z.ZodString;
580
+ }, z.core.$strict>, z.ZodObject<{
581
+ type: z.ZodLiteral<"agent">;
582
+ nodeId: z.ZodString;
583
+ }, z.core.$strict>], "type">>;
584
+ labels: z.ZodArray<z.ZodString>;
585
+ startDate: z.ZodNullable<z.ZodISODate>;
586
+ dueDate: z.ZodNullable<z.ZodISODate>;
587
+ parentId: z.ZodNullable<z.ZodString>;
588
+ dependsOn: z.ZodArray<z.ZodString>;
589
+ order: z.ZodString;
590
+ description: z.ZodString;
591
+ references: z.ZodArray<z.ZodString>;
592
+ }, z.core.$strict>>;
593
+ }, z.core.$strict>;
594
+ export type BoardDocument = z.infer<typeof BoardDocument>;
595
+ export declare const BoardMaxTaskDepth = 5;
596
+ export declare const GetBoardInput: z.ZodObject<{
597
+ nodeId: z.ZodString;
598
+ }, z.core.$strict>;
599
+ export type GetBoardInput = z.infer<typeof GetBoardInput>;
600
+ export declare const NodeBoard: z.ZodObject<{
601
+ node: z.ZodObject<{
602
+ id: z.ZodString;
603
+ parentId: z.ZodNullable<z.ZodString>;
604
+ kind: z.ZodEnum<{
605
+ folder: "folder";
606
+ document: "document";
607
+ attachment: "attachment";
608
+ table: "table";
609
+ agent: "agent";
610
+ board: "board";
611
+ }>;
612
+ title: z.ZodString;
613
+ description: z.ZodNullable<z.ZodString>;
614
+ ownerId: z.ZodString;
615
+ currentVersionId: z.ZodNullable<z.ZodString>;
616
+ createdAt: z.ZodISODateTime;
617
+ updatedAt: z.ZodISODateTime;
618
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
619
+ }, z.core.$strict>;
620
+ board: z.ZodObject<{
621
+ statuses: z.ZodArray<z.ZodObject<{
622
+ id: z.ZodString;
623
+ label: z.ZodString;
624
+ order: z.ZodNumber;
625
+ terminal: z.ZodBoolean;
626
+ }, z.core.$strict>>;
627
+ tasks: z.ZodArray<z.ZodObject<{
628
+ id: z.ZodString;
629
+ title: z.ZodString;
630
+ status: z.ZodString;
631
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
632
+ type: z.ZodLiteral<"user">;
633
+ id: z.ZodString;
634
+ }, z.core.$strict>, z.ZodObject<{
635
+ type: z.ZodLiteral<"agent">;
636
+ nodeId: z.ZodString;
637
+ }, z.core.$strict>], "type">>;
638
+ labels: z.ZodArray<z.ZodString>;
639
+ startDate: z.ZodNullable<z.ZodISODate>;
640
+ dueDate: z.ZodNullable<z.ZodISODate>;
641
+ parentId: z.ZodNullable<z.ZodString>;
642
+ dependsOn: z.ZodArray<z.ZodString>;
643
+ order: z.ZodString;
644
+ description: z.ZodString;
645
+ references: z.ZodArray<z.ZodString>;
646
+ }, z.core.$strict>>;
647
+ }, z.core.$strict>;
648
+ versionId: z.ZodNullable<z.ZodString>;
649
+ }, z.core.$strict>;
650
+ export type NodeBoard = z.infer<typeof NodeBoard>;
651
+ export declare const BoardStatusInput: z.ZodObject<{
652
+ id: z.ZodString;
653
+ label: z.ZodString;
654
+ terminal: z.ZodOptional<z.ZodBoolean>;
655
+ }, z.core.$strict>;
656
+ export type BoardStatusInput = z.infer<typeof BoardStatusInput>;
657
+ export declare const ConfigureBoardInput: z.ZodObject<{
658
+ nodeId: z.ZodString;
659
+ statuses: z.ZodArray<z.ZodObject<{
660
+ id: z.ZodString;
661
+ label: z.ZodString;
662
+ terminal: z.ZodOptional<z.ZodBoolean>;
663
+ }, z.core.$strict>>;
664
+ idempotencyKey: z.ZodString;
665
+ }, z.core.$strict>;
666
+ export type ConfigureBoardInput = z.infer<typeof ConfigureBoardInput>;
667
+ /**
668
+ * A new task (#285).
669
+ *
670
+ * ⚠️ No `baseVersionId`, on this and on every other task operation, and that absence is the
671
+ * feature. A board is addressed by stable task id and never by position, so two agents touching two
672
+ * different tasks cannot collide — demanding a base version would invent the `version_conflict`
673
+ * that #285 exists to remove, and force every caller to read the whole board first.
674
+ */
675
+ export declare const AddBoardTaskInput: z.ZodObject<{
676
+ nodeId: z.ZodString;
677
+ title: z.ZodString;
678
+ status: z.ZodOptional<z.ZodString>;
679
+ assignee: z.ZodDefault<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
680
+ type: z.ZodLiteral<"user">;
681
+ id: z.ZodString;
682
+ }, z.core.$strict>, z.ZodObject<{
683
+ type: z.ZodLiteral<"agent">;
684
+ nodeId: z.ZodString;
685
+ }, z.core.$strict>], "type">>>;
686
+ labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
687
+ startDate: z.ZodDefault<z.ZodNullable<z.ZodISODate>>;
688
+ dueDate: z.ZodDefault<z.ZodNullable<z.ZodISODate>>;
689
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
690
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
691
+ description: z.ZodDefault<z.ZodString>;
692
+ references: z.ZodDefault<z.ZodArray<z.ZodString>>;
693
+ afterTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
694
+ beforeTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
695
+ idempotencyKey: z.ZodString;
696
+ }, z.core.$strict>;
697
+ export type AddBoardTaskInput = z.infer<typeof AddBoardTaskInput>;
698
+ /**
699
+ * What a task says about itself.
700
+ *
701
+ * ⚠️ Deliberately no `status`, no `parentId` and no `order`: where a task SITS is a move, and a
702
+ * move is the operation that has to mint an order key and re-check the two cycle rules. Folding
703
+ * both into one call would mean every field edit pays for those checks and every move could quietly
704
+ * rewrite a description.
705
+ */
706
+ export declare const UpdateBoardTaskInput: z.ZodObject<{
707
+ nodeId: z.ZodString;
708
+ taskId: z.ZodString;
709
+ title: z.ZodOptional<z.ZodString>;
710
+ assignee: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
711
+ type: z.ZodLiteral<"user">;
712
+ id: z.ZodString;
713
+ }, z.core.$strict>, z.ZodObject<{
714
+ type: z.ZodLiteral<"agent">;
715
+ nodeId: z.ZodString;
716
+ }, z.core.$strict>], "type">>>;
717
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
718
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
719
+ dueDate: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
720
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
721
+ description: z.ZodOptional<z.ZodString>;
722
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
723
+ idempotencyKey: z.ZodString;
724
+ }, z.core.$strict>;
725
+ export type UpdateBoardTaskInput = z.infer<typeof UpdateBoardTaskInput>;
726
+ export declare const MoveBoardTaskInput: z.ZodObject<{
727
+ nodeId: z.ZodString;
728
+ taskId: z.ZodString;
729
+ status: z.ZodOptional<z.ZodString>;
730
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
731
+ afterTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
732
+ beforeTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
733
+ idempotencyKey: z.ZodString;
734
+ }, z.core.$strict>;
735
+ export type MoveBoardTaskInput = z.infer<typeof MoveBoardTaskInput>;
736
+ export declare const DeleteBoardTaskInput: z.ZodObject<{
737
+ nodeId: z.ZodString;
738
+ taskId: z.ZodString;
739
+ idempotencyKey: z.ZodString;
740
+ }, z.core.$strict>;
741
+ export type DeleteBoardTaskInput = z.infer<typeof DeleteBoardTaskInput>;
742
+ export declare const BoardTaskResult: z.ZodObject<{
743
+ node: z.ZodObject<{
744
+ id: z.ZodString;
745
+ parentId: z.ZodNullable<z.ZodString>;
746
+ kind: z.ZodEnum<{
747
+ folder: "folder";
748
+ document: "document";
749
+ attachment: "attachment";
750
+ table: "table";
751
+ agent: "agent";
752
+ board: "board";
753
+ }>;
754
+ title: z.ZodString;
755
+ description: z.ZodNullable<z.ZodString>;
756
+ ownerId: z.ZodString;
757
+ currentVersionId: z.ZodNullable<z.ZodString>;
758
+ createdAt: z.ZodISODateTime;
759
+ updatedAt: z.ZodISODateTime;
760
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
761
+ }, z.core.$strict>;
762
+ version: z.ZodObject<{
763
+ id: z.ZodString;
764
+ nodeId: z.ZodString;
765
+ sequence: z.ZodNumber;
766
+ contentKey: z.ZodString;
767
+ mediaType: z.ZodString;
768
+ contentHash: z.ZodString;
769
+ size: z.ZodNumber;
770
+ segment: z.ZodNullable<z.ZodEnum<{
771
+ append: "append";
772
+ snapshot: "snapshot";
773
+ }>>;
774
+ createdBy: z.ZodString;
775
+ createdAt: z.ZodISODateTime;
776
+ }, z.core.$strict>;
777
+ task: z.ZodObject<{
778
+ id: z.ZodString;
779
+ title: z.ZodString;
780
+ status: z.ZodString;
781
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
782
+ type: z.ZodLiteral<"user">;
783
+ id: z.ZodString;
784
+ }, z.core.$strict>, z.ZodObject<{
785
+ type: z.ZodLiteral<"agent">;
786
+ nodeId: z.ZodString;
787
+ }, z.core.$strict>], "type">>;
788
+ labels: z.ZodArray<z.ZodString>;
789
+ startDate: z.ZodNullable<z.ZodISODate>;
790
+ dueDate: z.ZodNullable<z.ZodISODate>;
791
+ parentId: z.ZodNullable<z.ZodString>;
792
+ dependsOn: z.ZodArray<z.ZodString>;
793
+ order: z.ZodString;
794
+ description: z.ZodString;
795
+ references: z.ZodArray<z.ZodString>;
796
+ }, z.core.$strict>;
797
+ }, z.core.$strict>;
798
+ export type BoardTaskResult = z.infer<typeof BoardTaskResult>;
799
+ export declare const DeleteBoardTaskResult: z.ZodObject<{
800
+ node: z.ZodObject<{
801
+ id: z.ZodString;
802
+ parentId: z.ZodNullable<z.ZodString>;
803
+ kind: z.ZodEnum<{
804
+ folder: "folder";
805
+ document: "document";
806
+ attachment: "attachment";
807
+ table: "table";
808
+ agent: "agent";
809
+ board: "board";
810
+ }>;
811
+ title: z.ZodString;
812
+ description: z.ZodNullable<z.ZodString>;
813
+ ownerId: z.ZodString;
814
+ currentVersionId: z.ZodNullable<z.ZodString>;
815
+ createdAt: z.ZodISODateTime;
816
+ updatedAt: z.ZodISODateTime;
817
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
818
+ }, z.core.$strict>;
819
+ version: z.ZodObject<{
820
+ id: z.ZodString;
821
+ nodeId: z.ZodString;
822
+ sequence: z.ZodNumber;
823
+ contentKey: z.ZodString;
824
+ mediaType: z.ZodString;
825
+ contentHash: z.ZodString;
826
+ size: z.ZodNumber;
827
+ segment: z.ZodNullable<z.ZodEnum<{
828
+ append: "append";
829
+ snapshot: "snapshot";
830
+ }>>;
831
+ createdBy: z.ZodString;
832
+ createdAt: z.ZodISODateTime;
833
+ }, z.core.$strict>;
834
+ deleted: z.ZodNumber;
835
+ }, z.core.$strict>;
836
+ export type DeleteBoardTaskResult = z.infer<typeof DeleteBoardTaskResult>;
837
+ export declare const ConfigureBoardResult: z.ZodObject<{
838
+ node: z.ZodObject<{
839
+ id: z.ZodString;
840
+ parentId: z.ZodNullable<z.ZodString>;
841
+ kind: z.ZodEnum<{
842
+ folder: "folder";
843
+ document: "document";
844
+ attachment: "attachment";
845
+ table: "table";
846
+ agent: "agent";
847
+ board: "board";
848
+ }>;
849
+ title: z.ZodString;
850
+ description: z.ZodNullable<z.ZodString>;
851
+ ownerId: z.ZodString;
852
+ currentVersionId: z.ZodNullable<z.ZodString>;
853
+ createdAt: z.ZodISODateTime;
854
+ updatedAt: z.ZodISODateTime;
855
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
856
+ }, z.core.$strict>;
857
+ version: z.ZodObject<{
858
+ id: z.ZodString;
859
+ nodeId: z.ZodString;
860
+ sequence: z.ZodNumber;
861
+ contentKey: z.ZodString;
862
+ mediaType: z.ZodString;
863
+ contentHash: z.ZodString;
864
+ size: z.ZodNumber;
865
+ segment: z.ZodNullable<z.ZodEnum<{
866
+ append: "append";
867
+ snapshot: "snapshot";
868
+ }>>;
869
+ createdBy: z.ZodString;
870
+ createdAt: z.ZodISODateTime;
871
+ }, z.core.$strict>;
872
+ statuses: z.ZodArray<z.ZodObject<{
873
+ id: z.ZodString;
874
+ label: z.ZodString;
875
+ order: z.ZodNumber;
876
+ terminal: z.ZodBoolean;
877
+ }, z.core.$strict>>;
878
+ }, z.core.$strict>;
879
+ export type ConfigureBoardResult = z.infer<typeof ConfigureBoardResult>;
457
880
  export declare const AgentMediaType = "application/vnd.anchrd.agent+json";
458
881
  export declare const AgentReferenceRole: z.ZodEnum<{
459
882
  "system-message": "system-message";
@@ -872,6 +1295,7 @@ export declare const NodeAgent: z.ZodObject<{
872
1295
  attachment: "attachment";
873
1296
  table: "table";
874
1297
  agent: "agent";
1298
+ board: "board";
875
1299
  }>;
876
1300
  title: z.ZodString;
877
1301
  description: z.ZodNullable<z.ZodString>;
@@ -956,6 +1380,7 @@ export declare const CreatedAgent: z.ZodObject<{
956
1380
  attachment: "attachment";
957
1381
  table: "table";
958
1382
  agent: "agent";
1383
+ board: "board";
959
1384
  }>;
960
1385
  title: z.ZodString;
961
1386
  description: z.ZodNullable<z.ZodString>;
@@ -1043,6 +1468,7 @@ export declare const AgentList: z.ZodObject<{
1043
1468
  attachment: "attachment";
1044
1469
  table: "table";
1045
1470
  agent: "agent";
1471
+ board: "board";
1046
1472
  }>;
1047
1473
  title: z.ZodString;
1048
1474
  description: z.ZodNullable<z.ZodString>;
@@ -1137,6 +1563,7 @@ export declare const NodeGraph: z.ZodObject<{
1137
1563
  attachment: "attachment";
1138
1564
  table: "table";
1139
1565
  agent: "agent";
1566
+ board: "board";
1140
1567
  }>;
1141
1568
  title: z.ZodString;
1142
1569
  description: z.ZodNullable<z.ZodString>;
@@ -1379,6 +1806,7 @@ export declare const ToolCatalog: z.ZodObject<{
1379
1806
  }, z.core.$strict>;
1380
1807
  fingerprint: z.ZodString;
1381
1808
  }, z.core.$strict>>;
1809
+ reached: z.ZodOptional<z.ZodArray<z.ZodString>>;
1382
1810
  }, z.core.$strict>;
1383
1811
  export type ToolCatalog = z.infer<typeof ToolCatalog>;
1384
1812
  /**
@@ -2361,6 +2789,7 @@ export declare const RelationNodeKind: z.ZodEnum<{
2361
2789
  attachment: "attachment";
2362
2790
  table: "table";
2363
2791
  agent: "agent";
2792
+ board: "board";
2364
2793
  flow: "flow";
2365
2794
  }>;
2366
2795
  export type RelationNodeKind = z.infer<typeof RelationNodeKind>;
@@ -2372,6 +2801,7 @@ export declare const RelationNode: z.ZodObject<{
2372
2801
  attachment: "attachment";
2373
2802
  table: "table";
2374
2803
  agent: "agent";
2804
+ board: "board";
2375
2805
  flow: "flow";
2376
2806
  }>;
2377
2807
  title: z.ZodString;
@@ -2423,6 +2853,7 @@ export declare const RelationGraph: z.ZodObject<{
2423
2853
  attachment: "attachment";
2424
2854
  table: "table";
2425
2855
  agent: "agent";
2856
+ board: "board";
2426
2857
  flow: "flow";
2427
2858
  }>;
2428
2859
  title: z.ZodString;
@@ -2793,6 +3224,7 @@ export declare const BundleEntryKind: z.ZodEnum<{
2793
3224
  attachment: "attachment";
2794
3225
  table: "table";
2795
3226
  agent: "agent";
3227
+ board: "board";
2796
3228
  flow: "flow";
2797
3229
  }>;
2798
3230
  export type BundleEntryKind = z.infer<typeof BundleEntryKind>;
@@ -2804,6 +3236,7 @@ export declare const BundleManifestEntry: z.ZodObject<{
2804
3236
  attachment: "attachment";
2805
3237
  table: "table";
2806
3238
  agent: "agent";
3239
+ board: "board";
2807
3240
  flow: "flow";
2808
3241
  }>;
2809
3242
  title: z.ZodString;
@@ -2831,6 +3264,7 @@ export declare const BundleManifest: z.ZodObject<{
2831
3264
  attachment: "attachment";
2832
3265
  table: "table";
2833
3266
  agent: "agent";
3267
+ board: "board";
2834
3268
  flow: "flow";
2835
3269
  }>;
2836
3270
  title: z.ZodString;
@@ -31,15 +31,17 @@ export const SessionUser = z.strictObject({
31
31
  export const IntelCapabilities = z.strictObject({
32
32
  agentRuntime: z.boolean(),
33
33
  });
34
- // The fourth kind is `table` (#40) and the fifth is `agent` (#139). Each is a kind of node, not a
35
- // kind of thing: it hangs in the same folder tree, inherits the same folder grants, carries the
36
- // same immutable versions and the same R2 body as a document (ADR-0004 §1, ADR-0005 §1). Only the
37
- // media type and the operations below differ.
34
+ // The fourth kind is `table` (#40), the fifth is `agent` (#139) and the sixth is `board` (#285).
35
+ // Each is a kind of node, not a kind of thing: it hangs in the same folder tree, inherits the same
36
+ // folder grants, carries the same immutable versions and the same R2 body as a document
37
+ // (ADR-0004 §1, ADR-0005 §1). Only the media type and the operations below differ.
38
38
  //
39
39
  // ⚠️ `agent` being optional is load-bearing (ADR-0005 §1): an installation without a single agent
40
40
  // node is complete, not unfinished, and nothing here asks anyone to classify a document as a skill
41
- // or a policy in order to file it.
42
- export const NodeKind = z.enum(["folder", "document", "attachment", "table", "agent"]);
41
+ // or a policy in order to file it. The same holds for `board`: it is a file somebody may make, not
42
+ // a place the tree grows a special corner for — which is exactly why a board is one node carrying
43
+ // its tasks and not a folder that only tasks may live in (#285).
44
+ export const NodeKind = z.enum(["folder", "document", "attachment", "table", "agent", "board"]);
43
45
  // ⚠️ There is no `ContextPolicy`, and it is not coming back in this shape (#76). It said whether a
44
46
  // document should be pinned into a context, be found by relevance, or be named explicitly — an
45
47
  // instruction to a retrieval Intel does not perform. Intel hands out references and the agent
@@ -266,6 +268,306 @@ export const RedefineTableInput = z.strictObject({
266
268
  }, { error: "A current column can fill only one new column" }),
267
269
  idempotencyKey: z.string().min(8).max(200),
268
270
  });
271
+ // ── The board (#285) ─────────────────────────────────────────────────────────────────────────────
272
+ //
273
+ // A board's body is a whole project board — the status list and every task — stored as one
274
+ // validated JSON version in R2, exactly the way an agent's definition is. It is a kind of node and
275
+ // not a kind of thing (see `NodeKind`): it hangs in a folder, inherits that folder's grants, has
276
+ // versions and is exported like everything else. Its own media type exists so a reader can tell a
277
+ // board from prose without parsing it.
278
+ export const BoardMediaType = "application/vnd.anchrd.board+json";
279
+ // ⚠️ `archived` belongs to EVERY status list and cannot be configured away (#285). It is the shelf
280
+ // tasks are swept onto, so that being finished with a task never has to mean deleting it — and
281
+ // getting one back is an explicit move to another status, never an undelete.
282
+ export const ArchivedBoardStatusId = "archived";
283
+ // A status id is referenced by every task that sits in that column, so it is machine-shaped and
284
+ // bounded rather than free text. Renaming a column changes its LABEL; the id stays, and no task has
285
+ // to be rewritten to follow it.
286
+ export const BoardStatusId = z.string().regex(/^[a-z0-9][a-z0-9_]{0,39}$/);
287
+ export const BoardStatus = z.strictObject({
288
+ id: BoardStatusId,
289
+ label: z.string().trim().min(1).max(60),
290
+ // ⚠️ Server-assigned from the position in `ConfigureBoardInput.statuses`, never sent. Two columns
291
+ // both claiming position 3 is a board no surface could draw, and it is a state nobody has to be
292
+ // able to reason about if it cannot be expressed.
293
+ order: z.number().int().nonnegative(),
294
+ /**
295
+ * Whether standing in this column means the work is finished (anchrd/intel#311).
296
+ *
297
+ * It answers the one question #285 left open — when a `dependsOn` is satisfied — and it is the
298
+ * ONLY answer to it. There is deliberately no second reading anywhere: a surface that decided
299
+ * "done" for itself would decide it differently the first time somebody reconfigured a board.
300
+ *
301
+ * ⚠️ It is a property of the status, not a position in the list, and that distinction is the
302
+ * whole ticket. #286 first read "the last column before `archived`" as done, reasoning by symmetry
303
+ * with the server's rule that a new task lands in the first column that is not `archived`. But a
304
+ * status list is configurable on purpose, so `… done → blocked → archived` makes "blocked" mean
305
+ * finished — silently, with a wrong blocked marker as the only symptom.
306
+ *
307
+ * ⚠️ Several columns may carry it. "Done" and a cancelled-like column are both ends of the work,
308
+ * and nothing waiting on a cancelled task is still blocked by it.
309
+ */
310
+ terminal: z.boolean(),
311
+ });
312
+ // What a board starts out with. Five columns, of which the last one is the fixed `archived` shelf.
313
+ // `done` and the shelf are where work ends; the three before them are not (anchrd/intel#311).
314
+ export const BoardDefaultStatuses = [
315
+ { id: "backlog", label: "Backlog", order: 0, terminal: false },
316
+ { id: "in_progress", label: "In progress", order: 1, terminal: false },
317
+ { id: "review", label: "Review", order: 2, terminal: false },
318
+ { id: "done", label: "Done", order: 3, terminal: true },
319
+ { id: ArchivedBoardStatusId, label: "Archived", order: 4, terminal: true },
320
+ ];
321
+ /**
322
+ * Who a task is on: a person Gate knows, or an agent node in this installation (#285).
323
+ *
324
+ * ⚠️ A `user` id is deliberately NOT validated against Intel's own id shape. Identity is Gate's
325
+ * (see the product boundary), so a rule here would be Intel inventing one about somebody else's
326
+ * identifier — the same reason `GateApplicationId` is a plain bounded string.
327
+ */
328
+ export const BoardAssignee = z.discriminatedUnion("type", [
329
+ z.strictObject({ type: z.literal("user"), id: z.string().min(1).max(255) }),
330
+ z.strictObject({ type: z.literal("agent"), nodeId: IntelId }),
331
+ ]);
332
+ /**
333
+ * A task's place among the others, as a fractional index (#285).
334
+ *
335
+ * ⚠️ Server-assigned, and a caller can never send one. A move names its NEIGHBOURS and the server
336
+ * mints a key between theirs, so moving one task writes one task and renumbers nothing — the whole
337
+ * reason a board is not addressed by position the way a table's rows are (`TableRowPosition`).
338
+ * A hand-written key could collide, and two tasks sharing a key have no defined order at all.
339
+ */
340
+ export const BoardTaskOrder = z.string().regex(/^[0-9A-Za-z]{1,64}$/);
341
+ export const BoardTaskId = IntelId;
342
+ export const BoardTaskLabel = z.string().trim().min(1).max(60);
343
+ // A day, not an instant. A task is due on a date; giving it a time zone would make the same task
344
+ // due on two different days depending on who is looking at it.
345
+ export const BoardTaskDate = z.iso.date();
346
+ // Markdown, and capped: a task's description is a card, and what needs more than this is a document
347
+ // the task can point at through `references`.
348
+ export const BoardTaskDescription = z.string().max(20_000);
349
+ /**
350
+ * The tasks one task waits for (#285), each of them at most once (anchrd/intel#318).
351
+ *
352
+ * ⚠️ Board-internal only, enforced on the write path: a dependency on a task in another board would
353
+ * hang this node on a file that can change without anyone here noticing. Across boards the link is
354
+ * `references`, which points at the board NODE and lands in the link graph.
355
+ *
356
+ * ⚠️ Refused rather than folded together, the same shape as the status ids in `ConfigureBoardInput`.
357
+ * A repeat carries no information — but that is a fact about the value, not about the answer: a
358
+ * caller handed back a shorter list than it sent is told nothing, and composes the same one again.
359
+ * The refusal names the mistake once, and the caller is holding the list it has to fix. (The one
360
+ * place a repeat is folded instead is `upgradeStoredBoard`, where there is no caller to tell.)
361
+ *
362
+ * ⚠️ It sits on the STORED task as well as on the two inputs, so a consumer may rely on it rather
363
+ * than defend against it — `createBoardGraph` mints one edge key per pair, and a second one threw
364
+ * the whole graph view off the screen for everybody looking at that board.
365
+ */
366
+ export const BoardTaskDependsOn = z
367
+ .array(BoardTaskId)
368
+ .max(64)
369
+ .refine((ids) => new Set(ids).size === ids.length, {
370
+ error: "A task can be named only once in dependsOn",
371
+ });
372
+ /**
373
+ * A task's labels, each of them at most once (anchrd/intel#318).
374
+ *
375
+ * ⚠️ The same rule the detail panel has always applied to what a person types — it refuses to add a
376
+ * label the task already carries — stated where every surface meets it, because the MCP write path
377
+ * did not. A repeated label draws the same chip twice on the card, with two remove buttons of which
378
+ * either takes both away, and weights that word higher in the search text (`indexing.ts`).
379
+ */
380
+ export const BoardTaskLabels = z
381
+ .array(BoardTaskLabel)
382
+ .max(32)
383
+ .refine((labels) => new Set(labels).size === labels.length, {
384
+ error: "A label can be named only once",
385
+ });
386
+ /**
387
+ * The Intel nodes a task points at, each of them at most once (anchrd/intel#318).
388
+ *
389
+ * They land in the link graph as `text` links, the same way a document's inline links do, so what a
390
+ * board points at is visible from the other side too.
391
+ *
392
+ * ⚠️ Distinct for the same reason as `labels`: the picker in the detail panel already refuses one
393
+ * the task holds, and the link graph counts a repeat once anyway (`ON CONFLICT DO NOTHING`), so a
394
+ * duplicate is a second row in the panel and nothing else — which is exactly the kind of value that
395
+ * has no reading and should not be storable.
396
+ */
397
+ export const BoardTaskReferences = z
398
+ .array(IntelId)
399
+ .max(64)
400
+ .refine((ids) => new Set(ids).size === ids.length, {
401
+ error: "A node can be referenced only once",
402
+ });
403
+ export const BoardTask = z.strictObject({
404
+ id: BoardTaskId,
405
+ title: z.string().trim().min(1).max(240),
406
+ status: BoardStatusId,
407
+ assignee: BoardAssignee.nullable(),
408
+ labels: BoardTaskLabels,
409
+ startDate: BoardTaskDate.nullable(),
410
+ dueDate: BoardTaskDate.nullable(),
411
+ // ⚠️ The whole hierarchy in one field, deliberately: epic, task and subtask are a DEPTH and not a
412
+ // type (#285). A `kind` beside it would allow a subtask under nothing and an epic under an epic,
413
+ // and every surface would then need its own opinion about which combinations mean anything.
414
+ parentId: BoardTaskId.nullable(),
415
+ dependsOn: BoardTaskDependsOn,
416
+ order: BoardTaskOrder,
417
+ description: BoardTaskDescription,
418
+ references: BoardTaskReferences,
419
+ });
420
+ // The whole board, as it is stored and as it is read. There is no second representation to keep in
421
+ // step with it — this document is the file.
422
+ export const BoardDocument = z.strictObject({
423
+ statuses: z.array(BoardStatus).min(1).max(32),
424
+ tasks: z.array(BoardTask).max(5_000),
425
+ });
426
+ // How deep `parentId` may nest. Five is epic → task → subtask with room left over; without a bound
427
+ // a chain of a thousand tasks would be a valid board that no view can draw and no walk can afford.
428
+ export const BoardMaxTaskDepth = 5;
429
+ export const GetBoardInput = z.strictObject({ nodeId: IntelId });
430
+ // A board as it is read. `versionId` is `null` while nothing has been written yet — the same answer
431
+ // a table gives before its header exists — and the document is then the defaults.
432
+ export const NodeBoard = z.strictObject({
433
+ node: Node,
434
+ board: BoardDocument,
435
+ versionId: IntelId.nullable(),
436
+ });
437
+ export const BoardStatusInput = z.strictObject({
438
+ id: BoardStatusId,
439
+ label: z.string().trim().min(1).max(60),
440
+ /**
441
+ * Whether this column means finished (anchrd/intel#311).
442
+ *
443
+ * ⚠️ Optional, and the absence is not the same as `false`. A caller who says nothing gets the
444
+ * server's answer — `false` for an ordinary column, `true` for the shelf, which cannot be
445
+ * anything else. Making it a required boolean would force every caller that only wanted to rename
446
+ * a column to restate the whole board's notion of done, and getting one entry wrong there is a
447
+ * silent change to what counts as blocked.
448
+ */
449
+ terminal: z.boolean().optional(),
450
+ });
451
+ // The status list, written whole and in the order it should be drawn — never a patch. Adding,
452
+ // renaming and reordering are all this one call, and `archived` has to be in what it is given.
453
+ export const ConfigureBoardInput = z.strictObject({
454
+ nodeId: IntelId,
455
+ statuses: z
456
+ .array(BoardStatusInput)
457
+ .min(1)
458
+ .max(32)
459
+ .refine((statuses) => new Set(statuses.map((status) => status.id)).size === statuses.length, {
460
+ error: "Status ids must be distinct",
461
+ })
462
+ .refine((statuses) => statuses.some((status) => status.id === ArchivedBoardStatusId), {
463
+ error: `The "${ArchivedBoardStatusId}" status cannot be removed`,
464
+ })
465
+ // ⚠️ Refused rather than corrected, the same way removing the shelf is refused. A task swept
466
+ // onto `archived` is finished with, and a board that could declare the shelf non-terminal would
467
+ // hold every archived task open as a blocker forever. Only an EXPLICIT `false` is refused —
468
+ // saying nothing is fine and means the server's `true` (anchrd/intel#311).
469
+ .refine((statuses) => statuses.find((status) => status.id === ArchivedBoardStatusId)?.terminal !== false, { error: `The "${ArchivedBoardStatusId}" status is always terminal` }),
470
+ idempotencyKey: z.string().min(8).max(200),
471
+ });
472
+ /**
473
+ * A new task (#285).
474
+ *
475
+ * ⚠️ No `baseVersionId`, on this and on every other task operation, and that absence is the
476
+ * feature. A board is addressed by stable task id and never by position, so two agents touching two
477
+ * different tasks cannot collide — demanding a base version would invent the `version_conflict`
478
+ * that #285 exists to remove, and force every caller to read the whole board first.
479
+ */
480
+ export const AddBoardTaskInput = z.strictObject({
481
+ nodeId: IntelId,
482
+ title: z.string().trim().min(1).max(240),
483
+ // Omitted means the first status that is not `archived`: a new task belongs on the board, not on
484
+ // the shelf.
485
+ status: BoardStatusId.optional(),
486
+ assignee: BoardAssignee.nullable().default(null),
487
+ labels: BoardTaskLabels.default([]),
488
+ startDate: BoardTaskDate.nullable().default(null),
489
+ dueDate: BoardTaskDate.nullable().default(null),
490
+ parentId: BoardTaskId.nullable().default(null),
491
+ dependsOn: BoardTaskDependsOn.default([]),
492
+ description: BoardTaskDescription.default(""),
493
+ references: BoardTaskReferences.default([]),
494
+ // Where among its neighbours it goes. Both absent puts it last in its column.
495
+ afterTaskId: BoardTaskId.nullable().default(null),
496
+ beforeTaskId: BoardTaskId.nullable().default(null),
497
+ idempotencyKey: z.string().min(8).max(200),
498
+ });
499
+ /**
500
+ * What a task says about itself.
501
+ *
502
+ * ⚠️ Deliberately no `status`, no `parentId` and no `order`: where a task SITS is a move, and a
503
+ * move is the operation that has to mint an order key and re-check the two cycle rules. Folding
504
+ * both into one call would mean every field edit pays for those checks and every move could quietly
505
+ * rewrite a description.
506
+ */
507
+ export const UpdateBoardTaskInput = z
508
+ .strictObject({
509
+ nodeId: IntelId,
510
+ taskId: BoardTaskId,
511
+ title: z.string().trim().min(1).max(240).optional(),
512
+ assignee: BoardAssignee.nullable().optional(),
513
+ labels: BoardTaskLabels.optional(),
514
+ startDate: BoardTaskDate.nullable().optional(),
515
+ dueDate: BoardTaskDate.nullable().optional(),
516
+ dependsOn: BoardTaskDependsOn.optional(),
517
+ description: BoardTaskDescription.optional(),
518
+ references: BoardTaskReferences.optional(),
519
+ idempotencyKey: z.string().min(8).max(200),
520
+ })
521
+ .refine((input) => input.title !== undefined ||
522
+ input.assignee !== undefined ||
523
+ input.labels !== undefined ||
524
+ input.startDate !== undefined ||
525
+ input.dueDate !== undefined ||
526
+ input.dependsOn !== undefined ||
527
+ input.description !== undefined ||
528
+ input.references !== undefined, { error: "At least one change is required" });
529
+ // Where a task sits: its column, its parent, its place among its neighbours. Archiving is this call
530
+ // with `status: "archived"` — there is no separate verb, because it is not a separate act.
531
+ export const MoveBoardTaskInput = z
532
+ .strictObject({
533
+ nodeId: IntelId,
534
+ taskId: BoardTaskId,
535
+ status: BoardStatusId.optional(),
536
+ parentId: BoardTaskId.nullable().optional(),
537
+ afterTaskId: BoardTaskId.nullable().default(null),
538
+ beforeTaskId: BoardTaskId.nullable().default(null),
539
+ idempotencyKey: z.string().min(8).max(200),
540
+ })
541
+ .refine((input) => input.status !== undefined ||
542
+ input.parentId !== undefined ||
543
+ input.afterTaskId !== null ||
544
+ input.beforeTaskId !== null, { error: "A move needs a status, a parent or a neighbour" });
545
+ // ⚠️ Deleting cascades to every descendant, and the count comes back so a surface can warn BEFORE
546
+ // asking. See `DeleteBoardTaskResult`.
547
+ export const DeleteBoardTaskInput = z.strictObject({
548
+ nodeId: IntelId,
549
+ taskId: BoardTaskId,
550
+ idempotencyKey: z.string().min(8).max(200),
551
+ });
552
+ // The one task that was written, not the whole board: a board can hold thousands of tasks, and
553
+ // answering a one-card edit with all of them would make every write pay for the read.
554
+ export const BoardTaskResult = z.strictObject({
555
+ node: Node,
556
+ version: NodeVersion,
557
+ task: BoardTask,
558
+ });
559
+ // `deleted` counts the task AND every descendant that went with it, so a caller can say what
560
+ // happened rather than "done".
561
+ export const DeleteBoardTaskResult = z.strictObject({
562
+ node: Node,
563
+ version: NodeVersion,
564
+ deleted: z.number().int().positive(),
565
+ });
566
+ export const ConfigureBoardResult = z.strictObject({
567
+ node: Node,
568
+ version: NodeVersion,
569
+ statuses: z.array(BoardStatus),
570
+ });
269
571
  // ── The agent definition (#139, ADR-0005 §4) ─────────────────────────────────────────────────────
270
572
  //
271
573
  // An agent's body is a definition, stored as an immutable version in R2 exactly like a document's.
@@ -810,6 +1112,24 @@ export const ToolCapability = z.strictObject({
810
1112
  export const ToolCatalog = z.strictObject({
811
1113
  portalConnected: z.boolean(),
812
1114
  items: z.array(ToolCapability),
1115
+ /**
1116
+ * Which delegated servers actually contributed a tool to this catalog (#289).
1117
+ *
1118
+ * ⚠️ Present only where the attribution was actually made — a delegated caller whose catalog was
1119
+ * read. It is absent for an ordinary user, and absent as well when the answer comes from one of
1120
+ * the short paths that never reach the portal (nothing delegated, no portal sign-in, connection
1121
+ * dropped). Absent therefore means "not stated", never "nothing arrived"; `[]` is the second one.
1122
+ *
1123
+ * That it is missing rather than empty on those paths is deliberate rather than half-finished:
1124
+ * the attribution already happens for a delegation — `capabilities` has to make it to cut the
1125
+ * list — so naming it costs nothing there, while computing the same thing for an ordinary user
1126
+ * would mean a second portal request per call, for a question their screen does not ask.
1127
+ *
1128
+ * ⚠️ It is the answer to "what arrived", never to "what was granted". A server missing here has
1129
+ * been switched off, revoked, or is failing right now; the delegation in the definition is
1130
+ * unchanged. Reading it the other way round would turn an outage into a permission change.
1131
+ */
1132
+ reached: z.array(ToolServerHandle).optional(),
813
1133
  });
814
1134
  /**
815
1135
  * One MCP server the asking user reaches right now, as the portal itself names it (D30).
@@ -1217,6 +1537,7 @@ export const RelationNodeKind = z.enum([
1217
1537
  "attachment",
1218
1538
  "table",
1219
1539
  "agent",
1540
+ "board",
1220
1541
  "flow",
1221
1542
  ]);
1222
1543
  export const RelationNode = z.strictObject({
@@ -1401,7 +1722,7 @@ export const FlowRunHistory = z.strictObject({
1401
1722
  // The one name the importer looks for at the zip root. A different spelling would make a bundle a
1402
1723
  // naked folder, so the constant lives in the contract rather than in each surface.
1403
1724
  export const BundleManifestFilename = "manifest.json";
1404
- // What a bundle entry can be. `flow` joins the five node kinds because a flow shares the folder
1725
+ // What a bundle entry can be. `flow` joins the six node kinds because a flow shares the folder
1405
1726
  // tree without being a node (ADR-0004), and the bundle mirrors the tree, not the tables.
1406
1727
  export const BundleEntryKind = z.enum([
1407
1728
  "folder",
@@ -1409,6 +1730,7 @@ export const BundleEntryKind = z.enum([
1409
1730
  "table",
1410
1731
  "attachment",
1411
1732
  "agent",
1733
+ "board",
1412
1734
  "flow",
1413
1735
  ]);
1414
1736
  // One entry of the manifest: the identity a re-import needs, next to the relative path where the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anchrd/intel-contract",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {