agent-recall-core 3.4.20 → 3.4.22

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.
Files changed (52) hide show
  1. package/dist/helpers/journal-files.d.ts +23 -0
  2. package/dist/helpers/journal-files.d.ts.map +1 -1
  3. package/dist/helpers/journal-files.js +99 -0
  4. package/dist/helpers/journal-files.js.map +1 -1
  5. package/dist/index.d.ts +11 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +6 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/palace/index-manager.d.ts.map +1 -1
  10. package/dist/palace/index-manager.js +33 -28
  11. package/dist/palace/index-manager.js.map +1 -1
  12. package/dist/palace/rooms.d.ts +21 -3
  13. package/dist/palace/rooms.d.ts.map +1 -1
  14. package/dist/palace/rooms.js +74 -10
  15. package/dist/palace/rooms.js.map +1 -1
  16. package/dist/storage/behavior-policies.d.ts +54 -0
  17. package/dist/storage/behavior-policies.d.ts.map +1 -0
  18. package/dist/storage/behavior-policies.js +98 -0
  19. package/dist/storage/behavior-policies.js.map +1 -0
  20. package/dist/storage/cwd-allowlist.d.ts +33 -0
  21. package/dist/storage/cwd-allowlist.d.ts.map +1 -0
  22. package/dist/storage/cwd-allowlist.js +106 -0
  23. package/dist/storage/cwd-allowlist.js.map +1 -0
  24. package/dist/storage/dream-health.d.ts +19 -0
  25. package/dist/storage/dream-health.d.ts.map +1 -0
  26. package/dist/storage/dream-health.js +79 -0
  27. package/dist/storage/dream-health.js.map +1 -0
  28. package/dist/storage/project.d.ts +6 -0
  29. package/dist/storage/project.d.ts.map +1 -1
  30. package/dist/storage/project.js +26 -1
  31. package/dist/storage/project.js.map +1 -1
  32. package/dist/tools-logic/check-action.d.ts +55 -0
  33. package/dist/tools-logic/check-action.d.ts.map +1 -0
  34. package/dist/tools-logic/check-action.js +152 -0
  35. package/dist/tools-logic/check-action.js.map +1 -0
  36. package/dist/tools-logic/palace-write.d.ts.map +1 -1
  37. package/dist/tools-logic/palace-write.js +9 -2
  38. package/dist/tools-logic/palace-write.js.map +1 -1
  39. package/dist/tools-logic/project-status.d.ts.map +1 -1
  40. package/dist/tools-logic/project-status.js +30 -0
  41. package/dist/tools-logic/project-status.js.map +1 -1
  42. package/dist/tools-logic/register-rule.d.ts +15 -0
  43. package/dist/tools-logic/register-rule.d.ts.map +1 -0
  44. package/dist/tools-logic/register-rule.js +13 -0
  45. package/dist/tools-logic/register-rule.js.map +1 -0
  46. package/dist/tools-logic/session-start.d.ts +24 -0
  47. package/dist/tools-logic/session-start.d.ts.map +1 -1
  48. package/dist/tools-logic/session-start.js +124 -18
  49. package/dist/tools-logic/session-start.js.map +1 -1
  50. package/dist/types.d.ts +1 -1
  51. package/dist/types.js +1 -1
  52. package/package.json +1 -1
