@anchrd/intel-contract 0.8.0 → 0.10.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,374 @@ 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
+ }, z.core.$strict>;
475
+ export type BoardStatus = z.infer<typeof BoardStatus>;
476
+ export declare const BoardDefaultStatuses: readonly BoardStatus[];
477
+ /**
478
+ * Who a task is on: a person Gate knows, or an agent node in this installation (#285).
479
+ *
480
+ * ⚠️ A `user` id is deliberately NOT validated against Intel's own id shape. Identity is Gate's
481
+ * (see the product boundary), so a rule here would be Intel inventing one about somebody else's
482
+ * identifier — the same reason `GateApplicationId` is a plain bounded string.
483
+ */
484
+ export declare const BoardAssignee: z.ZodDiscriminatedUnion<[z.ZodObject<{
485
+ type: z.ZodLiteral<"user">;
486
+ id: z.ZodString;
487
+ }, z.core.$strict>, z.ZodObject<{
488
+ type: z.ZodLiteral<"agent">;
489
+ nodeId: z.ZodString;
490
+ }, z.core.$strict>], "type">;
491
+ export type BoardAssignee = z.infer<typeof BoardAssignee>;
492
+ /**
493
+ * A task's place among the others, as a fractional index (#285).
494
+ *
495
+ * ⚠️ Server-assigned, and a caller can never send one. A move names its NEIGHBOURS and the server
496
+ * mints a key between theirs, so moving one task writes one task and renumbers nothing — the whole
497
+ * reason a board is not addressed by position the way a table's rows are (`TableRowPosition`).
498
+ * A hand-written key could collide, and two tasks sharing a key have no defined order at all.
499
+ */
500
+ export declare const BoardTaskOrder: z.ZodString;
501
+ export declare const BoardTaskId: z.ZodString;
502
+ export declare const BoardTaskLabel: z.ZodString;
503
+ export declare const BoardTaskDate: z.ZodISODate;
504
+ export declare const BoardTaskDescription: z.ZodString;
505
+ export declare const BoardTask: z.ZodObject<{
506
+ id: z.ZodString;
507
+ title: z.ZodString;
508
+ status: z.ZodString;
509
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
510
+ type: z.ZodLiteral<"user">;
511
+ id: z.ZodString;
512
+ }, z.core.$strict>, z.ZodObject<{
513
+ type: z.ZodLiteral<"agent">;
514
+ nodeId: z.ZodString;
515
+ }, z.core.$strict>], "type">>;
516
+ labels: z.ZodArray<z.ZodString>;
517
+ startDate: z.ZodNullable<z.ZodISODate>;
518
+ dueDate: z.ZodNullable<z.ZodISODate>;
519
+ parentId: z.ZodNullable<z.ZodString>;
520
+ dependsOn: z.ZodArray<z.ZodString>;
521
+ order: z.ZodString;
522
+ description: z.ZodString;
523
+ references: z.ZodArray<z.ZodString>;
524
+ }, z.core.$strict>;
525
+ export type BoardTask = z.infer<typeof BoardTask>;
526
+ export declare const BoardDocument: z.ZodObject<{
527
+ statuses: z.ZodArray<z.ZodObject<{
528
+ id: z.ZodString;
529
+ label: z.ZodString;
530
+ order: z.ZodNumber;
531
+ }, z.core.$strict>>;
532
+ tasks: z.ZodArray<z.ZodObject<{
533
+ id: z.ZodString;
534
+ title: z.ZodString;
535
+ status: z.ZodString;
536
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
537
+ type: z.ZodLiteral<"user">;
538
+ id: z.ZodString;
539
+ }, z.core.$strict>, z.ZodObject<{
540
+ type: z.ZodLiteral<"agent">;
541
+ nodeId: z.ZodString;
542
+ }, z.core.$strict>], "type">>;
543
+ labels: z.ZodArray<z.ZodString>;
544
+ startDate: z.ZodNullable<z.ZodISODate>;
545
+ dueDate: z.ZodNullable<z.ZodISODate>;
546
+ parentId: z.ZodNullable<z.ZodString>;
547
+ dependsOn: z.ZodArray<z.ZodString>;
548
+ order: z.ZodString;
549
+ description: z.ZodString;
550
+ references: z.ZodArray<z.ZodString>;
551
+ }, z.core.$strict>>;
552
+ }, z.core.$strict>;
553
+ export type BoardDocument = z.infer<typeof BoardDocument>;
554
+ export declare const BoardMaxTaskDepth = 5;
555
+ export declare const GetBoardInput: z.ZodObject<{
556
+ nodeId: z.ZodString;
557
+ }, z.core.$strict>;
558
+ export type GetBoardInput = z.infer<typeof GetBoardInput>;
559
+ export declare const NodeBoard: z.ZodObject<{
560
+ node: z.ZodObject<{
561
+ id: z.ZodString;
562
+ parentId: z.ZodNullable<z.ZodString>;
563
+ kind: z.ZodEnum<{
564
+ folder: "folder";
565
+ document: "document";
566
+ attachment: "attachment";
567
+ table: "table";
568
+ agent: "agent";
569
+ board: "board";
570
+ }>;
571
+ title: z.ZodString;
572
+ description: z.ZodNullable<z.ZodString>;
573
+ ownerId: z.ZodString;
574
+ currentVersionId: z.ZodNullable<z.ZodString>;
575
+ createdAt: z.ZodISODateTime;
576
+ updatedAt: z.ZodISODateTime;
577
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
578
+ }, z.core.$strict>;
579
+ board: z.ZodObject<{
580
+ statuses: z.ZodArray<z.ZodObject<{
581
+ id: z.ZodString;
582
+ label: z.ZodString;
583
+ order: z.ZodNumber;
584
+ }, z.core.$strict>>;
585
+ tasks: z.ZodArray<z.ZodObject<{
586
+ id: z.ZodString;
587
+ title: z.ZodString;
588
+ status: z.ZodString;
589
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
590
+ type: z.ZodLiteral<"user">;
591
+ id: z.ZodString;
592
+ }, z.core.$strict>, z.ZodObject<{
593
+ type: z.ZodLiteral<"agent">;
594
+ nodeId: z.ZodString;
595
+ }, z.core.$strict>], "type">>;
596
+ labels: z.ZodArray<z.ZodString>;
597
+ startDate: z.ZodNullable<z.ZodISODate>;
598
+ dueDate: z.ZodNullable<z.ZodISODate>;
599
+ parentId: z.ZodNullable<z.ZodString>;
600
+ dependsOn: z.ZodArray<z.ZodString>;
601
+ order: z.ZodString;
602
+ description: z.ZodString;
603
+ references: z.ZodArray<z.ZodString>;
604
+ }, z.core.$strict>>;
605
+ }, z.core.$strict>;
606
+ versionId: z.ZodNullable<z.ZodString>;
607
+ }, z.core.$strict>;
608
+ export type NodeBoard = z.infer<typeof NodeBoard>;
609
+ export declare const BoardStatusInput: z.ZodObject<{
610
+ id: z.ZodString;
611
+ label: z.ZodString;
612
+ }, z.core.$strict>;
613
+ export type BoardStatusInput = z.infer<typeof BoardStatusInput>;
614
+ export declare const ConfigureBoardInput: z.ZodObject<{
615
+ nodeId: z.ZodString;
616
+ statuses: z.ZodArray<z.ZodObject<{
617
+ id: z.ZodString;
618
+ label: z.ZodString;
619
+ }, z.core.$strict>>;
620
+ idempotencyKey: z.ZodString;
621
+ }, z.core.$strict>;
622
+ export type ConfigureBoardInput = z.infer<typeof ConfigureBoardInput>;
623
+ /**
624
+ * A new task (#285).
625
+ *
626
+ * ⚠️ No `baseVersionId`, on this and on every other task operation, and that absence is the
627
+ * feature. A board is addressed by stable task id and never by position, so two agents touching two
628
+ * different tasks cannot collide — demanding a base version would invent the `version_conflict`
629
+ * that #285 exists to remove, and force every caller to read the whole board first.
630
+ */
631
+ export declare const AddBoardTaskInput: z.ZodObject<{
632
+ nodeId: z.ZodString;
633
+ title: z.ZodString;
634
+ status: z.ZodOptional<z.ZodString>;
635
+ assignee: z.ZodDefault<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
636
+ type: z.ZodLiteral<"user">;
637
+ id: z.ZodString;
638
+ }, z.core.$strict>, z.ZodObject<{
639
+ type: z.ZodLiteral<"agent">;
640
+ nodeId: z.ZodString;
641
+ }, z.core.$strict>], "type">>>;
642
+ labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
643
+ startDate: z.ZodDefault<z.ZodNullable<z.ZodISODate>>;
644
+ dueDate: z.ZodDefault<z.ZodNullable<z.ZodISODate>>;
645
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
646
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString>>;
647
+ description: z.ZodDefault<z.ZodString>;
648
+ references: z.ZodDefault<z.ZodArray<z.ZodString>>;
649
+ afterTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
650
+ beforeTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
651
+ idempotencyKey: z.ZodString;
652
+ }, z.core.$strict>;
653
+ export type AddBoardTaskInput = z.infer<typeof AddBoardTaskInput>;
654
+ /**
655
+ * What a task says about itself.
656
+ *
657
+ * ⚠️ Deliberately no `status`, no `parentId` and no `order`: where a task SITS is a move, and a
658
+ * move is the operation that has to mint an order key and re-check the two cycle rules. Folding
659
+ * both into one call would mean every field edit pays for those checks and every move could quietly
660
+ * rewrite a description.
661
+ */
662
+ export declare const UpdateBoardTaskInput: z.ZodObject<{
663
+ nodeId: z.ZodString;
664
+ taskId: z.ZodString;
665
+ title: z.ZodOptional<z.ZodString>;
666
+ assignee: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
667
+ type: z.ZodLiteral<"user">;
668
+ id: z.ZodString;
669
+ }, z.core.$strict>, z.ZodObject<{
670
+ type: z.ZodLiteral<"agent">;
671
+ nodeId: z.ZodString;
672
+ }, z.core.$strict>], "type">>>;
673
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
674
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
675
+ dueDate: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
676
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
677
+ description: z.ZodOptional<z.ZodString>;
678
+ references: z.ZodOptional<z.ZodArray<z.ZodString>>;
679
+ idempotencyKey: z.ZodString;
680
+ }, z.core.$strict>;
681
+ export type UpdateBoardTaskInput = z.infer<typeof UpdateBoardTaskInput>;
682
+ export declare const MoveBoardTaskInput: z.ZodObject<{
683
+ nodeId: z.ZodString;
684
+ taskId: z.ZodString;
685
+ status: z.ZodOptional<z.ZodString>;
686
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
687
+ afterTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
688
+ beforeTaskId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
689
+ idempotencyKey: z.ZodString;
690
+ }, z.core.$strict>;
691
+ export type MoveBoardTaskInput = z.infer<typeof MoveBoardTaskInput>;
692
+ export declare const DeleteBoardTaskInput: z.ZodObject<{
693
+ nodeId: z.ZodString;
694
+ taskId: z.ZodString;
695
+ idempotencyKey: z.ZodString;
696
+ }, z.core.$strict>;
697
+ export type DeleteBoardTaskInput = z.infer<typeof DeleteBoardTaskInput>;
698
+ export declare const BoardTaskResult: z.ZodObject<{
699
+ node: z.ZodObject<{
700
+ id: z.ZodString;
701
+ parentId: z.ZodNullable<z.ZodString>;
702
+ kind: z.ZodEnum<{
703
+ folder: "folder";
704
+ document: "document";
705
+ attachment: "attachment";
706
+ table: "table";
707
+ agent: "agent";
708
+ board: "board";
709
+ }>;
710
+ title: z.ZodString;
711
+ description: z.ZodNullable<z.ZodString>;
712
+ ownerId: z.ZodString;
713
+ currentVersionId: z.ZodNullable<z.ZodString>;
714
+ createdAt: z.ZodISODateTime;
715
+ updatedAt: z.ZodISODateTime;
716
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
717
+ }, z.core.$strict>;
718
+ version: z.ZodObject<{
719
+ id: z.ZodString;
720
+ nodeId: z.ZodString;
721
+ sequence: z.ZodNumber;
722
+ contentKey: z.ZodString;
723
+ mediaType: z.ZodString;
724
+ contentHash: z.ZodString;
725
+ size: z.ZodNumber;
726
+ segment: z.ZodNullable<z.ZodEnum<{
727
+ append: "append";
728
+ snapshot: "snapshot";
729
+ }>>;
730
+ createdBy: z.ZodString;
731
+ createdAt: z.ZodISODateTime;
732
+ }, z.core.$strict>;
733
+ task: z.ZodObject<{
734
+ id: z.ZodString;
735
+ title: z.ZodString;
736
+ status: z.ZodString;
737
+ assignee: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
738
+ type: z.ZodLiteral<"user">;
739
+ id: z.ZodString;
740
+ }, z.core.$strict>, z.ZodObject<{
741
+ type: z.ZodLiteral<"agent">;
742
+ nodeId: z.ZodString;
743
+ }, z.core.$strict>], "type">>;
744
+ labels: z.ZodArray<z.ZodString>;
745
+ startDate: z.ZodNullable<z.ZodISODate>;
746
+ dueDate: z.ZodNullable<z.ZodISODate>;
747
+ parentId: z.ZodNullable<z.ZodString>;
748
+ dependsOn: z.ZodArray<z.ZodString>;
749
+ order: z.ZodString;
750
+ description: z.ZodString;
751
+ references: z.ZodArray<z.ZodString>;
752
+ }, z.core.$strict>;
753
+ }, z.core.$strict>;
754
+ export type BoardTaskResult = z.infer<typeof BoardTaskResult>;
755
+ export declare const DeleteBoardTaskResult: z.ZodObject<{
756
+ node: z.ZodObject<{
757
+ id: z.ZodString;
758
+ parentId: z.ZodNullable<z.ZodString>;
759
+ kind: z.ZodEnum<{
760
+ folder: "folder";
761
+ document: "document";
762
+ attachment: "attachment";
763
+ table: "table";
764
+ agent: "agent";
765
+ board: "board";
766
+ }>;
767
+ title: z.ZodString;
768
+ description: z.ZodNullable<z.ZodString>;
769
+ ownerId: z.ZodString;
770
+ currentVersionId: z.ZodNullable<z.ZodString>;
771
+ createdAt: z.ZodISODateTime;
772
+ updatedAt: z.ZodISODateTime;
773
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
774
+ }, z.core.$strict>;
775
+ version: z.ZodObject<{
776
+ id: z.ZodString;
777
+ nodeId: z.ZodString;
778
+ sequence: z.ZodNumber;
779
+ contentKey: z.ZodString;
780
+ mediaType: z.ZodString;
781
+ contentHash: z.ZodString;
782
+ size: z.ZodNumber;
783
+ segment: z.ZodNullable<z.ZodEnum<{
784
+ append: "append";
785
+ snapshot: "snapshot";
786
+ }>>;
787
+ createdBy: z.ZodString;
788
+ createdAt: z.ZodISODateTime;
789
+ }, z.core.$strict>;
790
+ deleted: z.ZodNumber;
791
+ }, z.core.$strict>;
792
+ export type DeleteBoardTaskResult = z.infer<typeof DeleteBoardTaskResult>;
793
+ export declare const ConfigureBoardResult: z.ZodObject<{
794
+ node: z.ZodObject<{
795
+ id: z.ZodString;
796
+ parentId: z.ZodNullable<z.ZodString>;
797
+ kind: z.ZodEnum<{
798
+ folder: "folder";
799
+ document: "document";
800
+ attachment: "attachment";
801
+ table: "table";
802
+ agent: "agent";
803
+ board: "board";
804
+ }>;
805
+ title: z.ZodString;
806
+ description: z.ZodNullable<z.ZodString>;
807
+ ownerId: z.ZodString;
808
+ currentVersionId: z.ZodNullable<z.ZodString>;
809
+ createdAt: z.ZodISODateTime;
810
+ updatedAt: z.ZodISODateTime;
811
+ archivedAt: z.ZodNullable<z.ZodISODateTime>;
812
+ }, z.core.$strict>;
813
+ version: z.ZodObject<{
814
+ id: z.ZodString;
815
+ nodeId: z.ZodString;
816
+ sequence: z.ZodNumber;
817
+ contentKey: z.ZodString;
818
+ mediaType: z.ZodString;
819
+ contentHash: z.ZodString;
820
+ size: z.ZodNumber;
821
+ segment: z.ZodNullable<z.ZodEnum<{
822
+ append: "append";
823
+ snapshot: "snapshot";
824
+ }>>;
825
+ createdBy: z.ZodString;
826
+ createdAt: z.ZodISODateTime;
827
+ }, z.core.$strict>;
828
+ statuses: z.ZodArray<z.ZodObject<{
829
+ id: z.ZodString;
830
+ label: z.ZodString;
831
+ order: z.ZodNumber;
832
+ }, z.core.$strict>>;
833
+ }, z.core.$strict>;
834
+ export type ConfigureBoardResult = z.infer<typeof ConfigureBoardResult>;
457
835
  export declare const AgentMediaType = "application/vnd.anchrd.agent+json";
