@massu/core 1.10.1 → 1.10.2
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/cli.js +40 -14
- package/dist/hooks/classify-failure.js +10 -10
- package/dist/hooks/cost-tracker.js +10 -10
- package/dist/hooks/incident-pipeline.js +10 -10
- package/dist/hooks/post-tool-use.js +10 -10
- package/dist/hooks/pre-compact.js +10 -10
- package/dist/hooks/quality-event.js +10 -10
- package/dist/hooks/session-end.js +76 -12
- package/dist/hooks/session-start.js +10 -10
- package/dist/hooks/user-prompt.js +10 -10
- package/package.json +1 -1
- package/src/cloud-sync.ts +27 -1
- package/src/knowledge-db.ts +8 -1
- package/src/knowledge-indexer.ts +6 -2
- package/src/memory-db.ts +42 -13
- package/src/security/registry-pubkey.generated.ts +1 -1
package/dist/cli.js
CHANGED
|
@@ -796,7 +796,7 @@ function initMemorySchema(db) {
|
|
|
796
796
|
response_tokens INTEGER,
|
|
797
797
|
created_at TEXT DEFAULT (datetime('now')),
|
|
798
798
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
799
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
799
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
800
800
|
);
|
|
801
801
|
|
|
802
802
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -817,7 +817,7 @@ function initMemorySchema(db) {
|
|
|
817
817
|
files_involved TEXT,
|
|
818
818
|
created_at TEXT DEFAULT (datetime('now')),
|
|
819
819
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
820
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
820
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
821
821
|
);
|
|
822
822
|
|
|
823
823
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -871,7 +871,7 @@ function initMemorySchema(db) {
|
|
|
871
871
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
872
872
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
873
873
|
created_at TEXT DEFAULT (datetime('now')),
|
|
874
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
874
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
875
875
|
);
|
|
876
876
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
877
877
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -891,7 +891,7 @@ function initMemorySchema(db) {
|
|
|
891
891
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
892
892
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
893
893
|
created_at TEXT DEFAULT (datetime('now')),
|
|
894
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
894
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
895
895
|
);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
897
897
|
`);
|
|
@@ -904,7 +904,7 @@ function initMemorySchema(db) {
|
|
|
904
904
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
905
905
|
commit_hash TEXT,
|
|
906
906
|
created_at TEXT DEFAULT (datetime('now')),
|
|
907
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
907
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
908
908
|
);
|
|
909
909
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
910
910
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -921,7 +921,7 @@ function initMemorySchema(db) {
|
|
|
921
921
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
922
922
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
923
923
|
created_at TEXT DEFAULT (datetime('now')),
|
|
924
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
924
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
925
925
|
);
|
|
926
926
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
927
927
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -940,7 +940,7 @@ function initMemorySchema(db) {
|
|
|
940
940
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
941
941
|
evidence TEXT,
|
|
942
942
|
metadata TEXT,
|
|
943
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
943
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
944
944
|
);
|
|
945
945
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
946
946
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -957,7 +957,7 @@ function initMemorySchema(db) {
|
|
|
957
957
|
details TEXT,
|
|
958
958
|
rules_violated TEXT,
|
|
959
959
|
created_at TEXT DEFAULT (datetime('now')),
|
|
960
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
960
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
961
961
|
);
|
|
962
962
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
963
963
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -975,7 +975,7 @@ function initMemorySchema(db) {
|
|
|
975
975
|
affected_files TEXT,
|
|
976
976
|
commit_hash TEXT,
|
|
977
977
|
created_at TEXT DEFAULT (datetime('now')),
|
|
978
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
978
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
979
979
|
);
|
|
980
980
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
981
981
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -988,7 +988,7 @@ function initMemorySchema(db) {
|
|
|
988
988
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
989
989
|
findings TEXT,
|
|
990
990
|
created_at TEXT DEFAULT (datetime('now')),
|
|
991
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
991
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
992
992
|
);
|
|
993
993
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
994
994
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -1141,11 +1141,29 @@ function enqueueSyncPayload(db, payload) {
|
|
|
1141
1141
|
}
|
|
1142
1142
|
function dequeuePendingSync(db, limit = 10) {
|
|
1143
1143
|
const stale = db.prepare(
|
|
1144
|
-
"SELECT id FROM pending_sync WHERE retry_count >= 10"
|
|
1144
|
+
"SELECT id, retry_count, last_error FROM pending_sync WHERE retry_count >= 10"
|
|
1145
1145
|
).all();
|
|
1146
1146
|
if (stale.length > 0) {
|
|
1147
1147
|
const ids = stale.map((s) => s.id);
|
|
1148
1148
|
db.prepare(`DELETE FROM pending_sync WHERE id IN (${ids.map(() => "?").join(",")})`).run(...ids);
|
|
1149
|
+
const lastErrors = [...new Set(stale.map((s) => s.last_error).filter(Boolean))];
|
|
1150
|
+
process.stderr.write(
|
|
1151
|
+
`[massu] WARNING: ${stale.length} cloud-sync queue item(s) discarded after 10+ retries. Likely cause: invalid API key or unreachable endpoint. Recent errors: ${lastErrors.slice(0, 3).join("; ") || "(none recorded)"}
|
|
1152
|
+
`
|
|
1153
|
+
);
|
|
1154
|
+
try {
|
|
1155
|
+
db.prepare(`
|
|
1156
|
+
INSERT INTO analytics_events (event_type, event_data, created_at)
|
|
1157
|
+
VALUES (?, ?, datetime('now'))
|
|
1158
|
+
`).run(
|
|
1159
|
+
"cloud_sync_giveup",
|
|
1160
|
+
JSON.stringify({
|
|
1161
|
+
discarded_count: stale.length,
|
|
1162
|
+
recent_errors: lastErrors.slice(0, 3)
|
|
1163
|
+
})
|
|
1164
|
+
);
|
|
1165
|
+
} catch {
|
|
1166
|
+
}
|
|
1149
1167
|
}
|
|
1150
1168
|
return db.prepare(
|
|
1151
1169
|
"SELECT id, payload, retry_count FROM pending_sync ORDER BY created_at ASC LIMIT ?"
|
|
@@ -25525,8 +25543,9 @@ function indexAllKnowledge(db) {
|
|
|
25525
25543
|
"INSERT OR IGNORE INTO knowledge_incidents (incident_num, date, type, gap_found, prevention) VALUES (?, ?, ?, ?, ?)"
|
|
25526
25544
|
);
|
|
25527
25545
|
const insertMismatch = db.prepare(
|
|
25528
|
-
"INSERT INTO knowledge_schema_mismatches (table_name, wrong_column, correct_column) VALUES (?, ?, ?)"
|
|
25546
|
+
"INSERT INTO knowledge_schema_mismatches (table_name, wrong_column, correct_column, source) VALUES (?, ?, ?, ?)"
|
|
25529
25547
|
);
|
|
25548
|
+
const defaultSource = getConfig().conventions?.knowledgeSourceFiles?.[0] ?? "CLAUDE.md";
|
|
25530
25549
|
const files = discoverMarkdownFiles(paths.claudeDir);
|
|
25531
25550
|
try {
|
|
25532
25551
|
const memFiles = discoverMarkdownFiles(paths.memoryDir);
|
|
@@ -25614,7 +25633,7 @@ function indexAllKnowledge(db) {
|
|
|
25614
25633
|
}
|
|
25615
25634
|
const mismatches = parseSchemaMismatches(content);
|
|
25616
25635
|
for (const m3 of mismatches) {
|
|
25617
|
-
insertMismatch.run(m3.table_name, m3.wrong_column, m3.correct_column);
|
|
25636
|
+
insertMismatch.run(m3.table_name, m3.wrong_column, m3.correct_column, defaultSource);
|
|
25618
25637
|
insertChunk.run(docId, "mismatch", m3.table_name, `${m3.table_name}: ${m3.wrong_column} -> ${m3.correct_column}`, null, null, JSON.stringify({ table: m3.table_name }));
|
|
25619
25638
|
stats.chunksCreated++;
|
|
25620
25639
|
}
|
|
@@ -26916,12 +26935,19 @@ function initKnowledgeSchema(db) {
|
|
|
26916
26935
|
CREATE INDEX IF NOT EXISTS idx_ki_cr ON knowledge_incidents(cr_added);
|
|
26917
26936
|
|
|
26918
26937
|
-- Schema mismatch quick lookup
|
|
26938
|
+
-- P-H013 (plan-stage-c-high-batch): the source column no longer has a
|
|
26939
|
+
-- SQL DEFAULT. Previously the value was a JS template-literal
|
|
26940
|
+
-- interpolation baked into the customer SQLite at schema creation
|
|
26941
|
+
-- time, so later config changes were ignored. Default is now applied
|
|
26942
|
+
-- at INSERT time via getConfig().conventions.knowledgeSourceFiles[0]
|
|
26943
|
+
-- in knowledge-indexer.ts -- a runtime config lookup that reflects
|
|
26944
|
+
-- the customers current config.
|
|
26919
26945
|
CREATE TABLE IF NOT EXISTS knowledge_schema_mismatches (
|
|
26920
26946
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
26921
26947
|
table_name TEXT NOT NULL,
|
|
26922
26948
|
wrong_column TEXT NOT NULL,
|
|
26923
26949
|
correct_column TEXT NOT NULL,
|
|
26924
|
-
source TEXT
|
|
26950
|
+
source TEXT NOT NULL
|
|
26925
26951
|
);
|
|
26926
26952
|
|
|
26927
26953
|
CREATE INDEX IF NOT EXISTS idx_ksm_table ON knowledge_schema_mismatches(table_name);
|
|
@@ -701,7 +701,7 @@ function initMemorySchema(db) {
|
|
|
701
701
|
response_tokens INTEGER,
|
|
702
702
|
created_at TEXT DEFAULT (datetime('now')),
|
|
703
703
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
704
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
704
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
705
705
|
);
|
|
706
706
|
|
|
707
707
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -722,7 +722,7 @@ function initMemorySchema(db) {
|
|
|
722
722
|
files_involved TEXT,
|
|
723
723
|
created_at TEXT DEFAULT (datetime('now')),
|
|
724
724
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
725
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
725
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
726
726
|
);
|
|
727
727
|
|
|
728
728
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -776,7 +776,7 @@ function initMemorySchema(db) {
|
|
|
776
776
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
777
777
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
778
778
|
created_at TEXT DEFAULT (datetime('now')),
|
|
779
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
779
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
780
780
|
);
|
|
781
781
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
782
782
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -796,7 +796,7 @@ function initMemorySchema(db) {
|
|
|
796
796
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
797
797
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
798
798
|
created_at TEXT DEFAULT (datetime('now')),
|
|
799
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
799
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
800
800
|
);
|
|
801
801
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
802
802
|
`);
|
|
@@ -809,7 +809,7 @@ function initMemorySchema(db) {
|
|
|
809
809
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
810
810
|
commit_hash TEXT,
|
|
811
811
|
created_at TEXT DEFAULT (datetime('now')),
|
|
812
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
812
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
813
813
|
);
|
|
814
814
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
815
815
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -826,7 +826,7 @@ function initMemorySchema(db) {
|
|
|
826
826
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
827
827
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
828
828
|
created_at TEXT DEFAULT (datetime('now')),
|
|
829
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
829
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
830
830
|
);
|
|
831
831
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
832
832
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -845,7 +845,7 @@ function initMemorySchema(db) {
|
|
|
845
845
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
846
846
|
evidence TEXT,
|
|
847
847
|
metadata TEXT,
|
|
848
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
848
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
849
849
|
);
|
|
850
850
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
851
851
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -862,7 +862,7 @@ function initMemorySchema(db) {
|
|
|
862
862
|
details TEXT,
|
|
863
863
|
rules_violated TEXT,
|
|
864
864
|
created_at TEXT DEFAULT (datetime('now')),
|
|
865
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
865
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
866
866
|
);
|
|
867
867
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
868
868
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -880,7 +880,7 @@ function initMemorySchema(db) {
|
|
|
880
880
|
affected_files TEXT,
|
|
881
881
|
commit_hash TEXT,
|
|
882
882
|
created_at TEXT DEFAULT (datetime('now')),
|
|
883
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
883
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
884
884
|
);
|
|
885
885
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
886
886
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -893,7 +893,7 @@ function initMemorySchema(db) {
|
|
|
893
893
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
894
894
|
findings TEXT,
|
|
895
895
|
created_at TEXT DEFAULT (datetime('now')),
|
|
896
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
896
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
897
897
|
);
|
|
898
898
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
899
899
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -698,7 +698,7 @@ function initMemorySchema(db) {
|
|
|
698
698
|
response_tokens INTEGER,
|
|
699
699
|
created_at TEXT DEFAULT (datetime('now')),
|
|
700
700
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
701
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
701
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
702
702
|
);
|
|
703
703
|
|
|
704
704
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -719,7 +719,7 @@ function initMemorySchema(db) {
|
|
|
719
719
|
files_involved TEXT,
|
|
720
720
|
created_at TEXT DEFAULT (datetime('now')),
|
|
721
721
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
722
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
722
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
723
723
|
);
|
|
724
724
|
|
|
725
725
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -773,7 +773,7 @@ function initMemorySchema(db) {
|
|
|
773
773
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
774
774
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
775
775
|
created_at TEXT DEFAULT (datetime('now')),
|
|
776
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
776
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
777
777
|
);
|
|
778
778
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
779
779
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -793,7 +793,7 @@ function initMemorySchema(db) {
|
|
|
793
793
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
794
794
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
795
795
|
created_at TEXT DEFAULT (datetime('now')),
|
|
796
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
796
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
797
797
|
);
|
|
798
798
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
799
799
|
`);
|
|
@@ -806,7 +806,7 @@ function initMemorySchema(db) {
|
|
|
806
806
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
807
807
|
commit_hash TEXT,
|
|
808
808
|
created_at TEXT DEFAULT (datetime('now')),
|
|
809
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
809
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
810
810
|
);
|
|
811
811
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
812
812
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -823,7 +823,7 @@ function initMemorySchema(db) {
|
|
|
823
823
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
824
824
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
825
825
|
created_at TEXT DEFAULT (datetime('now')),
|
|
826
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
826
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
827
827
|
);
|
|
828
828
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
829
829
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -842,7 +842,7 @@ function initMemorySchema(db) {
|
|
|
842
842
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
843
843
|
evidence TEXT,
|
|
844
844
|
metadata TEXT,
|
|
845
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
845
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
846
846
|
);
|
|
847
847
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
848
848
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -859,7 +859,7 @@ function initMemorySchema(db) {
|
|
|
859
859
|
details TEXT,
|
|
860
860
|
rules_violated TEXT,
|
|
861
861
|
created_at TEXT DEFAULT (datetime('now')),
|
|
862
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
862
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
863
863
|
);
|
|
864
864
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
865
865
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -877,7 +877,7 @@ function initMemorySchema(db) {
|
|
|
877
877
|
affected_files TEXT,
|
|
878
878
|
commit_hash TEXT,
|
|
879
879
|
created_at TEXT DEFAULT (datetime('now')),
|
|
880
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
880
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
881
881
|
);
|
|
882
882
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
883
883
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -890,7 +890,7 @@ function initMemorySchema(db) {
|
|
|
890
890
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
891
891
|
findings TEXT,
|
|
892
892
|
created_at TEXT DEFAULT (datetime('now')),
|
|
893
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
893
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
894
894
|
);
|
|
895
895
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -700,7 +700,7 @@ function initMemorySchema(db) {
|
|
|
700
700
|
response_tokens INTEGER,
|
|
701
701
|
created_at TEXT DEFAULT (datetime('now')),
|
|
702
702
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
703
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
703
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
704
704
|
);
|
|
705
705
|
|
|
706
706
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -721,7 +721,7 @@ function initMemorySchema(db) {
|
|
|
721
721
|
files_involved TEXT,
|
|
722
722
|
created_at TEXT DEFAULT (datetime('now')),
|
|
723
723
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
724
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
724
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
725
725
|
);
|
|
726
726
|
|
|
727
727
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -775,7 +775,7 @@ function initMemorySchema(db) {
|
|
|
775
775
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
776
776
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
777
777
|
created_at TEXT DEFAULT (datetime('now')),
|
|
778
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
778
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
779
779
|
);
|
|
780
780
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
781
781
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -795,7 +795,7 @@ function initMemorySchema(db) {
|
|
|
795
795
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
796
796
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
797
797
|
created_at TEXT DEFAULT (datetime('now')),
|
|
798
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
798
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
799
799
|
);
|
|
800
800
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
801
801
|
`);
|
|
@@ -808,7 +808,7 @@ function initMemorySchema(db) {
|
|
|
808
808
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
809
809
|
commit_hash TEXT,
|
|
810
810
|
created_at TEXT DEFAULT (datetime('now')),
|
|
811
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
811
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
812
812
|
);
|
|
813
813
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
814
814
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -825,7 +825,7 @@ function initMemorySchema(db) {
|
|
|
825
825
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
826
826
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
827
827
|
created_at TEXT DEFAULT (datetime('now')),
|
|
828
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
828
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
829
829
|
);
|
|
830
830
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
831
831
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -844,7 +844,7 @@ function initMemorySchema(db) {
|
|
|
844
844
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
845
845
|
evidence TEXT,
|
|
846
846
|
metadata TEXT,
|
|
847
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
847
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
848
848
|
);
|
|
849
849
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
850
850
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -861,7 +861,7 @@ function initMemorySchema(db) {
|
|
|
861
861
|
details TEXT,
|
|
862
862
|
rules_violated TEXT,
|
|
863
863
|
created_at TEXT DEFAULT (datetime('now')),
|
|
864
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
864
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
865
865
|
);
|
|
866
866
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
867
867
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -879,7 +879,7 @@ function initMemorySchema(db) {
|
|
|
879
879
|
affected_files TEXT,
|
|
880
880
|
commit_hash TEXT,
|
|
881
881
|
created_at TEXT DEFAULT (datetime('now')),
|
|
882
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
882
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
883
883
|
);
|
|
884
884
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
885
885
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -892,7 +892,7 @@ function initMemorySchema(db) {
|
|
|
892
892
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
893
893
|
findings TEXT,
|
|
894
894
|
created_at TEXT DEFAULT (datetime('now')),
|
|
895
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
895
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
896
896
|
);
|
|
897
897
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
898
898
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -698,7 +698,7 @@ function initMemorySchema(db) {
|
|
|
698
698
|
response_tokens INTEGER,
|
|
699
699
|
created_at TEXT DEFAULT (datetime('now')),
|
|
700
700
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
701
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
701
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
702
702
|
);
|
|
703
703
|
|
|
704
704
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -719,7 +719,7 @@ function initMemorySchema(db) {
|
|
|
719
719
|
files_involved TEXT,
|
|
720
720
|
created_at TEXT DEFAULT (datetime('now')),
|
|
721
721
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
722
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
722
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
723
723
|
);
|
|
724
724
|
|
|
725
725
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -773,7 +773,7 @@ function initMemorySchema(db) {
|
|
|
773
773
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
774
774
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
775
775
|
created_at TEXT DEFAULT (datetime('now')),
|
|
776
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
776
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
777
777
|
);
|
|
778
778
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
779
779
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -793,7 +793,7 @@ function initMemorySchema(db) {
|
|
|
793
793
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
794
794
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
795
795
|
created_at TEXT DEFAULT (datetime('now')),
|
|
796
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
796
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
797
797
|
);
|
|
798
798
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
799
799
|
`);
|
|
@@ -806,7 +806,7 @@ function initMemorySchema(db) {
|
|
|
806
806
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
807
807
|
commit_hash TEXT,
|
|
808
808
|
created_at TEXT DEFAULT (datetime('now')),
|
|
809
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
809
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
810
810
|
);
|
|
811
811
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
812
812
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -823,7 +823,7 @@ function initMemorySchema(db) {
|
|
|
823
823
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
824
824
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
825
825
|
created_at TEXT DEFAULT (datetime('now')),
|
|
826
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
826
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
827
827
|
);
|
|
828
828
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
829
829
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -842,7 +842,7 @@ function initMemorySchema(db) {
|
|
|
842
842
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
843
843
|
evidence TEXT,
|
|
844
844
|
metadata TEXT,
|
|
845
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
845
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
846
846
|
);
|
|
847
847
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
848
848
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -859,7 +859,7 @@ function initMemorySchema(db) {
|
|
|
859
859
|
details TEXT,
|
|
860
860
|
rules_violated TEXT,
|
|
861
861
|
created_at TEXT DEFAULT (datetime('now')),
|
|
862
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
862
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
863
863
|
);
|
|
864
864
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
865
865
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -877,7 +877,7 @@ function initMemorySchema(db) {
|
|
|
877
877
|
affected_files TEXT,
|
|
878
878
|
commit_hash TEXT,
|
|
879
879
|
created_at TEXT DEFAULT (datetime('now')),
|
|
880
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
880
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
881
881
|
);
|
|
882
882
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
883
883
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -890,7 +890,7 @@ function initMemorySchema(db) {
|
|
|
890
890
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
891
891
|
findings TEXT,
|
|
892
892
|
created_at TEXT DEFAULT (datetime('now')),
|
|
893
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
893
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
894
894
|
);
|
|
895
895
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -698,7 +698,7 @@ function initMemorySchema(db) {
|
|
|
698
698
|
response_tokens INTEGER,
|
|
699
699
|
created_at TEXT DEFAULT (datetime('now')),
|
|
700
700
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
701
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
701
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
702
702
|
);
|
|
703
703
|
|
|
704
704
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -719,7 +719,7 @@ function initMemorySchema(db) {
|
|
|
719
719
|
files_involved TEXT,
|
|
720
720
|
created_at TEXT DEFAULT (datetime('now')),
|
|
721
721
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
722
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
722
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
723
723
|
);
|
|
724
724
|
|
|
725
725
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -773,7 +773,7 @@ function initMemorySchema(db) {
|
|
|
773
773
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
774
774
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
775
775
|
created_at TEXT DEFAULT (datetime('now')),
|
|
776
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
776
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
777
777
|
);
|
|
778
778
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
779
779
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -793,7 +793,7 @@ function initMemorySchema(db) {
|
|
|
793
793
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
794
794
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
795
795
|
created_at TEXT DEFAULT (datetime('now')),
|
|
796
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
796
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
797
797
|
);
|
|
798
798
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
799
799
|
`);
|
|
@@ -806,7 +806,7 @@ function initMemorySchema(db) {
|
|
|
806
806
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
807
807
|
commit_hash TEXT,
|
|
808
808
|
created_at TEXT DEFAULT (datetime('now')),
|
|
809
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
809
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
810
810
|
);
|
|
811
811
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
812
812
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -823,7 +823,7 @@ function initMemorySchema(db) {
|
|
|
823
823
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
824
824
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
825
825
|
created_at TEXT DEFAULT (datetime('now')),
|
|
826
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
826
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
827
827
|
);
|
|
828
828
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
829
829
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -842,7 +842,7 @@ function initMemorySchema(db) {
|
|
|
842
842
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
843
843
|
evidence TEXT,
|
|
844
844
|
metadata TEXT,
|
|
845
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
845
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
846
846
|
);
|
|
847
847
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
848
848
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -859,7 +859,7 @@ function initMemorySchema(db) {
|
|
|
859
859
|
details TEXT,
|
|
860
860
|
rules_violated TEXT,
|
|
861
861
|
created_at TEXT DEFAULT (datetime('now')),
|
|
862
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
862
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
863
863
|
);
|
|
864
864
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
865
865
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -877,7 +877,7 @@ function initMemorySchema(db) {
|
|
|
877
877
|
affected_files TEXT,
|
|
878
878
|
commit_hash TEXT,
|
|
879
879
|
created_at TEXT DEFAULT (datetime('now')),
|
|
880
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
880
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
881
881
|
);
|
|
882
882
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
883
883
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -890,7 +890,7 @@ function initMemorySchema(db) {
|
|
|
890
890
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
891
891
|
findings TEXT,
|
|
892
892
|
created_at TEXT DEFAULT (datetime('now')),
|
|
893
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
893
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
894
894
|
);
|
|
895
895
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -698,7 +698,7 @@ function initMemorySchema(db) {
|
|
|
698
698
|
response_tokens INTEGER,
|
|
699
699
|
created_at TEXT DEFAULT (datetime('now')),
|
|
700
700
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
701
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
701
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
702
702
|
);
|
|
703
703
|
|
|
704
704
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -719,7 +719,7 @@ function initMemorySchema(db) {
|
|
|
719
719
|
files_involved TEXT,
|
|
720
720
|
created_at TEXT DEFAULT (datetime('now')),
|
|
721
721
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
722
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
722
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
723
723
|
);
|
|
724
724
|
|
|
725
725
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -773,7 +773,7 @@ function initMemorySchema(db) {
|
|
|
773
773
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
774
774
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
775
775
|
created_at TEXT DEFAULT (datetime('now')),
|
|
776
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
776
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
777
777
|
);
|
|
778
778
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
779
779
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -793,7 +793,7 @@ function initMemorySchema(db) {
|
|
|
793
793
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
794
794
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
795
795
|
created_at TEXT DEFAULT (datetime('now')),
|
|
796
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
796
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
797
797
|
);
|
|
798
798
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
799
799
|
`);
|
|
@@ -806,7 +806,7 @@ function initMemorySchema(db) {
|
|
|
806
806
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
807
807
|
commit_hash TEXT,
|
|
808
808
|
created_at TEXT DEFAULT (datetime('now')),
|
|
809
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
809
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
810
810
|
);
|
|
811
811
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
812
812
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -823,7 +823,7 @@ function initMemorySchema(db) {
|
|
|
823
823
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
824
824
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
825
825
|
created_at TEXT DEFAULT (datetime('now')),
|
|
826
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
826
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
827
827
|
);
|
|
828
828
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
829
829
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -842,7 +842,7 @@ function initMemorySchema(db) {
|
|
|
842
842
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
843
843
|
evidence TEXT,
|
|
844
844
|
metadata TEXT,
|
|
845
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
845
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
846
846
|
);
|
|
847
847
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
848
848
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -859,7 +859,7 @@ function initMemorySchema(db) {
|
|
|
859
859
|
details TEXT,
|
|
860
860
|
rules_violated TEXT,
|
|
861
861
|
created_at TEXT DEFAULT (datetime('now')),
|
|
862
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
862
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
863
863
|
);
|
|
864
864
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
865
865
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -877,7 +877,7 @@ function initMemorySchema(db) {
|
|
|
877
877
|
affected_files TEXT,
|
|
878
878
|
commit_hash TEXT,
|
|
879
879
|
created_at TEXT DEFAULT (datetime('now')),
|
|
880
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
880
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
881
881
|
);
|
|
882
882
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
883
883
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -890,7 +890,7 @@ function initMemorySchema(db) {
|
|
|
890
890
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
891
891
|
findings TEXT,
|
|
892
892
|
created_at TEXT DEFAULT (datetime('now')),
|
|
893
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
893
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
894
894
|
);
|
|
895
895
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -698,7 +698,7 @@ function initMemorySchema(db) {
|
|
|
698
698
|
response_tokens INTEGER,
|
|
699
699
|
created_at TEXT DEFAULT (datetime('now')),
|
|
700
700
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
701
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
701
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
702
702
|
);
|
|
703
703
|
|
|
704
704
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -719,7 +719,7 @@ function initMemorySchema(db) {
|
|
|
719
719
|
files_involved TEXT,
|
|
720
720
|
created_at TEXT DEFAULT (datetime('now')),
|
|
721
721
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
722
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
722
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
723
723
|
);
|
|
724
724
|
|
|
725
725
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -773,7 +773,7 @@ function initMemorySchema(db) {
|
|
|
773
773
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
774
774
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
775
775
|
created_at TEXT DEFAULT (datetime('now')),
|
|
776
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
776
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
777
777
|
);
|
|
778
778
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
779
779
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -793,7 +793,7 @@ function initMemorySchema(db) {
|
|
|
793
793
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
794
794
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
795
795
|
created_at TEXT DEFAULT (datetime('now')),
|
|
796
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
796
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
797
797
|
);
|
|
798
798
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
799
799
|
`);
|
|
@@ -806,7 +806,7 @@ function initMemorySchema(db) {
|
|
|
806
806
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
807
807
|
commit_hash TEXT,
|
|
808
808
|
created_at TEXT DEFAULT (datetime('now')),
|
|
809
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
809
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
810
810
|
);
|
|
811
811
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
812
812
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -823,7 +823,7 @@ function initMemorySchema(db) {
|
|
|
823
823
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
824
824
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
825
825
|
created_at TEXT DEFAULT (datetime('now')),
|
|
826
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
826
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
827
827
|
);
|
|
828
828
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
829
829
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -842,7 +842,7 @@ function initMemorySchema(db) {
|
|
|
842
842
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
843
843
|
evidence TEXT,
|
|
844
844
|
metadata TEXT,
|
|
845
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
845
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
846
846
|
);
|
|
847
847
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
848
848
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -859,7 +859,7 @@ function initMemorySchema(db) {
|
|
|
859
859
|
details TEXT,
|
|
860
860
|
rules_violated TEXT,
|
|
861
861
|
created_at TEXT DEFAULT (datetime('now')),
|
|
862
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
862
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
863
863
|
);
|
|
864
864
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
865
865
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -877,7 +877,7 @@ function initMemorySchema(db) {
|
|
|
877
877
|
affected_files TEXT,
|
|
878
878
|
commit_hash TEXT,
|
|
879
879
|
created_at TEXT DEFAULT (datetime('now')),
|
|
880
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
880
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
881
881
|
);
|
|
882
882
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
883
883
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -890,7 +890,7 @@ function initMemorySchema(db) {
|
|
|
890
890
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
891
891
|
findings TEXT,
|
|
892
892
|
created_at TEXT DEFAULT (datetime('now')),
|
|
893
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
893
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
894
894
|
);
|
|
895
895
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -1043,11 +1043,29 @@ function enqueueSyncPayload(db, payload) {
|
|
|
1043
1043
|
}
|
|
1044
1044
|
function dequeuePendingSync(db, limit = 10) {
|
|
1045
1045
|
const stale = db.prepare(
|
|
1046
|
-
"SELECT id FROM pending_sync WHERE retry_count >= 10"
|
|
1046
|
+
"SELECT id, retry_count, last_error FROM pending_sync WHERE retry_count >= 10"
|
|
1047
1047
|
).all();
|
|
1048
1048
|
if (stale.length > 0) {
|
|
1049
1049
|
const ids = stale.map((s) => s.id);
|
|
1050
1050
|
db.prepare(`DELETE FROM pending_sync WHERE id IN (${ids.map(() => "?").join(",")})`).run(...ids);
|
|
1051
|
+
const lastErrors = [...new Set(stale.map((s) => s.last_error).filter(Boolean))];
|
|
1052
|
+
process.stderr.write(
|
|
1053
|
+
`[massu] WARNING: ${stale.length} cloud-sync queue item(s) discarded after 10+ retries. Likely cause: invalid API key or unreachable endpoint. Recent errors: ${lastErrors.slice(0, 3).join("; ") || "(none recorded)"}
|
|
1054
|
+
`
|
|
1055
|
+
);
|
|
1056
|
+
try {
|
|
1057
|
+
db.prepare(`
|
|
1058
|
+
INSERT INTO analytics_events (event_type, event_data, created_at)
|
|
1059
|
+
VALUES (?, ?, datetime('now'))
|
|
1060
|
+
`).run(
|
|
1061
|
+
"cloud_sync_giveup",
|
|
1062
|
+
JSON.stringify({
|
|
1063
|
+
discarded_count: stale.length,
|
|
1064
|
+
recent_errors: lastErrors.slice(0, 3)
|
|
1065
|
+
})
|
|
1066
|
+
);
|
|
1067
|
+
} catch {
|
|
1068
|
+
}
|
|
1051
1069
|
}
|
|
1052
1070
|
return db.prepare(
|
|
1053
1071
|
"SELECT id, payload, retry_count FROM pending_sync ORDER BY created_at ASC LIMIT ?"
|
|
@@ -1415,6 +1433,33 @@ function estimateTokens(text) {
|
|
|
1415
1433
|
return Math.ceil(text.length / 4);
|
|
1416
1434
|
}
|
|
1417
1435
|
|
|
1436
|
+
// src/observation-extractor.ts
|
|
1437
|
+
var PRIVATE_PATTERNS = [
|
|
1438
|
+
/\/Users\/\w+/,
|
|
1439
|
+
// Absolute macOS paths
|
|
1440
|
+
/\/home\/\w+/,
|
|
1441
|
+
// Absolute Linux paths
|
|
1442
|
+
/[A-Z]:\\/,
|
|
1443
|
+
// Windows paths
|
|
1444
|
+
/\b(api[_-]?key|secret|token|password|credential|dsn)\b/i,
|
|
1445
|
+
// Secrets
|
|
1446
|
+
/\b(STRIPE_|SUPABASE_|SENTRY_|AWS_|DATABASE_URL)\b/,
|
|
1447
|
+
// Env var names
|
|
1448
|
+
/\.(env|pem|key|cert)\b/,
|
|
1449
|
+
// Sensitive file extensions
|
|
1450
|
+
/Bearer\s+\S+/,
|
|
1451
|
+
// Auth tokens
|
|
1452
|
+
/sk_live_|sk_test_|whsec_/
|
|
1453
|
+
// Stripe keys
|
|
1454
|
+
];
|
|
1455
|
+
function classifyVisibility(title, detail) {
|
|
1456
|
+
const text = `${title} ${detail ?? ""}`;
|
|
1457
|
+
for (const pattern of PRIVATE_PATTERNS) {
|
|
1458
|
+
if (pattern.test(text)) return "private";
|
|
1459
|
+
}
|
|
1460
|
+
return "public";
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1418
1463
|
// src/cloud-sync.ts
|
|
1419
1464
|
var MAX_RETRIES = 3;
|
|
1420
1465
|
var RETRY_DELAYS = [1e3, 2e3, 4e3];
|
|
@@ -1435,7 +1480,26 @@ async function syncToCloud(db, payload) {
|
|
|
1435
1480
|
const filteredPayload = {};
|
|
1436
1481
|
if (cloud.sync?.memory !== false) {
|
|
1437
1482
|
filteredPayload.sessions = payload.sessions;
|
|
1438
|
-
|
|
1483
|
+
if (payload.observations) {
|
|
1484
|
+
let droppedPrivate = 0;
|
|
1485
|
+
filteredPayload.observations = payload.observations.filter((obs) => {
|
|
1486
|
+
if (classifyVisibility(obs.content ?? "", obs.content ?? "") === "private") {
|
|
1487
|
+
droppedPrivate += 1;
|
|
1488
|
+
return false;
|
|
1489
|
+
}
|
|
1490
|
+
if (obs.file_path && classifyVisibility(obs.file_path, obs.file_path) === "private") {
|
|
1491
|
+
droppedPrivate += 1;
|
|
1492
|
+
return false;
|
|
1493
|
+
}
|
|
1494
|
+
return true;
|
|
1495
|
+
});
|
|
1496
|
+
if (droppedPrivate > 0) {
|
|
1497
|
+
process.stderr.write(
|
|
1498
|
+
`[massu] cloud-sync: dropped ${droppedPrivate} private observation(s) (PRIVATE_PATTERNS match)
|
|
1499
|
+
`
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1439
1503
|
}
|
|
1440
1504
|
if (cloud.sync?.analytics !== false) {
|
|
1441
1505
|
filteredPayload.analytics = payload.analytics;
|
|
@@ -6496,7 +6496,7 @@ function initMemorySchema(db) {
|
|
|
6496
6496
|
response_tokens INTEGER,
|
|
6497
6497
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6498
6498
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
6499
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6499
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6500
6500
|
);
|
|
6501
6501
|
|
|
6502
6502
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -6517,7 +6517,7 @@ function initMemorySchema(db) {
|
|
|
6517
6517
|
files_involved TEXT,
|
|
6518
6518
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6519
6519
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
6520
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6520
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6521
6521
|
);
|
|
6522
6522
|
|
|
6523
6523
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -6571,7 +6571,7 @@ function initMemorySchema(db) {
|
|
|
6571
6571
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
6572
6572
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
6573
6573
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6574
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6574
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6575
6575
|
);
|
|
6576
6576
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
6577
6577
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -6591,7 +6591,7 @@ function initMemorySchema(db) {
|
|
|
6591
6591
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
6592
6592
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
6593
6593
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6594
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6594
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6595
6595
|
);
|
|
6596
6596
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
6597
6597
|
`);
|
|
@@ -6604,7 +6604,7 @@ function initMemorySchema(db) {
|
|
|
6604
6604
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
6605
6605
|
commit_hash TEXT,
|
|
6606
6606
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6607
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6607
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6608
6608
|
);
|
|
6609
6609
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
6610
6610
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -6621,7 +6621,7 @@ function initMemorySchema(db) {
|
|
|
6621
6621
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
6622
6622
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
6623
6623
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6624
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6624
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6625
6625
|
);
|
|
6626
6626
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
6627
6627
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -6640,7 +6640,7 @@ function initMemorySchema(db) {
|
|
|
6640
6640
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
6641
6641
|
evidence TEXT,
|
|
6642
6642
|
metadata TEXT,
|
|
6643
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6643
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6644
6644
|
);
|
|
6645
6645
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
6646
6646
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -6657,7 +6657,7 @@ function initMemorySchema(db) {
|
|
|
6657
6657
|
details TEXT,
|
|
6658
6658
|
rules_violated TEXT,
|
|
6659
6659
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6660
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6660
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6661
6661
|
);
|
|
6662
6662
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
6663
6663
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -6675,7 +6675,7 @@ function initMemorySchema(db) {
|
|
|
6675
6675
|
affected_files TEXT,
|
|
6676
6676
|
commit_hash TEXT,
|
|
6677
6677
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6678
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6678
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6679
6679
|
);
|
|
6680
6680
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
6681
6681
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -6688,7 +6688,7 @@ function initMemorySchema(db) {
|
|
|
6688
6688
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
6689
6689
|
findings TEXT,
|
|
6690
6690
|
created_at TEXT DEFAULT (datetime('now')),
|
|
6691
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
6691
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
6692
6692
|
);
|
|
6693
6693
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
6694
6694
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -698,7 +698,7 @@ function initMemorySchema(db) {
|
|
|
698
698
|
response_tokens INTEGER,
|
|
699
699
|
created_at TEXT DEFAULT (datetime('now')),
|
|
700
700
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
701
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
701
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
702
702
|
);
|
|
703
703
|
|
|
704
704
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -719,7 +719,7 @@ function initMemorySchema(db) {
|
|
|
719
719
|
files_involved TEXT,
|
|
720
720
|
created_at TEXT DEFAULT (datetime('now')),
|
|
721
721
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
722
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
722
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
723
723
|
);
|
|
724
724
|
|
|
725
725
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -773,7 +773,7 @@ function initMemorySchema(db) {
|
|
|
773
773
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
774
774
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
775
775
|
created_at TEXT DEFAULT (datetime('now')),
|
|
776
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
776
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
777
777
|
);
|
|
778
778
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
779
779
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -793,7 +793,7 @@ function initMemorySchema(db) {
|
|
|
793
793
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
794
794
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
795
795
|
created_at TEXT DEFAULT (datetime('now')),
|
|
796
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
796
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
797
797
|
);
|
|
798
798
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
799
799
|
`);
|
|
@@ -806,7 +806,7 @@ function initMemorySchema(db) {
|
|
|
806
806
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
807
807
|
commit_hash TEXT,
|
|
808
808
|
created_at TEXT DEFAULT (datetime('now')),
|
|
809
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
809
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
810
810
|
);
|
|
811
811
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
812
812
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -823,7 +823,7 @@ function initMemorySchema(db) {
|
|
|
823
823
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
824
824
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
825
825
|
created_at TEXT DEFAULT (datetime('now')),
|
|
826
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
826
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
827
827
|
);
|
|
828
828
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
829
829
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -842,7 +842,7 @@ function initMemorySchema(db) {
|
|
|
842
842
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
843
843
|
evidence TEXT,
|
|
844
844
|
metadata TEXT,
|
|
845
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
845
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
846
846
|
);
|
|
847
847
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
848
848
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -859,7 +859,7 @@ function initMemorySchema(db) {
|
|
|
859
859
|
details TEXT,
|
|
860
860
|
rules_violated TEXT,
|
|
861
861
|
created_at TEXT DEFAULT (datetime('now')),
|
|
862
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
862
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
863
863
|
);
|
|
864
864
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
865
865
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -877,7 +877,7 @@ function initMemorySchema(db) {
|
|
|
877
877
|
affected_files TEXT,
|
|
878
878
|
commit_hash TEXT,
|
|
879
879
|
created_at TEXT DEFAULT (datetime('now')),
|
|
880
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
880
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
881
881
|
);
|
|
882
882
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
883
883
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -890,7 +890,7 @@ function initMemorySchema(db) {
|
|
|
890
890
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
891
891
|
findings TEXT,
|
|
892
892
|
created_at TEXT DEFAULT (datetime('now')),
|
|
893
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
893
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
894
894
|
);
|
|
895
895
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
896
896
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massu/core",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI Engineering Governance MCP Server - Session memory, knowledge system, feature registry, code intelligence, rule enforcement, tiered tooling (12 free / 73 total), 59 workflow commands, 11 agents, 20+ patterns",
|
|
6
6
|
"main": "src/server.ts",
|
package/src/cloud-sync.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
removePendingSync,
|
|
10
10
|
incrementRetryCount,
|
|
11
11
|
} from './memory-db.ts';
|
|
12
|
+
import { classifyVisibility } from './observation-extractor.ts';
|
|
12
13
|
|
|
13
14
|
// ============================================================
|
|
14
15
|
// Cloud Sync Module
|
|
@@ -98,7 +99,32 @@ export async function syncToCloud(
|
|
|
98
99
|
const filteredPayload: SyncPayload = {};
|
|
99
100
|
if (cloud.sync?.memory !== false) {
|
|
100
101
|
filteredPayload.sessions = payload.sessions;
|
|
101
|
-
|
|
102
|
+
// P-H020 (plan-stage-c-high-batch): consume classifyVisibility() to drop
|
|
103
|
+
// observations whose title/detail matches PRIVATE_PATTERNS (Stripe keys,
|
|
104
|
+
// env var names, file paths, Bearer tokens, etc.). Pre-fix: cloud-sync
|
|
105
|
+
// transmitted EVERY observation to Massu's Supabase, leaking customer
|
|
106
|
+
// secrets and absolute file paths.
|
|
107
|
+
if (payload.observations) {
|
|
108
|
+
let droppedPrivate = 0;
|
|
109
|
+
filteredPayload.observations = payload.observations.filter((obs) => {
|
|
110
|
+
if (classifyVisibility(obs.content ?? '', obs.content ?? '') === 'private') {
|
|
111
|
+
droppedPrivate += 1;
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
// Belt-and-suspenders: also drop if file_path matches private patterns.
|
|
115
|
+
if (obs.file_path && classifyVisibility(obs.file_path, obs.file_path) === 'private') {
|
|
116
|
+
droppedPrivate += 1;
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
});
|
|
121
|
+
if (droppedPrivate > 0) {
|
|
122
|
+
// Surface to the customer's stderr so they can audit what got filtered.
|
|
123
|
+
process.stderr.write(
|
|
124
|
+
`[massu] cloud-sync: dropped ${droppedPrivate} private observation(s) (PRIVATE_PATTERNS match)\n`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
102
128
|
}
|
|
103
129
|
if (cloud.sync?.analytics !== false) {
|
|
104
130
|
filteredPayload.analytics = payload.analytics;
|
package/src/knowledge-db.ts
CHANGED
|
@@ -104,12 +104,19 @@ export function initKnowledgeSchema(db: Database.Database): void {
|
|
|
104
104
|
CREATE INDEX IF NOT EXISTS idx_ki_cr ON knowledge_incidents(cr_added);
|
|
105
105
|
|
|
106
106
|
-- Schema mismatch quick lookup
|
|
107
|
+
-- P-H013 (plan-stage-c-high-batch): the source column no longer has a
|
|
108
|
+
-- SQL DEFAULT. Previously the value was a JS template-literal
|
|
109
|
+
-- interpolation baked into the customer SQLite at schema creation
|
|
110
|
+
-- time, so later config changes were ignored. Default is now applied
|
|
111
|
+
-- at INSERT time via getConfig().conventions.knowledgeSourceFiles[0]
|
|
112
|
+
-- in knowledge-indexer.ts -- a runtime config lookup that reflects
|
|
113
|
+
-- the customers current config.
|
|
107
114
|
CREATE TABLE IF NOT EXISTS knowledge_schema_mismatches (
|
|
108
115
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
109
116
|
table_name TEXT NOT NULL,
|
|
110
117
|
wrong_column TEXT NOT NULL,
|
|
111
118
|
correct_column TEXT NOT NULL,
|
|
112
|
-
source TEXT
|
|
119
|
+
source TEXT NOT NULL
|
|
113
120
|
);
|
|
114
121
|
|
|
115
122
|
CREATE INDEX IF NOT EXISTS idx_ksm_table ON knowledge_schema_mismatches(table_name);
|
package/src/knowledge-indexer.ts
CHANGED
|
@@ -440,9 +440,13 @@ export function indexAllKnowledge(db: Database.Database): IndexStats {
|
|
|
440
440
|
const insertIncident = db.prepare(
|
|
441
441
|
'INSERT OR IGNORE INTO knowledge_incidents (incident_num, date, type, gap_found, prevention) VALUES (?, ?, ?, ?, ?)'
|
|
442
442
|
);
|
|
443
|
+
// P-H013 (plan-stage-c-high-batch): source column now bound at insert time
|
|
444
|
+
// (was a SQL-DEFAULT template-literal interpolation baked into the customer's
|
|
445
|
+
// SQLite at schema creation time, ignoring later config changes).
|
|
443
446
|
const insertMismatch = db.prepare(
|
|
444
|
-
'INSERT INTO knowledge_schema_mismatches (table_name, wrong_column, correct_column) VALUES (?, ?, ?)'
|
|
447
|
+
'INSERT INTO knowledge_schema_mismatches (table_name, wrong_column, correct_column, source) VALUES (?, ?, ?, ?)'
|
|
445
448
|
);
|
|
449
|
+
const defaultSource = getConfig().conventions?.knowledgeSourceFiles?.[0] ?? 'CLAUDE.md';
|
|
446
450
|
|
|
447
451
|
// Discover all .claude/ markdown files
|
|
448
452
|
const files = discoverMarkdownFiles(paths.claudeDir);
|
|
@@ -567,7 +571,7 @@ export function indexAllKnowledge(db: Database.Database): IndexStats {
|
|
|
567
571
|
// Extract schema mismatches
|
|
568
572
|
const mismatches = parseSchemaMismatches(content);
|
|
569
573
|
for (const m of mismatches) {
|
|
570
|
-
insertMismatch.run(m.table_name, m.wrong_column, m.correct_column);
|
|
574
|
+
insertMismatch.run(m.table_name, m.wrong_column, m.correct_column, defaultSource);
|
|
571
575
|
insertChunk.run(docId, 'mismatch', m.table_name, `${m.table_name}: ${m.wrong_column} -> ${m.correct_column}`, null, null, JSON.stringify({ table: m.table_name }));
|
|
572
576
|
stats.chunksCreated++;
|
|
573
577
|
}
|
package/src/memory-db.ts
CHANGED
|
@@ -214,7 +214,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
214
214
|
response_tokens INTEGER,
|
|
215
215
|
created_at TEXT DEFAULT (datetime('now')),
|
|
216
216
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
217
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
217
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
218
218
|
);
|
|
219
219
|
|
|
220
220
|
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
@@ -237,7 +237,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
237
237
|
files_involved TEXT,
|
|
238
238
|
created_at TEXT DEFAULT (datetime('now')),
|
|
239
239
|
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
240
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
240
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
241
241
|
);
|
|
242
242
|
|
|
243
243
|
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
@@ -302,7 +302,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
302
302
|
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
303
303
|
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
304
304
|
created_at TEXT DEFAULT (datetime('now')),
|
|
305
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
305
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
306
306
|
);
|
|
307
307
|
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
308
308
|
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
@@ -324,7 +324,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
324
324
|
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
325
325
|
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
326
326
|
created_at TEXT DEFAULT (datetime('now')),
|
|
327
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
327
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
328
328
|
);
|
|
329
329
|
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
330
330
|
`);
|
|
@@ -339,7 +339,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
339
339
|
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
340
340
|
commit_hash TEXT,
|
|
341
341
|
created_at TEXT DEFAULT (datetime('now')),
|
|
342
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
342
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
343
343
|
);
|
|
344
344
|
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
345
345
|
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
@@ -358,7 +358,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
358
358
|
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
359
359
|
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
360
360
|
created_at TEXT DEFAULT (datetime('now')),
|
|
361
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
361
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
362
362
|
);
|
|
363
363
|
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
364
364
|
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
@@ -379,7 +379,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
379
379
|
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
380
380
|
evidence TEXT,
|
|
381
381
|
metadata TEXT,
|
|
382
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
382
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
383
383
|
);
|
|
384
384
|
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
385
385
|
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
@@ -398,7 +398,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
398
398
|
details TEXT,
|
|
399
399
|
rules_violated TEXT,
|
|
400
400
|
created_at TEXT DEFAULT (datetime('now')),
|
|
401
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
401
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
402
402
|
);
|
|
403
403
|
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
404
404
|
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
@@ -418,7 +418,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
418
418
|
affected_files TEXT,
|
|
419
419
|
commit_hash TEXT,
|
|
420
420
|
created_at TEXT DEFAULT (datetime('now')),
|
|
421
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
421
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
422
422
|
);
|
|
423
423
|
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
424
424
|
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
@@ -433,7 +433,7 @@ export function initMemorySchema(db: Database.Database): void {
|
|
|
433
433
|
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
434
434
|
findings TEXT,
|
|
435
435
|
created_at TEXT DEFAULT (datetime('now')),
|
|
436
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
436
|
+
FOREIGN KEY (session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
437
437
|
);
|
|
438
438
|
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
439
439
|
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
@@ -625,7 +625,13 @@ export function enqueueSyncPayload(db: Database.Database, payload: string): void
|
|
|
625
625
|
|
|
626
626
|
/**
|
|
627
627
|
* Dequeue pending sync items (oldest first).
|
|
628
|
-
*
|
|
628
|
+
*
|
|
629
|
+
* P-H012 (plan-stage-c-high-batch): when items exceed retry_count >= 10
|
|
630
|
+
* they are discarded — but the discard now emits a stderr warning AND
|
|
631
|
+
* inserts an analytics_events telemetry row so the customer can detect
|
|
632
|
+
* silent cloud-sync failure (e.g., invalid API key for >10 sync cycles).
|
|
633
|
+
* Previously this was a silent DELETE; customers lost all queued
|
|
634
|
+
* observations with no visibility.
|
|
629
635
|
*/
|
|
630
636
|
export function dequeuePendingSync(
|
|
631
637
|
db: Database.Database,
|
|
@@ -633,11 +639,34 @@ export function dequeuePendingSync(
|
|
|
633
639
|
): Array<{ id: number; payload: string; retry_count: number }> {
|
|
634
640
|
// First, discard items that have exceeded max retries
|
|
635
641
|
const stale = db.prepare(
|
|
636
|
-
'SELECT id FROM pending_sync WHERE retry_count >= 10'
|
|
637
|
-
).all() as Array<{ id: number }>;
|
|
642
|
+
'SELECT id, retry_count, last_error FROM pending_sync WHERE retry_count >= 10'
|
|
643
|
+
).all() as Array<{ id: number; retry_count: number; last_error: string | null }>;
|
|
638
644
|
if (stale.length > 0) {
|
|
639
645
|
const ids = stale.map(s => s.id);
|
|
640
646
|
db.prepare(`DELETE FROM pending_sync WHERE id IN (${ids.map(() => '?').join(',')})`).run(...ids);
|
|
647
|
+
// P-H012: stderr warning so the customer's terminal sees what happened.
|
|
648
|
+
const lastErrors = [...new Set(stale.map(s => s.last_error).filter(Boolean))];
|
|
649
|
+
process.stderr.write(
|
|
650
|
+
`[massu] WARNING: ${stale.length} cloud-sync queue item(s) discarded after 10+ retries. ` +
|
|
651
|
+
`Likely cause: invalid API key or unreachable endpoint. ` +
|
|
652
|
+
`Recent errors: ${lastErrors.slice(0, 3).join('; ') || '(none recorded)'}\n`,
|
|
653
|
+
);
|
|
654
|
+
// P-H012: telemetry event for dashboard surfacing. Use the analytics_events
|
|
655
|
+
// sink that already exists in memory-db (see addObservation pattern).
|
|
656
|
+
try {
|
|
657
|
+
db.prepare(`
|
|
658
|
+
INSERT INTO analytics_events (event_type, event_data, created_at)
|
|
659
|
+
VALUES (?, ?, datetime('now'))
|
|
660
|
+
`).run(
|
|
661
|
+
'cloud_sync_giveup',
|
|
662
|
+
JSON.stringify({
|
|
663
|
+
discarded_count: stale.length,
|
|
664
|
+
recent_errors: lastErrors.slice(0, 3),
|
|
665
|
+
}),
|
|
666
|
+
);
|
|
667
|
+
} catch {
|
|
668
|
+
// analytics_events may not exist in older schemas — best-effort.
|
|
669
|
+
}
|
|
641
670
|
}
|
|
642
671
|
|
|
643
672
|
return db.prepare(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// AUTO-GENERATED by scripts/bundle-pubkey.mjs at 2026-05-17T05:
|
|
1
|
+
// AUTO-GENERATED by scripts/bundle-pubkey.mjs at 2026-05-17T05:30:32.527Z.
|
|
2
2
|
// Source pem: packages/core/security/registry-pubkey.pem
|
|
3
3
|
// RAW-bytes sha256: 3b6226d036c472e533110d11a7d0cd2773ce1d7d4f1003517d5bd69c5418ed4c
|
|
4
4
|
// DO NOT EDIT — regenerate via `node scripts/bundle-pubkey.mjs` or
|