@remnic/core 9.3.685 → 9.3.687
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-boundary.d.ts +2 -2
- package/dist/access-boundary.js +2 -2
- package/dist/access-cli.js +88 -7
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +1 -1
- package/dist/access-http.js +5 -5
- package/dist/access-mcp.d.ts +12 -2
- package/dist/access-mcp.js +4 -4
- package/dist/access-operations.d.ts +8 -3
- package/dist/access-operations.js +5 -3
- package/dist/access-schema.d.ts +4 -4
- package/dist/{access-service-DeKrlYU_.d.ts → access-service-DmCHJ4cH.d.ts} +105 -29
- package/dist/access-service.d.ts +1 -1
- package/dist/access-service.js +1 -1
- package/dist/access-surface-catalog.d.ts +1 -1
- package/dist/access-surface-catalog.js +2 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/{chunk-OFUULUSY.js → chunk-473JIN2U.js} +56 -5
- package/dist/chunk-473JIN2U.js.map +1 -0
- package/dist/{chunk-SQGPGC76.js → chunk-FUCUR2OZ.js} +540 -43
- package/dist/chunk-FUCUR2OZ.js.map +1 -0
- package/dist/{chunk-IIDSFFE5.js → chunk-KFBOZYME.js} +42 -3
- package/dist/chunk-KFBOZYME.js.map +1 -0
- package/dist/{chunk-PK6RGRSD.js → chunk-NN7QYW5W.js} +2 -2
- package/dist/chunk-NN7QYW5W.js.map +1 -0
- package/dist/{chunk-JPCKLFWK.js → chunk-QVMXQGT7.js} +6 -5
- package/dist/chunk-QVMXQGT7.js.map +1 -0
- package/dist/{chunk-BZISAF67.js → chunk-S2OU5DZY.js} +28 -6
- package/dist/chunk-S2OU5DZY.js.map +1 -0
- package/dist/{cli-D3-Q5Uod.d.ts → cli-D8nZ2MPH.d.ts} +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/mcp-memory-inspector-app.d.ts +1 -1
- package/dist/schemas.d.ts +16 -16
- package/dist/transfer/types.d.ts +10 -10
- package/package.json +2 -2
- package/src/access-boundary.ts +2 -1
- package/src/access-cli.ts +94 -4
- package/src/access-http.ts +39 -1
- package/src/access-mcp.ts +54 -1
- package/src/access-operations.ts +66 -0
- package/src/access-service.ts +147 -62
- package/src/access-surface-catalog.test.ts +1 -1
- package/src/access-surface-catalog.ts +2 -0
- package/src/cli.ts +1 -0
- package/src/coding/decision-surfaces.test.ts +279 -0
- package/src/coding/decision-surfaces.ts +475 -0
- package/dist/chunk-BZISAF67.js.map +0 -1
- package/dist/chunk-IIDSFFE5.js.map +0 -1
- package/dist/chunk-JPCKLFWK.js.map +0 -1
- package/dist/chunk-OFUULUSY.js.map +0 -1
- package/dist/chunk-PK6RGRSD.js.map +0 -1
- package/dist/chunk-SQGPGC76.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -98,7 +98,7 @@ import {
|
|
|
98
98
|
registerTrainingExportAdapter,
|
|
99
99
|
runBulkImportCliCommand,
|
|
100
100
|
runWearablesCliCommand
|
|
101
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-QVMXQGT7.js";
|
|
102
102
|
import "./chunk-MC4FJXPA.js";
|
|
103
103
|
import "./chunk-LQHDIS7L.js";
|
|
104
104
|
import "./chunk-7F7Z6MOS.js";
|
|
@@ -500,7 +500,7 @@ import "./chunk-LBJBNWS2.js";
|
|
|
500
500
|
import "./chunk-OADWQ5CR.js";
|
|
501
501
|
import {
|
|
502
502
|
EngramAccessHttpServer
|
|
503
|
-
} from "./chunk-
|
|
503
|
+
} from "./chunk-S2OU5DZY.js";
|
|
504
504
|
import "./chunk-SEDEKFYQ.js";
|
|
505
505
|
import "./chunk-RKNJBZ55.js";
|
|
506
506
|
import "./chunk-J64TK33U.js";
|
|
@@ -514,7 +514,7 @@ import {
|
|
|
514
514
|
} from "./chunk-7WV3F5DQ.js";
|
|
515
515
|
import {
|
|
516
516
|
EngramMcpServer
|
|
517
|
-
} from "./chunk-
|
|
517
|
+
} from "./chunk-473JIN2U.js";
|
|
518
518
|
import {
|
|
519
519
|
REMNIC_CHATGPT_MEMORY_INSPECTOR_CANONICAL_TOOL,
|
|
520
520
|
REMNIC_CHATGPT_MEMORY_INSPECTOR_MIME_TYPE,
|
|
@@ -530,7 +530,7 @@ import {
|
|
|
530
530
|
parseOaiMemCitation,
|
|
531
531
|
sanitizeNoteForCitation
|
|
532
532
|
} from "./chunk-D24OXEPB.js";
|
|
533
|
-
import "./chunk-
|
|
533
|
+
import "./chunk-KFBOZYME.js";
|
|
534
534
|
import {
|
|
535
535
|
formatZodError,
|
|
536
536
|
memoryStoreRequestSchema,
|
|
@@ -539,13 +539,13 @@ import {
|
|
|
539
539
|
suggestionSubmitRequestSchema,
|
|
540
540
|
validateRequest
|
|
541
541
|
} from "./chunk-UDJLF3BO.js";
|
|
542
|
-
import "./chunk-
|
|
542
|
+
import "./chunk-NN7QYW5W.js";
|
|
543
543
|
import {
|
|
544
544
|
EngramAccessInputError,
|
|
545
545
|
EngramAccessService,
|
|
546
546
|
computeProcedureStats,
|
|
547
547
|
formatProcedureStatsText
|
|
548
|
-
} from "./chunk-
|
|
548
|
+
} from "./chunk-FUCUR2OZ.js";
|
|
549
549
|
import "./chunk-GDASG7NC.js";
|
|
550
550
|
import "./chunk-GDB4J2H3.js";
|
|
551
551
|
import {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as EngramAccessRecallResponse } from './access-service-DmCHJ4cH.js';
|
|
2
2
|
import { ActionConfidenceRequest } from './access-schema.js';
|
|
3
3
|
import { RecallXraySnapshot } from './recall-xray.js';
|
|
4
4
|
import { ActionConfidenceResult } from './action-confidence.js';
|
package/dist/schemas.d.ts
CHANGED
|
@@ -310,12 +310,12 @@ declare const ExtractedQuestionSchema: z.ZodObject<{
|
|
|
310
310
|
priority: z.ZodNumber;
|
|
311
311
|
}, "strip", z.ZodTypeAny, {
|
|
312
312
|
question: string;
|
|
313
|
-
priority: number;
|
|
314
313
|
context: string;
|
|
314
|
+
priority: number;
|
|
315
315
|
}, {
|
|
316
316
|
question: string;
|
|
317
|
-
priority: number;
|
|
318
317
|
context: string;
|
|
318
|
+
priority: number;
|
|
319
319
|
}>;
|
|
320
320
|
declare const ProactiveQuestionsResultSchema: z.ZodObject<{
|
|
321
321
|
questions: z.ZodArray<z.ZodObject<{
|
|
@@ -324,24 +324,24 @@ declare const ProactiveQuestionsResultSchema: z.ZodObject<{
|
|
|
324
324
|
priority: z.ZodNumber;
|
|
325
325
|
}, "strip", z.ZodTypeAny, {
|
|
326
326
|
question: string;
|
|
327
|
-
priority: number;
|
|
328
327
|
context: string;
|
|
328
|
+
priority: number;
|
|
329
329
|
}, {
|
|
330
330
|
question: string;
|
|
331
|
-
priority: number;
|
|
332
331
|
context: string;
|
|
332
|
+
priority: number;
|
|
333
333
|
}>, "many">;
|
|
334
334
|
}, "strip", z.ZodTypeAny, {
|
|
335
335
|
questions: {
|
|
336
336
|
question: string;
|
|
337
|
-
priority: number;
|
|
338
337
|
context: string;
|
|
338
|
+
priority: number;
|
|
339
339
|
}[];
|
|
340
340
|
}, {
|
|
341
341
|
questions: {
|
|
342
342
|
question: string;
|
|
343
|
-
priority: number;
|
|
344
343
|
context: string;
|
|
344
|
+
priority: number;
|
|
345
345
|
}[];
|
|
346
346
|
}>;
|
|
347
347
|
declare const ExtractedRelationshipSchema: z.ZodObject<{
|
|
@@ -987,12 +987,12 @@ declare const ExtractionResultSchema: z.ZodObject<{
|
|
|
987
987
|
priority: z.ZodNumber;
|
|
988
988
|
}, "strip", z.ZodTypeAny, {
|
|
989
989
|
question: string;
|
|
990
|
-
priority: number;
|
|
991
990
|
context: string;
|
|
991
|
+
priority: number;
|
|
992
992
|
}, {
|
|
993
993
|
question: string;
|
|
994
|
-
priority: number;
|
|
995
994
|
context: string;
|
|
995
|
+
priority: number;
|
|
996
996
|
}>, "many">;
|
|
997
997
|
identityReflection: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
998
998
|
relationships: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -1014,8 +1014,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
|
|
|
1014
1014
|
}, "strip", z.ZodTypeAny, {
|
|
1015
1015
|
questions: {
|
|
1016
1016
|
question: string;
|
|
1017
|
-
priority: number;
|
|
1018
1017
|
context: string;
|
|
1018
|
+
priority: number;
|
|
1019
1019
|
}[];
|
|
1020
1020
|
facts: {
|
|
1021
1021
|
tags: string[];
|
|
@@ -1069,8 +1069,8 @@ declare const ExtractionResultSchema: z.ZodObject<{
|
|
|
1069
1069
|
}, {
|
|
1070
1070
|
questions: {
|
|
1071
1071
|
question: string;
|
|
1072
|
-
priority: number;
|
|
1073
1072
|
context: string;
|
|
1073
|
+
priority: number;
|
|
1074
1074
|
}[];
|
|
1075
1075
|
facts: {
|
|
1076
1076
|
tags: string[];
|
|
@@ -1386,8 +1386,8 @@ declare const BehaviorLoopAdjustmentSchema: z.ZodObject<{
|
|
|
1386
1386
|
reason: z.ZodString;
|
|
1387
1387
|
appliedAt: z.ZodString;
|
|
1388
1388
|
}, "strip", z.ZodTypeAny, {
|
|
1389
|
-
reason: string;
|
|
1390
1389
|
confidence: number;
|
|
1390
|
+
reason: string;
|
|
1391
1391
|
parameter: string;
|
|
1392
1392
|
previousValue: number;
|
|
1393
1393
|
nextValue: number;
|
|
@@ -1395,8 +1395,8 @@ declare const BehaviorLoopAdjustmentSchema: z.ZodObject<{
|
|
|
1395
1395
|
evidenceCount: number;
|
|
1396
1396
|
appliedAt: string;
|
|
1397
1397
|
}, {
|
|
1398
|
-
reason: string;
|
|
1399
1398
|
confidence: number;
|
|
1399
|
+
reason: string;
|
|
1400
1400
|
parameter: string;
|
|
1401
1401
|
previousValue: number;
|
|
1402
1402
|
nextValue: number;
|
|
@@ -1420,8 +1420,8 @@ declare const BehaviorLoopPolicyStateSchema: z.ZodObject<{
|
|
|
1420
1420
|
reason: z.ZodString;
|
|
1421
1421
|
appliedAt: z.ZodString;
|
|
1422
1422
|
}, "strip", z.ZodTypeAny, {
|
|
1423
|
-
reason: string;
|
|
1424
1423
|
confidence: number;
|
|
1424
|
+
reason: string;
|
|
1425
1425
|
parameter: string;
|
|
1426
1426
|
previousValue: number;
|
|
1427
1427
|
nextValue: number;
|
|
@@ -1429,8 +1429,8 @@ declare const BehaviorLoopPolicyStateSchema: z.ZodObject<{
|
|
|
1429
1429
|
evidenceCount: number;
|
|
1430
1430
|
appliedAt: string;
|
|
1431
1431
|
}, {
|
|
1432
|
-
reason: string;
|
|
1433
1432
|
confidence: number;
|
|
1433
|
+
reason: string;
|
|
1434
1434
|
parameter: string;
|
|
1435
1435
|
previousValue: number;
|
|
1436
1436
|
nextValue: number;
|
|
@@ -1447,8 +1447,8 @@ declare const BehaviorLoopPolicyStateSchema: z.ZodObject<{
|
|
|
1447
1447
|
maxDeltaPerCycle: number;
|
|
1448
1448
|
protectedParams: string[];
|
|
1449
1449
|
adjustments: {
|
|
1450
|
-
reason: string;
|
|
1451
1450
|
confidence: number;
|
|
1451
|
+
reason: string;
|
|
1452
1452
|
parameter: string;
|
|
1453
1453
|
previousValue: number;
|
|
1454
1454
|
nextValue: number;
|
|
@@ -1464,8 +1464,8 @@ declare const BehaviorLoopPolicyStateSchema: z.ZodObject<{
|
|
|
1464
1464
|
maxDeltaPerCycle: number;
|
|
1465
1465
|
protectedParams: string[];
|
|
1466
1466
|
adjustments: {
|
|
1467
|
-
reason: string;
|
|
1468
1467
|
confidence: number;
|
|
1468
|
+
reason: string;
|
|
1469
1469
|
parameter: string;
|
|
1470
1470
|
previousValue: number;
|
|
1471
1471
|
nextValue: number;
|
package/dist/transfer/types.d.ts
CHANGED
|
@@ -108,6 +108,10 @@ declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
108
108
|
path: string;
|
|
109
109
|
}>, "many">;
|
|
110
110
|
}, "strip", z.ZodTypeAny, {
|
|
111
|
+
records: {
|
|
112
|
+
content: string;
|
|
113
|
+
path: string;
|
|
114
|
+
}[];
|
|
111
115
|
manifest: {
|
|
112
116
|
schemaVersion: 1;
|
|
113
117
|
createdAt: string;
|
|
@@ -120,11 +124,11 @@ declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
120
124
|
pluginVersion: string;
|
|
121
125
|
includesTranscripts: boolean;
|
|
122
126
|
};
|
|
127
|
+
}, {
|
|
123
128
|
records: {
|
|
124
129
|
content: string;
|
|
125
130
|
path: string;
|
|
126
131
|
}[];
|
|
127
|
-
}, {
|
|
128
132
|
manifest: {
|
|
129
133
|
schemaVersion: 1;
|
|
130
134
|
createdAt: string;
|
|
@@ -137,10 +141,6 @@ declare const ExportBundleV1Schema: z.ZodObject<{
|
|
|
137
141
|
pluginVersion: string;
|
|
138
142
|
includesTranscripts: boolean;
|
|
139
143
|
};
|
|
140
|
-
records: {
|
|
141
|
-
content: string;
|
|
142
|
-
path: string;
|
|
143
|
-
}[];
|
|
144
144
|
}>;
|
|
145
145
|
type ExportBundleV1 = z.infer<typeof ExportBundleV1Schema>;
|
|
146
146
|
/**
|
|
@@ -803,6 +803,10 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
803
803
|
path: string;
|
|
804
804
|
}>, "many">;
|
|
805
805
|
}, "strip", z.ZodTypeAny, {
|
|
806
|
+
records: {
|
|
807
|
+
content: string;
|
|
808
|
+
path: string;
|
|
809
|
+
}[];
|
|
806
810
|
manifest: {
|
|
807
811
|
schemaVersion: 2;
|
|
808
812
|
createdAt: string;
|
|
@@ -837,11 +841,11 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
837
841
|
};
|
|
838
842
|
};
|
|
839
843
|
};
|
|
844
|
+
}, {
|
|
840
845
|
records: {
|
|
841
846
|
content: string;
|
|
842
847
|
path: string;
|
|
843
848
|
}[];
|
|
844
|
-
}, {
|
|
845
849
|
manifest: {
|
|
846
850
|
schemaVersion: 2;
|
|
847
851
|
createdAt: string;
|
|
@@ -876,10 +880,6 @@ declare const ExportBundleV2Schema: z.ZodObject<{
|
|
|
876
880
|
} | null | undefined;
|
|
877
881
|
};
|
|
878
882
|
};
|
|
879
|
-
records: {
|
|
880
|
-
content: string;
|
|
881
|
-
path: string;
|
|
882
|
-
}[];
|
|
883
883
|
}>;
|
|
884
884
|
type ExportBundleV2 = z.infer<typeof ExportBundleV2Schema>;
|
|
885
885
|
type AnyExportManifest = ExportManifestV1 | ExportManifestV2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.687",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -2931,7 +2931,7 @@
|
|
|
2931
2931
|
"core"
|
|
2932
2932
|
],
|
|
2933
2933
|
"peerDependencies": {
|
|
2934
|
-
"@remnic/coding-graph": "^9.3.
|
|
2934
|
+
"@remnic/coding-graph": "^9.3.687"
|
|
2935
2935
|
},
|
|
2936
2936
|
"peerDependenciesMeta": {
|
|
2937
2937
|
"@remnic/coding-graph": {
|
package/src/access-boundary.ts
CHANGED
|
@@ -33,7 +33,8 @@ import { expandTildePath } from "./utils/path.js";
|
|
|
33
33
|
export type OperationName =
|
|
34
34
|
| "memory_get"
|
|
35
35
|
| "memory_search"
|
|
36
|
-
| "memory_store"
|
|
36
|
+
| "memory_store"
|
|
37
|
+
| "coding_decision";
|
|
37
38
|
|
|
38
39
|
// ---------------------------------------------------------------------------
|
|
39
40
|
// Operation context — what every handler receives
|
package/src/access-cli.ts
CHANGED
|
@@ -11,10 +11,11 @@ import { getOperation } from "./access-boundary.js";
|
|
|
11
11
|
// Importing access-operations registers the pilot boundary operations as a
|
|
12
12
|
// side effect; the store command dispatches through the registry (issue #1525).
|
|
13
13
|
import "./access-operations.js";
|
|
14
|
+
import { projectTagProjectId } from "./coding/coding-namespace.js";
|
|
14
15
|
|
|
15
16
|
const OPENCLAW_REMNIC_PLUGIN_IDS = ["openclaw-remnic", "openclaw-engram"] as const;
|
|
16
17
|
|
|
17
|
-
type CommandName = "browse" | "store";
|
|
18
|
+
type CommandName = "browse" | "store" | "decision";
|
|
18
19
|
|
|
19
20
|
type ParsedArgs = {
|
|
20
21
|
command: CommandName;
|
|
@@ -133,9 +134,9 @@ function writeCliOutput(text: string = ""): void {
|
|
|
133
134
|
|
|
134
135
|
function usage(): string {
|
|
135
136
|
return [
|
|
136
|
-
"Usage:",
|
|
137
137
|
" engram-access browse [options]",
|
|
138
138
|
" engram-access store [options]",
|
|
139
|
+
" engram-access decision [options]",
|
|
139
140
|
"",
|
|
140
141
|
"Browse options:",
|
|
141
142
|
" --namespace <name>",
|
|
@@ -160,6 +161,21 @@ function usage(): string {
|
|
|
160
161
|
" --source-reason <text>",
|
|
161
162
|
" --idempotency-key <key>",
|
|
162
163
|
" --dry-run",
|
|
164
|
+
"",
|
|
165
|
+
"Decision options:",
|
|
166
|
+
" --subcommand <list|get|record|supersede>",
|
|
167
|
+
" --namespace <name>",
|
|
168
|
+
" --session-key <key>",
|
|
169
|
+
" --principal <principal>",
|
|
170
|
+
" --id <id> (get/supersede)",
|
|
171
|
+
" --title <title> (record/supersede)",
|
|
172
|
+
" --status <proposed|accepted|superseded|rejected> (record)",
|
|
173
|
+
" --context <text> (record/supersede)",
|
|
174
|
+
" --decision <text> (record/supersede)",
|
|
175
|
+
" --consequences <text> (record/supersede)",
|
|
176
|
+
" --entity-ref <ref> (repeatable)",
|
|
177
|
+
" --project-tag <tag> (attach coding context for this invocation)",
|
|
178
|
+
" --supersedes-id <id> (alias for --id on supersede)",
|
|
163
179
|
].join("\n");
|
|
164
180
|
}
|
|
165
181
|
|
|
@@ -194,8 +210,25 @@ const COMMAND_SPECS: Record<CommandName, CommandSpec> = {
|
|
|
194
210
|
]),
|
|
195
211
|
flagOptions: new Set(["dry-run"]),
|
|
196
212
|
},
|
|
213
|
+
decision: {
|
|
214
|
+
valueOptions: new Set([
|
|
215
|
+
"subcommand",
|
|
216
|
+
"namespace",
|
|
217
|
+
"session-key",
|
|
218
|
+
"principal",
|
|
219
|
+
"id",
|
|
220
|
+
"title",
|
|
221
|
+
"status",
|
|
222
|
+
"context",
|
|
223
|
+
"decision",
|
|
224
|
+
"consequences",
|
|
225
|
+
"entity-ref",
|
|
226
|
+
"project-tag",
|
|
227
|
+
"supersedes-id",
|
|
228
|
+
]),
|
|
229
|
+
flagOptions: new Set(),
|
|
230
|
+
},
|
|
197
231
|
};
|
|
198
|
-
|
|
199
232
|
const BROWSE_SORT_VALUES = Object.freeze([
|
|
200
233
|
"updated_desc",
|
|
201
234
|
"updated_asc",
|
|
@@ -207,7 +240,7 @@ type BrowseSort = (typeof BROWSE_SORT_VALUES)[number];
|
|
|
207
240
|
|
|
208
241
|
function parseArgs(argv: string[]): ParsedArgs {
|
|
209
242
|
const [commandRaw, ...rest] = argv;
|
|
210
|
-
if (commandRaw !== "browse" && commandRaw !== "store") {
|
|
243
|
+
if (commandRaw !== "browse" && commandRaw !== "store" && commandRaw !== "decision") {
|
|
211
244
|
throw new UsageError("unsupported-command");
|
|
212
245
|
}
|
|
213
246
|
const spec = COMMAND_SPECS[commandRaw];
|
|
@@ -466,6 +499,59 @@ function expandOptionalPath(value: string | undefined): string | undefined {
|
|
|
466
499
|
return value === undefined ? undefined : expandTildePath(value);
|
|
467
500
|
}
|
|
468
501
|
|
|
502
|
+
/**
|
|
503
|
+
* Decision-record surface (issue #1548 Track A PR 2). Dispatches through the
|
|
504
|
+
* same `coding_decision` operation as the MCP tool and HTTP route — one
|
|
505
|
+
* validation boundary, three transports.
|
|
506
|
+
*/
|
|
507
|
+
async function runDecision(args: ParsedArgs, preferredId?: string): Promise<void> {
|
|
508
|
+
const subcommand = requireOption(args, "subcommand");
|
|
509
|
+
const { config, service } = buildRuntime(preferredId);
|
|
510
|
+
// The CLI creates a fresh Orchestrator per invocation, so the session
|
|
511
|
+
// coding-context map is empty. If --project-tag + --session-key are
|
|
512
|
+
// provided, attach a coding context BEFORE dispatching so the gate
|
|
513
|
+
// passes and project-scoped writes resolve to the right namespace
|
|
514
|
+
// (review P2).
|
|
515
|
+
const projectTag = getLastOption(args, "project-tag");
|
|
516
|
+
const sessionKey = getLastOption(args, "session-key");
|
|
517
|
+
if (projectTag && projectTag.trim().length > 0 && sessionKey && sessionKey.trim().length > 0) {
|
|
518
|
+
const projectId = projectTagProjectId(projectTag.trim());
|
|
519
|
+
service.setCodingContext({
|
|
520
|
+
sessionKey,
|
|
521
|
+
codingContext: {
|
|
522
|
+
projectId,
|
|
523
|
+
branch: null,
|
|
524
|
+
rootPath: projectId,
|
|
525
|
+
defaultBranch: null,
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
const op = getOperation("coding_decision");
|
|
530
|
+
if (!op) {
|
|
531
|
+
throw new Error("access-boundary: operation not registered: coding_decision");
|
|
532
|
+
}
|
|
533
|
+
const output = (await op.run(
|
|
534
|
+
{
|
|
535
|
+
subcommand,
|
|
536
|
+
namespace: getLastOption(args, "namespace"),
|
|
537
|
+
sessionKey,
|
|
538
|
+
id: getLastOption(args, "id"),
|
|
539
|
+
supersedesId: getLastOption(args, "supersedes-id"),
|
|
540
|
+
title: getLastOption(args, "title"),
|
|
541
|
+
status: getLastOption(args, "status"),
|
|
542
|
+
context: getLastOption(args, "context"),
|
|
543
|
+
decision: getLastOption(args, "decision"),
|
|
544
|
+
consequences: getLastOption(args, "consequences"),
|
|
545
|
+
entityRefs: getAllOptions(args, "entity-ref"),
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
service,
|
|
549
|
+
authenticatedPrincipal: getLastOption(args, "principal") ?? config.agentAccessHttp.principal,
|
|
550
|
+
},
|
|
551
|
+
)) as { result: unknown };
|
|
552
|
+
console.log(JSON.stringify(output.result, null, 2));
|
|
553
|
+
}
|
|
554
|
+
|
|
469
555
|
export async function main(
|
|
470
556
|
argv: string[] = process.argv.slice(2),
|
|
471
557
|
options: AccessCliOptions = {},
|
|
@@ -475,6 +561,10 @@ export async function main(
|
|
|
475
561
|
await runBrowse(args, options.preferredId);
|
|
476
562
|
return;
|
|
477
563
|
}
|
|
564
|
+
if (args.command === "decision") {
|
|
565
|
+
await runDecision(args, options.preferredId);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
478
568
|
await runStore(args, options.preferredId);
|
|
479
569
|
}
|
|
480
570
|
|
package/src/access-http.ts
CHANGED
|
@@ -315,6 +315,7 @@ export class EngramAccessHttpServer {
|
|
|
315
315
|
citationsEnabled: options.citationsEnabled,
|
|
316
316
|
citationsAutoDetect: options.citationsAutoDetect,
|
|
317
317
|
emitLegacyTools: options.emitLegacyTools,
|
|
318
|
+
codingDecisionVisible: this.service.decisionRecordSurfaceVisible,
|
|
318
319
|
});
|
|
319
320
|
}
|
|
320
321
|
|
|
@@ -1331,6 +1332,35 @@ export class EngramAccessHttpServer {
|
|
|
1331
1332
|
return;
|
|
1332
1333
|
}
|
|
1333
1334
|
|
|
1335
|
+
if (req.method === "POST" && pathname === "/engram/v1/coding/decisions") {
|
|
1336
|
+
// Migrated through the access boundary (issue #1525/#1548): the
|
|
1337
|
+
// registry entry owns schema validation and service dispatch. HTTP
|
|
1338
|
+
// resolves the request principal; the boundary re-validates the
|
|
1339
|
+
// cleaned envelope. record/supersede persist decision memories, so they
|
|
1340
|
+
// are gated by the same 30/min write quota as /engram/v1/memories,
|
|
1341
|
+
// suggestions, and observe; list/get are pure reads and stay uncounted
|
|
1342
|
+
// (review P2: apply write quotas to decision writes).
|
|
1343
|
+
const body = await this.readJsonBody(req);
|
|
1344
|
+
const isWriteSubcommand =
|
|
1345
|
+
body.subcommand === "record" || body.subcommand === "supersede";
|
|
1346
|
+
if (isWriteSubcommand) {
|
|
1347
|
+
this.ensureWriteRateLimitAvailable();
|
|
1348
|
+
}
|
|
1349
|
+
const op = getOperation("coding_decision");
|
|
1350
|
+
if (!op) {
|
|
1351
|
+
throw new EngramAccessInputError("access-boundary: operation not registered: coding_decision");
|
|
1352
|
+
}
|
|
1353
|
+
const output = (await op.run(body, {
|
|
1354
|
+
service: this.service,
|
|
1355
|
+
authenticatedPrincipal: this.resolveRequestPrincipal(req),
|
|
1356
|
+
})) as { result: unknown };
|
|
1357
|
+
if (isWriteSubcommand) {
|
|
1358
|
+
this.recordWriteRateLimitHit();
|
|
1359
|
+
}
|
|
1360
|
+
this.respondJson(res, 200, output.result);
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1334
1364
|
if (req.method === "POST" && pathname === "/engram/v1/suggestions") {
|
|
1335
1365
|
const body = await this.readValidatedBody(req, "suggestionSubmit");
|
|
1336
1366
|
const request = {
|
|
@@ -2183,6 +2213,13 @@ export class EngramAccessHttpServer {
|
|
|
2183
2213
|
typeof toolArgs === "object" &&
|
|
2184
2214
|
!Array.isArray(toolArgs) &&
|
|
2185
2215
|
(toolArgs as { dryRun?: unknown }).dryRun === true;
|
|
2216
|
+
const codingDecisionWrite =
|
|
2217
|
+
(toolName === "engram.coding_decision" || toolName === "remnic.coding_decision") &&
|
|
2218
|
+
toolArgs !== null &&
|
|
2219
|
+
typeof toolArgs === "object" &&
|
|
2220
|
+
!Array.isArray(toolArgs) &&
|
|
2221
|
+
((toolArgs as { subcommand?: unknown }).subcommand === "record" ||
|
|
2222
|
+
(toolArgs as { subcommand?: unknown }).subcommand === "supersede");
|
|
2186
2223
|
const isMcpWrite =
|
|
2187
2224
|
request.method === "tools/call" &&
|
|
2188
2225
|
(
|
|
@@ -2210,7 +2247,8 @@ export class EngramAccessHttpServer {
|
|
|
2210
2247
|
toolName === "engram.memory_action_apply" ||
|
|
2211
2248
|
toolName === "remnic.memory_action_apply"
|
|
2212
2249
|
)
|
|
2213
|
-
)
|
|
2250
|
+
) ||
|
|
2251
|
+
codingDecisionWrite
|
|
2214
2252
|
);
|
|
2215
2253
|
if (isMcpWrite) {
|
|
2216
2254
|
this.ensureWriteRateLimitAvailable();
|
package/src/access-mcp.ts
CHANGED
|
@@ -109,6 +109,7 @@ const MCP_MIGRATED_OPERATIONS: Readonly<Record<string, OperationName>> = {
|
|
|
109
109
|
"engram.memory_get": "memory_get",
|
|
110
110
|
"engram.memory_search": "memory_search",
|
|
111
111
|
"engram.memory_store": "memory_store",
|
|
112
|
+
"engram.coding_decision": "coding_decision",
|
|
112
113
|
};
|
|
113
114
|
|
|
114
115
|
function resolveChatGptInspectorRecallSessionKey(
|
|
@@ -304,7 +305,9 @@ export class EngramMcpServer {
|
|
|
304
305
|
*/
|
|
305
306
|
private initSessionIds = new Map<string, string>();
|
|
306
307
|
|
|
307
|
-
/**
|
|
308
|
+
/**
|
|
309
|
+
* Whether oai-mem-citation guidance is explicitly enabled via config.
|
|
310
|
+
*/
|
|
308
311
|
private readonly citationsEnabled: boolean;
|
|
309
312
|
/** Whether to auto-enable citations for Codex adapter connections. */
|
|
310
313
|
private readonly citationsAutoDetect: boolean;
|
|
@@ -314,6 +317,13 @@ export class EngramMcpServer {
|
|
|
314
317
|
* set false to halve the advertised `tools/list` surface.
|
|
315
318
|
*/
|
|
316
319
|
private readonly emitLegacyTools: boolean;
|
|
320
|
+
/**
|
|
321
|
+
* Whether the `coding_decision` tool should appear in `tools/list`. Gated on
|
|
322
|
+
* `codingKnowledge.enabled && codingKnowledge.decisionRecords` (issue #1548
|
|
323
|
+
* Track A PR 2, rule 39). When false the tools array is byte-identical to
|
|
324
|
+
* pre-feature.
|
|
325
|
+
*/
|
|
326
|
+
private readonly codingDecisionVisible: boolean;
|
|
317
327
|
|
|
318
328
|
constructor(
|
|
319
329
|
private readonly service: EngramAccessService,
|
|
@@ -322,11 +332,13 @@ export class EngramMcpServer {
|
|
|
322
332
|
citationsEnabled?: boolean;
|
|
323
333
|
citationsAutoDetect?: boolean;
|
|
324
334
|
emitLegacyTools?: boolean;
|
|
335
|
+
codingDecisionVisible?: boolean;
|
|
325
336
|
} = {},
|
|
326
337
|
) {
|
|
327
338
|
this.citationsEnabled = options.citationsEnabled === true;
|
|
328
339
|
this.citationsAutoDetect = options.citationsAutoDetect !== false;
|
|
329
340
|
this.emitLegacyTools = options.emitLegacyTools !== false;
|
|
341
|
+
this.codingDecisionVisible = options.codingDecisionVisible === true;
|
|
330
342
|
this.authenticatedPrincipal =
|
|
331
343
|
options.principal?.trim() ||
|
|
332
344
|
readEnvVar("OPENCLAW_ENGRAM_ACCESS_PRINCIPAL")?.trim() ||
|
|
@@ -1946,6 +1958,47 @@ export class EngramMcpServer {
|
|
|
1946
1958
|
},
|
|
1947
1959
|
},
|
|
1948
1960
|
].flatMap((tool) => withToolAliases(tool, this.emitLegacyTools));
|
|
1961
|
+
if (this.codingDecisionVisible) {
|
|
1962
|
+
const codingDecisionTools = withToolAliases(
|
|
1963
|
+
{
|
|
1964
|
+
name: "engram.coding_decision",
|
|
1965
|
+
description:
|
|
1966
|
+
"List, get, record, or supersede decision records in the session's coding namespace (issue #1548 Track A). Subcommands: list, get, record, supersede.",
|
|
1967
|
+
inputSchema: {
|
|
1968
|
+
type: "object",
|
|
1969
|
+
properties: {
|
|
1970
|
+
subcommand: {
|
|
1971
|
+
type: "string",
|
|
1972
|
+
enum: ["list", "get", "record", "supersede"],
|
|
1973
|
+
description: "Which decision-record operation to run.",
|
|
1974
|
+
},
|
|
1975
|
+
sessionKey: { type: "string", description: "Session identifier whose coding context scopes the operation." },
|
|
1976
|
+
namespace: { type: "string", description: "Optional explicit namespace (overrides coding-context overlay)." },
|
|
1977
|
+
id: { type: "string", description: "Decision record id (required for get and supersede)." },
|
|
1978
|
+
title: { type: "string", description: "Decision title (required for record and supersede)." },
|
|
1979
|
+
status: {
|
|
1980
|
+
type: "string",
|
|
1981
|
+
enum: ["proposed", "accepted", "superseded", "rejected"],
|
|
1982
|
+
description: "Decision status (record only; defaults to proposed).",
|
|
1983
|
+
},
|
|
1984
|
+
context: { type: "string", description: "Context/background for the decision." },
|
|
1985
|
+
decision: { type: "string", description: "The decision itself (required for record and supersede)." },
|
|
1986
|
+
consequences: { type: "string", description: "Consequences of the decision." },
|
|
1987
|
+
entityRefs: {
|
|
1988
|
+
type: "array",
|
|
1989
|
+
items: { type: "string" },
|
|
1990
|
+
description: "Entity references the decision relates to.",
|
|
1991
|
+
},
|
|
1992
|
+
supersedesId: { type: "string", description: "Id of the record this decision supersedes (supersede only)." },
|
|
1993
|
+
},
|
|
1994
|
+
required: ["subcommand"],
|
|
1995
|
+
additionalProperties: false,
|
|
1996
|
+
},
|
|
1997
|
+
},
|
|
1998
|
+
this.emitLegacyTools,
|
|
1999
|
+
);
|
|
2000
|
+
this.tools = [...this.tools, ...codingDecisionTools];
|
|
2001
|
+
}
|
|
1949
2002
|
}
|
|
1950
2003
|
|
|
1951
2004
|
/** Get clientInfo for a specific MCP session. Returns undefined for non-MCP requests. */
|