458
836
  export declare const AgentReferenceRole: z.ZodEnum<{
459
837
  "system-message": "system-message";
@@ -470,6 +848,41 @@ export declare const AgentReference: z.ZodObject<{
470
848
  }>;
471
849
  }, z.core.$strict>;
472
850
  export type AgentReference = z.infer<typeof AgentReference>;
851
+ /**
852
+ * Which kinds of node each role can actually be given (#255).
853
+ *
854
+ * ⚠️ Not every role takes every kind, and the reasons are about what the runtime DOES with a
855
+ * reference rather than about tidiness:
856
+ *
857
+ * `memory` is a folder because the agent WRITES there — `agent_remember` creates a note inside
858
+ * it. A single document as memory would mean the agent overwrites the document it was given.
859
+ *
860
+ * `semantic-context` is a folder because it is a search SPACE, searched per folder by
861
+ * `loop/scoped-search`. A single document is not a narrower search space; reading it whole is a
862
+ * different behaviour, and one that gets named before it is introduced, not slipped in.
863
+ *
864
+ * `system-message` reads single nodes already and takes a document or a table as well as a
865
+ * folder. A document is the natural case — a skill somebody wrote as ordinary text — and a table
866
+ * is the same read: the runtime asks intel for the node and prepends its content, which for a
867
+ * table is its CSV.
868
+ *
869
+ * ⚠️ `folder` stays on `system-message` although a folder carries no content of its own. Every
870
+ * definition written before #255 could only name folders, and taking the combination away here
871
+ * would refuse the next save of an agent that has been working for months — "existing definitions
872
+ * stay valid" is not only about reading them.
873
+ *
874
+ * ⚠️ This is the ONE place the rule lives. The screen offers what it says and the write path
875
+ * refuses what it forbids; a surface that made its own list would eventually disagree with the
876
+ * other, and the one that matters is whichever runs last.
877
+ */
878
+ export declare const AgentReferenceKinds: {
879
+ readonly "system-message": readonly ["folder", "document", "table"];
880
+ readonly "semantic-context": readonly ["folder"];
881
+ readonly memory: readonly ["folder"];
882
+ };
883
+ export declare function agentReferenceAccepts(role: AgentReferenceRole, kind: NodeKind): boolean;
884
+ /** The roles a node of this kind may be given — the same rule, read from the other side. */
885
+ export declare function agentReferenceRolesFor(kind: NodeKind): AgentReferenceRole[];
473
886
  export declare const AgentScheduleTarget: z.ZodObject<{
474
887
  kind: z.ZodEnum<{
475
888
  document: "document";
@@ -673,6 +1086,116 @@ export declare const RunAgentNowInput: z.ZodObject<{
673
1086
  }, z.core.$strict>;
674
1087
  }, z.core.$strict>;
675
1088
  export type RunAgentNowInput = z.infer<typeof RunAgentNowInput>;
1089
+ /**
1090
+ * What one agent has actually cost, read out of Cloudflare's AI Gateway log (#251).
1091
+ *
1092
+ * ⚠️ Intel computes none of this from tokens and a price table. The gateway publishes the billed
1093
+ * figure per call, and that figure is the debit from the Cloudflare balance 1:1 — Cloudflare takes
1094
+ * its 5 % when the balance is loaded and passes inference through unchanged (measured 2026-08-07).
1095
+ * A second, self-maintained answer beside it would be wrong on the day the two disagreed, and the
1096
+ * wrong one would be the one on screen.
1097
+ *
1098
+ * ⚠️ `status` travels with the numbers and may never be dropped. `runs: []` means "cost nothing"
1099
+ * only when `status` is `read`; under `not_configured` or `unreadable` it means "not known", and a
1100
+ * screen that renders the two alike reports an outage as a saving.
1101
+ */
1102
+ export declare const AgentCostStatus: z.ZodEnum<{
1103
+ read: "read";
1104
+ not_configured: "not_configured";
1105
+ unreadable: "unreadable";
1106
+ }>;
1107
+ export type AgentCostStatus = z.infer<typeof AgentCostStatus>;
1108
+ export declare const AgentRunCost: z.ZodObject<{
1109
+ runId: z.ZodString;
1110
+ cost: z.ZodNumber;
1111
+ calls: z.ZodNumber;
1112
+ }, z.core.$strict>;
1113
+ export type AgentRunCost = z.infer<typeof AgentRunCost>;
1114
+ export declare const AgentCostWindow: z.ZodObject<{
1115
+ days: z.ZodNumber;
1116
+ cost: z.ZodNumber;
1117
+ calls: z.ZodNumber;
1118
+ models: z.ZodArray<z.ZodString>;
1119
+ }, z.core.$strict>;
1120
+ export type AgentCostWindow = z.infer<typeof AgentCostWindow>;
1121
+ export declare const AgentCosts: z.ZodObject<{
1122
+ status: z.ZodEnum<{
1123
+ read: "read";
1124
+ not_configured: "not_configured";
1125
+ unreadable: "unreadable";
1126
+ }>;
1127
+ currency: z.ZodLiteral<"USD">;
1128
+ runs: z.ZodArray<z.ZodObject<{
1129
+ runId: z.ZodString;
1130
+ cost: z.ZodNumber;
1131
+ calls: z.ZodNumber;
1132
+ }, z.core.$strict>>;
1133
+ windows: z.ZodArray<z.ZodObject<{
1134
+ days: z.ZodNumber;
1135
+ cost: z.ZodNumber;
1136
+ calls: z.ZodNumber;
1137
+ models: z.ZodArray<z.ZodString>;
1138
+ }, z.core.$strict>>;
1139
+ partial: z.ZodBoolean;
1140
+ }, z.core.$strict>;
1141
+ export type AgentCosts = z.infer<typeof AgentCosts>;
1142
+ /**
1143
+ * What the models on offer cost and how much they hold (#257).
1144
+ *
1145
+ * ⚠️ `source` is per ENTRY and not per response, and that is not over-engineering. Cloudflare
1146
+ * publishes figures for the models it serves itself and none at all for the Anthropic models it
1147
+ * resells through Unified Billing — so a perfectly healthy read still leaves half the list on a
1148
+ * written-out table, and one flag for the whole answer would call either the read stale or the
1149
+ * table live.
1150
+ */
1151
+ export declare const ModelPrice: z.ZodObject<{
1152
+ inputPerMillion: z.ZodNumber;
1153
+ outputPerMillion: z.ZodNumber;
1154
+ }, z.core.$strict>;
1155
+ export type ModelPrice = z.infer<typeof ModelPrice>;
1156
+ export declare const ModelCatalogEntry: z.ZodObject<{
1157
+ provider: z.ZodEnum<{
1158
+ "workers-ai": "workers-ai";
1159
+ anthropic: "anthropic";
1160
+ }>;
1161
+ model: z.ZodString;
1162
+ name: z.ZodString;
1163
+ contextTokens: z.ZodNullable<z.ZodNumber>;
1164
+ price: z.ZodNullable<z.ZodObject<{
1165
+ inputPerMillion: z.ZodNumber;
1166
+ outputPerMillion: z.ZodNumber;
1167
+ }, z.core.$strict>>;
1168
+ source: z.ZodEnum<{
1169
+ cloudflare: "cloudflare";
1170
+ builtin: "builtin";
1171
+ }>;
1172
+ }, z.core.$strict>;
1173
+ export type ModelCatalogEntry = z.infer<typeof ModelCatalogEntry>;
1174
+ export declare const ModelCatalog: z.ZodObject<{
1175
+ entries: z.ZodArray<z.ZodObject<{
1176
+ provider: z.ZodEnum<{
1177
+ "workers-ai": "workers-ai";
1178
+ anthropic: "anthropic";
1179
+ }>;
1180
+ model: z.ZodString;
1181
+ name: z.ZodString;
1182
+ contextTokens: z.ZodNullable<z.ZodNumber>;
1183
+ price: z.ZodNullable<z.ZodObject<{
1184
+ inputPerMillion: z.ZodNumber;
1185
+ outputPerMillion: z.ZodNumber;
1186
+ }, z.core.$strict>>;
1187
+ source: z.ZodEnum<{
1188
+ cloudflare: "cloudflare";
1189
+ builtin: "builtin";
1190
+ }>;
1191
+ }, z.core.$strict>>;
1192
+ liveStatus: z.ZodEnum<{
1193
+ read: "read";
1194
+ not_configured: "not_configured";
1195
+ unreadable: "unreadable";
1196
+ }>;
1197
+ }, z.core.$strict>;
1198
+ export type ModelCatalog = z.infer<typeof ModelCatalog>;
676
1199
  export declare const ListAgentsInput: z.ZodObject<{
677
1200
  parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
678
1201
  includeArchived: z.ZodDefault<z.ZodBoolean>;
@@ -727,6 +1250,7 @@ export declare const NodeAgent: z.ZodObject<{
727
1250
  attachment: "attachment";
728
1251
  table: "table";
729
1252
  agent: "agent";
1253
+ board: "board";
730
1254
  }>;
731
1255
  title: z.ZodString;
732
1256
  description: z.ZodNullable<z.ZodString>;
@@ -811,6 +1335,7 @@ export declare const CreatedAgent: z.ZodObject<{
811
1335
  attachment: "attachment";
812
1336
  table: "table";
813
1337
  agent: "agent";
1338
+ board: "board";
814
1339
  }>;
815
1340
  title: z.ZodString;
816
1341
  description: z.ZodNullable<z.ZodString>;
@@ -898,6 +1423,7 @@ export declare const AgentList: z.ZodObject<{
898
1423
  attachment: "attachment";
899
1424
  table: "table";
900
1425
  agent: "agent";
1426
+ board: "board";
901
1427
  }>;
902
1428
  title: z.ZodString;
903
1429
  description: z.ZodNullable<z.ZodString>;
@@ -992,6 +1518,7 @@ export declare const NodeGraph: z.ZodObject<{
992
1518
  attachment: "attachment";
993
1519
  table: "table";
994
1520
  agent: "agent";
1521
+ board: "board";
995
1522
  }>;
996
1523
  title: z.ZodString;
997
1524
  description: z.ZodNullable<z.ZodString>;
@@ -2216,6 +2743,7 @@ export declare const RelationNodeKind: z.ZodEnum<{
2216
2743
  attachment: "attachment";
2217
2744
  table: "table";
2218
2745
  agent: "agent";
2746
+ board: "board";
2219
2747
  flow: "flow";
2220
2748
  }>;
2221
2749
  export type RelationNodeKind = z.infer<typeof RelationNodeKind>;
@@ -2227,6 +2755,7 @@ export declare const RelationNode: z.ZodObject<{
2227
2755
  attachment: "attachment";
2228
2756
  table: "table";
2229
2757
  agent: "agent";
2758
+ board: "board";
2230
2759
  flow: "flow";
2231
2760
  }>;
2232
2761
  title: z.ZodString;
@@ -2278,6 +2807,7 @@ export declare const RelationGraph: z.ZodObject<{
2278
2807
  attachment: "attachment";
2279
2808
  table: "table";
2280
2809
  agent: "agent";
2810
+ board: "board";
2281
2811
  flow: "flow";
2282
2812
  }>;
2283
2813
  title: z.ZodString;
@@ -2648,6 +3178,7 @@ export declare const BundleEntryKind: z.ZodEnum<{
2648
3178
  attachment: "attachment";
2649
3179
  table: "table";
2650
3180
  agent: "agent";
3181
+ board: "board";
2651
3182
  flow: "flow";
2652
3183
  }>;
2653
3184
  export type BundleEntryKind = z.infer<typeof BundleEntryKind>;
@@ -2659,6 +3190,7 @@ export declare const BundleManifestEntry: z.ZodObject<{
2659
3190
  attachment: "attachment";
2660
3191
  table: "table";
2661
3192
  agent: "agent";
3193
+ board: "board";
2662
3194
  flow: "flow";
2663
3195
  }>;
2664
3196
  title: z.ZodString;
@@ -2686,6 +3218,7 @@ export declare const BundleManifest: z.ZodObject<{
2686
3218
  attachment: "attachment";
2687
3219
  table: "table";
2688
3220
  agent: "agent";
3221
+ board: "board";
2689
3222
  flow: "flow";
2690
3223
  }>;
2691
3224
  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,224 @@ 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
+ // What a board starts out with. Five columns, of which the last one is the fixed `archived` shelf.
296
+ export const BoardDefaultStatuses = [
297
+ { id: "backlog", label: "Backlog", order: 0 },
298
+ { id: "in_progress", label: "In progress", order: 1 },
299
+ { id: "review", label: "Review", order: 2 },
300
+ { id: "done", label: "Done", order: 3 },
301
+ { id: ArchivedBoardStatusId, label: "Archived", order: 4 },
302
+ ];
303
+ /**
304
+ * Who a task is on: a person Gate knows, or an agent node in this installation (#285).
305
+ *
306
+ * ⚠️ A `user` id is deliberately NOT validated against Intel's own id shape. Identity is Gate's
307
+ * (see the product boundary), so a rule here would be Intel inventing one about somebody else's
308
+ * identifier — the same reason `GateApplicationId` is a plain bounded string.
309
+ */
310
+ export const BoardAssignee = z.discriminatedUnion("type", [
311
+ z.strictObject({ type: z.literal("user"), id: z.string().min(1).max(255) }),
312
+ z.strictObject({ type: z.literal("agent"), nodeId: IntelId }),
313
+ ]);
314
+ /**
315
+ * A task's place among the others, as a fractional index (#285).
316
+ *
317
+ * ⚠️ Server-assigned, and a caller can never send one. A move names its NEIGHBOURS and the server
318
+ * mints a key between theirs, so moving one task writes one task and renumbers nothing — the whole
319
+ * reason a board is not addressed by position the way a table's rows are (`TableRowPosition`).
320
+ * A hand-written key could collide, and two tasks sharing a key have no defined order at all.
321
+ */
322
+ export const BoardTaskOrder = z.string().regex(/^[0-9A-Za-z]{1,64}$/);
323
+ export const BoardTaskId = IntelId;
324
+ export const BoardTaskLabel = z.string().trim().min(1).max(60);
325
+ // A day, not an instant. A task is due on a date; giving it a time zone would make the same task
326
+ // due on two different days depending on who is looking at it.
327
+ export const BoardTaskDate = z.iso.date();
328
+ // Markdown, and capped: a task's description is a card, and what needs more than this is a document
329
+ // the task can point at through `references`.
330
+ export const BoardTaskDescription = z.string().max(20_000);
331
+ export const BoardTask = z.strictObject({
332
+ id: BoardTaskId,
333
+ title: z.string().trim().min(1).max(240),
334
+ status: BoardStatusId,
335
+ assignee: BoardAssignee.nullable(),
336
+ labels: z.array(BoardTaskLabel).max(32),
337
+ startDate: BoardTaskDate.nullable(),
338
+ dueDate: BoardTaskDate.nullable(),
339
+ // ⚠️ The whole hierarchy in one field, deliberately: epic, task and subtask are a DEPTH and not a
340
+ // type (#285). A `kind` beside it would allow a subtask under nothing and an epic under an epic,
341
+ // and every surface would then need its own opinion about which combinations mean anything.
342
+ parentId: BoardTaskId.nullable(),
343
+ // ⚠️ Board-internal only, enforced on the write path: a dependency on a task in another board
344
+ // would hang this node on a file that can change without anyone here noticing. Across boards the
345
+ // link is `references`, which points at the board NODE and lands in the link graph.
346
+ dependsOn: z.array(BoardTaskId).max(64),
347
+ order: BoardTaskOrder,
348
+ description: BoardTaskDescription,
349
+ // Node ids. They land in the link graph as `text` links, the same way a document's inline links
350
+ // do, so what a board points at is visible from the other side too.
351
+ references: z.array(IntelId).max(64),
352
+ });
353
+ // The whole board, as it is stored and as it is read. There is no second representation to keep in
354
+ // step with it — this document is the file.
355
+ export const BoardDocument = z.strictObject({
356
+ statuses: z.array(BoardStatus).min(1).max(32),
357
+ tasks: z.array(BoardTask).max(5_000),
358
+ });
359
+ // How deep `parentId` may nest. Five is epic → task → subtask with room left over; without a bound
360
+ // a chain of a thousand tasks would be a valid board that no view can draw and no walk can afford.
361
+ export const BoardMaxTaskDepth = 5;
362
+ export const GetBoardInput = z.strictObject({ nodeId: IntelId });
363
+ // A board as it is read. `versionId` is `null` while nothing has been written yet — the same answer
364
+ // a table gives before its header exists — and the document is then the defaults.
365
+ export const NodeBoard = z.strictObject({
366
+ node: Node,
367
+ board: BoardDocument,
368
+ versionId: IntelId.nullable(),
369
+ });
370
+ export const BoardStatusInput = z.strictObject({
371
+ id: BoardStatusId,
372
+ label: z.string().trim().min(1).max(60),
373
+ });
374
+ // The status list, written whole and in the order it should be drawn — never a patch. Adding,
375
+ // renaming and reordering are all this one call, and `archived` has to be in what it is given.
376
+ export const ConfigureBoardInput = z.strictObject({
377
+ nodeId: IntelId,
378
+ statuses: z
379
+ .array(BoardStatusInput)
380
+ .min(1)
381
+ .max(32)
382
+ .refine((statuses) => new Set(statuses.map((status) => status.id)).size === statuses.length, {
383
+ error: "Status ids must be distinct",
384
+ })
385
+ .refine((statuses) => statuses.some((status) => status.id === ArchivedBoardStatusId), {
386
+ error: `The "${ArchivedBoardStatusId}" status cannot be removed`,
387
+ }),
388
+ idempotencyKey: z.string().min(8).max(200),
389
+ });
390
+ /**
391
+ * A new task (#285).
392
+ *
393
+ * ⚠️ No `baseVersionId`, on this and on every other task operation, and that absence is the
394
+ * feature. A board is addressed by stable task id and never by position, so two agents touching two
395
+ * different tasks cannot collide — demanding a base version would invent the `version_conflict`
396
+ * that #285 exists to remove, and force every caller to read the whole board first.
397
+ */
398
+ export const AddBoardTaskInput = z.strictObject({
399
+ nodeId: IntelId,
400
+ title: z.string().trim().min(1).max(240),
401
+ // Omitted means the first status that is not `archived`: a new task belongs on the board, not on
402
+ // the shelf.
403
+ status: BoardStatusId.optional(),
404
+ assignee: BoardAssignee.nullable().default(null),
405
+ labels: z.array(BoardTaskLabel).max(32).default([]),
406
+ startDate: BoardTaskDate.nullable().default(null),
407
+ dueDate: BoardTaskDate.nullable().default(null),
408
+ parentId: BoardTaskId.nullable().default(null),
409
+ dependsOn: z.array(BoardTaskId).max(64).default([]),
410
+ description: BoardTaskDescription.default(""),
411
+ references: z.array(IntelId).max(64).default([]),
412
+ // Where among its neighbours it goes. Both absent puts it last in its column.
413
+ afterTaskId: BoardTaskId.nullable().default(null),
414
+ beforeTaskId: BoardTaskId.nullable().default(null),
415
+ idempotencyKey: z.string().min(8).max(200),
416
+ });
417
+ /**
418
+ * What a task says about itself.
419
+ *
420
+ * ⚠️ Deliberately no `status`, no `parentId` and no `order`: where a task SITS is a move, and a
421
+ * move is the operation that has to mint an order key and re-check the two cycle rules. Folding
422
+ * both into one call would mean every field edit pays for those checks and every move could quietly
423
+ * rewrite a description.
424
+ */
425
+ export const UpdateBoardTaskInput = z
426
+ .strictObject({
427
+ nodeId: IntelId,
428
+ taskId: BoardTaskId,
429
+ title: z.string().trim().min(1).max(240).optional(),
430
+ assignee: BoardAssignee.nullable().optional(),
431
+ labels: z.array(BoardTaskLabel).max(32).optional(),
432
+ startDate: BoardTaskDate.nullable().optional(),
433
+ dueDate: BoardTaskDate.nullable().optional(),
434
+ dependsOn: z.array(BoardTaskId).max(64).optional(),
435
+ description: BoardTaskDescription.optional(),
436
+ references: z.array(IntelId).max(64).optional(),
437
+ idempotencyKey: z.string().min(8).max(200),
438
+ })
439
+ .refine((input) => input.title !== undefined ||
440
+ input.assignee !== undefined ||
441
+ input.labels !== undefined ||
442
+ input.startDate !== undefined ||
443
+ input.dueDate !== undefined ||
444
+ input.dependsOn !== undefined ||
445
+ input.description !== undefined ||
446
+ input.references !== undefined, { error: "At least one change is required" });
447
+ // Where a task sits: its column, its parent, its place among its neighbours. Archiving is this call
448
+ // with `status: "archived"` — there is no separate verb, because it is not a separate act.
449
+ export const MoveBoardTaskInput = z
450
+ .strictObject({
451
+ nodeId: IntelId,
452
+ taskId: BoardTaskId,
453
+ status: BoardStatusId.optional(),
454
+ parentId: BoardTaskId.nullable().optional(),
455
+ afterTaskId: BoardTaskId.nullable().default(null),
456
+ beforeTaskId: BoardTaskId.nullable().default(null),
457
+ idempotencyKey: z.string().min(8).max(200),
458
+ })
459
+ .refine((input) => input.status !== undefined ||
460
+ input.parentId !== undefined ||
461
+ input.afterTaskId !== null ||
462
+ input.beforeTaskId !== null, { error: "A move needs a status, a parent or a neighbour" });
463
+ // ⚠️ Deleting cascades to every descendant, and the count comes back so a surface can warn BEFORE
464
+ // asking. See `DeleteBoardTaskResult`.
465
+ export const DeleteBoardTaskInput = z.strictObject({
466
+ nodeId: IntelId,
467
+ taskId: BoardTaskId,
468
+ idempotencyKey: z.string().min(8).max(200),
469
+ });
470
+ // The one task that was written, not the whole board: a board can hold thousands of tasks, and
471
+ // answering a one-card edit with all of them would make every write pay for the read.
472
+ export const BoardTaskResult = z.strictObject({
473
+ node: Node,
474
+ version: NodeVersion,
475
+ task: BoardTask,
476
+ });
477
+ // `deleted` counts the task AND every descendant that went with it, so a caller can say what
478
+ // happened rather than "done".
479
+ export const DeleteBoardTaskResult = z.strictObject({
480
+ node: Node,
481
+ version: NodeVersion,
482
+ deleted: z.number().int().positive(),
483
+ });
484
+ export const ConfigureBoardResult = z.strictObject({
485
+ node: Node,
486
+ version: NodeVersion,
487
+ statuses: z.array(BoardStatus),
488
+ });
269
489
  // ── The agent definition (#139, ADR-0005 §4) ─────────────────────────────────────────────────────
270
490
  //
271
491
  // An agent's body is a definition, stored as an immutable version in R2 exactly like a document's.
@@ -281,6 +501,45 @@ export const AgentMediaType = "application/vnd.anchrd.agent+json";
281
501
  // memory write target — ordinary Knowledge, versioned and readable like everything else
282
502
  export const AgentReferenceRole = z.enum(["system-message", "semantic-context", "memory"]);
283
503
  export const AgentReference = z.strictObject({ nodeId: IntelId, role: AgentReferenceRole });
504
+ /**
505
+ * Which kinds of node each role can actually be given (#255).
506
+ *
507
+ * ⚠️ Not every role takes every kind, and the reasons are about what the runtime DOES with a
508
+ * reference rather than about tidiness:
509
+ *
510
+ * `memory` is a folder because the agent WRITES there — `agent_remember` creates a note inside
511
+ * it. A single document as memory would mean the agent overwrites the document it was given.
512
+ *
513
+ * `semantic-context` is a folder because it is a search SPACE, searched per folder by
514
+ * `loop/scoped-search`. A single document is not a narrower search space; reading it whole is a
515
+ * different behaviour, and one that gets named before it is introduced, not slipped in.
516
+ *
517
+ * `system-message` reads single nodes already and takes a document or a table as well as a
518
+ * folder. A document is the natural case — a skill somebody wrote as ordinary text — and a table
519
+ * is the same read: the runtime asks intel for the node and prepends its content, which for a
520
+ * table is its CSV.
521
+ *
522
+ * ⚠️ `folder` stays on `system-message` although a folder carries no content of its own. Every
523
+ * definition written before #255 could only name folders, and taking the combination away here
524
+ * would refuse the next save of an agent that has been working for months — "existing definitions
525
+ * stay valid" is not only about reading them.
526
+ *
527
+ * ⚠️ This is the ONE place the rule lives. The screen offers what it says and the write path
528
+ * refuses what it forbids; a surface that made its own list would eventually disagree with the
529
+ * other, and the one that matters is whichever runs last.
530
+ */
531
+ export const AgentReferenceKinds = {
532
+ "system-message": ["folder", "document", "table"],
533
+ "semantic-context": ["folder"],
534
+ memory: ["folder"],
535
+ };
536
+ export function agentReferenceAccepts(role, kind) {
537
+ return AgentReferenceKinds[role].includes(kind);
538
+ }
539
+ /** The roles a node of this kind may be given — the same rule, read from the other side. */
540
+ export function agentReferenceRolesFor(kind) {
541
+ return AgentReferenceRole.options.filter((role) => agentReferenceAccepts(role, kind));
542
+ }
284
543
  // A `document` target means the content of that document is the instruction — a "skill" somebody
285
544
  // wrote as ordinary text; a `flow` target means a run is started through Intel MCP and worked step
286
545
  // by step. Both are references, so nothing in here goes stale (ADR-0005 §4).
@@ -442,6 +701,68 @@ export const RunAgentNowInput = z.strictObject({
442
701
  nodeId: IntelId,
443
702
  target: AgentScheduleTarget,
444
703
  });
704
+ /**
705
+ * What one agent has actually cost, read out of Cloudflare's AI Gateway log (#251).
706
+ *
707
+ * ⚠️ Intel computes none of this from tokens and a price table. The gateway publishes the billed
708
+ * figure per call, and that figure is the debit from the Cloudflare balance 1:1 — Cloudflare takes
709
+ * its 5 % when the balance is loaded and passes inference through unchanged (measured 2026-08-07).
710
+ * A second, self-maintained answer beside it would be wrong on the day the two disagreed, and the
711
+ * wrong one would be the one on screen.
712
+ *
713
+ * ⚠️ `status` travels with the numbers and may never be dropped. `runs: []` means "cost nothing"
714
+ * only when `status` is `read`; under `not_configured` or `unreadable` it means "not known", and a
715
+ * screen that renders the two alike reports an outage as a saving.
716
+ */
717
+ export const AgentCostStatus = z.enum(["read", "not_configured", "unreadable"]);
718
+ export const AgentRunCost = z.strictObject({
719
+ runId: z.string(),
720
+ cost: z.number(),
721
+ calls: z.number(),
722
+ });
723
+ export const AgentCostWindow = z.strictObject({
724
+ days: z.number(),
725
+ cost: z.number(),
726
+ calls: z.number(),
727
+ // Which models produced this figure. It is here so the model select can say the number is about
728
+ // the PAST (#257) — a reader who switched model would otherwise take it for a forecast.
729
+ models: z.array(z.string()),
730
+ });
731
+ export const AgentCosts = z.strictObject({
732
+ status: AgentCostStatus,
733
+ currency: z.literal("USD"),
734
+ runs: z.array(AgentRunCost),
735
+ windows: z.array(AgentCostWindow),
736
+ // The read hit its page limit, so every total above is a floor rather than a total.
737
+ partial: z.boolean(),
738
+ });
739
+ /**
740
+ * What the models on offer cost and how much they hold (#257).
741
+ *
742
+ * ⚠️ `source` is per ENTRY and not per response, and that is not over-engineering. Cloudflare
743
+ * publishes figures for the models it serves itself and none at all for the Anthropic models it
744
+ * resells through Unified Billing — so a perfectly healthy read still leaves half the list on a
745
+ * written-out table, and one flag for the whole answer would call either the read stale or the
746
+ * table live.
747
+ */
748
+ export const ModelPrice = z.strictObject({
749
+ inputPerMillion: z.number(),
750
+ outputPerMillion: z.number(),
751
+ });
752
+ export const ModelCatalogEntry = z.strictObject({
753
+ provider: z.enum(["workers-ai", "anthropic"]),
754
+ model: z.string(),
755
+ name: z.string(),
756
+ contextTokens: z.number().nullable(),
757
+ // `null` where this installation has no figure. Never zero and never a guess — an invented number
758
+ // is a false statement about money.
759
+ price: ModelPrice.nullable(),
760
+ source: z.enum(["cloudflare", "builtin"]),
761
+ });
762
+ export const ModelCatalog = z.strictObject({
763
+ entries: z.array(ModelCatalogEntry),
764
+ liveStatus: z.enum(["read", "not_configured", "unreadable"]),
765
+ });
445
766
  // ⚠️ Three states, not two, and the same three the flow list makes: omitted is the whole tree,
446
767
  // `null` is the root level, an ID is that folder. "Which agents may I use" is a question about the
447
768
  // tree rather than about one folder, so the useful answer has to be reachable without knowing where
@@ -1116,6 +1437,7 @@ export const RelationNodeKind = z.enum([
1116
1437
  "attachment",
1117
1438
  "table",
1118
1439
  "agent",
1440
+ "board",
1119
1441
  "flow",
1120
1442
  ]);
1121
1443
  export const RelationNode = z.strictObject({
@@ -1300,7 +1622,7 @@ export const FlowRunHistory = z.strictObject({
1300
1622
  // The one name the importer looks for at the zip root. A different spelling would make a bundle a
1301
1623
  // naked folder, so the constant lives in the contract rather than in each surface.
1302
1624
  export const BundleManifestFilename = "manifest.json";
1303
- // What a bundle entry can be. `flow` joins the five node kinds because a flow shares the folder
1625
+ // What a bundle entry can be. `flow` joins the six node kinds because a flow shares the folder
1304
1626
  // tree without being a node (ADR-0004), and the bundle mirrors the tree, not the tables.
1305
1627
  export const BundleEntryKind = z.enum([
1306
1628
  "folder",
@@ -1308,6 +1630,7 @@ export const BundleEntryKind = z.enum([
1308
1630
  "table",
1309
1631
  "attachment",
1310
1632
  "agent",
1633
+ "board",
1311
1634
  "flow",
1312
1635
  ]);
1313
1636
  // 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.8.0",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {