@remnic/core 9.7.12 → 9.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-cli.js +3 -3
- package/dist/access-http.js +2 -2
- package/dist/access-mcp.js +1 -1
- package/dist/access-operations.d.ts +3 -3
- package/dist/access-operations.js +1 -1
- package/dist/access-schema.d.ts +64 -64
- package/dist/{chunk-ZASJ53ML.js → chunk-2V5QI6NQ.js} +37 -5
- package/dist/chunk-2V5QI6NQ.js.map +1 -0
- package/dist/{chunk-AOWPZ7TM.js → chunk-KQMKF4G2.js} +2 -2
- package/dist/{chunk-TITSEN2M.js → chunk-Z6WN2KSH.js} +17 -3
- package/dist/chunk-Z6WN2KSH.js.map +1 -0
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +372 -372
- package/dist/index.js +3 -3
- package/dist/orchestrator.js +3 -3
- package/dist/schemas.d.ts +74 -74
- package/dist/shared-context/manager.d.ts +8 -8
- package/dist/transfer/types.d.ts +66 -66
- package/package.json +2 -2
- package/src/access-http.ts +40 -2
- package/src/relay/mission-access.test.ts +58 -3
- package/src/relay/mission-access.ts +17 -3
- package/src/relay/mission-ui.test.ts +90 -0
- package/dist/chunk-TITSEN2M.js.map +0 -1
- package/dist/chunk-ZASJ53ML.js.map +0 -1
- /package/dist/{chunk-AOWPZ7TM.js.map → chunk-KQMKF4G2.js.map} +0 -0
package/dist/transfer/types.d.ts
CHANGED
|
@@ -20,26 +20,26 @@ declare const ExportManifestV1Schema: z.ZodObject<{
|
|
|
20
20
|
bytes: number;
|
|
21
21
|
}>, "many">;
|
|
22
22
|
}, "strip", z.ZodTypeAny, {
|
|
23
|
-
|
|
23
|
+
schemaVersion: 1;
|
|
24
24
|
createdAt: string;
|
|
25
|
-
pluginVersion: string;
|
|
26
25
|
files: {
|
|
27
26
|
path: string;
|
|
28
27
|
sha256: string;
|
|
29
28
|
bytes: number;
|
|
30
29
|
}[];
|
|
31
|
-
|
|
30
|
+
format: "openclaw-engram-export";
|
|
31
|
+
pluginVersion: string;
|
|
32
32
|
includesTranscripts: boolean;
|
|
33
33
|
}, {
|
|
34
|
-
|
|
34
|
+
schemaVersion: 1;
|
|
35
35
|
createdAt: string;
|
|
36
|
-
pluginVersion: string;
|
|
37
36
|
files: {
|
|
38
37
|
path: string;
|
|
39
38
|
sha256: string;
|
|
40
39
|
bytes: number;
|
|
41
40
|
}[];
|
|
42
|
-
|
|
41
|
+
format: "openclaw-engram-export";
|
|
42
|
+
pluginVersion: string;
|
|
43
43
|
includesTranscripts: boolean;
|
|
44
44
|
}>;
|
|
45
45
|
type ExportManifestV1 = z.infer<typeof ExportManifestV1Schema>;
|
|
@@ -75,26 +75,26 @@ declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
75
75
|
bytes: number;
|
|
76
76
|
}>, "many">;
|
|
77
77
|
}, "strip", z.ZodTypeAny, {
|
|
78
|
-
|
|
78
|
+
schemaVersion: 1;
|
|
79
79
|
createdAt: string;
|
|
80
|
-
pluginVersion: string;
|
|
81
80
|
files: {
|
|
82
81
|
path: string;
|
|
83
82
|
sha256: string;
|
|
84
83
|
bytes: number;
|
|
85
84
|
}[];
|
|
86
|
-
|
|
85
|
+
format: "openclaw-engram-export";
|
|
86
|
+
pluginVersion: string;
|
|
87
87
|
includesTranscripts: boolean;
|
|
88
88
|
}, {
|
|
89
|
-
|
|
89
|
+
schemaVersion: 1;
|
|
90
90
|
createdAt: string;
|
|
91
|
-
pluginVersion: string;
|
|
92
91
|
files: {
|
|
93
92
|
path: string;
|
|
94
93
|
sha256: string;
|
|
95
94
|
bytes: number;
|
|
96
95
|
}[];
|
|
97
|
-
|
|
96
|
+
format: "openclaw-engram-export";
|
|
97
|
+
pluginVersion: string;
|
|
98
98
|
includesTranscripts: boolean;
|
|
99
99
|
}>;
|
|
100
100
|
records: z.ZodArray<z.ZodObject<{
|
|
@@ -109,15 +109,15 @@ declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
109
109
|
}>, "many">;
|
|
110
110
|
}, "strip", z.ZodTypeAny, {
|
|
111
111
|
manifest: {
|
|
112
|
-
|
|
112
|
+
schemaVersion: 1;
|
|
113
113
|
createdAt: string;
|
|
114
|
-
pluginVersion: string;
|
|
115
114
|
files: {
|
|
116
115
|
path: string;
|
|
117
116
|
sha256: string;
|
|
118
117
|
bytes: number;
|
|
119
118
|
}[];
|
|
120
|
-
|
|
119
|
+
format: "openclaw-engram-export";
|
|
120
|
+
pluginVersion: string;
|
|
121
121
|
includesTranscripts: boolean;
|
|
122
122
|
};
|
|
123
123
|
records: {
|
|
@@ -126,15 +126,15 @@ declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
126
126
|
}[];
|
|
127
127
|
}, {
|
|
128
128
|
manifest: {
|
|
129
|
-
|
|
129
|
+
schemaVersion: 1;
|
|
130
130
|
createdAt: string;
|
|
131
|
-
pluginVersion: string;
|
|
132
131
|
files: {
|
|
133
132
|
path: string;
|
|
134
133
|
sha256: string;
|
|
135
134
|
bytes: number;
|
|
136
135
|
}[];
|
|
137
|
-
|
|
136
|
+
format: "openclaw-engram-export";
|
|
137
|
+
pluginVersion: string;
|
|
138
138
|
includesTranscripts: boolean;
|
|
139
139
|
};
|
|
140
140
|
records: {
|
|
@@ -313,16 +313,16 @@ declare const CapsuleBlockSchema: z.ZodObject<{
|
|
|
313
313
|
peerProfiles: boolean;
|
|
314
314
|
}>;
|
|
315
315
|
}, "strip", z.ZodTypeAny, {
|
|
316
|
+
schemaVersion: string;
|
|
316
317
|
includes: {
|
|
317
318
|
procedural: boolean;
|
|
318
319
|
taxonomy: boolean;
|
|
319
320
|
identityAnchors: boolean;
|
|
320
321
|
peerProfiles: boolean;
|
|
321
322
|
};
|
|
322
|
-
description: string;
|
|
323
323
|
id: string;
|
|
324
|
-
schemaVersion: string;
|
|
325
324
|
version: string;
|
|
325
|
+
description: string;
|
|
326
326
|
parentCapsule: string | null;
|
|
327
327
|
retrievalPolicy: {
|
|
328
328
|
tierWeights: Record<string, number>;
|
|
@@ -334,16 +334,16 @@ declare const CapsuleBlockSchema: z.ZodObject<{
|
|
|
334
334
|
forkRoot: string;
|
|
335
335
|
} | null;
|
|
336
336
|
}, {
|
|
337
|
+
schemaVersion: string;
|
|
337
338
|
includes: {
|
|
338
339
|
procedural: boolean;
|
|
339
340
|
taxonomy: boolean;
|
|
340
341
|
identityAnchors: boolean;
|
|
341
342
|
peerProfiles: boolean;
|
|
342
343
|
};
|
|
343
|
-
description: string;
|
|
344
344
|
id: string;
|
|
345
|
-
schemaVersion: string;
|
|
346
345
|
version: string;
|
|
346
|
+
description: string;
|
|
347
347
|
parentCapsule: string | null;
|
|
348
348
|
retrievalPolicy: {
|
|
349
349
|
tierWeights: Record<string, number>;
|
|
@@ -464,16 +464,16 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
464
464
|
peerProfiles: boolean;
|
|
465
465
|
}>;
|
|
466
466
|
}, "strip", z.ZodTypeAny, {
|
|
467
|
+
schemaVersion: string;
|
|
467
468
|
includes: {
|
|
468
469
|
procedural: boolean;
|
|
469
470
|
taxonomy: boolean;
|
|
470
471
|
identityAnchors: boolean;
|
|
471
472
|
peerProfiles: boolean;
|
|
472
473
|
};
|
|
473
|
-
description: string;
|
|
474
474
|
id: string;
|
|
475
|
-
schemaVersion: string;
|
|
476
475
|
version: string;
|
|
476
|
+
description: string;
|
|
477
477
|
parentCapsule: string | null;
|
|
478
478
|
retrievalPolicy: {
|
|
479
479
|
tierWeights: Record<string, number>;
|
|
@@ -485,16 +485,16 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
485
485
|
forkRoot: string;
|
|
486
486
|
} | null;
|
|
487
487
|
}, {
|
|
488
|
+
schemaVersion: string;
|
|
488
489
|
includes: {
|
|
489
490
|
procedural: boolean;
|
|
490
491
|
taxonomy: boolean;
|
|
491
492
|
identityAnchors: boolean;
|
|
492
493
|
peerProfiles: boolean;
|
|
493
494
|
};
|
|
494
|
-
description: string;
|
|
495
495
|
id: string;
|
|
496
|
-
schemaVersion: string;
|
|
497
496
|
version: string;
|
|
497
|
+
description: string;
|
|
498
498
|
parentCapsule: string | null;
|
|
499
499
|
retrievalPolicy: {
|
|
500
500
|
tierWeights: Record<string, number>;
|
|
@@ -507,25 +507,27 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
507
507
|
} | null | undefined;
|
|
508
508
|
}>;
|
|
509
509
|
}, "strip", z.ZodTypeAny, {
|
|
510
|
-
|
|
510
|
+
schemaVersion: 2;
|
|
511
511
|
createdAt: string;
|
|
512
|
-
pluginVersion: string;
|
|
513
512
|
files: {
|
|
514
513
|
path: string;
|
|
515
514
|
sha256: string;
|
|
516
515
|
bytes: number;
|
|
517
516
|
}[];
|
|
517
|
+
format: "openclaw-engram-export";
|
|
518
|
+
pluginVersion: string;
|
|
519
|
+
includesTranscripts: boolean;
|
|
518
520
|
capsule: {
|
|
521
|
+
schemaVersion: string;
|
|
519
522
|
includes: {
|
|
520
523
|
procedural: boolean;
|
|
521
524
|
taxonomy: boolean;
|
|
522
525
|
identityAnchors: boolean;
|
|
523
526
|
peerProfiles: boolean;
|
|
524
527
|
};
|
|
525
|
-
description: string;
|
|
526
528
|
id: string;
|
|
527
|
-
schemaVersion: string;
|
|
528
529
|
version: string;
|
|
530
|
+
description: string;
|
|
529
531
|
parentCapsule: string | null;
|
|
530
532
|
retrievalPolicy: {
|
|
531
533
|
tierWeights: Record<string, number>;
|
|
@@ -537,28 +539,28 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
537
539
|
forkRoot: string;
|
|
538
540
|
} | null;
|
|
539
541
|
};
|
|
540
|
-
schemaVersion: 2;
|
|
541
|
-
includesTranscripts: boolean;
|
|
542
542
|
}, {
|
|
543
|
-
|
|
543
|
+
schemaVersion: 2;
|
|
544
544
|
createdAt: string;
|
|
545
|
-
pluginVersion: string;
|
|
546
545
|
files: {
|
|
547
546
|
path: string;
|
|
548
547
|
sha256: string;
|
|
549
548
|
bytes: number;
|
|
550
549
|
}[];
|
|
550
|
+
format: "openclaw-engram-export";
|
|
551
|
+
pluginVersion: string;
|
|
552
|
+
includesTranscripts: boolean;
|
|
551
553
|
capsule: {
|
|
554
|
+
schemaVersion: string;
|
|
552
555
|
includes: {
|
|
553
556
|
procedural: boolean;
|
|
554
557
|
taxonomy: boolean;
|
|
555
558
|
identityAnchors: boolean;
|
|
556
559
|
peerProfiles: boolean;
|
|
557
560
|
};
|
|
558
|
-
description: string;
|
|
559
561
|
id: string;
|
|
560
|
-
schemaVersion: string;
|
|
561
562
|
version: string;
|
|
563
|
+
description: string;
|
|
562
564
|
parentCapsule: string | null;
|
|
563
565
|
retrievalPolicy: {
|
|
564
566
|
tierWeights: Record<string, number>;
|
|
@@ -570,8 +572,6 @@ declare const ExportManifestV2Schema: z.ZodObject<{
|
|
|
570
572
|
forkRoot: string;
|
|
571
573
|
} | null | undefined;
|
|
572
574
|
};
|
|
573
|
-
schemaVersion: 2;
|
|
574
|
-
includesTranscripts: boolean;
|
|
575
575
|
}>;
|
|
576
576
|
type ExportManifestV2 = z.infer<typeof ExportManifestV2Schema>;
|
|
577
577
|
declare const ExportBundleV2Schema: z.ZodObject<{
|
|
@@ -683,16 +683,16 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
683
683
|
peerProfiles: boolean;
|
|
684
684
|
}>;
|
|
685
685
|
}, "strip", z.ZodTypeAny, {
|
|
686
|
+
schemaVersion: string;
|
|
686
687
|
includes: {
|
|
687
688
|
procedural: boolean;
|
|
688
689
|
taxonomy: boolean;
|
|
689
690
|
identityAnchors: boolean;
|
|
690
691
|
peerProfiles: boolean;
|
|
691
692
|
};
|
|
692
|
-
description: string;
|
|
693
693
|
id: string;
|
|
694
|
-
schemaVersion: string;
|
|
695
694
|
version: string;
|
|
695
|
+
description: string;
|
|
696
696
|
parentCapsule: string | null;
|
|
697
697
|
retrievalPolicy: {
|
|
698
698
|
tierWeights: Record<string, number>;
|
|
@@ -704,16 +704,16 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
704
704
|
forkRoot: string;
|
|
705
705
|
} | null;
|
|
706
706
|
}, {
|
|
707
|
+
schemaVersion: string;
|
|
707
708
|
includes: {
|
|
708
709
|
procedural: boolean;
|
|
709
710
|
taxonomy: boolean;
|
|
710
711
|
identityAnchors: boolean;
|
|
711
712
|
peerProfiles: boolean;
|
|
712
713
|
};
|
|
713
|
-
description: string;
|
|
714
714
|
id: string;
|
|
715
|
-
schemaVersion: string;
|
|
716
715
|
version: string;
|
|
716
|
+
description: string;
|
|
717
717
|
parentCapsule: string | null;
|
|
718
718
|
retrievalPolicy: {
|
|
719
719
|
tierWeights: Record<string, number>;
|
|
@@ -726,25 +726,27 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
726
726
|
} | null | undefined;
|
|
727
727
|
}>;
|
|
728
728
|
}, "strip", z.ZodTypeAny, {
|
|
729
|
-
|
|
729
|
+
schemaVersion: 2;
|
|
730
730
|
createdAt: string;
|
|
731
|
-
pluginVersion: string;
|
|
732
731
|
files: {
|
|
733
732
|
path: string;
|
|
734
733
|
sha256: string;
|
|
735
734
|
bytes: number;
|
|
736
735
|
}[];
|
|
736
|
+
format: "openclaw-engram-export";
|
|
737
|
+
pluginVersion: string;
|
|
738
|
+
includesTranscripts: boolean;
|
|
737
739
|
capsule: {
|
|
740
|
+
schemaVersion: string;
|
|
738
741
|
includes: {
|
|
739
742
|
procedural: boolean;
|
|
740
743
|
taxonomy: boolean;
|
|
741
744
|
identityAnchors: boolean;
|
|
742
745
|
peerProfiles: boolean;
|
|
743
746
|
};
|
|
744
|
-
description: string;
|
|
745
747
|
id: string;
|
|
746
|
-
schemaVersion: string;
|
|
747
748
|
version: string;
|
|
749
|
+
description: string;
|
|
748
750
|
parentCapsule: string | null;
|
|
749
751
|
retrievalPolicy: {
|
|
750
752
|
tierWeights: Record<string, number>;
|
|
@@ -756,28 +758,28 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
756
758
|
forkRoot: string;
|
|
757
759
|
} | null;
|
|
758
760
|
};
|
|
759
|
-
schemaVersion: 2;
|
|
760
|
-
includesTranscripts: boolean;
|
|
761
761
|
}, {
|
|
762
|
-
|
|
762
|
+
schemaVersion: 2;
|
|
763
763
|
createdAt: string;
|
|
764
|
-
pluginVersion: string;
|
|
765
764
|
files: {
|
|
766
765
|
path: string;
|
|
767
766
|
sha256: string;
|
|
768
767
|
bytes: number;
|
|
769
768
|
}[];
|
|
769
|
+
format: "openclaw-engram-export";
|
|
770
|
+
pluginVersion: string;
|
|
771
|
+
includesTranscripts: boolean;
|
|
770
772
|
capsule: {
|
|
773
|
+
schemaVersion: string;
|
|
771
774
|
includes: {
|
|
772
775
|
procedural: boolean;
|
|
773
776
|
taxonomy: boolean;
|
|
774
777
|
identityAnchors: boolean;
|
|
775
778
|
peerProfiles: boolean;
|
|
776
779
|
};
|
|
777
|
-
description: string;
|
|
778
780
|
id: string;
|
|
779
|
-
schemaVersion: string;
|
|
780
781
|
version: string;
|
|
782
|
+
description: string;
|
|
781
783
|
parentCapsule: string | null;
|
|
782
784
|
retrievalPolicy: {
|
|
783
785
|
tierWeights: Record<string, number>;
|
|
@@ -789,8 +791,6 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
789
791
|
forkRoot: string;
|
|
790
792
|
} | null | undefined;
|
|
791
793
|
};
|
|
792
|
-
schemaVersion: 2;
|
|
793
|
-
includesTranscripts: boolean;
|
|
794
794
|
}>;
|
|
795
795
|
records: z.ZodArray<z.ZodObject<{
|
|
796
796
|
path: z.ZodString;
|
|
@@ -804,25 +804,27 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
804
804
|
}>, "many">;
|
|
805
805
|
}, "strip", z.ZodTypeAny, {
|
|
806
806
|
manifest: {
|
|
807
|
-
|
|
807
|
+
schemaVersion: 2;
|
|
808
808
|
createdAt: string;
|
|
809
|
-
pluginVersion: string;
|
|
810
809
|
files: {
|
|
811
810
|
path: string;
|
|
812
811
|
sha256: string;
|
|
813
812
|
bytes: number;
|
|
814
813
|
}[];
|
|
814
|
+
format: "openclaw-engram-export";
|
|
815
|
+
pluginVersion: string;
|
|
816
|
+
includesTranscripts: boolean;
|
|
815
817
|
capsule: {
|
|
818
|
+
schemaVersion: string;
|
|
816
819
|
includes: {
|
|
817
820
|
procedural: boolean;
|
|
818
821
|
taxonomy: boolean;
|
|
819
822
|
identityAnchors: boolean;
|
|
820
823
|
peerProfiles: boolean;
|
|
821
824
|
};
|
|
822
|
-
description: string;
|
|
823
825
|
id: string;
|
|
824
|
-
schemaVersion: string;
|
|
825
826
|
version: string;
|
|
827
|
+
description: string;
|
|
826
828
|
parentCapsule: string | null;
|
|
827
829
|
retrievalPolicy: {
|
|
828
830
|
tierWeights: Record<string, number>;
|
|
@@ -834,8 +836,6 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
834
836
|
forkRoot: string;
|
|
835
837
|
} | null;
|
|
836
838
|
};
|
|
837
|
-
schemaVersion: 2;
|
|
838
|
-
includesTranscripts: boolean;
|
|
839
839
|
};
|
|
840
840
|
records: {
|
|
841
841
|
content: string;
|
|
@@ -843,25 +843,27 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
843
843
|
}[];
|
|
844
844
|
}, {
|
|
845
845
|
manifest: {
|
|
846
|
-
|
|
846
|
+
schemaVersion: 2;
|
|
847
847
|
createdAt: string;
|
|
848
|
-
pluginVersion: string;
|
|
849
848
|
files: {
|
|
850
849
|
path: string;
|
|
851
850
|
sha256: string;
|
|
852
851
|
bytes: number;
|
|
853
852
|
}[];
|
|
853
|
+
format: "openclaw-engram-export";
|
|
854
|
+
pluginVersion: string;
|
|
855
|
+
includesTranscripts: boolean;
|
|
854
856
|
capsule: {
|
|
857
|
+
schemaVersion: string;
|
|
855
858
|
includes: {
|
|
856
859
|
procedural: boolean;
|
|
857
860
|
taxonomy: boolean;
|
|
858
861
|
identityAnchors: boolean;
|
|
859
862
|
peerProfiles: boolean;
|
|
860
863
|
};
|
|
861
|
-
description: string;
|
|
862
864
|
id: string;
|
|
863
|
-
schemaVersion: string;
|
|
864
865
|
version: string;
|
|
866
|
+
description: string;
|
|
865
867
|
parentCapsule: string | null;
|
|
866
868
|
retrievalPolicy: {
|
|
867
869
|
tierWeights: Record<string, number>;
|
|
@@ -873,8 +875,6 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
873
875
|
forkRoot: string;
|
|
874
876
|
} | null | undefined;
|
|
875
877
|
};
|
|
876
|
-
schemaVersion: 2;
|
|
877
|
-
includesTranscripts: boolean;
|
|
878
878
|
};
|
|
879
879
|
records: {
|
|
880
880
|
content: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "9.7.
|
|
3
|
+
"version": "9.7.13",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -3010,7 +3010,7 @@
|
|
|
3010
3010
|
"core"
|
|
3011
3011
|
],
|
|
3012
3012
|
"peerDependencies": {
|
|
3013
|
-
"@remnic/coding-graph": "^9.7.
|
|
3013
|
+
"@remnic/coding-graph": "^9.7.13"
|
|
3014
3014
|
},
|
|
3015
3015
|
"peerDependenciesMeta": {
|
|
3016
3016
|
"@remnic/coding-graph": {
|
package/src/access-http.ts
CHANGED
|
@@ -213,6 +213,12 @@ function resolveDefaultAdminConsolePublicDir(): string {
|
|
|
213
213
|
|
|
214
214
|
const defaultAdminConsolePublicDir = resolveDefaultAdminConsolePublicDir();
|
|
215
215
|
const correlationIdStore = new AsyncLocalStorage<string>();
|
|
216
|
+
const RELAY_ADMIN_CONSOLE_ASSETS = new Map<string, string>([
|
|
217
|
+
["relay.css", "text/css; charset=utf-8"],
|
|
218
|
+
["relay-model.js", "application/javascript; charset=utf-8"],
|
|
219
|
+
["relay.js", "application/javascript; charset=utf-8"],
|
|
220
|
+
["replay.json", "application/json; charset=utf-8"],
|
|
221
|
+
]);
|
|
216
222
|
|
|
217
223
|
// Defaults for the write rate limit; overridable per instance via
|
|
218
224
|
// `writeRateLimitWindowMs` / `writeRateLimitMaxRequests` (issue #1937).
|
|
@@ -1780,6 +1786,7 @@ export class EngramAccessHttpServer {
|
|
|
1780
1786
|
if (!op) {
|
|
1781
1787
|
throw new Error("access-boundary: operation not registered: relay_mission_read");
|
|
1782
1788
|
}
|
|
1789
|
+
const authenticatedPrincipal = this.resolveRequestPrincipal(req)?.trim() || undefined;
|
|
1783
1790
|
const output = (await op.run(
|
|
1784
1791
|
{
|
|
1785
1792
|
missionId,
|
|
@@ -1790,10 +1797,21 @@ export class EngramAccessHttpServer {
|
|
|
1790
1797
|
},
|
|
1791
1798
|
{
|
|
1792
1799
|
service: this.service,
|
|
1793
|
-
authenticatedPrincipal
|
|
1800
|
+
authenticatedPrincipal,
|
|
1794
1801
|
},
|
|
1795
1802
|
)) as { result: unknown };
|
|
1796
1803
|
res.setHeader("cache-control", "no-store");
|
|
1804
|
+
if (authenticatedPrincipal !== undefined) {
|
|
1805
|
+
try {
|
|
1806
|
+
// Percent-encode so every configured principal remains a valid HTTP
|
|
1807
|
+
// header value. Mission Control decodes this before constructing the
|
|
1808
|
+
// server-validated human approval envelope.
|
|
1809
|
+
res.setHeader("x-remnic-authenticated-principal", encodeURIComponent(authenticatedPrincipal));
|
|
1810
|
+
} catch {
|
|
1811
|
+
// An invalid Unicode principal cannot be represented as a Relay actor
|
|
1812
|
+
// identifier. Omit it so Mission Control fails closed at the gate.
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1797
1815
|
this.respondJson(res, 200, output.result);
|
|
1798
1816
|
return;
|
|
1799
1817
|
}
|
|
@@ -3420,14 +3438,33 @@ export class EngramAccessHttpServer {
|
|
|
3420
3438
|
res.end();
|
|
3421
3439
|
return true;
|
|
3422
3440
|
}
|
|
3441
|
+
if (pathname === "/remnic/ui/relay" || pathname === "/engram/ui/relay") {
|
|
3442
|
+
res.statusCode = 301;
|
|
3443
|
+
res.setHeader("location", pathname + "/");
|
|
3444
|
+
res.end();
|
|
3445
|
+
return true;
|
|
3446
|
+
}
|
|
3423
3447
|
if (pathname === "/remnic/ui/" || pathname === "/engram/ui/") {
|
|
3424
3448
|
await this.respondAdminConsoleShell(req, res, pathname);
|
|
3425
3449
|
return true;
|
|
3426
3450
|
}
|
|
3451
|
+
if (pathname === "/remnic/ui/relay/" || pathname === "/engram/ui/relay/") {
|
|
3452
|
+
await this.respondAdminConsoleShell(req, res, pathname, "relay/index.html");
|
|
3453
|
+
return true;
|
|
3454
|
+
}
|
|
3427
3455
|
if (pathname === "/remnic/ui/app.js" || pathname === "/engram/ui/app.js") {
|
|
3428
3456
|
await this.respondStatic(res, path.join(this.adminConsolePublicDir, "app.js"), "application/javascript; charset=utf-8");
|
|
3429
3457
|
return true;
|
|
3430
3458
|
}
|
|
3459
|
+
const relayAsset = RELAY_ADMIN_CONSOLE_ASSETS.get(pathname.split("/").at(-1) ?? "");
|
|
3460
|
+
const isRelayAsset = pathname.startsWith("/remnic/ui/relay/") || pathname.startsWith("/engram/ui/relay/");
|
|
3461
|
+
if (isRelayAsset && relayAsset && pathname.split("/").length === 5) {
|
|
3462
|
+
const fileName = pathname.split("/").at(-1);
|
|
3463
|
+
if (fileName) {
|
|
3464
|
+
await this.respondStatic(res, path.join(this.adminConsolePublicDir, "relay", fileName), relayAsset);
|
|
3465
|
+
return true;
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3431
3468
|
return false;
|
|
3432
3469
|
}
|
|
3433
3470
|
|
|
@@ -3435,9 +3472,10 @@ export class EngramAccessHttpServer {
|
|
|
3435
3472
|
req: IncomingMessage,
|
|
3436
3473
|
res: ServerResponse,
|
|
3437
3474
|
pathname: string,
|
|
3475
|
+
relativePath = "index.html",
|
|
3438
3476
|
): Promise<void> {
|
|
3439
3477
|
try {
|
|
3440
|
-
let body = await readFile(path.join(this.adminConsolePublicDir,
|
|
3478
|
+
let body = await readFile(path.join(this.adminConsolePublicDir, relativePath), "utf-8");
|
|
3441
3479
|
const canPrefillToken = this.adminConsolePrefillToken && this.isAuthorized(req, pathname);
|
|
3442
3480
|
if (canPrefillToken) {
|
|
3443
3481
|
const script = `<script>window.__REMNIC_ADMIN_CONSOLE_PREFILL_TOKEN__=${JSON.stringify(this.adminConsolePrefillToken)};</script>`;
|
|
@@ -60,13 +60,33 @@ test("HTTP fixture endpoint returns one complete, namespace-authorized Relay rec
|
|
|
60
60
|
service: fakeService(root, calls),
|
|
61
61
|
port: 0,
|
|
62
62
|
authToken: "relay-token",
|
|
63
|
-
principal: "
|
|
63
|
+
principal: "operator-build-week",
|
|
64
64
|
adminConsoleEnabled: false,
|
|
65
65
|
});
|
|
66
66
|
const status = await server.start();
|
|
67
67
|
const base = `http://127.0.0.1:${status.port}/engram/v1/relay/missions/${RELAY_DEMO_MISSION_ID}`;
|
|
68
68
|
try {
|
|
69
69
|
const fixture = createRelayMissionFixture();
|
|
70
|
+
const approval = fixture.find((event) => event.payload.kind === "correction_approved");
|
|
71
|
+
assert.ok(approval && approval.payload.kind === "correction_approved");
|
|
72
|
+
const mismatchedApproval = await fetch(`${base}/events`, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers: authHeaders(),
|
|
75
|
+
body: JSON.stringify({
|
|
76
|
+
namespace: RELAY_DEMO_NAMESPACE,
|
|
77
|
+
event: {
|
|
78
|
+
...approval,
|
|
79
|
+
idempotencyKey: "mismatched-human-approval",
|
|
80
|
+
payload: {
|
|
81
|
+
...approval.payload,
|
|
82
|
+
approvedBy: { ...approval.payload.approvedBy, id: "different-operator" },
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
assert.equal(mismatchedApproval.status, 400);
|
|
88
|
+
assert.equal(((await mismatchedApproval.json()) as { code: string }).code, "input_error");
|
|
89
|
+
|
|
70
90
|
const blankNamespace = await fetch(`${base}/events`, {
|
|
71
91
|
method: "POST",
|
|
72
92
|
headers: authHeaders(),
|
|
@@ -91,7 +111,7 @@ test("HTTP fixture endpoint returns one complete, namespace-authorized Relay rec
|
|
|
91
111
|
assert.equal(response.status, 201, responseBody);
|
|
92
112
|
assert.equal(
|
|
93
113
|
(JSON.parse(responseBody) as { event: { authenticatedPrincipal?: string } }).event.authenticatedPrincipal,
|
|
94
|
-
"
|
|
114
|
+
"operator-build-week"
|
|
95
115
|
);
|
|
96
116
|
}
|
|
97
117
|
|
|
@@ -108,6 +128,7 @@ test("HTTP fixture endpoint returns one complete, namespace-authorized Relay rec
|
|
|
108
128
|
});
|
|
109
129
|
assert.equal(response.status, 200);
|
|
110
130
|
assert.equal(response.headers.get("cache-control"), "no-store");
|
|
131
|
+
assert.equal(response.headers.get("x-remnic-authenticated-principal"), "operator-build-week");
|
|
111
132
|
const snapshot = (await response.json()) as RelayMissionSnapshot;
|
|
112
133
|
assert.equal(snapshot.receipt.complete, true);
|
|
113
134
|
assert.deepEqual(snapshot.receipt.activeDecisionIds, ["decision-refresh-after-expiry"]);
|
|
@@ -115,7 +136,40 @@ test("HTTP fixture endpoint returns one complete, namespace-authorized Relay rec
|
|
|
115
136
|
assert.equal(snapshot.agents.length, 3);
|
|
116
137
|
assert.equal(snapshot.tests.at(-1)?.status, "passed");
|
|
117
138
|
assert.ok(calls.every((call) => call.namespace === RELAY_DEMO_NAMESPACE));
|
|
118
|
-
assert.ok(calls.every((call) => call.principal === "
|
|
139
|
+
assert.ok(calls.every((call) => call.principal === "operator-build-week"));
|
|
140
|
+
} finally {
|
|
141
|
+
await server.stop();
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("HTTP Relay rejects human approval without a server-resolved principal before persistence", async () => {
|
|
147
|
+
await withTempRoot(async (root) => {
|
|
148
|
+
const server = new EngramAccessHttpServer({
|
|
149
|
+
service: fakeService(root, []),
|
|
150
|
+
port: 0,
|
|
151
|
+
authToken: "relay-token",
|
|
152
|
+
adminConsoleEnabled: false,
|
|
153
|
+
});
|
|
154
|
+
const status = await server.start();
|
|
155
|
+
const base = `http://127.0.0.1:${status.port}/engram/v1/relay/missions/${RELAY_DEMO_MISSION_ID}`;
|
|
156
|
+
try {
|
|
157
|
+
const approval = createRelayMissionFixture().find((event) => event.payload.kind === "correction_approved");
|
|
158
|
+
assert.ok(approval);
|
|
159
|
+
const rejected = await fetch(`${base}/events`, {
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers: authHeaders(),
|
|
162
|
+
body: JSON.stringify({ namespace: RELAY_DEMO_NAMESPACE, event: approval }),
|
|
163
|
+
});
|
|
164
|
+
assert.equal(rejected.status, 400);
|
|
165
|
+
assert.equal(((await rejected.json()) as { code: string }).code, "input_error");
|
|
166
|
+
|
|
167
|
+
const snapshotResponse = await fetch(`${base}?namespace=${RELAY_DEMO_NAMESPACE}`, {
|
|
168
|
+
headers: authHeaders(),
|
|
169
|
+
});
|
|
170
|
+
assert.equal(snapshotResponse.status, 200);
|
|
171
|
+
assert.equal(snapshotResponse.headers.get("x-remnic-authenticated-principal"), null);
|
|
172
|
+
assert.equal(((await snapshotResponse.json()) as RelayMissionSnapshot).found, false);
|
|
119
173
|
} finally {
|
|
120
174
|
await server.stop();
|
|
121
175
|
}
|
|
@@ -150,6 +204,7 @@ test("HTTP Relay surface distinguishes empty, invalid, unauthorized, and backend
|
|
|
150
204
|
|
|
151
205
|
const empty = await fetch(emptyUrl, { headers: authHeaders("read-token") });
|
|
152
206
|
assert.equal(empty.status, 200);
|
|
207
|
+
assert.equal(empty.headers.get("x-remnic-authenticated-principal"), null);
|
|
153
208
|
assert.deepEqual(await empty.json(), assertEmptyMissionShape());
|
|
154
209
|
|
|
155
210
|
const badLimit = await fetch(`${emptyUrl}&limit=501`, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
import { type OperationContext, defineOperation } from "../access-boundary.js";
|
|
4
|
-
import type
|
|
4
|
+
import { EngramAccessInputError, type EngramAccessService } from "../access-service.js";
|
|
5
5
|
import {
|
|
6
6
|
RELAY_MISSION_MAX_EVENT_LIMIT,
|
|
7
7
|
RelayIsoDateTimeSchema,
|
|
@@ -76,12 +76,26 @@ export async function appendRelayMissionEvent(
|
|
|
76
76
|
authenticatedPrincipal?: string,
|
|
77
77
|
beforeAppend?: () => void | Promise<void>
|
|
78
78
|
): Promise<RelayMissionAppendResult> {
|
|
79
|
-
const
|
|
79
|
+
const event = RelayMissionEventInputSchema.parse(input.event);
|
|
80
|
+
const approvalPrincipal = authenticatedPrincipal?.trim() || undefined;
|
|
81
|
+
if (event.payload.kind === "correction_approved" && event.payload.approvedBy.kind === "human") {
|
|
82
|
+
if (!approvalPrincipal) {
|
|
83
|
+
throw new EngramAccessInputError(
|
|
84
|
+
"Relay human approval requires a server-resolved authenticated principal"
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (event.payload.approvedBy.id !== approvalPrincipal) {
|
|
88
|
+
throw new EngramAccessInputError(
|
|
89
|
+
"Relay human approval identity must match the server-resolved authenticated principal"
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const resolved = await service.getWritableStorageForNamespace(input.namespace ?? undefined, approvalPrincipal);
|
|
80
94
|
const store = new RelayMissionStore({
|
|
81
95
|
rootDir: resolved.storage.dir,
|
|
82
96
|
namespace: resolved.namespace,
|
|
83
97
|
});
|
|
84
|
-
return store.append(input.missionId,
|
|
98
|
+
return store.append(input.missionId, event, { authenticatedPrincipal: approvalPrincipal, beforeAppend });
|
|
85
99
|
}
|
|
86
100
|
|
|
87
101
|
/** Namespace-authorized, bounded Relay snapshot read shared by HTTP and UI. */
|