@@ -0,0 +1,152 @@
1
+ /**
2
+ * check_action — pre-action proactive matcher.
3
+ *
4
+ * Solves items 3 + 5 of the feedback brief:
5
+ * - "watch_for is too generic" — needs to fire when the agent is about to do
6
+ * something a past correction warned against, mid-session.
7
+ * - "no mid-session recall hook" — insights surface at startup and are
8
+ * forgotten by turn 20.
9
+ *
10
+ * Both pains share the same primitive: "before doing X, return matching
11
+ * rules / corrections / insights." This tool is that primitive.
12
+ *
13
+ * Deterministic keyword matching only (no LLM). The agent calls this before
14
+ * any non-trivial action; the result is a short list of relevant memory items
15
+ * that would otherwise have to be re-derived.
16
+ */
17
+ import { resolveProject } from "../storage/project.js";
18
+ import { readActiveCorrections } from "./../storage/corrections.js";
19
+ import { readBehaviorPolicies } from "../storage/behavior-policies.js";
20
+ import { readAwarenessState } from "../palace/awareness.js";
21
+ const STOPWORDS = new Set([
22
+ "the", "a", "an", "and", "or", "but", "is", "are", "was", "were", "be", "been",
23
+ "being", "have", "has", "had", "do", "does", "did", "will", "would", "should",
24
+ "could", "may", "might", "must", "shall", "can", "to", "of", "in", "on", "at",
25
+ "by", "for", "with", "about", "against", "between", "into", "through", "during",
26
+ "before", "after", "above", "below", "from", "up", "down", "out", "off", "over",
27
+ "under", "again", "further", "then", "once", "here", "there", "when", "where",
28
+ "why", "how", "all", "any", "both", "each", "few", "more", "most", "other",
29
+ "some", "such", "no", "nor", "not", "only", "own", "same", "so", "than", "too",
30
+ "very", "this", "that", "these", "those", "i", "you", "he", "she", "it", "we",
31
+ "they", "them", "their", "what", "which", "who", "whom", "whose", "as", "if",
32
+ "my", "your", "our", "let", "lets", "going", "make", "made", "go", "want", "need",
33
+ ]);
34
+ function tokenize(s) {
35
+ return new Set(s
36
+ .toLowerCase()
37
+ .normalize("NFKD")
38
+ .replace(/[^a-z0-9\s\-]+/g, " ")
39
+ .split(/\s+/)
40
+ .filter((w) => w.length >= 3 && !STOPWORDS.has(w)));
41
+ }
42
+ function overlap(a, b) {
43
+ const hits = [];
44
+ for (const t of a)
45
+ if (b.has(t))
46
+ hits.push(t);
47
+ return hits.sort();
48
+ }
49
+ export async function checkAction(input) {
50
+ const slug = await resolveProject(input.project);
51
+ const action = (input.action_description ?? "").trim();
52
+ if (!action) {
53
+ return {
54
+ success: false,
55
+ project: slug,
56
+ action: "",
57
+ matching_rules: [],
58
+ matching_corrections: [],
59
+ matching_insights: [],
60
+ warning: null,
61
+ };
62
+ }
63
+ // Default min_overlap=2 — with a populated awareness store, 1-token matches
64
+ // produce too many false positives (single common word in dozens of insights
65
+ // → noise). 2 requires the action and the memory item to share at least two
66
+ // distinct content words, which is the right floor for relevance.
67
+ const minOverlap = input.min_overlap && input.min_overlap > 0 ? input.min_overlap : 2;
68
+ const actionTokens = tokenize(action);
69
+ // 1. Behavior rules — match on rule.when + rule.do + rule.name
70
+ const ruleMatches = [];
71
+ const rules = readBehaviorPolicies(slug).rules;
72
+ for (const r of rules) {
73
+ const ruleTokens = tokenize(`${r.name} ${r.when} ${r.do}`);
74
+ const matched = overlap(actionTokens, ruleTokens);
75
+ if (matched.length >= minOverlap) {
76
+ ruleMatches.push({ id: r.id, name: r.name, when: r.when, do: r.do, matched_tokens: matched });
77
+ }
78
+ }
79
+ // 2. Corrections — match on rule + context
80
+ const correctionMatches = [];
81
+ const corrections = readActiveCorrections(slug);
82
+ for (const c of corrections) {
83
+ const cTokens = tokenize(`${c.rule} ${c.context} ${(c.tags ?? []).join(" ")}`);
84
+ const matched = overlap(actionTokens, cTokens);
85
+ if (matched.length >= minOverlap) {
86
+ correctionMatches.push({
87
+ id: c.id,
88
+ rule: c.rule,
89
+ severity: c.severity,
90
+ date: c.date,
91
+ matched_tokens: matched,
92
+ });
93
+ }
94
+ }
95
+ // 3. Insights — match on insight.title
96
+ const insightMatches = [];
97
+ const awareness = readAwarenessState();
98
+ for (const i of awareness?.topInsights ?? []) {
99
+ const iTokens = tokenize(i.title);
100
+ const matched = overlap(actionTokens, iTokens);
101
+ if (matched.length >= minOverlap) {
102
+ insightMatches.push({
103
+ title: i.title,
104
+ confirmations: i.confirmations ?? 1,
105
+ severity: i.severity ?? "important",
106
+ matched_tokens: matched,
107
+ });
108
+ }
109
+ }
110
+ // Sort each by relevance (matched_tokens.length DESC, then severity)
111
+ ruleMatches.sort((a, b) => b.matched_tokens.length - a.matched_tokens.length);
112
+ correctionMatches.sort((a, b) => {
113
+ if (a.severity !== b.severity)
114
+ return a.severity === "p0" ? -1 : 1;
115
+ return b.matched_tokens.length - a.matched_tokens.length;
116
+ });
117
+ insightMatches.sort((a, b) => {
118
+ if (b.matched_tokens.length !== a.matched_tokens.length) {
119
+ return b.matched_tokens.length - a.matched_tokens.length;
120
+ }
121
+ return b.confirmations - a.confirmations;
122
+ });
123
+ // Cap to keep output small
124
+ const topRules = ruleMatches.slice(0, 5);
125
+ const topCorrections = correctionMatches.slice(0, 5);
126
+ const topInsights = insightMatches.slice(0, 3);
127
+ // Build human-readable warning if anything matched
128
+ let warning = null;
129
+ if (topRules.length + topCorrections.length + topInsights.length > 0) {
130
+ const parts = [`Before "${action.slice(0, 80)}":`];
131
+ for (const r of topRules) {
132
+ parts.push(` 📜 RULE [${r.name}] WHEN ${r.when} → DO ${r.do}`);
133
+ }
134
+ for (const c of topCorrections) {
135
+ parts.push(` ⛔ ${c.severity.toUpperCase()} (${c.date}): ${c.rule}`);
136
+ }
137
+ for (const i of topInsights) {
138
+ parts.push(` 💡 [${i.confirmations}×] ${i.title}`);
139
+ }
140
+ warning = parts.join("\n");
141
+ }
142
+ return {
143
+ success: true,
144
+ project: slug,
145
+ action,
146
+ matching_rules: topRules,
147
+ matching_corrections: topCorrections,
148
+ matching_insights: topInsights,
149
+ warning,
150
+ };
151
+ }
152
+ //# sourceMappingURL=check-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-action.js","sourceRoot":"","sources":["../../src/tools-logic/check-action.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"palace-write.d.ts","sourceRoot":"","sources":["../../src/tools-logic/palace-write.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;CACjB;AASD,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgFrF"}
1
+ {"version":3,"file":"palace-write.d.ts","sourceRoot":"","sources":["../../src/tools-logic/palace-write.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE;QAAE,aAAa,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;CACjB;AASD,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuFrF"}
@@ -64,11 +64,18 @@ export async function palaceWrite(input) {
64
64
  }
65
65
  else {
66
66
  const fm = generateFrontmatter({ room: input.room, topic: targetTopic, created: timestamp, importance, tags: input.tags ?? [] });
67
- fs.writeFileSync(targetFile, `${fm}# ${input.room} / ${targetTopic}\n\n${content}\n`, "utf-8");
67
+ // Wrap the first write in a `### DATE — importance` entry block (same as the
68
+ // append path + README path). Without this, countRoomEntries() — which counts
69
+ // `### ` headers — would report 0 for a brand-new topic file, sorting a room
70
+ // with real content as "empty" and zeroing its salience.
71
+ const entry = `### ${timestamp.slice(0, 10)} — ${importance}\n\n${content}\n`;
72
+ fs.writeFileSync(targetFile, `${fm}# ${input.room} / ${targetTopic}\n\n${entry}`, "utf-8");
68
73
  }
69
74
  }
