superlocalmemory 3.8.14 → 4.0.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.
- package/ATTRIBUTION.md +4 -4
- package/CHANGELOG.md +113 -137
- package/README.md +65 -63
- package/docs/pi-dev-integration.md +1 -1
- package/package.json +6 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/CLAUDE.md +3 -3
- package/plugin/agents/slm-governance-advisor.md +1 -1
- package/plugin/agents/slm-loop-runner.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/agents/slm-optimize-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-cache/SKILL.md +1 -1
- package/plugin/skills/slm-compress/SKILL.md +1 -1
- package/plugin/skills/slm-governance/SKILL.md +1 -1
- package/plugin/skills/slm-graph/SKILL.md +1 -1
- package/plugin/skills/slm-loop/SKILL.md +1 -1
- package/plugin/skills/slm-mesh/SKILL.md +1 -1
- package/plugin/skills/slm-profile/SKILL.md +1 -1
- package/plugin/skills/slm-recall/SKILL.md +1 -1
- package/plugin/skills/slm-remember/SKILL.md +1 -1
- package/plugin/skills/slm-scope/SKILL.md +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin/skills/slm-status/SKILL.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/plugin-src/skills/slm-cache/SKILL.md +1 -1
- package/plugin-src/skills/slm-compress/SKILL.md +1 -1
- package/plugin-src/skills/slm-governance/SKILL.md +248 -0
- package/plugin-src/skills/slm-graph/SKILL.md +1 -1
- package/plugin-src/skills/slm-loop/SKILL.md +99 -0
- package/plugin-src/skills/slm-mesh/SKILL.md +282 -0
- package/plugin-src/skills/slm-profile/SKILL.md +148 -0
- package/plugin-src/skills/slm-recall/SKILL.md +1 -1
- package/plugin-src/skills/slm-remember/SKILL.md +1 -1
- package/plugin-src/skills/slm-scope/SKILL.md +176 -0
- package/plugin-src/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/skills/slm-status/SKILL.md +1 -1
- package/pyproject.toml +11 -4
- package/src/superlocalmemory/__init__.py +1 -1
- package/src/superlocalmemory/cli/commands.py +125 -11
- package/src/superlocalmemory/cli/daemon.py +5 -1
- package/src/superlocalmemory/cli/main.py +35 -2
- package/src/superlocalmemory/cli/ops_cmd.py +281 -0
- package/src/superlocalmemory/cli/setup_wizard.py +1 -1
- package/src/superlocalmemory/compliance/audit.py +65 -0
- package/src/superlocalmemory/compliance/eu_ai_act.py +27 -57
- package/src/superlocalmemory/compliance/gdpr.py +416 -20
- package/src/superlocalmemory/compliance/retention.py +74 -22
- package/src/superlocalmemory/compliance/scheduler.py +78 -9
- package/src/superlocalmemory/core/actor_context.py +166 -0
- package/src/superlocalmemory/core/admission.py +549 -0
- package/src/superlocalmemory/core/backend_orchestrator.py +23 -10
- package/src/superlocalmemory/core/config.py +202 -24
- package/src/superlocalmemory/core/consolidation_engine.py +13 -13
- package/src/superlocalmemory/core/context_cache.py +28 -0
- package/src/superlocalmemory/core/embeddings.py +64 -2
- package/src/superlocalmemory/core/engine.py +7 -2
- package/src/superlocalmemory/core/engine_ingestion.py +65 -3
- package/src/superlocalmemory/core/engine_wiring.py +32 -5
- package/src/superlocalmemory/core/ingest_policy.py +38 -0
- package/src/superlocalmemory/core/maintenance.py +255 -0
- package/src/superlocalmemory/core/modes.py +40 -13
- package/src/superlocalmemory/core/mutations.py +437 -44
- package/src/superlocalmemory/core/operation_policy.py +92 -0
- package/src/superlocalmemory/core/operation_policy_registry.py +542 -0
- package/src/superlocalmemory/core/operation_request.py +127 -0
- package/src/superlocalmemory/core/ops_remediation.py +542 -0
- package/src/superlocalmemory/core/recall_pipeline.py +7 -0
- package/src/superlocalmemory/core/remember_runtime.py +202 -4
- package/src/superlocalmemory/core/remote_mode.py +20 -5
- package/src/superlocalmemory/core/store_pipeline.py +150 -0
- package/src/superlocalmemory/core/topic_signature.py +19 -4
- package/src/superlocalmemory/core/transactions/__init__.py +78 -0
- package/src/superlocalmemory/core/transactions/concrete_owners.py +597 -0
- package/src/superlocalmemory/core/transactions/erasure.py +825 -0
- package/src/superlocalmemory/core/transactions/manifest.py +255 -0
- package/src/superlocalmemory/core/transactions/manifest_key.py +155 -0
- package/src/superlocalmemory/core/transactions/obligations.py +272 -0
- package/src/superlocalmemory/core/transactions/owners.py +114 -0
- package/src/superlocalmemory/core/transactions/reconciler.py +285 -0
- package/src/superlocalmemory/core/transactions/service.py +330 -0
- package/src/superlocalmemory/core/worker_pool.py +33 -5
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +70 -28
- package/src/superlocalmemory/encoding/emotional.py +75 -14
- package/src/superlocalmemory/encoding/temporal_parser.py +4 -0
- package/src/superlocalmemory/evolution/blind_verifier.py +11 -4
- package/src/superlocalmemory/evolution/evolution_store.py +244 -4
- package/src/superlocalmemory/evolution/llm_dispatch.py +40 -0
- package/src/superlocalmemory/evolution/model_selection.py +18 -3
- package/src/superlocalmemory/evolution/mutation_generator.py +3 -0
- package/src/superlocalmemory/evolution/skill_activator.py +270 -0
- package/src/superlocalmemory/evolution/skill_evolver.py +281 -59
- package/src/superlocalmemory/evolution/types.py +30 -8
- package/src/superlocalmemory/graph/cozo_backend.py +17 -9
- package/src/superlocalmemory/hooks/auto_invoker.py +2 -1
- package/src/superlocalmemory/hooks/auto_recall.py +64 -30
- package/src/superlocalmemory/hooks/codex_assets.py +14 -1
- package/src/superlocalmemory/infra/backup.py +434 -7
- package/src/superlocalmemory/infra/process_reaper.py +18 -0
- package/src/superlocalmemory/infra/self_heal.py +401 -0
- package/src/superlocalmemory/learning/feedback.py +52 -9
- package/src/superlocalmemory/loops/engine.py +10 -0
- package/src/superlocalmemory/mcp/_daemon_proxy.py +3 -0
- package/src/superlocalmemory/mcp/http_transport.py +30 -331
- package/src/superlocalmemory/mcp/profiles.py +5 -0
- package/src/superlocalmemory/mcp/resources.py +8 -0
- package/src/superlocalmemory/mcp/server.py +51 -4
- package/src/superlocalmemory/mcp/shared.py +19 -0
- package/src/superlocalmemory/mcp/tools_active.py +25 -4
- package/src/superlocalmemory/mcp/tools_code_graph.py +26 -18
- package/src/superlocalmemory/mcp/tools_context.py +50 -8
- package/src/superlocalmemory/mcp/tools_core.py +69 -21
- package/src/superlocalmemory/mcp/tools_evolution.py +9 -2
- package/src/superlocalmemory/mcp/tools_learning.py +21 -10
- package/src/superlocalmemory/mcp/tools_loops.py +29 -18
- package/src/superlocalmemory/mcp/tools_mesh.py +8 -0
- package/src/superlocalmemory/mcp/tools_ops.py +115 -0
- package/src/superlocalmemory/mcp/tools_optimize.py +4 -0
- package/src/superlocalmemory/mcp/tools_v28.py +10 -3
- package/src/superlocalmemory/mcp/tools_v3.py +34 -14
- package/src/superlocalmemory/mcp/tools_v33.py +18 -33
- package/src/superlocalmemory/mesh/broker.py +124 -46
- package/src/superlocalmemory/mesh/broker_security.py +470 -0
- package/src/superlocalmemory/mesh/discovery.py +365 -0
- package/src/superlocalmemory/mesh/lock_protocol.py +313 -0
- package/src/superlocalmemory/mesh/node_identity.py +97 -0
- package/src/superlocalmemory/mesh/outbox_remote.py +429 -0
- package/src/superlocalmemory/mesh/remote_sync.py +511 -28
- package/src/superlocalmemory/mesh/state_sync.py +286 -0
- package/src/superlocalmemory/optimize/config/store.py +45 -0
- package/src/superlocalmemory/parameterization/cross_project.py +12 -0
- package/src/superlocalmemory/parameterization/prompt_injector.py +13 -11
- package/src/superlocalmemory/parameterization/prompt_lifecycle.py +8 -2
- package/src/superlocalmemory/parameterization/workflow_miner.py +17 -0
- package/src/superlocalmemory/retrieval/ann_index.py +5 -0
- package/src/superlocalmemory/retrieval/bm25_channel.py +49 -2
- package/src/superlocalmemory/retrieval/engine.py +19 -4
- package/src/superlocalmemory/retrieval/fusion.py +4 -1
- package/src/superlocalmemory/retrieval/hopfield_channel.py +9 -3
- package/src/superlocalmemory/retrieval/remote_reranker.py +47 -22
- package/src/superlocalmemory/retrieval/reranker.py +32 -1
- package/src/superlocalmemory/retrieval/temporal_channel.py +16 -3
- package/src/superlocalmemory/retrieval/temporal_utils.py +107 -0
- package/src/superlocalmemory/retrieval/temporal_validity_filter.py +155 -42
- package/src/superlocalmemory/retrieval/vector_store.py +214 -8
- package/src/superlocalmemory/server/api.py +5 -5
- package/src/superlocalmemory/server/egress_policy.py +258 -0
- package/src/superlocalmemory/server/rbac_enforce.py +32 -0
- package/src/superlocalmemory/server/route_mutations.py +20 -0
- package/src/superlocalmemory/server/routes/compliance.py +153 -7
- package/src/superlocalmemory/server/routes/data_io.py +43 -2
- package/src/superlocalmemory/server/routes/events.py +15 -0
- package/src/superlocalmemory/server/routes/memories.py +56 -3
- package/src/superlocalmemory/server/routes/mesh.py +82 -1
- package/src/superlocalmemory/server/routes/mesh_lock.py +54 -0
- package/src/superlocalmemory/server/routes/mesh_state.py +63 -0
- package/src/superlocalmemory/server/routes/v3_api.py +50 -27
- package/src/superlocalmemory/server/routes/ws.py +86 -0
- package/src/superlocalmemory/server/ui.py +6 -6
- package/src/superlocalmemory/server/unified_daemon.py +942 -119
- package/src/superlocalmemory/storage/_migration_internals.py +568 -0
- package/src/superlocalmemory/storage/_schema_version.py +110 -0
- package/src/superlocalmemory/storage/database.py +329 -24
- package/src/superlocalmemory/storage/embedding_migrator.py +246 -51
- package/src/superlocalmemory/storage/erasure_fence.py +45 -0
- package/src/superlocalmemory/storage/generation_fence.py +63 -0
- package/src/superlocalmemory/storage/migration_runner.py +140 -424
- package/src/superlocalmemory/storage/migrations/M009_model_lineage.py +40 -0
- package/src/superlocalmemory/storage/migrations/M033_projection_transactions.py +148 -0
- package/src/superlocalmemory/storage/migrations/M034_obligation_integrity.py +58 -0
- package/src/superlocalmemory/storage/migrations/M035_erasure_receipts.py +113 -0
- package/src/superlocalmemory/storage/migrations/M036_vector_row_map.py +107 -0
- package/src/superlocalmemory/storage/migrations/M037_manifest_hmac_version.py +162 -0
- package/src/superlocalmemory/storage/migrations/{M033_learning_feedback_channel.py → M038_learning_feedback_channel.py} +3 -3
- package/src/superlocalmemory/storage/migrations/{M034_scene_fact_members.py → M039_scene_fact_members.py} +15 -5
- package/src/superlocalmemory/storage/migrations/__init__.py +4 -4
- package/src/superlocalmemory/storage/schema.py +10 -2
- package/src/superlocalmemory/storage/write_coordinator.py +125 -0
- package/src/superlocalmemory/trust/scorer.py +28 -4
- package/src/superlocalmemory/ui/index.html +14 -3
- package/src/superlocalmemory/ui/js/auto-settings.js +12 -1
- package/src/superlocalmemory/ui/js/brain.js +6 -4
- package/src/superlocalmemory/ui/js/compliance.js +66 -12
- package/src/superlocalmemory/ui/js/dashboard.js +13 -3
- package/src/superlocalmemory/ui/js/feedback.js +8 -2
- package/src/superlocalmemory/ui/js/lifecycle.js +7 -1
- package/src/superlocalmemory/ui/js/modal.js +272 -5
- package/src/superlocalmemory/ui/js/od-backup.js +9 -2
- package/src/superlocalmemory/ui/js/od-compliance-ext.js +301 -0
- package/src/superlocalmemory/ui/js/od-operations.js +154 -23
- package/src/superlocalmemory/ui/js/od-ops-health.js +417 -0
- package/src/superlocalmemory/ui/js/od-optimize.js +35 -21
- package/src/superlocalmemory/ui/js/od-team.js +9 -2
- package/src/superlocalmemory/ui/js/optimize.js +13 -16
- package/src/superlocalmemory/ui/js/profiles.js +7 -3
- package/src/superlocalmemory/ui/js/settings.js +7 -1
- package/src/superlocalmemory/vector/lancedb_backend.py +19 -9
- package/src/superlocalmemory/attribution/mathematical_dna.py +0 -235
- package/src/superlocalmemory/cli/post_install.py +0 -114
- package/src/superlocalmemory/core/clock_monitor.py +0 -45
- package/src/superlocalmemory/core/db_pool.py +0 -80
- package/src/superlocalmemory/core/error_catalog.py +0 -113
- package/src/superlocalmemory/core/loop_watchdog.py +0 -56
- package/src/superlocalmemory/core/priority_queue.py +0 -61
- package/src/superlocalmemory/core/pruning_engine.py +0 -216
- package/src/superlocalmemory/core/queue_dispatcher.py +0 -73
- package/src/superlocalmemory/core/slmignore.py +0 -125
- package/src/superlocalmemory/infra/heartbeat_monitor.py +0 -140
- package/src/superlocalmemory/infra/webhook_dispatcher.py +0 -247
- package/src/superlocalmemory/learning/quantization_scheduler.py +0 -320
- package/src/superlocalmemory/storage/access_control.py +0 -182
|
@@ -403,11 +403,24 @@
|
|
|
403
403
|
'</div>' +
|
|
404
404
|
'</div>' +
|
|
405
405
|
|
|
406
|
-
// Audit trail with All/Denied segment filter
|
|
406
|
+
// Audit trail with All/Denied segment filter + event-type API filter
|
|
407
407
|
'<div class="card" style="margin-top:16px">' +
|
|
408
408
|
'<div class="card-head">' +
|
|
409
409
|
'<h3>Audit trail</h3>' +
|
|
410
|
+
// Task C: chain-integrity badge
|
|
411
|
+
'<span id="od-audit-chain-status"></span>' +
|
|
410
412
|
'<div class="spacer"></div>' +
|
|
413
|
+
// Task C: event-type filter select (calls API)
|
|
414
|
+
'<select id="od-audit-evt-filter" style="padding:4px 8px;border-radius:6px;' +
|
|
415
|
+
'border:1px solid var(--border);background:var(--card);color:var(--fg);font-size:12px">' +
|
|
416
|
+
'<option value="">All types</option>' +
|
|
417
|
+
'<option value="recall">recall</option>' +
|
|
418
|
+
'<option value="remember">remember</option>' +
|
|
419
|
+
'<option value="delete">delete</option>' +
|
|
420
|
+
'<option value="lifecycle_transition">lifecycle</option>' +
|
|
421
|
+
'<option value="access_denied">access_denied</option>' +
|
|
422
|
+
'<option value="retention_enforced">retention</option>' +
|
|
423
|
+
'</select>' +
|
|
411
424
|
'<div class="seg" id="od-audit-filter">' +
|
|
412
425
|
'<button class="active" data-filter="all">All</button>' +
|
|
413
426
|
'<button data-filter="denied">Denied</button>' +
|
|
@@ -675,8 +688,14 @@
|
|
|
675
688
|
|
|
676
689
|
if (applyBtn) {
|
|
677
690
|
applyBtn.addEventListener('click', function () {
|
|
678
|
-
|
|
679
|
-
|
|
691
|
+
window.confirmDestructive({
|
|
692
|
+
title: 'Apply compaction',
|
|
693
|
+
target: 'All eligible memories',
|
|
694
|
+
consequence: 'Transitions memories to lower lifecycle states.',
|
|
695
|
+
confirmLabel: 'Apply',
|
|
696
|
+
}).then(function(confirmed) {
|
|
697
|
+
if (!confirmed) return;
|
|
698
|
+
applyBtn.disabled = true;
|
|
680
699
|
applyBtn.textContent = 'Running…';
|
|
681
700
|
|
|
682
701
|
fetch('/api/lifecycle/compact', {
|
|
@@ -708,6 +727,7 @@
|
|
|
708
727
|
applyBtn.disabled = false;
|
|
709
728
|
applyBtn.textContent = 'Apply compaction';
|
|
710
729
|
});
|
|
730
|
+
});
|
|
711
731
|
});
|
|
712
732
|
}
|
|
713
733
|
}
|
|
@@ -722,10 +742,14 @@
|
|
|
722
742
|
var summary = document.getElementById('od-restart-summary');
|
|
723
743
|
if (!btn) return;
|
|
724
744
|
btn.addEventListener('click', function () {
|
|
725
|
-
|
|
726
|
-
'Restart
|
|
727
|
-
'
|
|
728
|
-
|
|
745
|
+
window.confirmDestructive({
|
|
746
|
+
title: 'Restart memory daemon',
|
|
747
|
+
target: 'Memory daemon',
|
|
748
|
+
consequence: 'Will be unavailable for a few seconds. Your memories are not affected.',
|
|
749
|
+
confirmLabel: 'Restart',
|
|
750
|
+
}).then(function(confirmed) {
|
|
751
|
+
if (!confirmed) return;
|
|
752
|
+
btn.disabled = true;
|
|
729
753
|
btn.textContent = 'Restarting…';
|
|
730
754
|
if (summary) summary.textContent = 'Restart requested — waiting for the daemon to come back…';
|
|
731
755
|
|
|
@@ -782,6 +806,7 @@
|
|
|
782
806
|
if (tries > 30) { clearInterval(poll); btn.disabled = false; btn.textContent = 'Restart daemon'; }
|
|
783
807
|
}, 1000);
|
|
784
808
|
});
|
|
809
|
+
});
|
|
785
810
|
});
|
|
786
811
|
}
|
|
787
812
|
|
|
@@ -903,40 +928,81 @@
|
|
|
903
928
|
|
|
904
929
|
var ACTION_CLS = { archive: 'neutral', tombstone: 'danger', notify: 'warn' };
|
|
905
930
|
|
|
931
|
+
// Build rows then wire delete buttons post-inject (avoids inline onclick — CSP safe)
|
|
906
932
|
retTbody.innerHTML = policies.map(function (p) {
|
|
907
933
|
var ac = ACTION_CLS[p.action] || 'neutral';
|
|
908
|
-
// CRIT(c): name, category, action through esc()
|
|
909
934
|
return (
|
|
910
935
|
'<tr>' +
|
|
911
936
|
'<td><b>' + esc(p.name || '') + '</b></td>' +
|
|
912
937
|
'<td class="num">' + esc(String(p.retention_days || '—')) + '</td>' +
|
|
913
938
|
'<td><span class="badge neutral">' + esc(p.category || 'all') + '</span></td>' +
|
|
914
939
|
'<td><span class="badge ' + ac + '">' + esc(p.action || '') + '</span></td>' +
|
|
940
|
+
// Task E: per-row delete — data-pol-name used by wireRetentionDeleteBtns()
|
|
915
941
|
'<td style="text-align:right">' +
|
|
916
|
-
'<button class="btn sm
|
|
917
|
-
|
|
942
|
+
'<button class="btn sm danger" data-pol-name="' + esc(p.name || '') + '">' +
|
|
943
|
+
'Delete' +
|
|
944
|
+
'</button>' +
|
|
918
945
|
'</td>' +
|
|
919
946
|
'</tr>'
|
|
920
947
|
);
|
|
921
948
|
}).join('');
|
|
949
|
+
|
|
950
|
+
// Task E: wire delete buttons (CSP-safe addEventListener after innerHTML set)
|
|
951
|
+
wireRetentionDeleteBtns(retTbody);
|
|
922
952
|
}
|
|
923
953
|
|
|
924
954
|
// Cache of all audit rows (for client-side All/Denied filter)
|
|
925
955
|
var _allAuditRows = [];
|
|
926
956
|
/**
|
|
927
|
-
* Populate the audit trail table.
|
|
957
|
+
* Task C: Populate the audit trail table.
|
|
958
|
+
* auditFull: response from /api/compliance/audit (preferred, up to 100 events).
|
|
959
|
+
* comp: response from /api/compliance/status (fallback, recent_audit_events).
|
|
928
960
|
* CRIT(c): actor, action, target, result all through esc().
|
|
929
961
|
*/
|
|
930
|
-
function populateAuditTrail(comp) {
|
|
962
|
+
function populateAuditTrail(comp, auditFull) {
|
|
931
963
|
var auditTbody = document.getElementById('od-audit-body');
|
|
932
964
|
if (!auditTbody) return;
|
|
933
965
|
|
|
934
|
-
|
|
966
|
+
// Prefer full audit endpoint data; fall back to status data
|
|
967
|
+
var events = (auditFull && auditFull.events) || (comp && comp.recent_audit_events) || [];
|
|
935
968
|
_allAuditRows = events;
|
|
936
969
|
|
|
937
970
|
renderAuditRows(auditTbody, events);
|
|
938
971
|
}
|
|
939
972
|
|
|
973
|
+
/**
|
|
974
|
+
* Task C: Render the chain-integrity badge inside the audit trail card header.
|
|
975
|
+
* Appended to #od-audit-chain-status if it exists.
|
|
976
|
+
*/
|
|
977
|
+
function showAuditChainStatus(auditFull) {
|
|
978
|
+
var el = document.getElementById('od-audit-chain-status');
|
|
979
|
+
if (!el || !auditFull) return;
|
|
980
|
+
var ok = auditFull.chain_verified !== false;
|
|
981
|
+
el.innerHTML = ok
|
|
982
|
+
? '<span class="badge ok" style="margin-left:8px">Chain verified</span>'
|
|
983
|
+
: '<span class="badge danger" style="margin-left:8px">Chain integrity issue</span>';
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/** Task C: re-fetch audit trail from API with a specific event_type filter. */
|
|
987
|
+
function fetchAndRenderAudit(eventType) {
|
|
988
|
+
var auditTbody = document.getElementById('od-audit-body');
|
|
989
|
+
if (!auditTbody) return;
|
|
990
|
+
auditTbody.innerHTML = '<tr><td colspan="6" class="dim" style="text-align:center;padding:16px">Loading…</td></tr>';
|
|
991
|
+
var url = '/api/compliance/audit?limit=100';
|
|
992
|
+
if (eventType && eventType !== 'all') url += '&event_type=' + encodeURIComponent(eventType);
|
|
993
|
+
fetch(url)
|
|
994
|
+
.then(function (r) { return r.ok ? r.json() : null; })
|
|
995
|
+
.then(function (d) {
|
|
996
|
+
if (!d) return;
|
|
997
|
+
_allAuditRows = d.events || [];
|
|
998
|
+
renderAuditRows(auditTbody, _allAuditRows);
|
|
999
|
+
showAuditChainStatus(d);
|
|
1000
|
+
})
|
|
1001
|
+
.catch(function () {
|
|
1002
|
+
if (auditTbody) auditTbody.innerHTML = '<tr><td colspan="6" class="dim" style="text-align:center;padding:16px">Failed to load audit trail.</td></tr>';
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
|
|
940
1006
|
/** Render audit table rows into tbody, filtering by mode ('all' or 'denied'). */
|
|
941
1007
|
function renderAuditRows(tbody, events) {
|
|
942
1008
|
if (events.length === 0) {
|
|
@@ -974,14 +1040,16 @@
|
|
|
974
1040
|
}).join('');
|
|
975
1041
|
}
|
|
976
1042
|
/**
|
|
977
|
-
*
|
|
978
|
-
*
|
|
1043
|
+
* Task C: Wire audit filters.
|
|
1044
|
+
* - All/Denied segment: client-side filter (fast).
|
|
1045
|
+
* - Event-type select (#od-audit-evt-filter): calls API to get filtered results.
|
|
979
1046
|
*/
|
|
980
|
-
function wireAuditFilter() {
|
|
1047
|
+
function wireAuditFilter(auditFull) {
|
|
981
1048
|
var filterEl = document.getElementById('od-audit-filter');
|
|
982
1049
|
var tbody = document.getElementById('od-audit-body');
|
|
983
1050
|
if (!filterEl || !tbody) return;
|
|
984
1051
|
|
|
1052
|
+
// All / Denied segment buttons — client-side
|
|
985
1053
|
filterEl.querySelectorAll('button').forEach(function (btn) {
|
|
986
1054
|
btn.addEventListener('click', function () {
|
|
987
1055
|
var mode = btn.getAttribute('data-filter');
|
|
@@ -1000,6 +1068,54 @@
|
|
|
1000
1068
|
renderAuditRows(tbody, rows);
|
|
1001
1069
|
});
|
|
1002
1070
|
});
|
|
1071
|
+
|
|
1072
|
+
// Task C: Event-type select — re-fetches from API
|
|
1073
|
+
var evtSelect = document.getElementById('od-audit-evt-filter');
|
|
1074
|
+
if (evtSelect) {
|
|
1075
|
+
evtSelect.addEventListener('change', function () {
|
|
1076
|
+
fetchAndRenderAudit(evtSelect.value);
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Task E: Wire delete buttons injected by populateRetentionPolicies.
|
|
1083
|
+
* Data attribute data-pol-name carries the policy name (already esc'd in innerHTML).
|
|
1084
|
+
* Uses confirmDestructive before calling DELETE /api/compliance/retention-policy?name=.
|
|
1085
|
+
*/
|
|
1086
|
+
function wireRetentionDeleteBtns(tbody) {
|
|
1087
|
+
tbody.querySelectorAll('[data-pol-name]').forEach(function (btn) {
|
|
1088
|
+
btn.addEventListener('click', function () {
|
|
1089
|
+
var policyName = btn.getAttribute('data-pol-name');
|
|
1090
|
+
window.confirmDestructive({
|
|
1091
|
+
title: 'Delete retention policy',
|
|
1092
|
+
target: policyName,
|
|
1093
|
+
consequence: 'This policy will no longer be enforced on any memory.',
|
|
1094
|
+
confirmLabel: 'Delete',
|
|
1095
|
+
}).then(function (confirmed) {
|
|
1096
|
+
if (!confirmed) return;
|
|
1097
|
+
btn.disabled = true;
|
|
1098
|
+
fetch('/api/compliance/retention-policy?name=' + encodeURIComponent(policyName), {
|
|
1099
|
+
method: 'DELETE',
|
|
1100
|
+
})
|
|
1101
|
+
.then(function (r) { return r.json(); })
|
|
1102
|
+
.then(function (d) {
|
|
1103
|
+
if (d && d.success !== false) {
|
|
1104
|
+
var pane = document.getElementById('operations-pane');
|
|
1105
|
+
if (pane && typeof window.odRenderOperations === 'function') {
|
|
1106
|
+
window.odRenderOperations(pane);
|
|
1107
|
+
}
|
|
1108
|
+
} else {
|
|
1109
|
+
btn.disabled = false;
|
|
1110
|
+
if (typeof console !== 'undefined') {
|
|
1111
|
+
console.error('[od-ops] retention delete failed:', d && d.error);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
})
|
|
1115
|
+
.catch(function () { btn.disabled = false; });
|
|
1116
|
+
});
|
|
1117
|
+
});
|
|
1118
|
+
});
|
|
1003
1119
|
}
|
|
1004
1120
|
|
|
1005
1121
|
/**
|
|
@@ -1043,11 +1159,18 @@
|
|
|
1043
1159
|
})
|
|
1044
1160
|
.then(function (r) { return r.json(); })
|
|
1045
1161
|
.then(function (d) {
|
|
1046
|
-
if (summary)
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1162
|
+
if (!summary) return;
|
|
1163
|
+
// Task E: surface all returned counts from the enforce response
|
|
1164
|
+
if (d && d.success) {
|
|
1165
|
+
var parts = [];
|
|
1166
|
+
if (d.archived != null) parts.push('archived ' + fmtNum(d.archived));
|
|
1167
|
+
if (d.tombstoned != null) parts.push('tombstoned ' + fmtNum(d.tombstoned));
|
|
1168
|
+
if (d.notified != null) parts.push('flagged ' + fmtNum(d.notified));
|
|
1169
|
+
if (d.evaluated != null) parts.push('evaluated ' + fmtNum(d.evaluated));
|
|
1170
|
+
if (d.policies_run != null) parts.push('policies run: ' + fmtNum(d.policies_run));
|
|
1171
|
+
summary.textContent = 'Retention applied — ' + (parts.join(', ') || 'no changes needed') + '.';
|
|
1172
|
+
} else {
|
|
1173
|
+
summary.textContent = 'Retention failed: ' + ((d && d.error) || 'unknown');
|
|
1051
1174
|
}
|
|
1052
1175
|
})
|
|
1053
1176
|
.catch(function () { if (summary) summary.textContent = 'Retention run failed. Check console.'; })
|
|
@@ -1216,10 +1339,13 @@
|
|
|
1216
1339
|
fetch('/api/lifecycle/status').then(function (r) { return r.ok ? r.json() : null; }).catch(function () { return null; }),
|
|
1217
1340
|
fetch('/api/trust/stats').then(function (r) { return r.ok ? r.json() : null; }).catch(function () { return null; }),
|
|
1218
1341
|
fetch('/api/compliance/status').then(function (r) { return r.ok ? r.json() : null; }).catch(function () { return null; }),
|
|
1342
|
+
// Task C: wire the full audit trail endpoint (up to 100 events, chain_verified)
|
|
1343
|
+
fetch('/api/compliance/audit?limit=100').then(function (r) { return r.ok ? r.json() : null; }).catch(function () { return null; }),
|
|
1219
1344
|
]).then(function (results) {
|
|
1220
1345
|
var lc = results[0];
|
|
1221
1346
|
var trustStats = results[1];
|
|
1222
1347
|
var comp = results[2];
|
|
1348
|
+
var auditFull = results[3]; // {available, events, chain_verified, ...}
|
|
1223
1349
|
|
|
1224
1350
|
// Inject .ctl class styles (used by Trust section control rows)
|
|
1225
1351
|
injectCtlStyle();
|
|
@@ -1243,10 +1369,15 @@
|
|
|
1243
1369
|
// Populate compliance
|
|
1244
1370
|
populateComplianceKpi(comp);
|
|
1245
1371
|
populateRetentionPolicies(comp);
|
|
1246
|
-
|
|
1372
|
+
// Task C: prefer the full audit trail from the dedicated endpoint;
|
|
1373
|
+
// fall back to the status endpoint's recent_audit_events on failure.
|
|
1374
|
+
populateAuditTrail(comp, auditFull);
|
|
1375
|
+
|
|
1376
|
+
// Task C: show chain-integrity indicator
|
|
1377
|
+
showAuditChainStatus(auditFull);
|
|
1247
1378
|
|
|
1248
1379
|
// Wire audit filter and new-policy button (listeners on injected DOM)
|
|
1249
|
-
wireAuditFilter();
|
|
1380
|
+
wireAuditFilter(auditFull);
|
|
1250
1381
|
wireNewPolicyBtn();
|
|
1251
1382
|
wireGdprBtns();
|
|
1252
1383
|
|