shieldcortex 2.19.0 → 2.19.3
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/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_25b1b286._.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/{6bf7d89d34068ecb.js → 7d04c140073d99aa.js} +3 -3
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/94d1921c4f61a608.css +3 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/cac330f9511d34e5.js +1 -0
- package/dist/api/control.d.ts +28 -11
- package/dist/api/control.d.ts.map +1 -1
- package/dist/api/control.js +120 -19
- package/dist/api/control.js.map +1 -1
- package/dist/api/events.d.ts +12 -1
- package/dist/api/events.d.ts.map +1 -1
- package/dist/api/events.js +9 -0
- package/dist/api/events.js.map +1 -1
- package/dist/api/visualization-server.d.ts.map +1 -1
- package/dist/api/visualization-server.js +88 -36
- package/dist/api/visualization-server.js.map +1 -1
- package/dist/cloud/quarantine-sync.d.ts +3 -0
- package/dist/cloud/quarantine-sync.d.ts.map +1 -1
- package/dist/cloud/quarantine-sync.js +7 -0
- package/dist/cloud/quarantine-sync.js.map +1 -1
- package/dist/cloud/sync.d.ts +11 -0
- package/dist/cloud/sync.d.ts.map +1 -1
- package/dist/cloud/sync.js +37 -0
- package/dist/cloud/sync.js.map +1 -1
- package/dist/defence/index.d.ts +2 -0
- package/dist/defence/index.d.ts.map +1 -1
- package/dist/defence/index.js +2 -0
- package/dist/defence/index.js.map +1 -1
- package/dist/defence/input-sanitisation/index.d.ts +28 -0
- package/dist/defence/input-sanitisation/index.d.ts.map +1 -0
- package/dist/defence/input-sanitisation/index.js +71 -0
- package/dist/defence/input-sanitisation/index.js.map +1 -0
- package/dist/defence/iron-dome/config.js +5 -5
- package/dist/defence/iron-dome/config.js.map +1 -1
- package/dist/defence/iron-dome/index.d.ts +6 -0
- package/dist/defence/iron-dome/index.d.ts.map +1 -1
- package/dist/defence/iron-dome/index.js +19 -0
- package/dist/defence/iron-dome/index.js.map +1 -1
- package/dist/defence/pipeline.d.ts.map +1 -1
- package/dist/defence/pipeline.js +21 -11
- package/dist/defence/pipeline.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +2 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +2 -0
- package/dist/lib.js.map +1 -1
- package/dist/license/keys.d.ts +1 -1
- package/dist/license/keys.js +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +193 -45
- package/dist/server.js.map +1 -1
- package/dist/tools/context.d.ts +4 -4
- package/dist/tools/forget.d.ts +4 -4
- package/dist/tools/recall.d.ts +9 -9
- package/dist/tools/remember.d.ts +4 -4
- package/hooks/openclaw/cortex-memory/handler.ts +8 -18
- package/package.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/1a71c9a52f0c9b16.css +0 -3
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/d0dcb5e0e04ae015.js +0 -1
- /package/dashboard/.next/standalone/dashboard/.next/static/{OfvwyqIJFP9N3Qdb23S-6 → x5pEZRSDizF1dS-qqTezT}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{OfvwyqIJFP9N3Qdb23S-6 → x5pEZRSDizF1dS-qqTezT}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{OfvwyqIJFP9N3Qdb23S-6 → x5pEZRSDizF1dS-qqTezT}/_ssgManifest.js +0 -0
|
@@ -21,7 +21,7 @@ import { detectContradictions, getContradictionsFor } from '../memory/contradict
|
|
|
21
21
|
import { enrichMemory } from '../memory/store.js';
|
|
22
22
|
import { memoryEvents, emitDecayTick, emitConsolidation, getUnprocessedEvents, markEventsProcessed, cleanupOldEvents, } from './events.js';
|
|
23
23
|
import { BrainWorker } from '../worker/brain-worker.js';
|
|
24
|
-
import { pause, resume, getControlStatus } from './control.js';
|
|
24
|
+
import { pause, resume, getControlStatus, isKillSwitchActive, getKillSwitchMeta, activateKillSwitch, deactivateKillSwitch } from './control.js';
|
|
25
25
|
import { getCurrentVersion, getRunningVersion, checkForUpdates, performUpdate, scheduleRestart } from './version.js';
|
|
26
26
|
import { runDefencePipeline } from '../defence/pipeline.js';
|
|
27
27
|
import { DEFAULT_DEFENCE_CONFIG } from '../defence/types.js';
|
|
@@ -129,6 +129,23 @@ export function startVisualizationServer(dbPath) {
|
|
|
129
129
|
res.json({ token });
|
|
130
130
|
});
|
|
131
131
|
// ============================================
|
|
132
|
+
// KILL SWITCH GUARD MIDDLEWARE
|
|
133
|
+
// ============================================
|
|
134
|
+
/**
|
|
135
|
+
* Express middleware that blocks requests when the kill switch is active.
|
|
136
|
+
* Returns 423 Locked with kill switch metadata.
|
|
137
|
+
*/
|
|
138
|
+
function requireNotLocked(_req, res, next) {
|
|
139
|
+
if (!isKillSwitchActive())
|
|
140
|
+
return next();
|
|
141
|
+
const meta = getKillSwitchMeta();
|
|
142
|
+
res.status(423).json({
|
|
143
|
+
error: 'Kill switch active — operation blocked',
|
|
144
|
+
code: 'KILL_SWITCH_ACTIVE',
|
|
145
|
+
killSwitch: meta,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// ============================================
|
|
132
149
|
// REST API ENDPOINTS
|
|
133
150
|
// ============================================
|
|
134
151
|
// Health check
|
|
@@ -142,7 +159,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
142
159
|
res.json({ total, byFeature: { ...gatedCounters } });
|
|
143
160
|
});
|
|
144
161
|
// Get all memories with filters and pagination
|
|
145
|
-
app.get('/api/memories', async (req, res) => {
|
|
162
|
+
app.get('/api/memories', requireNotLocked, async (req, res) => {
|
|
146
163
|
try {
|
|
147
164
|
// Extract query params as strings
|
|
148
165
|
const project = typeof req.query.project === 'string' ? req.query.project : undefined;
|
|
@@ -204,7 +221,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
204
221
|
}
|
|
205
222
|
});
|
|
206
223
|
// Activity data for heatmap (must be before :id route)
|
|
207
|
-
app.get('/api/memories/activity', (req, res) => {
|
|
224
|
+
app.get('/api/memories/activity', requireNotLocked, (req, res) => {
|
|
208
225
|
try {
|
|
209
226
|
const project = typeof req.query.project === 'string' ? req.query.project : undefined;
|
|
210
227
|
const db = getDatabase();
|
|
@@ -229,7 +246,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
229
246
|
}
|
|
230
247
|
});
|
|
231
248
|
// Memory quality analysis (must be before :id route)
|
|
232
|
-
app.get('/api/memories/quality', (req, res) => {
|
|
249
|
+
app.get('/api/memories/quality', requireNotLocked, (req, res) => {
|
|
233
250
|
try {
|
|
234
251
|
const project = typeof req.query.project === 'string' ? req.query.project : undefined;
|
|
235
252
|
const db = getDatabase();
|
|
@@ -265,7 +282,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
265
282
|
}
|
|
266
283
|
});
|
|
267
284
|
// Get single memory by ID
|
|
268
|
-
app.get('/api/memories/:id', (req, res) => {
|
|
285
|
+
app.get('/api/memories/:id', requireNotLocked, (req, res) => {
|
|
269
286
|
try {
|
|
270
287
|
const id = parseInt(req.params.id);
|
|
271
288
|
const memory = getMemoryById(id);
|
|
@@ -282,7 +299,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
282
299
|
}
|
|
283
300
|
});
|
|
284
301
|
// Create memory
|
|
285
|
-
app.post('/api/memories', (req, res) => {
|
|
302
|
+
app.post('/api/memories', requireNotLocked, (req, res) => {
|
|
286
303
|
try {
|
|
287
304
|
const { title, content, type, category, project, tags, salience } = req.body;
|
|
288
305
|
if (!title || !content) {
|
|
@@ -312,7 +329,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
312
329
|
}
|
|
313
330
|
});
|
|
314
331
|
// Delete memory
|
|
315
|
-
app.delete('/api/memories/:id', (req, res) => {
|
|
332
|
+
app.delete('/api/memories/:id', requireNotLocked, (req, res) => {
|
|
316
333
|
try {
|
|
317
334
|
const id = parseInt(req.params.id);
|
|
318
335
|
const success = deleteMemory(id);
|
|
@@ -326,7 +343,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
326
343
|
}
|
|
327
344
|
});
|
|
328
345
|
// Access/reinforce memory
|
|
329
|
-
app.post('/api/memories/:id/access', (req, res) => {
|
|
346
|
+
app.post('/api/memories/:id/access', requireNotLocked, (req, res) => {
|
|
330
347
|
try {
|
|
331
348
|
const id = parseInt(req.params.id);
|
|
332
349
|
const memory = accessMemory(id);
|
|
@@ -382,7 +399,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
382
399
|
}
|
|
383
400
|
});
|
|
384
401
|
// Get currently activated memories (spreading activation)
|
|
385
|
-
app.get('/api/activation', (_req, res) => {
|
|
402
|
+
app.get('/api/activation', requireNotLocked, (_req, res) => {
|
|
386
403
|
try {
|
|
387
404
|
const activeMemories = getActiveMemories();
|
|
388
405
|
const stats = getActivationStats();
|
|
@@ -400,7 +417,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
400
417
|
// ORGANIC BRAIN ENDPOINTS (Phase 3)
|
|
401
418
|
// ============================================
|
|
402
419
|
// Get detected contradictions
|
|
403
|
-
app.get('/api/contradictions', (req, res) => {
|
|
420
|
+
app.get('/api/contradictions', requireNotLocked, (req, res) => {
|
|
404
421
|
try {
|
|
405
422
|
const project = typeof req.query.project === 'string' ? req.query.project : undefined;
|
|
406
423
|
const category = typeof req.query.category === 'string' ? req.query.category : undefined;
|
|
@@ -433,7 +450,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
433
450
|
}
|
|
434
451
|
});
|
|
435
452
|
// Get contradictions for a specific memory
|
|
436
|
-
app.get('/api/memories/:id/contradictions', (req, res) => {
|
|
453
|
+
app.get('/api/memories/:id/contradictions', requireNotLocked, (req, res) => {
|
|
437
454
|
try {
|
|
438
455
|
const id = parseInt(req.params.id);
|
|
439
456
|
if (isNaN(id)) {
|
|
@@ -457,7 +474,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
457
474
|
}
|
|
458
475
|
});
|
|
459
476
|
// Manually enrich a memory with new context
|
|
460
|
-
app.post('/api/memories/:id/enrich', (req, res) => {
|
|
477
|
+
app.post('/api/memories/:id/enrich', requireNotLocked, (req, res) => {
|
|
461
478
|
try {
|
|
462
479
|
const id = parseInt(req.params.id);
|
|
463
480
|
if (isNaN(id)) {
|
|
@@ -513,9 +530,12 @@ export function startVisualizationServer(dbPath) {
|
|
|
513
530
|
res.status(500).json({ error: error.message });
|
|
514
531
|
}
|
|
515
532
|
});
|
|
516
|
-
// Pause memory creation
|
|
533
|
+
// Pause memory creation (soft pause — kill switch takes precedence)
|
|
517
534
|
app.post('/api/control/pause', (_req, res) => {
|
|
518
535
|
try {
|
|
536
|
+
if (isKillSwitchActive()) {
|
|
537
|
+
return res.status(409).json({ error: 'Kill switch is active — use /api/iron-dome/resume to deactivate first', code: 'KILL_SWITCH_ACTIVE' });
|
|
538
|
+
}
|
|
519
539
|
pause();
|
|
520
540
|
res.json({ paused: true, message: 'Memory creation paused' });
|
|
521
541
|
}
|
|
@@ -523,9 +543,12 @@ export function startVisualizationServer(dbPath) {
|
|
|
523
543
|
res.status(500).json({ error: error.message });
|
|
524
544
|
}
|
|
525
545
|
});
|
|
526
|
-
// Resume memory creation
|
|
546
|
+
// Resume memory creation (soft resume — cannot override kill switch)
|
|
527
547
|
app.post('/api/control/resume', (_req, res) => {
|
|
528
548
|
try {
|
|
549
|
+
if (isKillSwitchActive()) {
|
|
550
|
+
return res.status(409).json({ error: 'Kill switch is active — use /api/iron-dome/resume to deactivate first', code: 'KILL_SWITCH_ACTIVE' });
|
|
551
|
+
}
|
|
529
552
|
resume();
|
|
530
553
|
res.json({ paused: false, message: 'Memory creation resumed' });
|
|
531
554
|
}
|
|
@@ -727,7 +750,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
727
750
|
}
|
|
728
751
|
});
|
|
729
752
|
// Get memory links/relationships
|
|
730
|
-
app.get('/api/links', (req, res) => {
|
|
753
|
+
app.get('/api/links', requireNotLocked, (req, res) => {
|
|
731
754
|
try {
|
|
732
755
|
const project = typeof req.query.project === 'string' ? req.query.project : undefined;
|
|
733
756
|
const db = getDatabase();
|
|
@@ -780,7 +803,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
780
803
|
// SQL CONSOLE ENDPOINT
|
|
781
804
|
// ============================================
|
|
782
805
|
// Execute SQL query (with safety restrictions)
|
|
783
|
-
app.post('/api/sql', (req, res) => {
|
|
806
|
+
app.post('/api/sql', requireNotLocked, (req, res) => {
|
|
784
807
|
try {
|
|
785
808
|
const { query, allowWrite } = req.body;
|
|
786
809
|
if (!query || typeof query !== 'string') {
|
|
@@ -837,7 +860,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
837
860
|
}
|
|
838
861
|
});
|
|
839
862
|
// Trigger consolidation
|
|
840
|
-
app.post('/api/consolidate', (_req, res) => {
|
|
863
|
+
app.post('/api/consolidate', requireNotLocked, (_req, res) => {
|
|
841
864
|
try {
|
|
842
865
|
const result = consolidate();
|
|
843
866
|
// Emit event for Activity log
|
|
@@ -852,7 +875,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
852
875
|
}
|
|
853
876
|
});
|
|
854
877
|
// Get context summary
|
|
855
|
-
app.get('/api/context', async (req, res) => {
|
|
878
|
+
app.get('/api/context', requireNotLocked, async (req, res) => {
|
|
856
879
|
try {
|
|
857
880
|
const project = typeof req.query.project === 'string' ? req.query.project : undefined;
|
|
858
881
|
const summary = await generateContextSummary(project);
|
|
@@ -867,7 +890,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
867
890
|
}
|
|
868
891
|
});
|
|
869
892
|
// Get search suggestions (for autocomplete)
|
|
870
|
-
app.get('/api/suggestions', (req, res) => {
|
|
893
|
+
app.get('/api/suggestions', requireNotLocked, (req, res) => {
|
|
871
894
|
try {
|
|
872
895
|
const query = typeof req.query.q === 'string' ? req.query.q : '';
|
|
873
896
|
const limit = typeof req.query.limit === 'string' ? parseInt(req.query.limit) : 10;
|
|
@@ -926,7 +949,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
926
949
|
// GRAPH / ONTOLOGY ENDPOINTS
|
|
927
950
|
// ============================================
|
|
928
951
|
// List entities with optional filters and pagination
|
|
929
|
-
app.get('/api/graph/entities', (req, res) => {
|
|
952
|
+
app.get('/api/graph/entities', requireNotLocked, (req, res) => {
|
|
930
953
|
try {
|
|
931
954
|
const db = getDatabase();
|
|
932
955
|
const type = typeof req.query.type === 'string' ? req.query.type : undefined;
|
|
@@ -971,7 +994,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
971
994
|
}
|
|
972
995
|
});
|
|
973
996
|
// Get triples for a specific entity
|
|
974
|
-
app.get('/api/graph/entities/:id/triples', (req, res) => {
|
|
997
|
+
app.get('/api/graph/entities/:id/triples', requireNotLocked, (req, res) => {
|
|
975
998
|
try {
|
|
976
999
|
const db = getDatabase();
|
|
977
1000
|
const id = parseInt(req.params.id);
|
|
@@ -994,7 +1017,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
994
1017
|
}
|
|
995
1018
|
});
|
|
996
1019
|
// Get memories linked to a specific entity
|
|
997
|
-
app.get('/api/graph/entities/:id/memories', (req, res) => {
|
|
1020
|
+
app.get('/api/graph/entities/:id/memories', requireNotLocked, (req, res) => {
|
|
998
1021
|
try {
|
|
999
1022
|
const db = getDatabase();
|
|
1000
1023
|
const id = parseInt(req.params.id);
|
|
@@ -1016,7 +1039,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1016
1039
|
}
|
|
1017
1040
|
});
|
|
1018
1041
|
// List triples with optional predicate filter and pagination
|
|
1019
|
-
app.get('/api/graph/triples', (req, res) => {
|
|
1042
|
+
app.get('/api/graph/triples', requireNotLocked, (req, res) => {
|
|
1020
1043
|
try {
|
|
1021
1044
|
const db = getDatabase();
|
|
1022
1045
|
const predicate = typeof req.query.predicate === 'string' ? req.query.predicate : undefined;
|
|
@@ -1047,7 +1070,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1047
1070
|
}
|
|
1048
1071
|
});
|
|
1049
1072
|
// Search entities by name
|
|
1050
|
-
app.get('/api/graph/search', (req, res) => {
|
|
1073
|
+
app.get('/api/graph/search', requireNotLocked, (req, res) => {
|
|
1051
1074
|
try {
|
|
1052
1075
|
const db = getDatabase();
|
|
1053
1076
|
const q = typeof req.query.q === 'string' ? req.query.q : '';
|
|
@@ -1078,7 +1101,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1078
1101
|
}
|
|
1079
1102
|
});
|
|
1080
1103
|
// Find path between two entities using BFS
|
|
1081
|
-
app.get('/api/graph/paths', (req, res) => {
|
|
1104
|
+
app.get('/api/graph/paths', requireNotLocked, (req, res) => {
|
|
1082
1105
|
try {
|
|
1083
1106
|
const db = getDatabase();
|
|
1084
1107
|
const fromName = typeof req.query.from === 'string' ? req.query.from : '';
|
|
@@ -1164,7 +1187,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1164
1187
|
// BRAIN CONTROL CENTRE
|
|
1165
1188
|
// ============================================
|
|
1166
1189
|
// Boost memory salience (+0.15, capped at 1.0)
|
|
1167
|
-
app.post('/api/memories/:id/boost', (req, res) => {
|
|
1190
|
+
app.post('/api/memories/:id/boost', requireNotLocked, (req, res) => {
|
|
1168
1191
|
try {
|
|
1169
1192
|
const id = parseInt(req.params.id);
|
|
1170
1193
|
const memory = getMemoryById(id);
|
|
@@ -1180,7 +1203,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1180
1203
|
}
|
|
1181
1204
|
});
|
|
1182
1205
|
// Demote memory salience (-0.15, floor at 0.05)
|
|
1183
|
-
app.post('/api/memories/:id/demote', (req, res) => {
|
|
1206
|
+
app.post('/api/memories/:id/demote', requireNotLocked, (req, res) => {
|
|
1184
1207
|
try {
|
|
1185
1208
|
const id = parseInt(req.params.id);
|
|
1186
1209
|
const memory = getMemoryById(id);
|
|
@@ -1196,7 +1219,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1196
1219
|
}
|
|
1197
1220
|
});
|
|
1198
1221
|
// Promote memory from STM to LTM
|
|
1199
|
-
app.post('/api/memories/:id/promote', (req, res) => {
|
|
1222
|
+
app.post('/api/memories/:id/promote', requireNotLocked, (req, res) => {
|
|
1200
1223
|
try {
|
|
1201
1224
|
const id = parseInt(req.params.id);
|
|
1202
1225
|
const memory = promoteMemory(id);
|
|
@@ -1210,7 +1233,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1210
1233
|
}
|
|
1211
1234
|
});
|
|
1212
1235
|
// Update memory (partial: title, content, tags, category)
|
|
1213
|
-
app.patch('/api/memories/:id', (req, res) => {
|
|
1236
|
+
app.patch('/api/memories/:id', requireNotLocked, (req, res) => {
|
|
1214
1237
|
try {
|
|
1215
1238
|
const id = parseInt(req.params.id);
|
|
1216
1239
|
const updated = updateMemory(id, req.body);
|
|
@@ -1224,7 +1247,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1224
1247
|
}
|
|
1225
1248
|
});
|
|
1226
1249
|
// Quarantine a memory (move to quarantine table, delete original)
|
|
1227
|
-
app.post('/api/memories/:id/quarantine', (req, res) => {
|
|
1250
|
+
app.post('/api/memories/:id/quarantine', requireNotLocked, (req, res) => {
|
|
1228
1251
|
try {
|
|
1229
1252
|
const id = parseInt(req.params.id);
|
|
1230
1253
|
const memory = getMemoryById(id);
|
|
@@ -1242,7 +1265,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1242
1265
|
}
|
|
1243
1266
|
});
|
|
1244
1267
|
// Create a manual link between two memories
|
|
1245
|
-
app.post('/api/links', (req, res) => {
|
|
1268
|
+
app.post('/api/links', requireNotLocked, (req, res) => {
|
|
1246
1269
|
try {
|
|
1247
1270
|
const { sourceId, targetId, relationship, strength } = req.body;
|
|
1248
1271
|
if (!sourceId || !targetId || !relationship) {
|
|
@@ -1447,6 +1470,35 @@ export function startVisualizationServer(dbPath) {
|
|
|
1447
1470
|
res.status(500).json({ error: error.message });
|
|
1448
1471
|
}
|
|
1449
1472
|
});
|
|
1473
|
+
// Emergency Stop — activates kill switch, blocks ALL agent operations
|
|
1474
|
+
app.post('/api/iron-dome/emergency-stop', (_req, res) => {
|
|
1475
|
+
try {
|
|
1476
|
+
activateKillSwitch({ source: 'manual' });
|
|
1477
|
+
res.json({
|
|
1478
|
+
stopped: true,
|
|
1479
|
+
killSwitchActive: true,
|
|
1480
|
+
message: 'Kill switch activated. All agent operations blocked. Iron Dome remains active. Investigate before resuming.',
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
catch (error) {
|
|
1484
|
+
res.status(500).json({ error: error.message });
|
|
1485
|
+
}
|
|
1486
|
+
});
|
|
1487
|
+
// Resume agent operations after investigation (requires reason)
|
|
1488
|
+
app.post('/api/iron-dome/resume', (req, res) => {
|
|
1489
|
+
try {
|
|
1490
|
+
const reason = req.body?.reason || 'Resumed via dashboard';
|
|
1491
|
+
deactivateKillSwitch(reason);
|
|
1492
|
+
res.json({
|
|
1493
|
+
resumed: true,
|
|
1494
|
+
killSwitchActive: false,
|
|
1495
|
+
message: 'Kill switch deactivated. Agent operations resumed. Iron Dome continues protecting.',
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
catch (error) {
|
|
1499
|
+
res.status(500).json({ error: error.message });
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1450
1502
|
app.post('/api/iron-dome/scan', (req, res) => {
|
|
1451
1503
|
try {
|
|
1452
1504
|
const { text } = req.body;
|
|
@@ -1648,7 +1700,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1648
1700
|
}
|
|
1649
1701
|
});
|
|
1650
1702
|
// Approve quarantined item
|
|
1651
|
-
app.post('/api/v1/quarantine/:id/approve', (req, res) => {
|
|
1703
|
+
app.post('/api/v1/quarantine/:id/approve', requireNotLocked, (req, res) => {
|
|
1652
1704
|
try {
|
|
1653
1705
|
const db = getDatabase();
|
|
1654
1706
|
const id = parseInt(req.params.id, 10);
|
|
@@ -1664,7 +1716,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1664
1716
|
}
|
|
1665
1717
|
});
|
|
1666
1718
|
// Reject quarantined item
|
|
1667
|
-
app.post('/api/v1/quarantine/:id/reject', (req, res) => {
|
|
1719
|
+
app.post('/api/v1/quarantine/:id/reject', requireNotLocked, (req, res) => {
|
|
1668
1720
|
try {
|
|
1669
1721
|
const db = getDatabase();
|
|
1670
1722
|
const id = parseInt(req.params.id, 10);
|
|
@@ -1681,7 +1733,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1681
1733
|
}
|
|
1682
1734
|
});
|
|
1683
1735
|
// Retroactive sync: push existing quarantine items to cloud
|
|
1684
|
-
app.post('/api/quarantine/sync-to-cloud', async (_req, res) => {
|
|
1736
|
+
app.post('/api/quarantine/sync-to-cloud', requireNotLocked, async (_req, res) => {
|
|
1685
1737
|
try {
|
|
1686
1738
|
const config = getCloudConfig();
|
|
1687
1739
|
if (!config.cloudEnabled || !config.cloudApiKey) {
|
|
@@ -1752,7 +1804,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1752
1804
|
}
|
|
1753
1805
|
});
|
|
1754
1806
|
// Manually trigger light tick (for testing)
|
|
1755
|
-
app.post('/api/worker/trigger-light', async (_req, res) => {
|
|
1807
|
+
app.post('/api/worker/trigger-light', requireNotLocked, async (_req, res) => {
|
|
1756
1808
|
try {
|
|
1757
1809
|
const result = await brainWorker.triggerLightTick();
|
|
1758
1810
|
res.json({
|
|
@@ -1766,7 +1818,7 @@ export function startVisualizationServer(dbPath) {
|
|
|
1766
1818
|
}
|
|
1767
1819
|
});
|
|
1768
1820
|
// Manually trigger medium tick (for testing)
|
|
1769
|
-
app.post('/api/worker/trigger-medium', async (_req, res) => {
|
|
1821
|
+
app.post('/api/worker/trigger-medium', requireNotLocked, async (_req, res) => {
|
|
1770
1822
|
try {
|
|
1771
1823
|
const result = await brainWorker.triggerMediumTick();
|
|
1772
1824
|
res.json({
|