70
75
  updateRoomMeta(slug, input.room, { updated: timestamp });
71
- recordAccess(slug, input.room);
76
+ // Propagate the real importance of this write into the salience formula so
77
+ // --importance high measurably raises the room's salience (not always medium).
78
+ recordAccess(slug, input.room, importance);
72
79
  // Async sync to Supabase (non-blocking)
73
80
  const writtenContent = fs.readFileSync(targetFile, "utf-8");
74
81
  syncToSupabase(targetFile, writtenContent, slug, "palace", input.room);
@@ -1 +1 @@
1
- {"version":3,"file":"palace-write.js","sourceRoot":"","sources":["../../src/tools-logic/palace-write.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"palace-write.js","sourceRoot":"","sources":["../../src/tools-logic/palace-write.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"project-status.d.ts","sourceRoot":"","sources":["../../src/tools-logic/project-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACvE,YAAY,EAAE,MAAM,CAAC;CACtB;AA6BD,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyF3F"}
1
+ {"version":3,"file":"project-status.d.ts","sourceRoot":"","sources":["../../src/tools-logic/project-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACvE,YAAY,EAAE,MAAM,CAAC;CACtB;AA6BD,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkH3F"}
@@ -82,6 +82,36 @@ export async function projectStatus(input) {
82
82
  }
83
83
  // Sort candidates newest first (by date prefix then reverse alpha for same-day)
84
84
  candidateFiles.sort((a, b) => path.basename(b).localeCompare(path.basename(a)));
85
+ // 4b. Capture-log fallback — a project with ONLY journal_capture writes (no
86
+ // committed session_end) still has real on-disk memory. session_start treats
87
+ // these as non-empty, so project_status must agree: fold capture-log dates
88
+ // into latestDate when no committed daily journal exists. (Capture logs are
89
+ // excluded from trajectory extraction above — they have no ## Next section.)
90
+ if (!latestDate) {
91
+ for (const dir of dirs) {
92
+ if (!fs.existsSync(dir))
93
+ continue;
94
+ let files;
95
+ try {
96
+ files = fs.readdirSync(dir);
97
+ }
98
+ catch {
99
+ continue;
100
+ }
101
+ for (const f of files) {
102
+ if (!f.endsWith(".md"))
103
+ continue;
104
+ if (!f.includes("-log.") && !f.includes("--capture--"))
105
+ continue;
106
+ const dateMatch = f.match(/^(\d{4}-\d{2}-\d{2})/);
107
+ if (!dateMatch)
108
+ continue;
109
+ const d = dateMatch[1];
110
+ if (!latestDate || d > latestDate)
111
+ latestDate = d;
112
+ }
113
+ }
114
+ }
85
115
  // 5. Extract trajectory — scan candidates until ## Next is found (fallback across files)
86
116
  let last_trajectory = null;
87
117
  for (const file of candidateFiles) {
@@ -1 +1 @@
1
- {"version":3,"file":"project-status.js","sourceRoot":"","sources":["../../src/tools-logic/project-status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-status.js","sourceRoot":"","sources":["../../src/tools-logic/project-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface RegisterRuleToolInput {
2
+ project?: string;
3
+ name: string;
4
+ when: string;
5
+ do: string;
6
+ }
7
+ export interface RegisterRuleToolResult {
8
+ success: boolean;
9
+ project: string;
10
+ rule_id?: string;
11
+ total_rules?: number;
12
+ error?: string;
13
+ }
14
+ export declare function registerRule(input: RegisterRuleToolInput): Promise<RegisterRuleToolResult>;
15
+ //# sourceMappingURL=register-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-rule.d.ts","sourceRoot":"","sources":["../../src/tools-logic/register-rule.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAShG"}
@@ -0,0 +1,13 @@
1
+ import { resolveProject } from "../storage/project.js";
2
+ import { registerBehaviorRule } from "../storage/behavior-policies.js";
3
+ export async function registerRule(input) {
4
+ const slug = await resolveProject(input.project);
5
+ const r = registerBehaviorRule({
6
+ project: slug,
7
+ name: input.name,
8
+ when: input.when,
9
+ do: input.do,
10
+ });
11
+ return { ...r, project: slug };
12
+ }
13
+ //# sourceMappingURL=register-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-rule.js","sourceRoot":"","sources":["../../src/tools-logic/register-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAiBvE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAA4B;IAC7D,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,CAAC,GAAG,oBAAoB,CAAC;QAC7B,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC"}
@@ -6,6 +6,8 @@
6
6
  */
7
7
  import { type WatchForPattern } from "../helpers/alignment-patterns.js";
8
8
  import { type CorrectionRecord } from "../storage/corrections.js";
9
+ import { type DreamHealth } from "../storage/dream-health.js";
10
+ import { type BehaviorRule } from "../storage/behavior-policies.js";
9
11
  export interface SessionStartInput {
10
12
  project?: string;
11
13
  context?: string;
@@ -37,6 +39,16 @@ export interface SessionStartResult {
37
39
  yesterday: string | null;
38
40
  older_count: number;
39
41
  };
42
+ /**
43
+ * Capture-log entries written by `journal_capture` that have NOT yet been
44
+ * committed via `session_end`. Surfaced so the agent sees in-flight work
45
+ * instead of "No memory found". Empty array when there are none.
46
+ */
47
+ recent_captures: Array<{
48
+ date: string;
49
+ question: string;
50
+ answer: string;
51
+ }>;
40
52
  watch_for: WatchForPattern[];
41
53
  corrections: CorrectionRecord[];
42
54
  resume: {
@@ -44,6 +56,18 @@ export interface SessionStartResult {
44
56
  last_trajectory: string | null;
45
57
  sessions_count: number;
46
58
  } | null;
59
+ /**
60
+ * Always-loaded behavior policies — IF-THEN rules that govern agent
61
+ * conduct. Surfaced at the TOP of session_start above insights/rooms so
62
+ * the agent treats them as commitments, not advisory context.
63
+ */
64
+ behavior_rules: BehaviorRule[];
65
+ /**
66
+ * Dream cron health — null when healthy, populated when ≥2 consecutive
67
+ * failure nights detected. Surfaced as a red banner so users notice the
68
+ * awareness backfill is broken instead of finding out days later.
69
+ */
70
+ dream_health: DreamHealth | null;
47
71
  /**
48
72
  * Project narrative spine summary. Null when no pipeline files exist.
49
73
  * Shape: { active_phase, closed_count, last_synthesis, stale_days }
@@ -1 +1 @@
1
- {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/tools-logic/session-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,EAAsE,KAAK,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAC5I,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAkBrF,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxF,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpI,aAAa,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChF,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI,CAAC;IACT;;;OAGG;IACH,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,uBAAuB,EAAE,MAAM,CAAC;QAChC,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,GAAG,IAAI,CAAC;IACT,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoNxF"}
1
+ {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/tools-logic/session-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,EAAsE,KAAK,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAC5I,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAUrF,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAA0C,KAAK,YAAY,EAAE,MAAM,iCAAiC,CAAC;AA4B5G,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxF,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpI,aAAa,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChF;;;;OAIG;IACH,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3E,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI,CAAC;IACT;;;;OAIG;IACH,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B;;;;OAIG;IACH,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;;OAGG;IACH,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,uBAAuB,EAAE,MAAM,CAAC;QAChC,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,GAAG,IAAI,CAAC;IACT,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA6SxF"}
@@ -6,10 +6,10 @@
6
6
  */
7
7
  import { resolveProject } from "../storage/project.js";
8
8
  import { resetOwnedFiles } from "../storage/session.js";
9
- import { ensurePalaceInitialized, listRooms, isRoomStale } from "../palace/rooms.js";
9
+ import { ensurePalaceInitialized, listRooms, isRoomStale, countRoomEntries } from "../palace/rooms.js";
10
10
  import { readIdentity } from "../palace/identity.js";
11
11
  import { readAwarenessState, fetchDashboardArchivedTitles } from "../palace/awareness.js";
12
- import { recallInsights } from "../palace/insights-index.js";
12
+ import { recallInsights, readInsightsIndex } from "../palace/insights-index.js";
13
13
  import { journalDirs } from "../storage/paths.js";
14
14
  import { extractSection } from "../helpers/sections.js";
15
15
  import { todayISO } from "../storage/fs-utils.js";
@@ -17,12 +17,15 @@ import { readAlignmentLog, extractWatchPatterns, computeDecisionCalibration } fr
17
17
  import { readP0Corrections } from "../storage/corrections.js";
18
18
  import { extractKeywords } from "../helpers/auto-name.js";
19
19
  import { isJournalFile } from "../helpers/journal-filter.js";
20
+ import { hasCaptureLogs, readRecentCaptures } from "../helpers/journal-files.js";
20
21
  import * as fs from "node:fs";
21
22
  import * as path from "node:path";
22
23
  import { getRoot } from "../types.js";
23
24
  import { readSupabaseConfig } from "../supabase/config.js";
24
25
  import { backfill } from "../supabase/sync.js";
25
26
  import { listMilestones } from "../palace/pipeline.js";
27
+ import { getDreamHealth } from "../storage/dream-health.js";
28
+ import { readBehaviorPolicies, recordPolicyLoad } from "../storage/behavior-policies.js";
26
29
  /** Slice text at the nearest word boundary, avoiding mid-word truncation. */
27
30
  function sliceAtWord(text, maxLen) {
28
31
  if (text.length <= maxLen)
@@ -31,6 +34,23 @@ function sliceAtWord(text, maxLen) {
31
34
  const lastSpace = sliced.lastIndexOf(" ");
32
35
  return lastSpace > maxLen * 0.6 ? sliced.slice(0, lastSpace) : sliced;
33
36
  }
37
+ /**
38
+ * Strip markdown ATX headers from a journal fragment before embedding it into
39
+ * a card field. `extractSection(content, "next")` returns the section heading
40
+ * line ("## Next") followed by the body, so a naive embed leaks
41
+ * "Trajectory: ## Next…" into the card. We drop entire heading lines
42
+ * (`^#+\s.*`) rather than just the `#` markers — otherwise "## Next" collapses
43
+ * to a stray "Next" line in front of the real content. Blank lines are then
44
+ * collapsed and the result trimmed.
45
+ */
46
+ function stripMarkdownHeaders(text) {
47
+ return text
48
+ .split("\n")
49
+ .filter((line) => !/^\s*#+\s/.test(line))
50
+ .join("\n")
51
+ .replace(/\n{2,}/g, "\n")
52
+ .trim();
53
+ }
34
54
  export async function sessionStart(input) {
35
55
  // Reset owned-files state from any previous session in the same process
36
56
  resetOwnedFiles();
@@ -63,19 +83,65 @@ export async function sessionStart(input) {
63
83
  // Tiebreak: most recently confirmed first
64
84
  return (b.lastConfirmed ?? "").localeCompare(a.lastConfirmed ?? "");
65
85
  });
66
- // Filter out insights archived via the dashboard (Supabase sync-back)
67
- const archivedTitles = await fetchDashboardArchivedTitles();
68
- if (archivedTitles.length > 0) {
69
- sortedInsights = sortedInsights.filter(i => !archivedTitles.includes(i.title));
86
+ // Filter out insights archived via the dashboard (Supabase sync-back).
87
+ // Case-insensitive match dedup elsewhere normalizes to lowercase, so the
88
+ // archive filter must too (else "Bug Fix" fails to suppress "bug fix").
89
+ const archivedLower = new Set((await fetchDashboardArchivedTitles()).map((t) => t.toLowerCase()));
90
+ if (archivedLower.size > 0) {
91
+ sortedInsights = sortedInsights.filter(i => !archivedLower.has(i.title.toLowerCase()));
70
92
  }
71
- const insights = sortedInsights.slice(0, 8).map((i) => ({
93
+ // Cap startup noise: top 3 awareness insights (was 8). Anything below the
94
+ // top 3 by salience pollutes more than it informs at session-start. Agents
95
+ // can pull deeper via recall() on demand.
96
+ const insights = sortedInsights.slice(0, 3).map((i) => ({
72
97
  title: sliceAtWord(i.title, 200),
73
98
  confirmed: i.confirmations ?? 1,
74
99
  severity: i.severity ?? "important",
75
100
  trend: i.trend,
76
101
  }));
77
- // 3. Active rooms top 5 by salience
78
- const rooms = listRooms(slug).slice(0, 5);
102
+ // 2b. P0-3guarantee a session-1 insight is visible at session-2.
103
+ // Confirmation count must control ORDER/verbosity, never EXISTENCE. The
104
+ // global awareness `topInsights` only receives an index insight once
105
+ // `promoteConfirmedInsights` fires (confirmed_count >= 3), so a brand-new
106
+ // single-confirmation insight stored by session_end can be absent from
107
+ // `topInsights` while living in the project-scoped insights-index. Surface
108
+ // those directly so they appear from confirmation count 1.
109
+ const index = readInsightsIndex();
110
+ const projectIndexInsights = index.insights
111
+ .filter((i) => (i.projects ?? []).includes(slug))
112
+ .filter((i) => !archivedLower.has(i.title.toLowerCase()))
113
+ .sort((a, b) => b.confirmed_count - a.confirmed_count || (b.last_confirmed ?? "").localeCompare(a.last_confirmed ?? ""));
114
+ // RESERVED SLOTS: project-scoped index insights get their own budget (up to 2)
115
+ // ON TOP of the awareness top-3. If we shared one cap, an established project
116
+ // whose global awareness already has 3+ insights would never surface a fresh
117
+ // session-1 insight — the cap would be full before this loop ran. P0-3 requires
118
+ // existence, not just ordering, so the budget must be independent.
119
+ const seenTitles = new Set(insights.map((i) => i.title.toLowerCase()));
120
+ const PROJECT_INSIGHT_BUDGET = 2;
121
+ let projectAdded = 0;
122
+ for (const idx of projectIndexInsights) {
123
+ if (projectAdded >= PROJECT_INSIGHT_BUDGET)
124
+ break;
125
+ if (seenTitles.has(idx.title.toLowerCase()))
126
+ continue;
127
+ insights.push({
128
+ title: sliceAtWord(idx.title, 200),
129
+ confirmed: idx.confirmed_count ?? 1,
130
+ severity: idx.severity ?? "important",
131
+ trend: undefined,
132
+ });
133
+ seenTitles.add(idx.title.toLowerCase());
134
+ projectAdded++;
135
+ }
136
+ // Keep highest-confirmed first (order, not existence, is the threshold's job).
137
+ // Total visible = up to 3 awareness + up to 2 project-scoped = max 5.
138
+ insights.sort((a, b) => b.confirmed - a.confirmed);
139
+ // 3. Active rooms — top 3 by salience (was 5). Same noise-cap rationale.
140
+ // Call listRooms ONCE — it internally scans every room via countRoomEntries
141
+ // to enforce the empty-last sort. Reuse the result for both active_rooms and
142
+ // the hasPalaceContent check below (avoids a 2nd full sort + 3rd scan pass).
143
+ const allRooms = listRooms(slug);
144
+ const rooms = allRooms.slice(0, 3);
79
145
  const active_rooms = rooms.map((r) => ({
80
146
  name: r.name,
81
147
  salience: r.salience,
@@ -93,9 +159,11 @@ export async function sessionStart(input) {
93
159
  active_rooms[i].topics = topics;
94
160
  }
95
161
  }
96
- // 4. Cross-project insights matching current context
162
+ // 4. Cross-project insights matching current context — cap at 1 (was 5).
163
+ // The top match is almost always the only one worth surfacing at startup;
164
+ // additional hits are noise. Agents can pull more via recall() when needed.
97
165
  const context = input.context ?? slug;
98
- const matched = recallInsights(context, 5, slug);
166
+ const matched = recallInsights(context, 1, slug);
99
167
  const cross_project = matched.map((i) => ({
100
168
  title: sliceAtWord(i.title, 100),
101
169
  from_project: (i.projects?.[0] ?? (i.source ?? "unknown").replace(/\s+\d{4}-\d{2}-\d{2}.*$/, "")).slice(0, 30),
@@ -120,13 +188,15 @@ export async function sessionStart(input) {
120
188
  if (d === today) {
121
189
  const content = fs.readFileSync(path.join(dir, file), "utf-8");
122
190
  const brief = extractSection(content, "brief");
123
- const entry = brief ? sliceAtWord(brief, 400) : sliceAtWord(content.split("\n").slice(0, 3).join(" "), 400);
191
+ const raw = brief ? brief : content.split("\n").slice(0, 3).join(" ");
192
+ const entry = sliceAtWord(stripMarkdownHeaders(raw), 400);
124
193
  todayBrief = todayBrief ? `${todayBrief} | ${entry}` : entry;
125
194
  }
126
195
  else if (d === yesterday && !yesterdayBrief) {
127
196
  const content = fs.readFileSync(path.join(dir, file), "utf-8");
128
197
  const brief = extractSection(content, "brief");
129
- yesterdayBrief = brief ? sliceAtWord(brief, 400) : sliceAtWord(content.split("\n").slice(0, 3).join(" "), 400);
198
+ const raw = brief ? brief : content.split("\n").slice(0, 3).join(" ");
199
+ yesterdayBrief = sliceAtWord(stripMarkdownHeaders(raw), 400);
130
200
  }
131
201
  else if (d < yesterday) {
132
202
  olderCount++;
@@ -175,7 +245,9 @@ export async function sessionStart(input) {
175
245
  // session_end writes trajectory under "## Next" — use "next" key to extract it
176
246
  const trajectorySection = extractSection(content, "next") ?? extractSection(content, "trajectory");
177
247
  if (trajectorySection) {
178
- lastTrajectory = sliceAtWord(trajectorySection, 200);
248
+ // Strip the leading "## Next" (or any markdown header) so it never
249
+ // leaks into the rendered card as "Trajectory: ## Next…".
250
+ lastTrajectory = sliceAtWord(stripMarkdownHeaders(trajectorySection), 200);
179
251
  }
180
252
  }
181
253
  resume = {
@@ -184,13 +256,31 @@ export async function sessionStart(input) {
184
256
  sessions_count: sessionsCount,
185
257
  };
186
258
  }
187
- // 9. Empty state detection guide first-time agents on THIS project
188
- // Uses project-scoped signals only: no journals, no corrections, no resume
189
- // cross_project and insights are global a returning user always has those
259
+ // 8c. Recent capturesjournal_capture writes that pre-date any session_end.
260
+ // These live in `*-log.md` / `--capture--` files the orientation path skips,
261
+ // so without this an agent that captured 4 things sees "No memory found".
262
+ const recentCaptures = readRecentCaptures(slug, 5);
263
+ // 9. Empty state detection — guide first-time agents on THIS project.
264
+ // The filesystem is the single source of truth: ANY committed store
265
+ // (resume/journal/corrections) OR uncommitted store (captures) OR real
266
+ // palace content makes the project non-empty. session_end is NOT a
267
+ // prerequisite for visibility.
268
+ //
269
+ // Short-circuit order is cheapest-first: in-memory checks (resume,
270
+ // corrections, briefs) before the fs/palace scans (captures, room content).
271
+ //
272
+ // hasPalaceContent: a freshly-initialized palace has scaffold rooms with
273
+ // zero `### ` entries — those don't count. countRoomEntries() (palace's own
274
+ // public helper) tells a real room from scaffold without touching palace
275
+ // internals, so "non-empty" is precise rather than `active_rooms.length > 0`.
276
+ const hasPalaceContent = allRooms.some((r) => countRoomEntries(slug, r.slug) > 0);
277
+ const hasCaptures = recentCaptures.length > 0 || hasCaptureLogs(slug);
190
278
  const isEmpty = !resume &&
191
279
  corrections.length === 0 &&
192
280
  !todayBrief && !yesterdayBrief &&
193
- olderCount === 0;
281
+ olderCount === 0 &&
282
+ !hasCaptures &&
283
+ !hasPalaceContent;
194
284
  // Trigger backfill if Supabase is configured (non-blocking)
195
285
  const sbConfig = readSupabaseConfig();
196
286
  if (sbConfig) {
@@ -198,6 +288,15 @@ export async function sessionStart(input) {
198
288
  void autoBackfill(slug);
199
289
  });
200
290
  }
291
+ // Behavior policies — always-loaded high-salience rules. Bump hit counter
292
+ // FIRST so the returned objects reflect post-bump state (the on-disk store
293
+ // and the result payload agree on what an agent saw this session).
294
+ if (readBehaviorPolicies(slug).rules.length > 0)
295
+ recordPolicyLoad(slug);
296
+ const behaviorRules = readBehaviorPolicies(slug).rules;
297
+ // Dream cron health — surface when broken for ≥2 nights
298
+ const dreamHealthRaw = getDreamHealth();
299
+ const dreamHealth = dreamHealthRaw.banner ? dreamHealthRaw : null;
201
300
  // Pipeline narrative spine summary — null if no pipeline files exist for project
202
301
  const pipelineMilestones = listMilestones(slug);
203
302
  let pipeline = null;
@@ -226,9 +325,16 @@ export async function sessionStart(input) {
226
325
  active_rooms,
227
326
  cross_project,
228
327
  recent: { today: todayBrief, yesterday: yesterdayBrief, older_count: olderCount },
328
+ recent_captures: recentCaptures.map((c) => ({
329
+ date: c.date,
330
+ question: sliceAtWord(c.question, 120),
331
+ answer: sliceAtWord(c.answer, 200),
332
+ })),
229
333
  watch_for,
230
334
  corrections,
231
335
  resume,
336
+ behavior_rules: behaviorRules,
337
+ dream_health: dreamHealth,
232
338
  pipeline,
233
339
  empty_state: isEmpty ? "No memory found for this project. Try: bootstrap_scan() to import existing projects, or start working and use remember() to save decisions." : undefined,
234
340
  };