@triedotdev/mcp 1.0.165 → 1.0.167
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/README.md +337 -801
- package/dist/chunk-2HF65EHQ.js +311 -0
- package/dist/chunk-2HF65EHQ.js.map +1 -0
- package/dist/{chunk-M7HMBZ3R.js → chunk-4MXH2ZPT.js} +12 -12
- package/dist/chunk-4MXH2ZPT.js.map +1 -0
- package/dist/{chunk-LR5M4RTN.js → chunk-575YT2SD.js} +1 -1
- package/dist/chunk-575YT2SD.js.map +1 -0
- package/dist/{chunk-HC5P6FZD.js → chunk-5BRRRTN6.js} +4 -4
- package/dist/{chunk-IPNPHPNN.js → chunk-7WITSO22.js} +3 -3
- package/dist/{chunk-ACU2RJUJ.js → chunk-F6WFNUAY.js} +2 -2
- package/dist/{chunk-VR4VWXXU.js → chunk-G2TGF6TR.js} +9 -2
- package/dist/chunk-G2TGF6TR.js.map +1 -0
- package/dist/{chunk-ZBXW244P.js → chunk-HVCDY3AK.js} +3 -3
- package/dist/chunk-HVCDY3AK.js.map +1 -0
- package/dist/{chunk-CDG2GVBP.js → chunk-LQIMKE3P.js} +700 -151
- package/dist/chunk-LQIMKE3P.js.map +1 -0
- package/dist/{chunk-RQ6QZBIN.js → chunk-MRHKX5M5.js} +3 -3
- package/dist/{chunk-OLNZJ3XV.js → chunk-Q63FFI6D.js} +2 -2
- package/dist/{chunk-SS2O3MTC.js → chunk-XE6KQRKZ.js} +9 -8
- package/dist/chunk-XE6KQRKZ.js.map +1 -0
- package/dist/{chunk-GDWA3CH3.js → chunk-XPZZFPBZ.js} +30 -6
- package/dist/chunk-XPZZFPBZ.js.map +1 -0
- package/dist/{chunk-WRYQHVPD.js → chunk-XTFWT2XM.js} +2 -2
- package/dist/{chunk-IS5UBN2R.js → chunk-YDHUCDHM.js} +18 -112
- package/dist/chunk-YDHUCDHM.js.map +1 -0
- package/dist/{chunk-5LRDF2WB.js → chunk-YZ6Y2H3P.js} +21 -196
- package/dist/chunk-YZ6Y2H3P.js.map +1 -0
- package/dist/{chunk-YAL3SUBG.js → chunk-ZJF5FTBX.js} +126 -355
- package/dist/chunk-ZJF5FTBX.js.map +1 -0
- package/dist/cli/create-agent.js +1 -1
- package/dist/cli/create-agent.js.map +1 -1
- package/dist/cli/main.js +194 -849
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +15 -14
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{fast-analyzer-54AHLVO5.js → fast-analyzer-XXYMOXRK.js} +3 -3
- package/dist/git-EO5SRFMN.js +28 -0
- package/dist/{github-ingester-TFBDUDIY.js → github-ingester-ZOKK6GRS.js} +3 -3
- package/dist/{goal-manager-563BNILQ.js → goal-manager-YOB7VWK7.js} +5 -4
- package/dist/{goal-validator-FJEDIYU7.js → goal-validator-ULKIBDPX.js} +5 -4
- package/dist/{hypothesis-4KC7XRBZ.js → hypothesis-7BFFT5JY.js} +5 -4
- package/dist/index.js +19 -18
- package/dist/index.js.map +1 -1
- package/dist/{issue-store-FOS4T736.js → issue-store-ZIRP23EP.js} +4 -3
- package/dist/{ledger-EDLPF6SB.js → ledger-TWZTGDFA.js} +3 -2
- package/dist/{linear-ingester-PLES2BRS.js → linear-ingester-XXPAZZRW.js} +3 -3
- package/dist/{output-manager-JNMEAXFO.js → output-manager-RVJ37XKA.js} +2 -2
- package/dist/server/mcp-server.js +19 -18
- package/dist/{tiered-storage-OP74NPJY.js → tiered-storage-Z3YCR465.js} +2 -2
- package/dist/{trie-agent-TM6ATSNR.js → trie-agent-3YDPEGHJ.js} +9 -8
- package/dist/trie-agent-3YDPEGHJ.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-5LRDF2WB.js.map +0 -1
- package/dist/chunk-CDG2GVBP.js.map +0 -1
- package/dist/chunk-GDWA3CH3.js.map +0 -1
- package/dist/chunk-IS5UBN2R.js.map +0 -1
- package/dist/chunk-LR5M4RTN.js.map +0 -1
- package/dist/chunk-M7HMBZ3R.js.map +0 -1
- package/dist/chunk-SS2O3MTC.js.map +0 -1
- package/dist/chunk-VR4VWXXU.js.map +0 -1
- package/dist/chunk-YAL3SUBG.js.map +0 -1
- package/dist/chunk-ZBXW244P.js.map +0 -1
- /package/dist/{chunk-HC5P6FZD.js.map → chunk-5BRRRTN6.js.map} +0 -0
- /package/dist/{chunk-IPNPHPNN.js.map → chunk-7WITSO22.js.map} +0 -0
- /package/dist/{chunk-ACU2RJUJ.js.map → chunk-F6WFNUAY.js.map} +0 -0
- /package/dist/{chunk-RQ6QZBIN.js.map → chunk-MRHKX5M5.js.map} +0 -0
- /package/dist/{chunk-OLNZJ3XV.js.map → chunk-Q63FFI6D.js.map} +0 -0
- /package/dist/{chunk-WRYQHVPD.js.map → chunk-XTFWT2XM.js.map} +0 -0
- /package/dist/{fast-analyzer-54AHLVO5.js.map → fast-analyzer-XXYMOXRK.js.map} +0 -0
- /package/dist/{github-ingester-TFBDUDIY.js.map → git-EO5SRFMN.js.map} +0 -0
- /package/dist/{goal-manager-563BNILQ.js.map → github-ingester-ZOKK6GRS.js.map} +0 -0
- /package/dist/{goal-validator-FJEDIYU7.js.map → goal-manager-YOB7VWK7.js.map} +0 -0
- /package/dist/{hypothesis-4KC7XRBZ.js.map → goal-validator-ULKIBDPX.js.map} +0 -0
- /package/dist/{issue-store-FOS4T736.js.map → hypothesis-7BFFT5JY.js.map} +0 -0
- /package/dist/{ledger-EDLPF6SB.js.map → issue-store-ZIRP23EP.js.map} +0 -0
- /package/dist/{linear-ingester-PLES2BRS.js.map → ledger-TWZTGDFA.js.map} +0 -0
- /package/dist/{output-manager-JNMEAXFO.js.map → linear-ingester-XXPAZZRW.js.map} +0 -0
- /package/dist/{tiered-storage-OP74NPJY.js.map → output-manager-RVJ37XKA.js.map} +0 -0
- /package/dist/{trie-agent-TM6ATSNR.js.map → tiered-storage-Z3YCR465.js.map} +0 -0
|
@@ -1,54 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CodebaseIndex
|
|
3
|
+
} from "./chunk-Q5EKA5YA.js";
|
|
1
4
|
import {
|
|
2
5
|
getChatStore
|
|
3
6
|
} from "./chunk-JVMBCWKS.js";
|
|
4
7
|
import {
|
|
5
8
|
getTrieAgent
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-4MXH2ZPT.js";
|
|
7
10
|
import {
|
|
8
11
|
parseGoalViolation
|
|
9
12
|
} from "./chunk-WCN7S3EI.js";
|
|
10
|
-
import {
|
|
11
|
-
CodebaseIndex
|
|
12
|
-
} from "./chunk-Q5EKA5YA.js";
|
|
13
13
|
import {
|
|
14
14
|
getOutputManager
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-G2TGF6TR.js";
|
|
16
16
|
import {
|
|
17
17
|
getInsightStore
|
|
18
18
|
} from "./chunk-T63OHG4Q.js";
|
|
19
19
|
import {
|
|
20
20
|
LearningEngine,
|
|
21
21
|
formatFriendlyError,
|
|
22
|
-
getLastCheckpoint,
|
|
23
22
|
isTrieInitialized,
|
|
24
|
-
listCheckpoints,
|
|
25
23
|
perceiveCurrentChanges,
|
|
26
|
-
reasonAboutChangesHumanReadable
|
|
27
|
-
|
|
28
|
-
} from "./chunk-5LRDF2WB.js";
|
|
24
|
+
reasonAboutChangesHumanReadable
|
|
25
|
+
} from "./chunk-YZ6Y2H3P.js";
|
|
29
26
|
import {
|
|
30
27
|
measureInitialGoalValue
|
|
31
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-5BRRRTN6.js";
|
|
32
29
|
import {
|
|
33
30
|
exportToJson
|
|
34
31
|
} from "./chunk-OBQ74FOU.js";
|
|
35
32
|
import {
|
|
36
33
|
loadConfig,
|
|
37
34
|
saveConfig
|
|
38
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-XPZZFPBZ.js";
|
|
39
36
|
import {
|
|
40
37
|
IncidentIndex
|
|
41
38
|
} from "./chunk-TN5WEKWI.js";
|
|
42
39
|
import {
|
|
43
40
|
findCrossProjectPatterns
|
|
44
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-7WITSO22.js";
|
|
45
42
|
import {
|
|
46
43
|
ContextGraph
|
|
47
44
|
} from "./chunk-VUL52BQL.js";
|
|
48
45
|
import {
|
|
49
46
|
TieredStorage,
|
|
50
47
|
getStorage
|
|
51
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-575YT2SD.js";
|
|
52
49
|
import {
|
|
53
50
|
getKeyFromKeychain,
|
|
54
51
|
isAIAvailable,
|
|
@@ -57,25 +54,27 @@ import {
|
|
|
57
54
|
setAPIKey
|
|
58
55
|
} from "./chunk-FQ45QP5A.js";
|
|
59
56
|
import {
|
|
57
|
+
getRecentIssues,
|
|
60
58
|
storeIssues
|
|
61
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-XE6KQRKZ.js";
|
|
60
|
+
import {
|
|
61
|
+
generateKeyPair,
|
|
62
|
+
getLedgerBlocks,
|
|
63
|
+
getPublicKey,
|
|
64
|
+
hasSigningKey,
|
|
65
|
+
saveKeyPair
|
|
66
|
+
} from "./chunk-ZJF5FTBX.js";
|
|
62
67
|
import {
|
|
63
68
|
getProjectState
|
|
64
69
|
} from "./chunk-GTKYBOXL.js";
|
|
70
|
+
import {
|
|
71
|
+
atomicWriteJSON
|
|
72
|
+
} from "./chunk-43X6JBEM.js";
|
|
65
73
|
import {
|
|
66
74
|
getAutonomyConfig,
|
|
67
75
|
loadAutonomyConfig,
|
|
68
76
|
saveAutonomyConfig
|
|
69
77
|
} from "./chunk-ME2OERF5.js";
|
|
70
|
-
import {
|
|
71
|
-
generateKeyPair,
|
|
72
|
-
getChangedFilesSinceTimestamp,
|
|
73
|
-
getGitChangedFiles,
|
|
74
|
-
getLedgerBlocks,
|
|
75
|
-
getPublicKey,
|
|
76
|
-
hasSigningKey,
|
|
77
|
-
saveKeyPair
|
|
78
|
-
} from "./chunk-YAL3SUBG.js";
|
|
79
78
|
import {
|
|
80
79
|
getTrieDirectory,
|
|
81
80
|
getWorkingDirectory
|
|
@@ -83,6 +82,10 @@ import {
|
|
|
83
82
|
import {
|
|
84
83
|
isInteractiveMode
|
|
85
84
|
} from "./chunk-KDHN2ZQE.js";
|
|
85
|
+
import {
|
|
86
|
+
getChangedFilesSinceTimestamp,
|
|
87
|
+
getGitChangedFiles
|
|
88
|
+
} from "./chunk-2HF65EHQ.js";
|
|
86
89
|
|
|
87
90
|
// src/utils/streaming.ts
|
|
88
91
|
var shouldSuppressConsole = () => isInteractiveMode();
|
|
@@ -2060,7 +2063,7 @@ function AgentView() {
|
|
|
2060
2063
|
const { getInsightStore: getInsightStore2 } = await import("./insight-store-EC4PLSAW.js");
|
|
2061
2064
|
const store = getInsightStore2(workDir);
|
|
2062
2065
|
await store.dismissInsight(insight.id);
|
|
2063
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
2066
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-Z3YCR465.js");
|
|
2064
2067
|
const storage = getStorage2(workDir);
|
|
2065
2068
|
await storage.dismissNudge(insight.id).catch(() => {
|
|
2066
2069
|
});
|
|
@@ -2072,7 +2075,7 @@ function AgentView() {
|
|
|
2072
2075
|
const clearAllNudges = useCallback(async () => {
|
|
2073
2076
|
try {
|
|
2074
2077
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2075
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
2078
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-Z3YCR465.js");
|
|
2076
2079
|
const storage = getStorage2(workDir);
|
|
2077
2080
|
await storage.clearAllNudges();
|
|
2078
2081
|
dispatch({ type: "CLEAR_ALL_INSIGHTS" });
|
|
@@ -2446,7 +2449,7 @@ function GoalsView() {
|
|
|
2446
2449
|
dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Starting scan..." });
|
|
2447
2450
|
dispatch({ type: "ADD_ACTIVITY", message: `Scanning goal: ${goalSummary.description}...` });
|
|
2448
2451
|
dispatch({ type: "SET_GOAL_SCANNING", goalId, progress: "Loading goal configuration..." });
|
|
2449
|
-
const { checkFilesForGoalViolations } = await import("./goal-validator-
|
|
2452
|
+
const { checkFilesForGoalViolations } = await import("./goal-validator-ULKIBDPX.js");
|
|
2450
2453
|
const agentState = getProjectState(workDir);
|
|
2451
2454
|
await agentState.load();
|
|
2452
2455
|
const fullGoal = agentState.getAllGoals().find((g) => g.id === goalId);
|
|
@@ -2721,7 +2724,7 @@ function HypothesesView() {
|
|
|
2721
2724
|
dispatch({ type: "SET_HYPOTHESIS_SCANNING", hypothesisId: hypoId, progress: "Gathering evidence..." });
|
|
2722
2725
|
dispatch({ type: "ADD_ACTIVITY", message: `Testing hypothesis: ${hypo.statement}` });
|
|
2723
2726
|
dispatch({ type: "SHOW_NOTIFICATION", message: `Gathering evidence for hypothesis...`, severity: "info", autoHideMs: 3e3 });
|
|
2724
|
-
const { gatherEvidenceForHypothesis } = await import("./hypothesis-
|
|
2727
|
+
const { gatherEvidenceForHypothesis } = await import("./hypothesis-7BFFT5JY.js");
|
|
2725
2728
|
const evidence = await gatherEvidenceForHypothesis(hypoId, workDir, signal);
|
|
2726
2729
|
scanAbortRef.current = null;
|
|
2727
2730
|
dispatch({ type: "SET_HYPOTHESIS_SCANNING", hypothesisId: null, progress: "" });
|
|
@@ -6477,7 +6480,7 @@ ${"\u2501".repeat(60)}
|
|
|
6477
6480
|
|
|
6478
6481
|
`;
|
|
6479
6482
|
if (pendingFixes.size === 0) {
|
|
6480
|
-
output += `No pending fixes. Run \`
|
|
6483
|
+
output += `No pending fixes. Run \`trie watch\` or \`trie check\` first to detect issues.
|
|
6481
6484
|
`;
|
|
6482
6485
|
return { content: [{ type: "text", text: output }] };
|
|
6483
6486
|
}
|
|
@@ -6602,9 +6605,9 @@ function getPendingFixes() {
|
|
|
6602
6605
|
}
|
|
6603
6606
|
async function loadPendingFixesFromMemory() {
|
|
6604
6607
|
try {
|
|
6605
|
-
const { getRecentIssues } = await import("./issue-store-
|
|
6608
|
+
const { getRecentIssues: getRecentIssues2 } = await import("./issue-store-ZIRP23EP.js");
|
|
6606
6609
|
pendingFixes.clear();
|
|
6607
|
-
const recentIssues = await
|
|
6610
|
+
const recentIssues = await getRecentIssues2({ limit: 50, includeResolved: false });
|
|
6608
6611
|
for (const storedIssue of recentIssues) {
|
|
6609
6612
|
const fix = {
|
|
6610
6613
|
id: storedIssue.id,
|
|
@@ -6905,8 +6908,8 @@ var TrieCloudFixTool = class {
|
|
|
6905
6908
|
if (pending.length === 0) {
|
|
6906
6909
|
try {
|
|
6907
6910
|
console.log("Loading issues from memory...");
|
|
6908
|
-
const { getRecentIssues } = await import("./issue-store-
|
|
6909
|
-
const recentIssues = await
|
|
6911
|
+
const { getRecentIssues: getRecentIssues2 } = await import("./issue-store-ZIRP23EP.js");
|
|
6912
|
+
const recentIssues = await getRecentIssues2({ limit: 50, includeResolved: false });
|
|
6910
6913
|
console.log(`Found ${recentIssues.length} recent issues in memory`);
|
|
6911
6914
|
const memoryIssues = recentIssues.map((storedIssue) => ({
|
|
6912
6915
|
id: storedIssue.id,
|
|
@@ -7211,7 +7214,7 @@ var TrieGetNudgesTool = class {
|
|
|
7211
7214
|
return {
|
|
7212
7215
|
content: [{
|
|
7213
7216
|
type: "text",
|
|
7214
|
-
text: "No unresolved nudges (goal violations) found. Run trie
|
|
7217
|
+
text: "No unresolved nudges (goal violations) found. Run `trie watch` to detect issues as you code."
|
|
7215
7218
|
}]
|
|
7216
7219
|
};
|
|
7217
7220
|
}
|
|
@@ -7505,64 +7508,6 @@ var TrieQueryLedgerBlocksTool = class {
|
|
|
7505
7508
|
}
|
|
7506
7509
|
};
|
|
7507
7510
|
|
|
7508
|
-
// src/tools/checkpoint.ts
|
|
7509
|
-
async function handleCheckpointTool(input) {
|
|
7510
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
7511
|
-
switch (input.action) {
|
|
7512
|
-
case "save": {
|
|
7513
|
-
const saveOptions = {
|
|
7514
|
-
files: input.files || [],
|
|
7515
|
-
workDir,
|
|
7516
|
-
createdBy: "mcp"
|
|
7517
|
-
};
|
|
7518
|
-
if (input.message !== void 0) {
|
|
7519
|
-
saveOptions.message = input.message;
|
|
7520
|
-
}
|
|
7521
|
-
if (input.notes !== void 0) {
|
|
7522
|
-
saveOptions.notes = input.notes;
|
|
7523
|
-
}
|
|
7524
|
-
const checkpoint = await saveCheckpoint(saveOptions);
|
|
7525
|
-
return `# Checkpoint Saved
|
|
7526
|
-
|
|
7527
|
-
**ID:** ${checkpoint.id}
|
|
7528
|
-
**Time:** ${checkpoint.timestamp}
|
|
7529
|
-
${checkpoint.message ? `**Message:** ${checkpoint.message}` : ""}
|
|
7530
|
-
${checkpoint.notes ? `**Notes:** ${checkpoint.notes}` : ""}
|
|
7531
|
-
${checkpoint.files.length > 0 ? `**Files:** ${checkpoint.files.join(", ")}` : ""}
|
|
7532
|
-
|
|
7533
|
-
Context saved to \`.trie/\`. This checkpoint will be visible in other tools (Cursor, Claude Code, CLI).`;
|
|
7534
|
-
}
|
|
7535
|
-
case "list": {
|
|
7536
|
-
const checkpoints = await listCheckpoints(workDir);
|
|
7537
|
-
if (checkpoints.length === 0) {
|
|
7538
|
-
return 'No checkpoints yet. Use `trie_checkpoint action="save"` to create one.';
|
|
7539
|
-
}
|
|
7540
|
-
const lines = ["# Recent Checkpoints", ""];
|
|
7541
|
-
for (const cp of checkpoints.slice(-10).reverse()) {
|
|
7542
|
-
const date = new Date(cp.timestamp).toLocaleString();
|
|
7543
|
-
lines.push(`- **${cp.id}** (${date}): ${cp.message || "(no message)"}`);
|
|
7544
|
-
}
|
|
7545
|
-
return lines.join("\n");
|
|
7546
|
-
}
|
|
7547
|
-
case "last": {
|
|
7548
|
-
const checkpoint = await getLastCheckpoint(workDir);
|
|
7549
|
-
if (!checkpoint) {
|
|
7550
|
-
return 'No checkpoints yet. Use `trie_checkpoint action="save"` to create one.';
|
|
7551
|
-
}
|
|
7552
|
-
return `# Last Checkpoint
|
|
7553
|
-
|
|
7554
|
-
**ID:** ${checkpoint.id}
|
|
7555
|
-
**Time:** ${new Date(checkpoint.timestamp).toLocaleString()}
|
|
7556
|
-
${checkpoint.message ? `**Message:** ${checkpoint.message}` : ""}
|
|
7557
|
-
${checkpoint.notes ? `**Notes:** ${checkpoint.notes}` : ""}
|
|
7558
|
-
${checkpoint.files.length > 0 ? `**Files:** ${checkpoint.files.join(", ")}` : ""}
|
|
7559
|
-
**Created by:** ${checkpoint.createdBy}`;
|
|
7560
|
-
}
|
|
7561
|
-
default:
|
|
7562
|
-
return "Unknown action. Use: save, list, or last";
|
|
7563
|
-
}
|
|
7564
|
-
}
|
|
7565
|
-
|
|
7566
7511
|
// src/tools/pipeline.ts
|
|
7567
7512
|
var TriePipelineTool = class {
|
|
7568
7513
|
async execute(input) {
|
|
@@ -8245,7 +8190,7 @@ var CHAT_TOOLS = [
|
|
|
8245
8190
|
},
|
|
8246
8191
|
{
|
|
8247
8192
|
name: "trie_get_pipeline",
|
|
8248
|
-
description: "Get current pipeline status: open PRs, active Linear tickets, open GitHub issues, and Trie
|
|
8193
|
+
description: "Get current pipeline status: open PRs, active Linear tickets, open GitHub issues, and Trie issues not yet tracked in any ticket or PR. Use when the user asks about the status of work, what PRs are open, or what tickets are in progress.",
|
|
8249
8194
|
input_schema: {
|
|
8250
8195
|
type: "object",
|
|
8251
8196
|
properties: {
|
|
@@ -8258,20 +8203,6 @@ var CHAT_TOOLS = [
|
|
|
8258
8203
|
}
|
|
8259
8204
|
}
|
|
8260
8205
|
},
|
|
8261
|
-
{
|
|
8262
|
-
name: "trie_checkpoint",
|
|
8263
|
-
description: "Save a work checkpoint, list recent checkpoints, or get the last one.",
|
|
8264
|
-
input_schema: {
|
|
8265
|
-
type: "object",
|
|
8266
|
-
properties: {
|
|
8267
|
-
action: { type: "string", enum: ["save", "list", "last"], description: "What to do" },
|
|
8268
|
-
message: { type: "string", description: "Checkpoint message (for save)" },
|
|
8269
|
-
notes: { type: "string", description: "Additional notes (for save)" },
|
|
8270
|
-
files: { type: "array", items: { type: "string" }, description: "Files to associate (for save)" }
|
|
8271
|
-
},
|
|
8272
|
-
required: ["action"]
|
|
8273
|
-
}
|
|
8274
|
-
},
|
|
8275
8206
|
{
|
|
8276
8207
|
name: "trie_add_goal",
|
|
8277
8208
|
description: "Create a new goal for the user to track. Use when the user asks to set, add, or create a goal.",
|
|
@@ -8518,10 +8449,6 @@ async function executeTool(name, input, onProgress) {
|
|
|
8518
8449
|
const result = await pipelineTool.execute(pipelineArgs);
|
|
8519
8450
|
return textFromResult(result);
|
|
8520
8451
|
}
|
|
8521
|
-
case "trie_checkpoint": {
|
|
8522
|
-
const result = await handleCheckpointTool(input);
|
|
8523
|
-
return result;
|
|
8524
|
-
}
|
|
8525
8452
|
case "trie_add_goal": {
|
|
8526
8453
|
const desc = String(input.description || "").trim();
|
|
8527
8454
|
if (!desc) return "Goal description is required.";
|
|
@@ -8760,7 +8687,7 @@ ${truncated}`;
|
|
|
8760
8687
|
const goalId = input.goalId ? String(input.goalId).trim() : void 0;
|
|
8761
8688
|
try {
|
|
8762
8689
|
onProgress?.("Loading goals...");
|
|
8763
|
-
const { getActiveGoals } = await import("./goal-validator-
|
|
8690
|
+
const { getActiveGoals } = await import("./goal-validator-ULKIBDPX.js");
|
|
8764
8691
|
const agentState = getProjectState(directory);
|
|
8765
8692
|
await agentState.load();
|
|
8766
8693
|
const allGoals = await getActiveGoals(directory);
|
|
@@ -8769,7 +8696,7 @@ ${truncated}`;
|
|
|
8769
8696
|
return goalId ? `No active goal found with ID: ${goalId}` : "No active goals to check. Add goals in the Goals view first.";
|
|
8770
8697
|
}
|
|
8771
8698
|
onProgress?.("Scanning codebase for violations...");
|
|
8772
|
-
const { analyzeFilesRapidly } = await import("./fast-analyzer-
|
|
8699
|
+
const { analyzeFilesRapidly } = await import("./fast-analyzer-XXYMOXRK.js");
|
|
8773
8700
|
const analysisOptions = {
|
|
8774
8701
|
maxFiles: 50,
|
|
8775
8702
|
enableSmartBatching: true
|
|
@@ -8783,7 +8710,7 @@ ${truncated}`;
|
|
|
8783
8710
|
const cacheInfo2 = analysisResult.cacheHitRatio > 0 ? ` (${Math.round(analysisResult.cacheHitRatio * 100)}% cache hit, ${analysisResult.timeMs}ms)` : ` (${analysisResult.timeMs}ms)`;
|
|
8784
8711
|
return `\u2713 Scan complete! No violations found for ${goalsToCheck.length} goal(s).${cacheInfo2}`;
|
|
8785
8712
|
}
|
|
8786
|
-
const { storeIssues: storeIssues2 } = await import("./issue-store-
|
|
8713
|
+
const { storeIssues: storeIssues2 } = await import("./issue-store-ZIRP23EP.js");
|
|
8787
8714
|
const { basename: basename2 } = await import("path");
|
|
8788
8715
|
const issuesToStore = violations.map((v, i) => ({
|
|
8789
8716
|
id: `goal-violation-${Date.now()}-${i}`,
|
|
@@ -8862,7 +8789,7 @@ ${truncated}`;
|
|
|
8862
8789
|
}
|
|
8863
8790
|
try {
|
|
8864
8791
|
onProgress?.("Gathering evidence for hypothesis...");
|
|
8865
|
-
const { gatherEvidenceForHypothesis } = await import("./hypothesis-
|
|
8792
|
+
const { gatherEvidenceForHypothesis } = await import("./hypothesis-7BFFT5JY.js");
|
|
8866
8793
|
const evidence = await gatherEvidenceForHypothesis(hypothesisId, directory);
|
|
8867
8794
|
if (evidence.length === 0) {
|
|
8868
8795
|
return `No evidence found for this hypothesis yet. The codebase may not have enough data to validate it \u2014 try running trie_scan_for_goal_violations first to populate issues, or add more context.`;
|
|
@@ -8952,6 +8879,23 @@ async function buildContext(workDir, dashboardState) {
|
|
|
8952
8879
|
} catch (error) {
|
|
8953
8880
|
console.error("Failed to load project state:", error);
|
|
8954
8881
|
}
|
|
8882
|
+
try {
|
|
8883
|
+
const { getLedgerBlocks: getLedgerBlocks2 } = await import("./ledger-TWZTGDFA.js");
|
|
8884
|
+
const blocks = await getLedgerBlocks2(workDir);
|
|
8885
|
+
const allEntries = blocks.flatMap((b) => b.entries);
|
|
8886
|
+
const recentEntries = allEntries.filter((e) => e.status !== "false-positive" && e.issue).slice(-20);
|
|
8887
|
+
if (recentEntries.length > 0) {
|
|
8888
|
+
parts.push("Recent issues from ledger (learn from these patterns):\n" + recentEntries.map((e) => {
|
|
8889
|
+
const severity = e.severity === "critical" ? "\u{1F534}" : e.severity === "high" ? "\u{1F7E0}" : e.severity === "moderate" ? "\u{1F7E1}" : "\u{1F535}";
|
|
8890
|
+
const file = e.file.split("/").pop() || e.file;
|
|
8891
|
+
const issue = e.issue || "No description";
|
|
8892
|
+
const fix = e.fix ? ` \u2192 Fix: ${e.fix}` : "";
|
|
8893
|
+
return ` ${severity} [${file}] ${issue}${fix}`;
|
|
8894
|
+
}).join("\n"));
|
|
8895
|
+
}
|
|
8896
|
+
} catch (error) {
|
|
8897
|
+
console.error("Failed to load ledger entries:", error);
|
|
8898
|
+
}
|
|
8955
8899
|
try {
|
|
8956
8900
|
const storage = new TieredStorage(workDir);
|
|
8957
8901
|
try {
|
|
@@ -9035,7 +8979,11 @@ var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
|
|
|
9035
8979
|
- Create and manage goals and hypotheses
|
|
9036
8980
|
- Propose fixes for goal violations (requires user confirmation before spawning Claude Code)
|
|
9037
8981
|
- Run AI-powered scans to detect goal violations across the entire codebase
|
|
9038
|
-
|
|
8982
|
+
|
|
8983
|
+
**AUTONOMOUS AWARENESS:**
|
|
8984
|
+
- The project context includes "Recent issues from ledger" \u2014 these are patterns you should AVOID in new code
|
|
8985
|
+
- Learn from past mistakes: If you see repeated issues in the ledger, proactively suggest preventive measures
|
|
8986
|
+
- When coding or reviewing code, check if similar issues appear in the ledger history
|
|
9039
8987
|
|
|
9040
8988
|
**IMPORTANT - Finding Code Issues:**
|
|
9041
8989
|
- You have a trie_scan_for_goal_violations tool - use this to scan the codebase for goal violations
|
|
@@ -9048,7 +8996,7 @@ var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
|
|
|
9048
8996
|
- **Blockers** = Things preventing progress (from governance). Use trie_get_blockers when user asks about "blockers" or "what's blocking me".
|
|
9049
8997
|
|
|
9050
8998
|
**When user asks "what are my goals", "show hypotheses", "any nudges", "latest decisions", etc.:**
|
|
9051
|
-
- The project context block already includes goals, hypotheses, nudges, decisions, blockers
|
|
8999
|
+
- The project context block already includes goals, hypotheses, nudges, decisions, blockers, and recent ledger entries
|
|
9052
9000
|
- If the user wants more detail or the context seems stale: Call trie_query_context with the relevant query (e.g. query: "goals", type: "goals")
|
|
9053
9001
|
- trie_query_context returns goals, hypotheses, nudges, decisions, and blockers \u2014 use it for any "what do I have" questions
|
|
9054
9002
|
|
|
@@ -9801,7 +9749,7 @@ ${content}
|
|
|
9801
9749
|
fixedContent = fixedContent.replace(/^```\w*\n?/, "").replace(/\n?```$/, "");
|
|
9802
9750
|
}
|
|
9803
9751
|
await writeFile2(fullPath, fixedContent, "utf-8");
|
|
9804
|
-
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-
|
|
9752
|
+
const { recordGoalViolationFixed, getActiveGoals } = await import("./goal-validator-ULKIBDPX.js");
|
|
9805
9753
|
const goals = await getActiveGoals(projectPath);
|
|
9806
9754
|
const matchedGoal = goals.find((g) => g.description === fix.goalDescription);
|
|
9807
9755
|
if (matchedGoal) {
|
|
@@ -9917,7 +9865,7 @@ function DashboardApp({ onReady }) {
|
|
|
9917
9865
|
const loadPersistedNudges = useCallback7(async () => {
|
|
9918
9866
|
try {
|
|
9919
9867
|
const workDir = getWorkingDirectory(void 0, true);
|
|
9920
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
9868
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-Z3YCR465.js");
|
|
9921
9869
|
const storage = getStorage2(workDir);
|
|
9922
9870
|
await storage.initialize();
|
|
9923
9871
|
const nudges = await storage.queryNudges({ resolved: false, limit: 50 });
|
|
@@ -10186,9 +10134,9 @@ var InteractiveDashboard = class {
|
|
|
10186
10134
|
};
|
|
10187
10135
|
|
|
10188
10136
|
// src/tools/watch.ts
|
|
10189
|
-
import { watch, existsSync as
|
|
10190
|
-
import { stat, readFile as
|
|
10191
|
-
import { join as
|
|
10137
|
+
import { watch, existsSync as existsSync7, readFileSync as readFileSync2 } from "fs";
|
|
10138
|
+
import { stat, readFile as readFile6 } from "fs/promises";
|
|
10139
|
+
import { join as join5, extname as extname3, basename } from "path";
|
|
10192
10140
|
import { createHash as createHash3 } from "crypto";
|
|
10193
10141
|
|
|
10194
10142
|
// src/agent/signal-summarizer.ts
|
|
@@ -10430,6 +10378,528 @@ function getSignalSummarizer(projectPath) {
|
|
|
10430
10378
|
return summarizer;
|
|
10431
10379
|
}
|
|
10432
10380
|
|
|
10381
|
+
// src/compliance/false-negative-detector.ts
|
|
10382
|
+
import { join as join4 } from "path";
|
|
10383
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
10384
|
+
import { existsSync as existsSync6 } from "fs";
|
|
10385
|
+
var FalseNegativeDetector = class {
|
|
10386
|
+
workDir;
|
|
10387
|
+
alertsPath;
|
|
10388
|
+
coveragePath;
|
|
10389
|
+
constructor(workDir) {
|
|
10390
|
+
this.workDir = workDir || getWorkingDirectory(void 0, true);
|
|
10391
|
+
const memoryDir = join4(getTrieDirectory(this.workDir), "memory");
|
|
10392
|
+
this.alertsPath = join4(memoryDir, "false-negative-alerts.json");
|
|
10393
|
+
this.coveragePath = join4(memoryDir, "compliance-coverage.json");
|
|
10394
|
+
}
|
|
10395
|
+
/**
|
|
10396
|
+
* Run continuous validation checks
|
|
10397
|
+
*/
|
|
10398
|
+
async runValidation(complianceFrameworks) {
|
|
10399
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
10400
|
+
const alerts = [];
|
|
10401
|
+
const coverageGaps = [];
|
|
10402
|
+
const recommendations = [];
|
|
10403
|
+
try {
|
|
10404
|
+
const crossValidationAlerts = await this.performCrossValidation(complianceFrameworks);
|
|
10405
|
+
alerts.push(...crossValidationAlerts);
|
|
10406
|
+
const patternDriftAlerts = await this.detectPatternDrift();
|
|
10407
|
+
alerts.push(...patternDriftAlerts);
|
|
10408
|
+
const coverageAnalysis = await this.analyzeCoverageGaps(complianceFrameworks);
|
|
10409
|
+
coverageGaps.push(...coverageAnalysis.gaps);
|
|
10410
|
+
alerts.push(...coverageAnalysis.alerts);
|
|
10411
|
+
const auditTrailAlerts = await this.validateAuditTrails(complianceFrameworks);
|
|
10412
|
+
alerts.push(...auditTrailAlerts);
|
|
10413
|
+
recommendations.push(...await this.generateRecommendations(alerts, coverageGaps));
|
|
10414
|
+
await this.storeAlerts(alerts);
|
|
10415
|
+
return {
|
|
10416
|
+
valid: alerts.filter((a) => a.severity === "critical" || a.severity === "high").length === 0,
|
|
10417
|
+
alerts,
|
|
10418
|
+
coverageGaps,
|
|
10419
|
+
recommendations,
|
|
10420
|
+
validationTimestamp: timestamp
|
|
10421
|
+
};
|
|
10422
|
+
} catch (error) {
|
|
10423
|
+
const criticalAlert = {
|
|
10424
|
+
id: `validation-failure-${Date.now()}`,
|
|
10425
|
+
timestamp,
|
|
10426
|
+
type: "compliance_gap",
|
|
10427
|
+
severity: "critical",
|
|
10428
|
+
description: `False negative validation failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
10429
|
+
affectedFiles: [],
|
|
10430
|
+
complianceFrameworks,
|
|
10431
|
+
suggestedAction: "Investigate validation system failure and restore monitoring",
|
|
10432
|
+
confidence: 100,
|
|
10433
|
+
context: { riskScore: 100 }
|
|
10434
|
+
};
|
|
10435
|
+
return {
|
|
10436
|
+
valid: false,
|
|
10437
|
+
alerts: [criticalAlert],
|
|
10438
|
+
coverageGaps: ["validation-system"],
|
|
10439
|
+
recommendations: ["Fix validation system immediately"],
|
|
10440
|
+
validationTimestamp: timestamp
|
|
10441
|
+
};
|
|
10442
|
+
}
|
|
10443
|
+
}
|
|
10444
|
+
/**
|
|
10445
|
+
* Cross-validate current detections against historical patterns
|
|
10446
|
+
*/
|
|
10447
|
+
async performCrossValidation(frameworks) {
|
|
10448
|
+
const alerts = [];
|
|
10449
|
+
const blocks = await getLedgerBlocks(this.workDir);
|
|
10450
|
+
const recentIssues = await getRecentIssues({ workDir: this.workDir, limit: 100 });
|
|
10451
|
+
const historicalDetectionRates = this.calculateHistoricalDetectionRates(blocks, frameworks);
|
|
10452
|
+
const currentDetectionRate = this.calculateCurrentDetectionRate(recentIssues, frameworks);
|
|
10453
|
+
for (const framework of frameworks) {
|
|
10454
|
+
const historical = historicalDetectionRates.get(framework) || 0;
|
|
10455
|
+
const current = currentDetectionRate.get(framework) || 0;
|
|
10456
|
+
const dropThreshold = 0.3;
|
|
10457
|
+
if (historical > 0 && (historical - current) / historical > dropThreshold) {
|
|
10458
|
+
alerts.push({
|
|
10459
|
+
id: `detection-drop-${framework}-${Date.now()}`,
|
|
10460
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10461
|
+
type: "missing_detection",
|
|
10462
|
+
severity: current === 0 ? "critical" : "high",
|
|
10463
|
+
description: `${framework} detection rate dropped ${Math.round((historical - current) / historical * 100)}% from historical average`,
|
|
10464
|
+
affectedFiles: [],
|
|
10465
|
+
complianceFrameworks: [framework],
|
|
10466
|
+
suggestedAction: "Review detection rules and validate scanning coverage",
|
|
10467
|
+
confidence: 85,
|
|
10468
|
+
context: {
|
|
10469
|
+
expectedDetection: `${historical.toFixed(2)} issues per scan`,
|
|
10470
|
+
actualDetection: `${current.toFixed(2)} issues per scan`,
|
|
10471
|
+
riskScore: current === 0 ? 100 : 70
|
|
10472
|
+
}
|
|
10473
|
+
});
|
|
10474
|
+
}
|
|
10475
|
+
}
|
|
10476
|
+
return alerts;
|
|
10477
|
+
}
|
|
10478
|
+
/**
|
|
10479
|
+
* Detect if detection patterns are drifting unexpectedly
|
|
10480
|
+
*/
|
|
10481
|
+
async detectPatternDrift() {
|
|
10482
|
+
const alerts = [];
|
|
10483
|
+
const blocks = await getLedgerBlocks(this.workDir);
|
|
10484
|
+
const patternStability = this.analyzePatternStability(blocks);
|
|
10485
|
+
for (const [pattern, stability] of Array.from(patternStability.entries())) {
|
|
10486
|
+
if (stability < 0.7) {
|
|
10487
|
+
alerts.push({
|
|
10488
|
+
id: `pattern-drift-${pattern.replace(/[^a-zA-Z0-9]/g, "-")}-${Date.now()}`,
|
|
10489
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10490
|
+
type: "pattern_drift",
|
|
10491
|
+
severity: stability < 0.5 ? "high" : "medium",
|
|
10492
|
+
description: `Detection pattern '${pattern}' showing instability (${Math.round(stability * 100)}% stable)`,
|
|
10493
|
+
affectedFiles: [],
|
|
10494
|
+
complianceFrameworks: this.inferComplianceFrameworks(pattern),
|
|
10495
|
+
suggestedAction: "Review and stabilize detection pattern or investigate environmental changes",
|
|
10496
|
+
confidence: Math.round((1 - stability) * 100),
|
|
10497
|
+
context: {
|
|
10498
|
+
riskScore: Math.round((1 - stability) * 80),
|
|
10499
|
+
lastValidated: this.getLastPatternValidation(pattern)
|
|
10500
|
+
}
|
|
10501
|
+
});
|
|
10502
|
+
}
|
|
10503
|
+
}
|
|
10504
|
+
return alerts;
|
|
10505
|
+
}
|
|
10506
|
+
/**
|
|
10507
|
+
* Analyze coverage gaps in compliance monitoring
|
|
10508
|
+
*/
|
|
10509
|
+
async analyzeCoverageGaps(frameworks) {
|
|
10510
|
+
const gaps = [];
|
|
10511
|
+
const alerts = [];
|
|
10512
|
+
const requiredControls = this.getRequiredControls(frameworks);
|
|
10513
|
+
const currentCoverage = await this.getCurrentCoverage();
|
|
10514
|
+
for (const [framework, controls] of Array.from(requiredControls.entries())) {
|
|
10515
|
+
const coveredControls = currentCoverage.get(framework) || /* @__PURE__ */ new Set();
|
|
10516
|
+
const missingControls = controls.filter((control) => !coveredControls.has(control));
|
|
10517
|
+
if (missingControls.length > 0) {
|
|
10518
|
+
gaps.push(...missingControls.map((c) => `${framework}:${c}`));
|
|
10519
|
+
const criticalControls = this.getCriticalControls(framework, missingControls);
|
|
10520
|
+
if (criticalControls.length > 0) {
|
|
10521
|
+
alerts.push({
|
|
10522
|
+
id: `coverage-gap-${framework}-${Date.now()}`,
|
|
10523
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10524
|
+
type: "coverage_hole",
|
|
10525
|
+
severity: "critical",
|
|
10526
|
+
description: `Missing critical ${framework} controls: ${criticalControls.join(", ")}`,
|
|
10527
|
+
affectedFiles: [],
|
|
10528
|
+
complianceFrameworks: [framework],
|
|
10529
|
+
suggestedAction: "Implement monitoring for missing critical controls immediately",
|
|
10530
|
+
confidence: 100,
|
|
10531
|
+
context: {
|
|
10532
|
+
riskScore: 95,
|
|
10533
|
+
expectedDetection: `Controls: ${controls.join(", ")}`,
|
|
10534
|
+
actualDetection: `Missing: ${criticalControls.join(", ")}`
|
|
10535
|
+
}
|
|
10536
|
+
});
|
|
10537
|
+
}
|
|
10538
|
+
}
|
|
10539
|
+
}
|
|
10540
|
+
return { gaps, alerts };
|
|
10541
|
+
}
|
|
10542
|
+
/**
|
|
10543
|
+
* Validate that audit trails are complete and tamper-evident
|
|
10544
|
+
*/
|
|
10545
|
+
async validateAuditTrails(frameworks) {
|
|
10546
|
+
const alerts = [];
|
|
10547
|
+
const blocks = await getLedgerBlocks(this.workDir);
|
|
10548
|
+
const auditGaps = this.findAuditTrailGaps(blocks, frameworks);
|
|
10549
|
+
for (const gap of auditGaps) {
|
|
10550
|
+
alerts.push({
|
|
10551
|
+
id: `audit-gap-${gap.type}-${Date.now()}`,
|
|
10552
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10553
|
+
type: "compliance_gap",
|
|
10554
|
+
severity: gap.critical ? "critical" : "high",
|
|
10555
|
+
description: `Audit trail gap: ${gap.description}`,
|
|
10556
|
+
affectedFiles: gap.affectedFiles,
|
|
10557
|
+
complianceFrameworks: gap.frameworks,
|
|
10558
|
+
suggestedAction: gap.remediation,
|
|
10559
|
+
confidence: 95,
|
|
10560
|
+
context: {
|
|
10561
|
+
riskScore: gap.critical ? 90 : 60,
|
|
10562
|
+
lastValidated: gap.lastSeen
|
|
10563
|
+
}
|
|
10564
|
+
});
|
|
10565
|
+
}
|
|
10566
|
+
const integrityIssues = await this.validateCryptographicIntegrity(blocks);
|
|
10567
|
+
for (const issue of integrityIssues) {
|
|
10568
|
+
alerts.push({
|
|
10569
|
+
id: `integrity-${issue.type}-${Date.now()}`,
|
|
10570
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10571
|
+
type: "compliance_gap",
|
|
10572
|
+
severity: "critical",
|
|
10573
|
+
description: `Audit trail integrity compromised: ${issue.description}`,
|
|
10574
|
+
affectedFiles: [],
|
|
10575
|
+
complianceFrameworks: frameworks,
|
|
10576
|
+
suggestedAction: "Investigate potential tampering and restore audit trail integrity",
|
|
10577
|
+
confidence: 100,
|
|
10578
|
+
context: { riskScore: 100 }
|
|
10579
|
+
});
|
|
10580
|
+
}
|
|
10581
|
+
return alerts;
|
|
10582
|
+
}
|
|
10583
|
+
/**
|
|
10584
|
+
* Generate actionable recommendations based on findings
|
|
10585
|
+
*/
|
|
10586
|
+
async generateRecommendations(alerts, gaps) {
|
|
10587
|
+
const recommendations = [];
|
|
10588
|
+
const alertsByType = alerts.reduce((acc, alert) => {
|
|
10589
|
+
if (!acc[alert.type]) acc[alert.type] = [];
|
|
10590
|
+
acc[alert.type].push(alert);
|
|
10591
|
+
return acc;
|
|
10592
|
+
}, {});
|
|
10593
|
+
if (alertsByType.missing_detection?.length > 0) {
|
|
10594
|
+
recommendations.push("Increase detection frequency and review agent configurations");
|
|
10595
|
+
recommendations.push("Implement additional cross-validation mechanisms");
|
|
10596
|
+
}
|
|
10597
|
+
if (alertsByType.pattern_drift?.length > 0) {
|
|
10598
|
+
recommendations.push("Stabilize detection patterns through improved training data");
|
|
10599
|
+
recommendations.push("Implement pattern validation checkpoints");
|
|
10600
|
+
}
|
|
10601
|
+
if (alertsByType.coverage_hole?.length > 0) {
|
|
10602
|
+
recommendations.push("Expand compliance monitoring coverage to include missing controls");
|
|
10603
|
+
recommendations.push("Implement automated compliance mapping validation");
|
|
10604
|
+
}
|
|
10605
|
+
if (alertsByType.compliance_gap?.length > 0) {
|
|
10606
|
+
recommendations.push("Strengthen audit trail generation and validation processes");
|
|
10607
|
+
recommendations.push("Implement real-time compliance monitoring dashboards");
|
|
10608
|
+
}
|
|
10609
|
+
if (gaps.length > 0) {
|
|
10610
|
+
recommendations.push(`Address ${gaps.length} compliance coverage gaps immediately`);
|
|
10611
|
+
recommendations.push("Implement automated gap detection and remediation");
|
|
10612
|
+
}
|
|
10613
|
+
const criticalAlerts = alerts.filter((a) => a.severity === "critical");
|
|
10614
|
+
if (criticalAlerts.length > 0) {
|
|
10615
|
+
recommendations.push(`URGENT: ${criticalAlerts.length} critical compliance issues require immediate attention`);
|
|
10616
|
+
}
|
|
10617
|
+
return recommendations;
|
|
10618
|
+
}
|
|
10619
|
+
/**
|
|
10620
|
+
* Store alerts for trending and historical analysis
|
|
10621
|
+
*/
|
|
10622
|
+
async storeAlerts(alerts) {
|
|
10623
|
+
if (alerts.length === 0) return;
|
|
10624
|
+
try {
|
|
10625
|
+
let existingAlerts = [];
|
|
10626
|
+
if (existsSync6(this.alertsPath)) {
|
|
10627
|
+
const content = await readFile5(this.alertsPath, "utf-8");
|
|
10628
|
+
existingAlerts = JSON.parse(content);
|
|
10629
|
+
}
|
|
10630
|
+
const ninetyDaysAgo = /* @__PURE__ */ new Date();
|
|
10631
|
+
ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90);
|
|
10632
|
+
const recentAlerts = existingAlerts.filter(
|
|
10633
|
+
(alert) => new Date(alert.timestamp) > ninetyDaysAgo
|
|
10634
|
+
);
|
|
10635
|
+
const allAlerts = [...recentAlerts, ...alerts];
|
|
10636
|
+
await atomicWriteJSON(this.alertsPath, allAlerts);
|
|
10637
|
+
} catch (error) {
|
|
10638
|
+
console.error("Failed to store false negative alerts:", error);
|
|
10639
|
+
}
|
|
10640
|
+
}
|
|
10641
|
+
// Helper methods for calculations and analysis
|
|
10642
|
+
calculateHistoricalDetectionRates(blocks, frameworks) {
|
|
10643
|
+
const rates = /* @__PURE__ */ new Map();
|
|
10644
|
+
const thirtyDaysAgo = /* @__PURE__ */ new Date();
|
|
10645
|
+
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
|
10646
|
+
const recentBlocks = blocks.filter(
|
|
10647
|
+
(block) => new Date(block.date) > thirtyDaysAgo
|
|
10648
|
+
);
|
|
10649
|
+
for (const framework of frameworks) {
|
|
10650
|
+
let totalDetections = 0;
|
|
10651
|
+
let blockCount = 0;
|
|
10652
|
+
for (const block of recentBlocks) {
|
|
10653
|
+
const frameworkDetections = block.entries.filter(
|
|
10654
|
+
(entry) => entry.context?.complianceViolations?.includes(framework) || this.inferFrameworkFromEntry(entry) === framework
|
|
10655
|
+
).length;
|
|
10656
|
+
totalDetections += frameworkDetections;
|
|
10657
|
+
blockCount++;
|
|
10658
|
+
}
|
|
10659
|
+
rates.set(framework, blockCount > 0 ? totalDetections / blockCount : 0);
|
|
10660
|
+
}
|
|
10661
|
+
return rates;
|
|
10662
|
+
}
|
|
10663
|
+
calculateCurrentDetectionRate(issues, frameworks) {
|
|
10664
|
+
const rates = /* @__PURE__ */ new Map();
|
|
10665
|
+
const oneDayAgo = /* @__PURE__ */ new Date();
|
|
10666
|
+
oneDayAgo.setDate(oneDayAgo.getDate() - 1);
|
|
10667
|
+
const recentIssues = issues.filter(
|
|
10668
|
+
(issue) => new Date(issue.timestamp) > oneDayAgo
|
|
10669
|
+
);
|
|
10670
|
+
for (const framework of frameworks) {
|
|
10671
|
+
const frameworkIssues = recentIssues.filter(
|
|
10672
|
+
(issue) => this.inferFrameworkFromIssue(issue) === framework
|
|
10673
|
+
);
|
|
10674
|
+
rates.set(framework, frameworkIssues.length);
|
|
10675
|
+
}
|
|
10676
|
+
return rates;
|
|
10677
|
+
}
|
|
10678
|
+
analyzePatternStability(blocks) {
|
|
10679
|
+
const stability = /* @__PURE__ */ new Map();
|
|
10680
|
+
const patterns = this.extractDetectionPatterns(blocks);
|
|
10681
|
+
for (const [pattern, occurrences] of Array.from(patterns.entries())) {
|
|
10682
|
+
const mean = occurrences.reduce((a, b) => a + b, 0) / occurrences.length;
|
|
10683
|
+
const variance = occurrences.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / occurrences.length;
|
|
10684
|
+
const stdDev = Math.sqrt(variance);
|
|
10685
|
+
const cv = mean > 0 ? stdDev / mean : 1;
|
|
10686
|
+
stability.set(pattern, Math.max(0, 1 - cv));
|
|
10687
|
+
}
|
|
10688
|
+
return stability;
|
|
10689
|
+
}
|
|
10690
|
+
extractDetectionPatterns(blocks) {
|
|
10691
|
+
const patterns = /* @__PURE__ */ new Map();
|
|
10692
|
+
const weeklyData = /* @__PURE__ */ new Map();
|
|
10693
|
+
for (const block of blocks) {
|
|
10694
|
+
const weekKey = this.getWeekKey(new Date(block.date));
|
|
10695
|
+
if (!weeklyData.has(weekKey)) {
|
|
10696
|
+
weeklyData.set(weekKey, /* @__PURE__ */ new Map());
|
|
10697
|
+
}
|
|
10698
|
+
const weekData = weeklyData.get(weekKey);
|
|
10699
|
+
for (const entry of block.entries) {
|
|
10700
|
+
const pattern = `${entry.agent}:${entry.severity}`;
|
|
10701
|
+
weekData.set(pattern, (weekData.get(pattern) || 0) + 1);
|
|
10702
|
+
}
|
|
10703
|
+
}
|
|
10704
|
+
const allWeeks = Array.from(weeklyData.keys()).sort();
|
|
10705
|
+
const allPatterns = /* @__PURE__ */ new Set();
|
|
10706
|
+
for (const weekData of Array.from(weeklyData.values())) {
|
|
10707
|
+
for (const pattern of Array.from(weekData.keys())) {
|
|
10708
|
+
allPatterns.add(pattern);
|
|
10709
|
+
}
|
|
10710
|
+
}
|
|
10711
|
+
for (const pattern of Array.from(allPatterns)) {
|
|
10712
|
+
const timeSeries = [];
|
|
10713
|
+
for (const week of allWeeks) {
|
|
10714
|
+
const weekData = weeklyData.get(week);
|
|
10715
|
+
timeSeries.push(weekData.get(pattern) || 0);
|
|
10716
|
+
}
|
|
10717
|
+
patterns.set(pattern, timeSeries);
|
|
10718
|
+
}
|
|
10719
|
+
return patterns;
|
|
10720
|
+
}
|
|
10721
|
+
getWeekKey(date) {
|
|
10722
|
+
const year = date.getFullYear();
|
|
10723
|
+
const week = Math.floor((date.getTime() - new Date(year, 0, 1).getTime()) / (7 * 24 * 60 * 60 * 1e3));
|
|
10724
|
+
return `${year}-W${week.toString().padStart(2, "0")}`;
|
|
10725
|
+
}
|
|
10726
|
+
getRequiredControls(frameworks) {
|
|
10727
|
+
const controls = /* @__PURE__ */ new Map();
|
|
10728
|
+
const frameworkControls = {
|
|
10729
|
+
SOC2: ["access-control", "data-encryption", "audit-logging", "incident-response"],
|
|
10730
|
+
GDPR: ["data-protection", "consent-management", "data-breach-notification", "privacy-by-design"],
|
|
10731
|
+
HIPAA: ["phi-protection", "access-controls", "audit-controls", "transmission-security"],
|
|
10732
|
+
"ISO27001": ["information-security-policy", "risk-management", "access-control", "cryptography"],
|
|
10733
|
+
"PCI-DSS": ["cardholder-data-protection", "secure-networks", "vulnerability-management", "access-control"],
|
|
10734
|
+
SOX: ["financial-reporting-controls", "segregation-of-duties", "audit-trail", "change-management"],
|
|
10735
|
+
ICFR: ["control-environment", "risk-assessment", "control-activities", "monitoring"],
|
|
10736
|
+
"FDA21CFR11": ["electronic-records", "electronic-signatures", "audit-trail", "system-validation"],
|
|
10737
|
+
GLBA: ["customer-information-protection", "access-control", "disposal-procedures", "incident-response"],
|
|
10738
|
+
FFIEC: ["authentication", "access-control", "encryption", "incident-response"],
|
|
10739
|
+
FINRA: ["recordkeeping", "supervision", "reporting", "compliance-monitoring"]
|
|
10740
|
+
};
|
|
10741
|
+
for (const framework of frameworks) {
|
|
10742
|
+
const frameworkKey = framework;
|
|
10743
|
+
if (frameworkControls[frameworkKey]) {
|
|
10744
|
+
controls.set(framework, frameworkControls[frameworkKey]);
|
|
10745
|
+
}
|
|
10746
|
+
}
|
|
10747
|
+
return controls;
|
|
10748
|
+
}
|
|
10749
|
+
async getCurrentCoverage() {
|
|
10750
|
+
const coverage = /* @__PURE__ */ new Map();
|
|
10751
|
+
try {
|
|
10752
|
+
const blocks = await getLedgerBlocks(this.workDir);
|
|
10753
|
+
for (const block of blocks) {
|
|
10754
|
+
for (const entry of block.entries) {
|
|
10755
|
+
const frameworks = entry.context?.complianceViolations || [this.inferFrameworkFromEntry(entry)].filter(Boolean);
|
|
10756
|
+
for (const framework of frameworks) {
|
|
10757
|
+
if (!coverage.has(framework)) {
|
|
10758
|
+
coverage.set(framework, /* @__PURE__ */ new Set());
|
|
10759
|
+
}
|
|
10760
|
+
const control = this.inferControlFromEntry(entry);
|
|
10761
|
+
if (control) {
|
|
10762
|
+
coverage.get(framework).add(control);
|
|
10763
|
+
}
|
|
10764
|
+
}
|
|
10765
|
+
}
|
|
10766
|
+
}
|
|
10767
|
+
} catch (error) {
|
|
10768
|
+
console.error("Failed to calculate current coverage:", error);
|
|
10769
|
+
}
|
|
10770
|
+
return coverage;
|
|
10771
|
+
}
|
|
10772
|
+
getCriticalControls(framework, missingControls) {
|
|
10773
|
+
const criticalControlsByFramework = {
|
|
10774
|
+
SOC2: /* @__PURE__ */ new Set(["access-control", "audit-logging"]),
|
|
10775
|
+
GDPR: /* @__PURE__ */ new Set(["data-protection", "consent-management"]),
|
|
10776
|
+
HIPAA: /* @__PURE__ */ new Set(["phi-protection", "access-controls"]),
|
|
10777
|
+
"ISO27001": /* @__PURE__ */ new Set(["information-security-policy", "access-control"]),
|
|
10778
|
+
"PCI-DSS": /* @__PURE__ */ new Set(["cardholder-data-protection", "secure-networks"]),
|
|
10779
|
+
SOX: /* @__PURE__ */ new Set(["financial-reporting-controls", "audit-trail"]),
|
|
10780
|
+
ICFR: /* @__PURE__ */ new Set(["control-environment", "monitoring"]),
|
|
10781
|
+
"FDA21CFR11": /* @__PURE__ */ new Set(["electronic-records", "audit-trail"]),
|
|
10782
|
+
GLBA: /* @__PURE__ */ new Set(["customer-information-protection"]),
|
|
10783
|
+
FFIEC: /* @__PURE__ */ new Set(["authentication", "encryption"]),
|
|
10784
|
+
FINRA: /* @__PURE__ */ new Set(["recordkeeping", "compliance-monitoring"])
|
|
10785
|
+
};
|
|
10786
|
+
const criticalControls = criticalControlsByFramework[framework] || /* @__PURE__ */ new Set();
|
|
10787
|
+
return missingControls.filter((control) => criticalControls.has(control));
|
|
10788
|
+
}
|
|
10789
|
+
findAuditTrailGaps(blocks, frameworks) {
|
|
10790
|
+
const gaps = [];
|
|
10791
|
+
const unsignedEntries = blocks.flatMap(
|
|
10792
|
+
(block) => block.entries.filter((entry) => !entry.signature)
|
|
10793
|
+
);
|
|
10794
|
+
if (unsignedEntries.length > 0) {
|
|
10795
|
+
gaps.push({
|
|
10796
|
+
type: "missing-signatures",
|
|
10797
|
+
description: `${unsignedEntries.length} audit entries lack cryptographic signatures`,
|
|
10798
|
+
critical: true,
|
|
10799
|
+
affectedFiles: Array.from(new Set(unsignedEntries.map((e) => e.file))),
|
|
10800
|
+
frameworks,
|
|
10801
|
+
remediation: "Enable cryptographic signing for all audit entries"
|
|
10802
|
+
});
|
|
10803
|
+
}
|
|
10804
|
+
const sortedBlocks = blocks.sort((a, b) => a.date.localeCompare(b.date));
|
|
10805
|
+
for (let i = 1; i < sortedBlocks.length; i++) {
|
|
10806
|
+
const prevDate = new Date(sortedBlocks[i - 1].date);
|
|
10807
|
+
const currDate = new Date(sortedBlocks[i].date);
|
|
10808
|
+
const daysDiff = (currDate.getTime() - prevDate.getTime()) / (1e3 * 60 * 60 * 24);
|
|
10809
|
+
if (daysDiff > 7) {
|
|
10810
|
+
gaps.push({
|
|
10811
|
+
type: "temporal-gap",
|
|
10812
|
+
description: `${Math.floor(daysDiff)} day gap in audit trail between ${prevDate.toISOString().slice(0, 10)} and ${currDate.toISOString().slice(0, 10)}`,
|
|
10813
|
+
critical: daysDiff > 30,
|
|
10814
|
+
affectedFiles: [],
|
|
10815
|
+
frameworks,
|
|
10816
|
+
remediation: "Investigate cause of audit trail gap and ensure continuous monitoring",
|
|
10817
|
+
lastSeen: prevDate.toISOString()
|
|
10818
|
+
});
|
|
10819
|
+
}
|
|
10820
|
+
}
|
|
10821
|
+
return gaps;
|
|
10822
|
+
}
|
|
10823
|
+
async validateCryptographicIntegrity(blocks) {
|
|
10824
|
+
const issues = [];
|
|
10825
|
+
for (let i = 1; i < blocks.length; i++) {
|
|
10826
|
+
const prevBlock = blocks[i - 1];
|
|
10827
|
+
const currBlock = blocks[i];
|
|
10828
|
+
if (currBlock.previousHash !== prevBlock.blockHash) {
|
|
10829
|
+
issues.push({
|
|
10830
|
+
type: "chain-break",
|
|
10831
|
+
description: `Block chain integrity compromised at block ${i}: expected ${prevBlock.blockHash}, got ${currBlock.previousHash}`
|
|
10832
|
+
});
|
|
10833
|
+
}
|
|
10834
|
+
}
|
|
10835
|
+
for (const block of blocks) {
|
|
10836
|
+
if (block.entries.length > 0 && !block.merkleRoot) {
|
|
10837
|
+
issues.push({
|
|
10838
|
+
type: "missing-merkle",
|
|
10839
|
+
description: `Block ${block.date} missing merkle root for ${block.entries.length} entries`
|
|
10840
|
+
});
|
|
10841
|
+
}
|
|
10842
|
+
}
|
|
10843
|
+
return issues;
|
|
10844
|
+
}
|
|
10845
|
+
// Framework inference helpers
|
|
10846
|
+
inferComplianceFrameworks(pattern) {
|
|
10847
|
+
const frameworks = [];
|
|
10848
|
+
if (pattern.includes("security") || pattern.includes("auth")) {
|
|
10849
|
+
frameworks.push("SOC2", "ISO27001");
|
|
10850
|
+
}
|
|
10851
|
+
if (pattern.includes("privacy") || pattern.includes("pii")) {
|
|
10852
|
+
frameworks.push("GDPR", "CCPA");
|
|
10853
|
+
}
|
|
10854
|
+
if (pattern.includes("health") || pattern.includes("phi")) {
|
|
10855
|
+
frameworks.push("HIPAA");
|
|
10856
|
+
}
|
|
10857
|
+
if (pattern.includes("payment") || pattern.includes("card")) {
|
|
10858
|
+
frameworks.push("PCI-DSS");
|
|
10859
|
+
}
|
|
10860
|
+
if (pattern.includes("financial") || pattern.includes("audit")) {
|
|
10861
|
+
frameworks.push("SOX", "ICFR");
|
|
10862
|
+
}
|
|
10863
|
+
return frameworks.length > 0 ? frameworks : ["SOC2"];
|
|
10864
|
+
}
|
|
10865
|
+
inferFrameworkFromEntry(entry) {
|
|
10866
|
+
if (entry.context?.complianceViolations?.length) {
|
|
10867
|
+
return entry.context.complianceViolations[0];
|
|
10868
|
+
}
|
|
10869
|
+
const content = `${entry.issue} ${entry.fix} ${entry.file}`.toLowerCase();
|
|
10870
|
+
if (content.includes("phi") || content.includes("health")) return "HIPAA";
|
|
10871
|
+
if (content.includes("pii") || content.includes("personal")) return "GDPR";
|
|
10872
|
+
if (content.includes("payment") || content.includes("card")) return "PCI-DSS";
|
|
10873
|
+
if (content.includes("financial")) return "SOX";
|
|
10874
|
+
return "SOC2";
|
|
10875
|
+
}
|
|
10876
|
+
inferFrameworkFromIssue(issue) {
|
|
10877
|
+
const content = `${issue.issue} ${issue.fix} ${issue.file}`.toLowerCase();
|
|
10878
|
+
if (content.includes("phi") || content.includes("health")) return "HIPAA";
|
|
10879
|
+
if (content.includes("pii") || content.includes("personal")) return "GDPR";
|
|
10880
|
+
if (content.includes("payment") || content.includes("card")) return "PCI-DSS";
|
|
10881
|
+
if (content.includes("financial")) return "SOX";
|
|
10882
|
+
return "SOC2";
|
|
10883
|
+
}
|
|
10884
|
+
inferControlFromEntry(entry) {
|
|
10885
|
+
const content = `${entry.issue} ${entry.fix} ${entry.agent}`.toLowerCase();
|
|
10886
|
+
if (content.includes("access") || content.includes("auth")) return "access-control";
|
|
10887
|
+
if (content.includes("encrypt") || content.includes("crypto")) return "data-encryption";
|
|
10888
|
+
if (content.includes("audit") || content.includes("log")) return "audit-logging";
|
|
10889
|
+
if (content.includes("incident") || content.includes("response")) return "incident-response";
|
|
10890
|
+
if (content.includes("privacy") || content.includes("consent")) return "consent-management";
|
|
10891
|
+
if (content.includes("protection") || content.includes("security")) return "data-protection";
|
|
10892
|
+
return null;
|
|
10893
|
+
}
|
|
10894
|
+
getLastPatternValidation(pattern) {
|
|
10895
|
+
return new Date(Date.now() - 24 * 60 * 60 * 1e3).toISOString();
|
|
10896
|
+
}
|
|
10897
|
+
};
|
|
10898
|
+
async function runFalseNegativeValidation(complianceFrameworks, workDir) {
|
|
10899
|
+
const detector = new FalseNegativeDetector(workDir);
|
|
10900
|
+
return detector.runValidation(complianceFrameworks);
|
|
10901
|
+
}
|
|
10902
|
+
|
|
10433
10903
|
// src/tools/watch.ts
|
|
10434
10904
|
var WATCH_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
10435
10905
|
".ts",
|
|
@@ -10692,7 +11162,7 @@ Your Trie agent is now autonomously watching and learning from your codebase.
|
|
|
10692
11162
|
return parts.some((p) => SKIP_DIRS.has(p) || p.startsWith(".") && p !== ".");
|
|
10693
11163
|
}
|
|
10694
11164
|
async watchDirectory(dir, debounceMs) {
|
|
10695
|
-
if (!
|
|
11165
|
+
if (!existsSync7(dir)) return;
|
|
10696
11166
|
try {
|
|
10697
11167
|
const dirStat = await stat(dir);
|
|
10698
11168
|
if (!dirStat.isDirectory()) return;
|
|
@@ -10701,8 +11171,8 @@ Your Trie agent is now autonomously watching and learning from your codebase.
|
|
|
10701
11171
|
if (this.shouldSkipPath(filename)) return;
|
|
10702
11172
|
const ext = extname3(filename).toLowerCase();
|
|
10703
11173
|
if (!WATCH_EXTENSIONS.has(ext)) return;
|
|
10704
|
-
const fullPath =
|
|
10705
|
-
if (!
|
|
11174
|
+
const fullPath = join5(dir, filename);
|
|
11175
|
+
if (!existsSync7(fullPath)) return;
|
|
10706
11176
|
this.state.pendingFiles.add(fullPath);
|
|
10707
11177
|
if (this.state.scanDebounceTimer) {
|
|
10708
11178
|
clearTimeout(this.state.scanDebounceTimer);
|
|
@@ -10733,8 +11203,8 @@ Your Trie agent is now autonomously watching and learning from your codebase.
|
|
|
10733
11203
|
* Watch .trie/context.json for incident changes
|
|
10734
11204
|
*/
|
|
10735
11205
|
async watchContextGraph(directory) {
|
|
10736
|
-
const contextPath =
|
|
10737
|
-
if (!
|
|
11206
|
+
const contextPath = join5(getTrieDirectory(directory), "context.json");
|
|
11207
|
+
if (!existsSync7(contextPath)) {
|
|
10738
11208
|
console.debug("[Watch] No context.json found, skipping incident watcher");
|
|
10739
11209
|
return;
|
|
10740
11210
|
}
|
|
@@ -10815,7 +11285,7 @@ Detected changes in ${files.length} file(s):`);
|
|
|
10815
11285
|
const fileContents = await Promise.all(
|
|
10816
11286
|
files.map(async (file) => {
|
|
10817
11287
|
try {
|
|
10818
|
-
const content = await
|
|
11288
|
+
const content = await readFile6(file, "utf-8");
|
|
10819
11289
|
return { file, content };
|
|
10820
11290
|
} catch {
|
|
10821
11291
|
return null;
|
|
@@ -10897,7 +11367,7 @@ ${f.content.slice(0, 1e3)}`
|
|
|
10897
11367
|
}
|
|
10898
11368
|
isQuiet() {
|
|
10899
11369
|
const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
|
|
10900
|
-
const quietPath =
|
|
11370
|
+
const quietPath = join5(getTrieDirectory(projectPath), "quiet.json");
|
|
10901
11371
|
try {
|
|
10902
11372
|
const raw = readFileSync2(quietPath, "utf-8");
|
|
10903
11373
|
const data = JSON.parse(raw);
|
|
@@ -10914,8 +11384,8 @@ ${f.content.slice(0, 1e3)}`
|
|
|
10914
11384
|
async checkAndGenerateHypotheses(projectPath) {
|
|
10915
11385
|
if (!isAIAvailable()) return;
|
|
10916
11386
|
try {
|
|
10917
|
-
const { getHypothesisEngine } = await import("./hypothesis-
|
|
10918
|
-
const { getOutputManager: getOutputManager2 } = await import("./output-manager-
|
|
11387
|
+
const { getHypothesisEngine } = await import("./hypothesis-7BFFT5JY.js");
|
|
11388
|
+
const { getOutputManager: getOutputManager2 } = await import("./output-manager-RVJ37XKA.js");
|
|
10919
11389
|
const hypothesisEngine = getHypothesisEngine(projectPath);
|
|
10920
11390
|
const recentIssues = Array.from(this.state.issueCache.values()).flat();
|
|
10921
11391
|
const patterns = [];
|
|
@@ -10979,7 +11449,7 @@ ${f.content.slice(0, 1e3)}`
|
|
|
10979
11449
|
*/
|
|
10980
11450
|
async discoverPatternsFromIssues(projectPath) {
|
|
10981
11451
|
try {
|
|
10982
|
-
const { searchIssues } = await import("./issue-store-
|
|
11452
|
+
const { searchIssues } = await import("./issue-store-ZIRP23EP.js");
|
|
10983
11453
|
const allIssues = await searchIssues("", {
|
|
10984
11454
|
workDir: projectPath,
|
|
10985
11455
|
limit: 1e3,
|
|
@@ -11081,7 +11551,7 @@ ${f.content.slice(0, 1e3)}`
|
|
|
11081
11551
|
if (lastClean && Date.now() - lastClean < this.cleanFileCooldownMs) {
|
|
11082
11552
|
return 0;
|
|
11083
11553
|
}
|
|
11084
|
-
const fileNode = await graph.getNode("file",
|
|
11554
|
+
const fileNode = await graph.getNode("file", join5(projectPath, file));
|
|
11085
11555
|
if (!fileNode) return score;
|
|
11086
11556
|
const data = fileNode.data;
|
|
11087
11557
|
const riskScores = { critical: 10, high: 6, medium: 2, low: 1 };
|
|
@@ -11140,7 +11610,7 @@ ${f.content.slice(0, 1e3)}`
|
|
|
11140
11610
|
if (remaining < 500) return;
|
|
11141
11611
|
try {
|
|
11142
11612
|
const graph = new ContextGraph(projectPath);
|
|
11143
|
-
const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-
|
|
11613
|
+
const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-ULKIBDPX.js");
|
|
11144
11614
|
console.debug("[AI Watcher] Loading active goals...");
|
|
11145
11615
|
const activeGoals = await getActiveGoals(projectPath);
|
|
11146
11616
|
const hasGoals = activeGoals.length > 0;
|
|
@@ -11169,7 +11639,7 @@ ${f.content.slice(0, 1e3)}`
|
|
|
11169
11639
|
const fileContents = await Promise.all(
|
|
11170
11640
|
filesToScan.map(async ({ file, relativePath }) => {
|
|
11171
11641
|
try {
|
|
11172
|
-
const content = await
|
|
11642
|
+
const content = await readFile6(file, "utf-8");
|
|
11173
11643
|
return { path: relativePath, content: content.slice(0, charLimit) };
|
|
11174
11644
|
} catch {
|
|
11175
11645
|
return null;
|
|
@@ -11337,7 +11807,7 @@ ${filesBlock}`,
|
|
|
11337
11807
|
fixChangeId: null,
|
|
11338
11808
|
reportedVia: "detected"
|
|
11339
11809
|
});
|
|
11340
|
-
const filePath =
|
|
11810
|
+
const filePath = join5(projectPath, issue.file);
|
|
11341
11811
|
const fileNode = await graph.getNode("file", filePath);
|
|
11342
11812
|
if (fileNode) {
|
|
11343
11813
|
await graph.addEdge(fileNode.id, incident.id, "affects");
|
|
@@ -11395,7 +11865,7 @@ ${filesBlock}`,
|
|
|
11395
11865
|
const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
|
|
11396
11866
|
console.debug("[Initial Hypothesis] Starting initial hypothesis generation", { projectPath });
|
|
11397
11867
|
try {
|
|
11398
|
-
const { getHypothesisEngine } = await import("./hypothesis-
|
|
11868
|
+
const { getHypothesisEngine } = await import("./hypothesis-7BFFT5JY.js");
|
|
11399
11869
|
const hypothesisEngine = getHypothesisEngine(projectPath);
|
|
11400
11870
|
console.debug("[Initial Hypothesis] Running AI-powered hypothesis generation...");
|
|
11401
11871
|
const generated = await hypothesisEngine.generateHypothesesWithAI({
|
|
@@ -11409,7 +11879,7 @@ ${filesBlock}`,
|
|
|
11409
11879
|
hypotheses: generated.map((h) => ({ statement: h.statement, confidence: h.confidence }))
|
|
11410
11880
|
});
|
|
11411
11881
|
if (generated.length > 0) {
|
|
11412
|
-
const { getOutputManager: getOutputManager2 } = await import("./output-manager-
|
|
11882
|
+
const { getOutputManager: getOutputManager2 } = await import("./output-manager-RVJ37XKA.js");
|
|
11413
11883
|
const outputManager = getOutputManager2();
|
|
11414
11884
|
for (const hypothesis of generated.slice(0, 2)) {
|
|
11415
11885
|
const message = `[Initial Hypothesis] "${hypothesis.statement}" (${Math.round(hypothesis.confidence * 100)}% confidence)`;
|
|
@@ -11453,7 +11923,7 @@ ${filesBlock}`,
|
|
|
11453
11923
|
const projectPath = this.watchedDirectory || getWorkingDirectory(void 0, true);
|
|
11454
11924
|
console.debug("[Initial Scan] Starting initial goal compliance scan", { projectPath });
|
|
11455
11925
|
try {
|
|
11456
|
-
const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-
|
|
11926
|
+
const { getActiveGoals, recordGoalViolationCaught } = await import("./goal-validator-ULKIBDPX.js");
|
|
11457
11927
|
const activeGoals = await getActiveGoals(projectPath);
|
|
11458
11928
|
console.debug("[Initial Scan] Loaded goals for initial scan:", {
|
|
11459
11929
|
goalCount: activeGoals.length,
|
|
@@ -11469,7 +11939,7 @@ ${filesBlock}`,
|
|
|
11469
11939
|
const recentFiles = /* @__PURE__ */ new Set();
|
|
11470
11940
|
const uncommittedFiles = await getGitChangedFiles(projectPath);
|
|
11471
11941
|
if (uncommittedFiles) {
|
|
11472
|
-
uncommittedFiles.forEach((f) => recentFiles.add(
|
|
11942
|
+
uncommittedFiles.forEach((f) => recentFiles.add(join5(projectPath, f)));
|
|
11473
11943
|
}
|
|
11474
11944
|
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1e3;
|
|
11475
11945
|
const recentChanges = await getChangedFilesSinceTimestamp(projectPath, oneDayAgo);
|
|
@@ -11478,7 +11948,7 @@ ${filesBlock}`,
|
|
|
11478
11948
|
}
|
|
11479
11949
|
const filesToCheck = Array.from(recentFiles).filter((file) => {
|
|
11480
11950
|
const ext = extname3(file).toLowerCase();
|
|
11481
|
-
return WATCH_EXTENSIONS.has(ext) &&
|
|
11951
|
+
return WATCH_EXTENSIONS.has(ext) && existsSync7(file);
|
|
11482
11952
|
});
|
|
11483
11953
|
console.debug("[Initial Scan] Files discovered for initial scan:", {
|
|
11484
11954
|
totalRecentFiles: recentFiles.size,
|
|
@@ -11500,7 +11970,7 @@ ${filesBlock}`,
|
|
|
11500
11970
|
const fileContents = await Promise.all(
|
|
11501
11971
|
filesToScan.map(async (file) => {
|
|
11502
11972
|
try {
|
|
11503
|
-
const content = await
|
|
11973
|
+
const content = await readFile6(file, "utf-8");
|
|
11504
11974
|
const relativePath = file.replace(projectPath + "/", "");
|
|
11505
11975
|
return { path: relativePath, content: content.slice(0, maxCharsPerFile) };
|
|
11506
11976
|
} catch {
|
|
@@ -11596,11 +12066,12 @@ ${filesBlock}`,
|
|
|
11596
12066
|
this.streamingManager.reportLedgerUpdate(issuesToStore.length, "goal-violation");
|
|
11597
12067
|
}
|
|
11598
12068
|
}
|
|
11599
|
-
|
|
11600
|
-
const {
|
|
12069
|
+
await this.runComplianceValidation(projectPath);
|
|
12070
|
+
const { resolveGoalViolation } = await import("./issue-store-ZIRP23EP.js");
|
|
12071
|
+
const { recordGoalViolationFixed } = await import("./goal-validator-ULKIBDPX.js");
|
|
11601
12072
|
const scannedFiles = new Set(valid.map((f) => f.path));
|
|
11602
12073
|
const filesWithViolations = new Set(issuesToStore.map((i) => i.file));
|
|
11603
|
-
for (const scannedFile of scannedFiles) {
|
|
12074
|
+
for (const scannedFile of Array.from(scannedFiles)) {
|
|
11604
12075
|
if (!filesWithViolations.has(scannedFile)) {
|
|
11605
12076
|
for (const goal of activeGoals) {
|
|
11606
12077
|
const resolvedCount = await resolveGoalViolation(scannedFile, goal.description, projectPath);
|
|
@@ -11636,7 +12107,7 @@ ${filesBlock}`,
|
|
|
11636
12107
|
const graph = new ContextGraph(projectPath);
|
|
11637
12108
|
if (hasLinear) {
|
|
11638
12109
|
try {
|
|
11639
|
-
const { LinearIngester } = await import("./linear-ingester-
|
|
12110
|
+
const { LinearIngester } = await import("./linear-ingester-XXPAZZRW.js");
|
|
11640
12111
|
const ingester = new LinearIngester(projectPath, graph);
|
|
11641
12112
|
await ingester.syncTickets();
|
|
11642
12113
|
if (!isInteractiveMode()) {
|
|
@@ -11650,7 +12121,7 @@ ${filesBlock}`,
|
|
|
11650
12121
|
}
|
|
11651
12122
|
if (hasGithub) {
|
|
11652
12123
|
try {
|
|
11653
|
-
const { GitHubIngester } = await import("./github-ingester-
|
|
12124
|
+
const { GitHubIngester } = await import("./github-ingester-ZOKK6GRS.js");
|
|
11654
12125
|
const ingester = new GitHubIngester(graph);
|
|
11655
12126
|
const token = await ingester.getApiToken();
|
|
11656
12127
|
const repoInfo = ingester.getRepoInfo(projectPath);
|
|
@@ -11750,7 +12221,7 @@ Use \`trie_watch start\` to begin autonomous scanning.`
|
|
|
11750
12221
|
).join("\n");
|
|
11751
12222
|
let agencyStatus = "";
|
|
11752
12223
|
try {
|
|
11753
|
-
const { getTrieAgent: getTrieAgent2 } = await import("./trie-agent-
|
|
12224
|
+
const { getTrieAgent: getTrieAgent2 } = await import("./trie-agent-3YDPEGHJ.js");
|
|
11754
12225
|
const trieAgent = getTrieAgent2(this.watchedDirectory || getWorkingDirectory(void 0, true));
|
|
11755
12226
|
await trieAgent.initialize();
|
|
11756
12227
|
const status = await trieAgent.getAgencyStatus();
|
|
@@ -11923,7 +12394,7 @@ To get a full report, run \`trie watch\` on your codebase.`
|
|
|
11923
12394
|
console.debug("[Watch] resolveNudgesForMissingFiles failed:", e);
|
|
11924
12395
|
}
|
|
11925
12396
|
try {
|
|
11926
|
-
const { getActiveGoals } = await import("./goal-validator-
|
|
12397
|
+
const { getActiveGoals } = await import("./goal-validator-ULKIBDPX.js");
|
|
11927
12398
|
const { getProjectState: getProjectState2 } = await import("./project-state-AHPA77SM.js");
|
|
11928
12399
|
const projectState = getProjectState2(directory);
|
|
11929
12400
|
await projectState.load();
|
|
@@ -11946,6 +12417,85 @@ To get a full report, run \`trie watch\` on your codebase.`
|
|
|
11946
12417
|
console.log(`[Watch] \u2713 Cleaned up ${totalResolved} stale nudge(s)`);
|
|
11947
12418
|
}
|
|
11948
12419
|
}
|
|
12420
|
+
/**
|
|
12421
|
+
* Run compliance validation to detect false negatives
|
|
12422
|
+
*/
|
|
12423
|
+
async runComplianceValidation(projectPath) {
|
|
12424
|
+
try {
|
|
12425
|
+
const config = await loadConfig(projectPath);
|
|
12426
|
+
const complianceFrameworks = config?.compliance?.standards || ["SOC2"];
|
|
12427
|
+
if (!config?.compliance?.falseNegativeDetection?.enabled) {
|
|
12428
|
+
return;
|
|
12429
|
+
}
|
|
12430
|
+
const samplingRate = config?.compliance?.falseNegativeDetection?.samplingRate || 0.1;
|
|
12431
|
+
if (Math.random() > samplingRate) {
|
|
12432
|
+
return;
|
|
12433
|
+
}
|
|
12434
|
+
console.log(`[Watch] Running compliance validation for frameworks: ${complianceFrameworks.join(", ")}`);
|
|
12435
|
+
const validation = await runFalseNegativeValidation(complianceFrameworks, projectPath);
|
|
12436
|
+
const criticalAlerts = validation.alerts.filter((a) => a.severity === "critical");
|
|
12437
|
+
if (criticalAlerts.length > 0) {
|
|
12438
|
+
console.error(`[Watch] \u26A0\uFE0F ${criticalAlerts.length} critical compliance alert(s) detected:`);
|
|
12439
|
+
for (const alert of criticalAlerts) {
|
|
12440
|
+
console.error(` - ${alert.type}: ${alert.description}`);
|
|
12441
|
+
console.error(` Action: ${alert.suggestedAction}`);
|
|
12442
|
+
}
|
|
12443
|
+
const complianceIssues = criticalAlerts.map((alert) => ({
|
|
12444
|
+
id: alert.id,
|
|
12445
|
+
hash: createHash3("sha256").update(`${alert.id}-${alert.timestamp}`).digest("hex"),
|
|
12446
|
+
file: "compliance-validation",
|
|
12447
|
+
line: 1,
|
|
12448
|
+
agent: "compliance-validator",
|
|
12449
|
+
issue: alert.description,
|
|
12450
|
+
fix: alert.suggestedAction,
|
|
12451
|
+
severity: alert.severity,
|
|
12452
|
+
timestamp: alert.timestamp,
|
|
12453
|
+
category: "compliance",
|
|
12454
|
+
confidence: alert.confidence,
|
|
12455
|
+
autoFixable: false
|
|
12456
|
+
}));
|
|
12457
|
+
await storeIssues(complianceIssues, basename(projectPath), projectPath);
|
|
12458
|
+
if (this.streamingManager) {
|
|
12459
|
+
this.streamingManager.reportLedgerUpdate(complianceIssues.length, "incident");
|
|
12460
|
+
}
|
|
12461
|
+
}
|
|
12462
|
+
const highAlerts = validation.alerts.filter((a) => a.severity === "high");
|
|
12463
|
+
if (highAlerts.length > 0) {
|
|
12464
|
+
console.warn(`[Watch] \u26A0\uFE0F ${highAlerts.length} high-priority compliance alert(s) detected`);
|
|
12465
|
+
}
|
|
12466
|
+
if (validation.coverageGaps.length > 0) {
|
|
12467
|
+
console.warn(`[Watch] \u26A0\uFE0F ${validation.coverageGaps.length} compliance coverage gap(s) detected`);
|
|
12468
|
+
}
|
|
12469
|
+
if (validation.recommendations.length > 0 && criticalAlerts.length === 0) {
|
|
12470
|
+
console.log(`[Watch] \u{1F4A1} ${validation.recommendations.length} compliance recommendation(s) available`);
|
|
12471
|
+
}
|
|
12472
|
+
if (validation.valid) {
|
|
12473
|
+
console.log("[Watch] \u2713 Compliance validation passed");
|
|
12474
|
+
}
|
|
12475
|
+
} catch (error) {
|
|
12476
|
+
console.error("[Watch] Compliance validation failed:", error);
|
|
12477
|
+
if (error instanceof Error) {
|
|
12478
|
+
const validationFailure = [{
|
|
12479
|
+
id: `compliance-validation-error-${Date.now()}`,
|
|
12480
|
+
hash: createHash3("sha256").update(`validation-error-${Date.now()}`).digest("hex"),
|
|
12481
|
+
file: "compliance-validation",
|
|
12482
|
+
line: 1,
|
|
12483
|
+
agent: "compliance-validator",
|
|
12484
|
+
issue: `Compliance validation system failure: ${error.message}`,
|
|
12485
|
+
fix: "Investigate and restore compliance validation system",
|
|
12486
|
+
severity: "critical",
|
|
12487
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12488
|
+
category: "compliance",
|
|
12489
|
+
confidence: 100,
|
|
12490
|
+
autoFixable: false
|
|
12491
|
+
}];
|
|
12492
|
+
await storeIssues(validationFailure, basename(projectPath), projectPath);
|
|
12493
|
+
if (this.streamingManager) {
|
|
12494
|
+
this.streamingManager.reportLedgerUpdate(1, "incident");
|
|
12495
|
+
}
|
|
12496
|
+
}
|
|
12497
|
+
}
|
|
12498
|
+
}
|
|
11949
12499
|
};
|
|
11950
12500
|
|
|
11951
12501
|
export {
|
|
@@ -11966,10 +12516,9 @@ export {
|
|
|
11966
12516
|
TrieGetNudgesTool,
|
|
11967
12517
|
TrieQueryContextTool,
|
|
11968
12518
|
TrieQueryLedgerBlocksTool,
|
|
11969
|
-
handleCheckpointTool,
|
|
11970
12519
|
TriePipelineTool,
|
|
11971
12520
|
GitHubBranchesTool,
|
|
11972
12521
|
InteractiveDashboard,
|
|
11973
12522
|
TrieWatchTool
|
|
11974
12523
|
};
|
|
11975
|
-
//# sourceMappingURL=chunk-
|
|
12524
|
+
//# sourceMappingURL=chunk-LQIMKE3P.js.map
|