agent-recall-core 3.4.31 → 3.4.36
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 +121 -441
- package/dist/digest/store.d.ts.map +1 -1
- package/dist/digest/store.js +4 -3
- package/dist/digest/store.js.map +1 -1
- package/dist/display/board-render.d.ts +61 -0
- package/dist/display/board-render.d.ts.map +1 -0
- package/dist/display/board-render.js +223 -0
- package/dist/display/board-render.js.map +1 -0
- package/dist/helpers/alignment-patterns.d.ts +10 -0
- package/dist/helpers/alignment-patterns.d.ts.map +1 -1
- package/dist/helpers/alignment-patterns.js +5 -1
- package/dist/helpers/alignment-patterns.js.map +1 -1
- package/dist/helpers/blind-spots.d.ts +86 -0
- package/dist/helpers/blind-spots.d.ts.map +1 -0
- package/dist/helpers/blind-spots.js +205 -0
- package/dist/helpers/blind-spots.js.map +1 -0
- package/dist/helpers/conflict-scan.d.ts +10 -0
- package/dist/helpers/conflict-scan.d.ts.map +1 -1
- package/dist/helpers/conflict-scan.js +3 -3
- package/dist/helpers/conflict-scan.js.map +1 -1
- package/dist/helpers/semantic-match.d.ts +82 -0
- package/dist/helpers/semantic-match.d.ts.map +1 -0
- package/dist/helpers/semantic-match.js +229 -0
- package/dist/helpers/semantic-match.js.map +1 -0
- package/dist/index.d.ts +57 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -14
- package/dist/index.js.map +1 -1
- package/dist/palace/awareness.d.ts +30 -0
- package/dist/palace/awareness.d.ts.map +1 -1
- package/dist/palace/awareness.js +65 -2
- package/dist/palace/awareness.js.map +1 -1
- package/dist/palace/consolidate.d.ts.map +1 -1
- package/dist/palace/consolidate.js +17 -0
- package/dist/palace/consolidate.js.map +1 -1
- package/dist/palace/decay-pass.d.ts +46 -0
- package/dist/palace/decay-pass.d.ts.map +1 -0
- package/dist/palace/decay-pass.js +87 -0
- package/dist/palace/decay-pass.js.map +1 -0
- package/dist/palace/insights-index.d.ts.map +1 -1
- package/dist/palace/insights-index.js +4 -2
- package/dist/palace/insights-index.js.map +1 -1
- package/dist/palace/skills.d.ts +41 -2
- package/dist/palace/skills.d.ts.map +1 -1
- package/dist/palace/skills.js +106 -4
- package/dist/palace/skills.js.map +1 -1
- package/dist/prompts/consolidation-prompt.d.ts +25 -0
- package/dist/prompts/consolidation-prompt.d.ts.map +1 -0
- package/dist/prompts/consolidation-prompt.js +91 -0
- package/dist/prompts/consolidation-prompt.js.map +1 -0
- package/dist/storage/ab-experiment.d.ts +184 -0
- package/dist/storage/ab-experiment.d.ts.map +1 -0
- package/dist/storage/ab-experiment.js +294 -0
- package/dist/storage/ab-experiment.js.map +1 -0
- package/dist/storage/archive-prune.d.ts +56 -0
- package/dist/storage/archive-prune.d.ts.map +1 -0
- package/dist/storage/archive-prune.js +118 -0
- package/dist/storage/archive-prune.js.map +1 -0
- package/dist/storage/archive-write.d.ts +38 -0
- package/dist/storage/archive-write.d.ts.map +1 -0
- package/dist/storage/archive-write.js +98 -0
- package/dist/storage/archive-write.js.map +1 -0
- package/dist/storage/blind-spots-store.d.ts +30 -0
- package/dist/storage/blind-spots-store.d.ts.map +1 -0
- package/dist/storage/blind-spots-store.js +91 -0
- package/dist/storage/blind-spots-store.js.map +1 -0
- package/dist/storage/capture-router.d.ts +60 -0
- package/dist/storage/capture-router.d.ts.map +1 -0
- package/dist/storage/capture-router.js +133 -0
- package/dist/storage/capture-router.js.map +1 -0
- package/dist/storage/classification.d.ts +36 -0
- package/dist/storage/classification.d.ts.map +1 -0
- package/dist/storage/classification.js +78 -0
- package/dist/storage/classification.js.map +1 -0
- package/dist/storage/consolidation-queue.d.ts +39 -0
- package/dist/storage/consolidation-queue.d.ts.map +1 -0
- package/dist/storage/consolidation-queue.js +120 -0
- package/dist/storage/consolidation-queue.js.map +1 -0
- package/dist/storage/content-guard.d.ts +74 -0
- package/dist/storage/content-guard.d.ts.map +1 -0
- package/dist/storage/content-guard.js +179 -0
- package/dist/storage/content-guard.js.map +1 -0
- package/dist/storage/corrections.d.ts +329 -22
- package/dist/storage/corrections.d.ts.map +1 -1
- package/dist/storage/corrections.js +788 -58
- package/dist/storage/corrections.js.map +1 -1
- package/dist/storage/durable-intent.d.ts +49 -0
- package/dist/storage/durable-intent.d.ts.map +1 -0
- package/dist/storage/durable-intent.js +124 -0
- package/dist/storage/durable-intent.js.map +1 -0
- package/dist/storage/filelock.d.ts +6 -0
- package/dist/storage/filelock.d.ts.map +1 -1
- package/dist/storage/filelock.js +6 -1
- package/dist/storage/filelock.js.map +1 -1
- package/dist/storage/memory-protocol.d.ts +19 -0
- package/dist/storage/memory-protocol.d.ts.map +1 -0
- package/dist/storage/memory-protocol.js +101 -0
- package/dist/storage/memory-protocol.js.map +1 -0
- package/dist/storage/paths.d.ts +23 -0
- package/dist/storage/paths.d.ts.map +1 -1
- package/dist/storage/paths.js +39 -0
- package/dist/storage/paths.js.map +1 -1
- package/dist/storage/retention.d.ts +23 -0
- package/dist/storage/retention.d.ts.map +1 -0
- package/dist/storage/retention.js +48 -0
- package/dist/storage/retention.js.map +1 -0
- package/dist/storage/session.d.ts +2 -2
- package/dist/storage/session.d.ts.map +1 -1
- package/dist/storage/session.js +11 -1
- package/dist/storage/session.js.map +1 -1
- package/dist/supabase/config.d.ts +26 -0
- package/dist/supabase/config.d.ts.map +1 -1
- package/dist/supabase/config.js +11 -0
- package/dist/supabase/config.js.map +1 -1
- package/dist/supabase/recall-backend.d.ts +1 -0
- package/dist/supabase/recall-backend.d.ts.map +1 -1
- package/dist/supabase/recall-backend.js +13 -13
- package/dist/supabase/recall-backend.js.map +1 -1
- package/dist/supabase/sync.d.ts +1 -1
- package/dist/supabase/sync.d.ts.map +1 -1
- package/dist/supabase/sync.js +85 -3
- package/dist/supabase/sync.js.map +1 -1
- package/dist/tools-logic/bootstrap.d.ts +15 -0
- package/dist/tools-logic/bootstrap.d.ts.map +1 -1
- package/dist/tools-logic/bootstrap.js +238 -47
- package/dist/tools-logic/bootstrap.js.map +1 -1
- package/dist/tools-logic/brief.d.ts +84 -0
- package/dist/tools-logic/brief.d.ts.map +1 -0
- package/dist/tools-logic/brief.js +193 -0
- package/dist/tools-logic/brief.js.map +1 -0
- package/dist/tools-logic/check-action.d.ts +9 -0
- package/dist/tools-logic/check-action.d.ts.map +1 -1
- package/dist/tools-logic/check-action.js +61 -3
- package/dist/tools-logic/check-action.js.map +1 -1
- package/dist/tools-logic/check.d.ts +7 -0
- package/dist/tools-logic/check.d.ts.map +1 -1
- package/dist/tools-logic/check.js +24 -2
- package/dist/tools-logic/check.js.map +1 -1
- package/dist/tools-logic/confidence.d.ts +50 -0
- package/dist/tools-logic/confidence.d.ts.map +1 -0
- package/dist/tools-logic/confidence.js +70 -0
- package/dist/tools-logic/confidence.js.map +1 -0
- package/dist/tools-logic/drill-down.d.ts +37 -0
- package/dist/tools-logic/drill-down.d.ts.map +1 -0
- package/dist/tools-logic/drill-down.js +63 -0
- package/dist/tools-logic/drill-down.js.map +1 -0
- package/dist/tools-logic/export-corrections.d.ts +63 -0
- package/dist/tools-logic/export-corrections.d.ts.map +1 -0
- package/dist/tools-logic/export-corrections.js +124 -0
- package/dist/tools-logic/export-corrections.js.map +1 -0
- package/dist/tools-logic/journal-capture.d.ts.map +1 -1
- package/dist/tools-logic/journal-capture.js +4 -1
- package/dist/tools-logic/journal-capture.js.map +1 -1
- package/dist/tools-logic/journal-write.d.ts.map +1 -1
- package/dist/tools-logic/journal-write.js +3 -2
- package/dist/tools-logic/journal-write.js.map +1 -1
- package/dist/tools-logic/local-archive-backend.d.ts +33 -0
- package/dist/tools-logic/local-archive-backend.d.ts.map +1 -0
- package/dist/tools-logic/local-archive-backend.js +124 -0
- package/dist/tools-logic/local-archive-backend.js.map +1 -0
- package/dist/tools-logic/memory-backend.d.ts +74 -0
- package/dist/tools-logic/memory-backend.d.ts.map +1 -0
- package/dist/tools-logic/memory-backend.js +172 -0
- package/dist/tools-logic/memory-backend.js.map +1 -0
- package/dist/tools-logic/memory-query.d.ts +10 -3
- package/dist/tools-logic/memory-query.d.ts.map +1 -1
- package/dist/tools-logic/memory-query.js +31 -7
- package/dist/tools-logic/memory-query.js.map +1 -1
- package/dist/tools-logic/mirror-builder.d.ts +115 -0
- package/dist/tools-logic/mirror-builder.d.ts.map +1 -0
- package/dist/tools-logic/mirror-builder.js +348 -0
- package/dist/tools-logic/mirror-builder.js.map +1 -0
- package/dist/tools-logic/palace-write.d.ts.map +1 -1
- package/dist/tools-logic/palace-write.js +3 -2
- package/dist/tools-logic/palace-write.js.map +1 -1
- package/dist/tools-logic/pipeline-close.d.ts.map +1 -1
- package/dist/tools-logic/pipeline-close.js +2 -1
- package/dist/tools-logic/pipeline-close.js.map +1 -1
- package/dist/tools-logic/pipeline-open.d.ts.map +1 -1
- package/dist/tools-logic/pipeline-open.js +2 -1
- package/dist/tools-logic/pipeline-open.js.map +1 -1
- package/dist/tools-logic/predict-correction.d.ts +47 -0
- package/dist/tools-logic/predict-correction.d.ts.map +1 -0
- package/dist/tools-logic/predict-correction.js +137 -0
- package/dist/tools-logic/predict-correction.js.map +1 -0
- package/dist/tools-logic/prior-builder.d.ts +27 -0
- package/dist/tools-logic/prior-builder.d.ts.map +1 -0
- package/dist/tools-logic/prior-builder.js +90 -0
- package/dist/tools-logic/prior-builder.js.map +1 -0
- package/dist/tools-logic/recognition-builder.d.ts +122 -0
- package/dist/tools-logic/recognition-builder.d.ts.map +1 -0
- package/dist/tools-logic/recognition-builder.js +289 -0
- package/dist/tools-logic/recognition-builder.js.map +1 -0
- package/dist/tools-logic/safety-consolidation.d.ts +104 -0
- package/dist/tools-logic/safety-consolidation.d.ts.map +1 -0
- package/dist/tools-logic/safety-consolidation.js +256 -0
- package/dist/tools-logic/safety-consolidation.js.map +1 -0
- package/dist/tools-logic/session-end-reflect.d.ts +18 -0
- package/dist/tools-logic/session-end-reflect.d.ts.map +1 -1
- package/dist/tools-logic/session-end-reflect.js +69 -30
- package/dist/tools-logic/session-end-reflect.js.map +1 -1
- package/dist/tools-logic/session-end.d.ts +18 -0
- package/dist/tools-logic/session-end.d.ts.map +1 -1
- package/dist/tools-logic/session-end.js +189 -34
- package/dist/tools-logic/session-end.js.map +1 -1
- package/dist/tools-logic/session-start-lite.d.ts +2 -0
- package/dist/tools-logic/session-start-lite.d.ts.map +1 -1
- package/dist/tools-logic/session-start-lite.js +11 -2
- package/dist/tools-logic/session-start-lite.js.map +1 -1
- package/dist/tools-logic/session-start.d.ts +81 -2
- package/dist/tools-logic/session-start.d.ts.map +1 -1
- package/dist/tools-logic/session-start.js +357 -40
- package/dist/tools-logic/session-start.js.map +1 -1
- package/dist/tools-logic/skill-propose.d.ts +27 -0
- package/dist/tools-logic/skill-propose.d.ts.map +1 -0
- package/dist/tools-logic/skill-propose.js +66 -0
- package/dist/tools-logic/skill-propose.js.map +1 -0
- package/dist/tools-logic/skill-recall.d.ts +5 -0
- package/dist/tools-logic/skill-recall.d.ts.map +1 -1
- package/dist/tools-logic/skill-recall.js +14 -1
- package/dist/tools-logic/skill-recall.js.map +1 -1
- package/dist/tools-logic/smart-recall.d.ts +17 -0
- package/dist/tools-logic/smart-recall.d.ts.map +1 -1
- package/dist/tools-logic/smart-recall.js +51 -16
- package/dist/tools-logic/smart-recall.js.map +1 -1
- package/dist/tools-logic/smart-remember.js +8 -9
- package/dist/tools-logic/smart-remember.js.map +1 -1
- package/dist/tools-logic/store-doctor.d.ts +71 -0
- package/dist/tools-logic/store-doctor.d.ts.map +1 -0
- package/dist/tools-logic/store-doctor.js +387 -0
- package/dist/tools-logic/store-doctor.js.map +1 -0
- package/dist/tools-logic/store-repair.d.ts +64 -0
- package/dist/tools-logic/store-repair.d.ts.map +1 -0
- package/dist/tools-logic/store-repair.js +243 -0
- package/dist/tools-logic/store-repair.js.map +1 -0
- package/dist/tools-logic/supersession.d.ts +34 -0
- package/dist/tools-logic/supersession.d.ts.map +1 -0
- package/dist/tools-logic/supersession.js +103 -0
- package/dist/tools-logic/supersession.js.map +1 -0
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/vector/embedding.d.ts +8 -0
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +9 -1
- package/dist/vector/embedding.js.map +1 -1
- package/dist/vector/local-vector-backend.d.ts.map +1 -1
- package/dist/vector/local-vector-backend.js +14 -17
- package/dist/vector/local-vector-backend.js.map +1 -1
- package/package.json +2 -2
- package/dist/relevance/injector.d.ts +0 -51
- package/dist/relevance/injector.d.ts.map +0 -1
- package/dist/relevance/injector.js +0 -121
- package/dist/relevance/injector.js.map +0 -1
- package/dist/relevance/precision.d.ts +0 -109
- package/dist/relevance/precision.d.ts.map +0 -1
- package/dist/relevance/precision.js +0 -279
- package/dist/relevance/precision.js.map +0 -1
- package/dist/relevance/promoter.d.ts +0 -60
- package/dist/relevance/promoter.d.ts.map +0 -1
- package/dist/relevance/promoter.js +0 -336
- package/dist/relevance/promoter.js.map +0 -1
- package/dist/relevance/stager.d.ts +0 -61
- package/dist/relevance/stager.d.ts.map +0 -1
- package/dist/relevance/stager.js +0 -251
- package/dist/relevance/stager.js.map +0 -1
- package/dist/relevance/surfacer.d.ts +0 -34
- package/dist/relevance/surfacer.d.ts.map +0 -1
- package/dist/relevance/surfacer.js +0 -333
- package/dist/relevance/surfacer.js.map +0 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recognition.ts — Loop 4 north-star: REAL-TIME RECOGNITION at session start.
|
|
3
|
+
*
|
|
4
|
+
* When a session opens, the agent must instantly know FOUR things from LOCAL
|
|
5
|
+
* data only — zero network, no Supabase, no LLM on the hot path, deterministic:
|
|
6
|
+
*
|
|
7
|
+
* 1. WHO — identity / role (from palace/identity.ts + owner)
|
|
8
|
+
* 2. CAN_DO — capabilities (palace/skills + capability-bearing corrections)
|
|
9
|
+
* 3. PROJECT — project + progress (status board + journal + palace state)
|
|
10
|
+
* 4. PERSON — "what kind of person" = blind-spots profile rendered as
|
|
11
|
+
* tendencies-to-watch, WITH an explicit low-confidence caveat
|
|
12
|
+
* (Loop 3 measured this profile at 0/13 predictive — surface,
|
|
13
|
+
* never over-claim).
|
|
14
|
+
*
|
|
15
|
+
* This module ASSEMBLES existing stores — it does NOT rebuild them. Every read
|
|
16
|
+
* is a pure, synchronous filesystem read of already-derived artifacts. The
|
|
17
|
+
* payload is deterministically ordered so the same on-disk state yields a
|
|
18
|
+
* byte-identical JSON across repeated runs (no timestamps, no Date.now in the
|
|
19
|
+
* output — those would break determinism and aren't part of "recognition").
|
|
20
|
+
*
|
|
21
|
+
* Honesty law: WHO is `'unknown'` when no identity card exists. We NEVER infer
|
|
22
|
+
* or fabricate a persona. CAN_DO and PERSON are honestly empty when nothing is
|
|
23
|
+
* known.
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from "node:fs";
|
|
26
|
+
import * as path from "node:path";
|
|
27
|
+
import { palaceDir, journalDirs } from "../storage/paths.js";
|
|
28
|
+
import { readIdentity } from "../palace/identity.js";
|
|
29
|
+
import { listSkills } from "../palace/skills.js";
|
|
30
|
+
import { listRooms, isRoomStale } from "../palace/rooms.js";
|
|
31
|
+
import { readActiveCorrections } from "../storage/corrections.js";
|
|
32
|
+
import { readBlindSpots } from "../storage/blind-spots-store.js";
|
|
33
|
+
import { isJournalFile } from "../helpers/journal-filter.js";
|
|
34
|
+
// ── Constants ──────────────────────────────────────────────────────────────────
|
|
35
|
+
/**
|
|
36
|
+
* The mandatory low-confidence caveat for the person profile. Loop 3's
|
|
37
|
+
* leave-one-out eval measured the blind-spots profile at 0/13 predictive on real
|
|
38
|
+
* corrections, so it is surfaced for orientation only — never as validated truth.
|
|
39
|
+
*/
|
|
40
|
+
export const PERSON_LOW_CONFIDENCE_CAVEAT = "low-confidence: 0/13 predictive (Loop 3) — not validated, orientation only.";
|
|
41
|
+
/**
|
|
42
|
+
* Trajectory-classification: a `## Next` line containing any of these reads as
|
|
43
|
+
* actionable work the human can pick up now ("needs-you"). Mirrors project-board's
|
|
44
|
+
* grammar but inverted for the recognition bucket.
|
|
45
|
+
*/
|
|
46
|
+
const NEEDS_YOU_RE = /\bnext\b|\btodo\b|\bfix\b|\bimplement\b|\bship\b|\badd\b|\bwire\b|\bfinish\b|\bcontinue\b/i;
|
|
47
|
+
/** Days of journal silence past which a project is "stale". */
|
|
48
|
+
const STALE_DAYS = 14;
|
|
49
|
+
/**
|
|
50
|
+
* Corrections that read as a standing capability / permission / tool constraint.
|
|
51
|
+
* Used to surface "what they can (not) do" from the corrections store without an
|
|
52
|
+
* LLM — pure keyword match over the cleaned rule text.
|
|
53
|
+
*/
|
|
54
|
+
const PERMISSION_RE = /\b(push|publish|deploy|delete|version bump|approval|permission|credential|secret|token|never|always|must not|do not|forbid)\b/i;
|
|
55
|
+
const TEMPLATE_STUB_RE = /_\(fill in/;
|
|
56
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
57
|
+
/** Trim + collapse whitespace; bounded slice at a word boundary for stable output. */
|
|
58
|
+
function clean(text, maxLen = 200) {
|
|
59
|
+
const t = text.replace(/\s+/g, " ").trim();
|
|
60
|
+
if (t.length <= maxLen)
|
|
61
|
+
return t;
|
|
62
|
+
const sliced = t.slice(0, maxLen);
|
|
63
|
+
const lastSpace = sliced.lastIndexOf(" ");
|
|
64
|
+
return lastSpace > maxLen * 0.6 ? sliced.slice(0, lastSpace) : sliced;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse the identity card into WHO. Returns `unknown:true` + `name:'unknown'`
|
|
68
|
+
* when there is no real identity content (missing file or template stub only).
|
|
69
|
+
* NEVER fabricates a name or role.
|
|
70
|
+
*/
|
|
71
|
+
function readWho(project) {
|
|
72
|
+
const idPath = path.join(palaceDir(project), "identity.md");
|
|
73
|
+
const hasFile = fs.existsSync(idPath);
|
|
74
|
+
const raw = hasFile ? readIdentity(project) : "";
|
|
75
|
+
// No file, or the fallback "no identity card yet" sentinel from readIdentity:
|
|
76
|
+
// both mean the identity is unknown.
|
|
77
|
+
if (!hasFile || /No identity card yet/.test(raw)) {
|
|
78
|
+
return { name: "unknown", role: null, owner: null, unknown: true };
|
|
79
|
+
}
|
|
80
|
+
let name = null;
|
|
81
|
+
let role = null;
|
|
82
|
+
let owner = null;
|
|
83
|
+
// Track whether the card carries any SUBSTANTIVE authored body — a line that is
|
|
84
|
+
// not the heading, not the fill-in stub, not frontmatter/frontmatter-fence, and
|
|
85
|
+
// not the structural markers we already capture as role/owner. A freshly
|
|
86
|
+
// bootstrapped card (`# <slug>` + only a `_(fill in...)_` stub) has NONE, so
|
|
87
|
+
// its slug heading is not a real identity (Loop 5 carry-in fix).
|
|
88
|
+
let hasAuthoredBody = false;
|
|
89
|
+
let inFrontmatter = false;
|
|
90
|
+
for (const lineRaw of raw.split("\n")) {
|
|
91
|
+
const line = lineRaw.trim();
|
|
92
|
+
if (!line)
|
|
93
|
+
continue;
|
|
94
|
+
// Skip YAML frontmatter (--- … ---): it is bootstrap metadata, never identity.
|
|
95
|
+
if (line === "---") {
|
|
96
|
+
inFrontmatter = !inFrontmatter;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (inFrontmatter)
|
|
100
|
+
continue;
|
|
101
|
+
// First ATX heading that is not an empty stub becomes the name.
|
|
102
|
+
if (name === null && line.startsWith("#")) {
|
|
103
|
+
const h = line.replace(/^#+\s*/, "").trim();
|
|
104
|
+
if (h && !TEMPLATE_STUB_RE.test(h))
|
|
105
|
+
name = h;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
// Owner / source marker.
|
|
109
|
+
if (owner === null && /^-?\s*(source|owner|maintainer)\s*:/i.test(line)) {
|
|
110
|
+
const v = line.replace(/^-?\s*\w+\s*:\s*/i, "").trim();
|
|
111
|
+
if (v)
|
|
112
|
+
owner = clean(v, 160);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// Intention / role marker (skip frontmatter, blockquotes, template stubs).
|
|
116
|
+
// Handles both `**Intention:** value` (colon inside bold) and
|
|
117
|
+
// `**Intention**: value` / `Intention: value` forms — the leading marker
|
|
118
|
+
// and any stray bold/colon are stripped before capture.
|
|
119
|
+
if (role === null) {
|
|
120
|
+
if (line.startsWith(">") && TEMPLATE_STUB_RE.test(line))
|
|
121
|
+
continue;
|
|
122
|
+
const m = line.match(/^\*{0,2}(intention|role|purpose)\*{0,2}\s*:\*{0,2}\s*(.+)$/i);
|
|
123
|
+
if (m) {
|
|
124
|
+
const value = m[2].replace(/^\*+/, "").trim();
|
|
125
|
+
if (value && !TEMPLATE_STUB_RE.test(value)) {
|
|
126
|
+
role = clean(value, 200);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Any remaining non-empty line that is NOT a fill-in stub counts as authored
|
|
132
|
+
// body — the human added real content beyond the bootstrap skeleton.
|
|
133
|
+
if (!TEMPLATE_STUB_RE.test(line))
|
|
134
|
+
hasAuthoredBody = true;
|
|
135
|
+
}
|
|
136
|
+
if (name === null) {
|
|
137
|
+
return { name: "unknown", role: null, owner: null, unknown: true };
|
|
138
|
+
}
|
|
139
|
+
// Honesty law (Loop 5 carry-in): a card whose heading is just the project slug
|
|
140
|
+
// with NO authored body — no role, no owner, no other real line, only the
|
|
141
|
+
// bootstrap fill-in stub — is NOT a real identity. `ensurePalaceInitialized`
|
|
142
|
+
// writes exactly this (`# <slug>` + `_(fill in...)_`), so it must read as
|
|
143
|
+
// unknown rather than echoing the slug back as a fabricated persona. A human
|
|
144
|
+
// who fills in an intention/owner/body makes `role`/`owner`/`hasAuthoredBody`
|
|
145
|
+
// truthy and the card becomes known.
|
|
146
|
+
const isBootstrapStub = name === project && role === null && owner === null && !hasAuthoredBody;
|
|
147
|
+
if (isBootstrapStub) {
|
|
148
|
+
return { name: "unknown", role: null, owner: null, unknown: true };
|
|
149
|
+
}
|
|
150
|
+
return { name, role, owner, unknown: false };
|
|
151
|
+
}
|
|
152
|
+
/** Assemble CAN_DO from the procedural skills store + capability-bearing corrections. */
|
|
153
|
+
function readCapabilities(project, maxSkills, maxPermissions) {
|
|
154
|
+
// Skills — already deterministically slug-sorted by listSkills.
|
|
155
|
+
const skills = listSkills(project)
|
|
156
|
+
.slice(0, maxSkills)
|
|
157
|
+
.map((s) => ({
|
|
158
|
+
slug: s.meta.slug,
|
|
159
|
+
name: clean(s.meta.name, 80),
|
|
160
|
+
topic: clean(s.meta.topic, 40),
|
|
161
|
+
triggers: [...s.meta.triggers].sort((a, b) => a.localeCompare(b)),
|
|
162
|
+
}));
|
|
163
|
+
// Permission/capability signals from active corrections.
|
|
164
|
+
const permsAll = readActiveCorrections(project)
|
|
165
|
+
.filter((c) => c.rule && PERMISSION_RE.test(c.rule))
|
|
166
|
+
.map((c) => ({ id: c.id, rule: clean(c.rule, 160), severity: c.severity }));
|
|
167
|
+
// Deterministic order: P0 before P1, then by id (stable, date-prefixed).
|
|
168
|
+
permsAll.sort((a, b) => {
|
|
169
|
+
if (a.severity !== b.severity)
|
|
170
|
+
return a.severity === "p0" ? -1 : 1;
|
|
171
|
+
return a.id.localeCompare(b.id);
|
|
172
|
+
});
|
|
173
|
+
const permissions = permsAll.slice(0, maxPermissions);
|
|
174
|
+
return { skills, permissions };
|
|
175
|
+
}
|
|
176
|
+
/** Find the newest journal file + its `## Next` trajectory. Pure local fs scan. */
|
|
177
|
+
function readProjectProgress(project, maxRooms) {
|
|
178
|
+
const dirs = journalDirs(project);
|
|
179
|
+
let lastDate = null;
|
|
180
|
+
let newestPath = null;
|
|
181
|
+
for (const dir of dirs) {
|
|
182
|
+
if (!fs.existsSync(dir))
|
|
183
|
+
continue;
|
|
184
|
+
let files;
|
|
185
|
+
try {
|
|
186
|
+
files = fs.readdirSync(dir).filter(isJournalFile);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
for (const file of files) {
|
|
192
|
+
const m = file.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
193
|
+
if (!m)
|
|
194
|
+
continue;
|
|
195
|
+
const d = m[1];
|
|
196
|
+
if (!lastDate || d > lastDate) {
|
|
197
|
+
lastDate = d;
|
|
198
|
+
newestPath = path.join(dir, file);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Trajectory — first non-empty `## Next` line of the newest journal.
|
|
203
|
+
let trajectory = null;
|
|
204
|
+
if (newestPath && fs.existsSync(newestPath)) {
|
|
205
|
+
try {
|
|
206
|
+
const content = fs.readFileSync(newestPath, "utf-8");
|
|
207
|
+
const nextMatch = content.match(/^## Next\r?\n([\s\S]*?)(?=^##|\s*$)/m);
|
|
208
|
+
if (nextMatch) {
|
|
209
|
+
const lines = nextMatch[1]
|
|
210
|
+
.split("\n")
|
|
211
|
+
.map((l) => l.trim().replace(/^[-*]\s*/, ""))
|
|
212
|
+
.filter(Boolean);
|
|
213
|
+
if (lines.length > 0)
|
|
214
|
+
trajectory = clean(lines[0], 200);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// non-blocking
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Status bucket — deterministic from journal freshness + trajectory text.
|
|
222
|
+
let status;
|
|
223
|
+
if (!lastDate) {
|
|
224
|
+
status = "empty";
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
// Day-granularity gap from the journal date (no time-of-day, so the bucket
|
|
228
|
+
// is stable within a calendar day — recognition is deterministic per-day).
|
|
229
|
+
const daysAgo = Math.floor((Date.parse(`${new Date().toISOString().slice(0, 10)}T00:00:00Z`) -
|
|
230
|
+
Date.parse(`${lastDate}T00:00:00Z`)) /
|
|
231
|
+
86_400_000);
|
|
232
|
+
if (daysAgo > STALE_DAYS)
|
|
233
|
+
status = "stale";
|
|
234
|
+
else if (trajectory && NEEDS_YOU_RE.test(trajectory))
|
|
235
|
+
status = "needs-you";
|
|
236
|
+
else
|
|
237
|
+
status = "backlog";
|
|
238
|
+
}
|
|
239
|
+
// Rooms — listRooms is salience-sorted; take top N, then re-sort
|
|
240
|
+
// deterministically by (salience desc, name asc) so ties are stable.
|
|
241
|
+
const rooms = listRooms(project)
|
|
242
|
+
.map((r) => ({ name: r.name, salience: r.salience, stale: isRoomStale(r) }))
|
|
243
|
+
.sort((a, b) => (b.salience !== a.salience ? b.salience - a.salience : a.name.localeCompare(b.name)))
|
|
244
|
+
.slice(0, maxRooms);
|
|
245
|
+
return { slug: project, last_journal_date: lastDate, status, trajectory, rooms };
|
|
246
|
+
}
|
|
247
|
+
/** Assemble the PERSON profile (read-only) with its mandatory low-confidence caveat. */
|
|
248
|
+
function readPerson(project, maxTendencies) {
|
|
249
|
+
let tendencies = [];
|
|
250
|
+
const profile = readBlindSpots(project);
|
|
251
|
+
if (profile && profile.blind_spots.length > 0) {
|
|
252
|
+
tendencies = profile.blind_spots
|
|
253
|
+
.map((b) => ({
|
|
254
|
+
tendency: clean(b.tendency, 160),
|
|
255
|
+
severity: b.severity,
|
|
256
|
+
evidence_count: b.evidence_count,
|
|
257
|
+
}))
|
|
258
|
+
// Deterministic: P0 before P1, then by evidence desc, then by tendency text.
|
|
259
|
+
.sort((a, b) => {
|
|
260
|
+
if (a.severity !== b.severity)
|
|
261
|
+
return a.severity === "p0" ? -1 : 1;
|
|
262
|
+
if (b.evidence_count !== a.evidence_count)
|
|
263
|
+
return b.evidence_count - a.evidence_count;
|
|
264
|
+
return a.tendency.localeCompare(b.tendency);
|
|
265
|
+
})
|
|
266
|
+
.slice(0, maxTendencies);
|
|
267
|
+
}
|
|
268
|
+
return { tendencies, caveat: PERSON_LOW_CONFIDENCE_CAVEAT };
|
|
269
|
+
}
|
|
270
|
+
// ── Public API ──────────────────────────────────────────────────────────────
|
|
271
|
+
/**
|
|
272
|
+
* Assemble the real-time recognition payload for a project from LOCAL stores
|
|
273
|
+
* only. Synchronous, deterministic, zero-network. Caller must have already
|
|
274
|
+
* resolved `project` to a concrete slug (this function does not auto-detect, so
|
|
275
|
+
* it never shells out to git — keeping the hot path pure and fast).
|
|
276
|
+
*/
|
|
277
|
+
export function buildRecognition(project, opts = {}) {
|
|
278
|
+
const maxSkills = opts.maxSkills ?? 8;
|
|
279
|
+
const maxPermissions = opts.maxPermissions ?? 5;
|
|
280
|
+
const maxRooms = opts.maxRooms ?? 3;
|
|
281
|
+
const maxTendencies = opts.maxTendencies ?? 3;
|
|
282
|
+
return {
|
|
283
|
+
who: readWho(project),
|
|
284
|
+
can_do: readCapabilities(project, maxSkills, maxPermissions),
|
|
285
|
+
project: readProjectProgress(project, maxRooms),
|
|
286
|
+
person: readPerson(project, maxTendencies),
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=recognition-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recognition-builder.js","sourceRoot":"","sources":["../../src/tools-logic/recognition-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AA6E7D,kFAAkF;AAElF;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GACvC,6EAA6E,CAAC;AAEhF;;;;GAIG;AACH,MAAM,YAAY,GAAG,4FAA4F,CAAC;AAClH,+DAA+D;AAC/D,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB;;;;GAIG;AACH,MAAM,aAAa,GACjB,gIAAgI,CAAC;AAEnI,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAEtC,gFAAgF;AAEhF,sFAAsF;AACtF,SAAS,KAAK,CAAC,IAAY,EAAE,MAAM,GAAG,GAAG;IACvC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,SAAS,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,SAAS,OAAO,CAAC,OAAe;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjD,8EAA8E;IAC9E,qCAAqC;IACrC,IAAI,CAAC,OAAO,IAAI,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,gFAAgF;IAChF,gFAAgF;IAChF,yEAAyE;IACzE,6EAA6E;IAC7E,iEAAiE;IACjE,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,+EAA+E;QAC/E,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,aAAa,GAAG,CAAC,aAAa,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,IAAI,aAAa;YAAE,SAAS;QAC5B,gEAAgE;QAChE,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAAE,IAAI,GAAG,CAAC,CAAC;YAC7C,SAAS;QACX,CAAC;QACD,yBAAyB;QACzB,IAAI,KAAK,KAAK,IAAI,IAAI,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxE,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,CAAC;gBAAE,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,2EAA2E;QAC3E,8DAA8D;QAC9D,yEAAyE;QACzE,wDAAwD;QACxD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAClE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;YACpF,IAAI,CAAC,EAAE,CAAC;gBACN,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC9C,IAAI,KAAK,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC3C,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBACzB,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QACD,6EAA6E;QAC7E,qEAAqE;QACrE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,eAAe,GAAG,IAAI,CAAC;IAC3D,CAAC;IAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,+EAA+E;IAC/E,0EAA0E;IAC1E,6EAA6E;IAC7E,0EAA0E;IAC1E,6EAA6E;IAC7E,8EAA8E;IAC9E,qCAAqC;IACrC,MAAM,eAAe,GACnB,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC;IAC1E,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,yFAAyF;AACzF,SAAS,gBAAgB,CAAC,OAAe,EAAE,SAAiB,EAAE,cAAsB;IAClF,gEAAgE;IAChE,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC;SAC/B,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;SACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;QACjB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QAC9B,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;KAClE,CAAC,CAAC,CAAC;IAEN,yDAAyD;IACzD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,OAAO,CAAC;SAC5C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SACnD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAE9E,yEAAyE;IACzE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;YAAE,OAAO,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IAEtD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACjC,CAAC;AAED,mFAAmF;AACnF,SAAS,mBAAmB,CAAC,OAAe,EAAE,QAAgB;IAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,UAAU,GAAkB,IAAI,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClC,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAC7C,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,IAAI,CAAC,QAAQ,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC;gBAC9B,QAAQ,GAAG,CAAC,CAAC;gBACb,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,UAAU,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACxE,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC;qBACvB,KAAK,CAAC,IAAI,CAAC;qBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;qBAC5C,MAAM,CAAC,OAAO,CAAC,CAAC;gBACnB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;oBAAE,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,IAAI,MAAoC,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,OAAO,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,2EAA2E;QAC3E,2EAA2E;QAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,YAAY,CAAC,CAAC;YACpC,UAAU,CACb,CAAC;QACF,IAAI,OAAO,GAAG,UAAU;YAAE,MAAM,GAAG,OAAO,CAAC;aACtC,IAAI,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,MAAM,GAAG,WAAW,CAAC;;YACtE,MAAM,GAAG,SAAS,CAAC;IAC1B,CAAC;IAED,iEAAiE;IACjE,qEAAqE;IACrE,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC3E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;SACpG,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEtB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACnF,CAAC;AAED,wFAAwF;AACxF,SAAS,UAAU,CAAC,OAAe,EAAE,aAAqB;IACxD,IAAI,UAAU,GAAoC,EAAE,CAAC;IACrD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,UAAU,GAAG,OAAO,CAAC,WAAW;aAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC;YAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,cAAc,EAAE,CAAC,CAAC,cAAc;SACjC,CAAC,CAAC;YACH,6EAA6E;aAC5E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;gBAAE,OAAO,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,CAAC,cAAc,KAAK,CAAC,CAAC,cAAc;gBAAE,OAAO,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC;YACtF,OAAO,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC;AAC9D,CAAC;AAED,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAAgC,EAAE;IAClF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;IACtC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;IACpC,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;IAE9C,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,cAAc,CAAC;QAC5D,OAAO,EAAE,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC/C,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* safety-consolidation.ts — the LOGIN-FREE, LLM-FREE background safety pass.
|
|
3
|
+
*
|
|
4
|
+
* The operator's #1 priority: the three maintenance steps that keep memory
|
|
5
|
+
* healthy (FSRS/salience decay, raw-archive retention, candidate graduation)
|
|
6
|
+
* must run AUTOMATICALLY and WITHOUT a Claude login or any OPENAI_API_KEY.
|
|
7
|
+
*
|
|
8
|
+
* Before this module those steps only fired when the un-cron'd overnight
|
|
9
|
+
* dreaming agent drained the async queue (`ar consolidate-async`), which fails
|
|
10
|
+
* often — so decay rarely ran, pruneRawArchive had ZERO callers (the archive
|
|
11
|
+
* grew unbounded), and crystallization candidates never graduated.
|
|
12
|
+
*
|
|
13
|
+
* This pass wires the EXISTING, already-headless primitives together:
|
|
14
|
+
* (a) decay → consolidateJournalToPalace (runs runDecayPass + markKeystones
|
|
15
|
+
* internally; pure regex/fs, no LLM)
|
|
16
|
+
* (b) prune → pruneRawArchive (the dead retention pass), gated by the
|
|
17
|
+
* `.consumed.json` marker which this pass advances by the
|
|
18
|
+
* deterministic "older than the retention window ⇒ distilled"
|
|
19
|
+
* rule (monotonic ⇒ idempotent)
|
|
20
|
+
* (c) graduate → findCrystallizationCandidates + a DETERMINISTIC threshold
|
|
21
|
+
* rule that re-titles the strongest member `CRYSTALLIZED: …`.
|
|
22
|
+
* No LLM-authored summary — that stays the optional dreaming
|
|
23
|
+
* path. Idempotent because findCrystallizationCandidates
|
|
24
|
+
* excludes already-CRYSTALLIZED titles.
|
|
25
|
+
* NOTE (sync side effect): when a candidate actually graduates,
|
|
26
|
+
* this step persists the mutated awareness state and calls
|
|
27
|
+
* renderAwareness, which (via writeAwareness) fires a GATED,
|
|
28
|
+
* non-blocking Supabase sync of the awareness markdown. The
|
|
29
|
+
* sync is a no-op unless Supabase is configured AND sync_enabled
|
|
30
|
+
* (readSupabaseConfig returns null otherwise), so it never
|
|
31
|
+
* requires a network round-trip or a login to complete the pass
|
|
32
|
+
* — it does NOT violate the login-free contract below. dryRun
|
|
33
|
+
* and "nothing graduated" paths perform NO write and NO sync.
|
|
34
|
+
*
|
|
35
|
+
* HARD contract:
|
|
36
|
+
* - NONE of the three steps may require an LLM / OPENAI_API_KEY / Claude login.
|
|
37
|
+
* - EACH step is wrapped in its own try/catch so one throwing does NOT abort
|
|
38
|
+
* the others (best-effort, per-step isolation).
|
|
39
|
+
* - dryRun computes counts but writes NOTHING.
|
|
40
|
+
*/
|
|
41
|
+
import { DEFAULT_ARCHIVE_RETENTION_DAYS } from "../storage/retention.js";
|
|
42
|
+
export { DEFAULT_ARCHIVE_RETENTION_DAYS };
|
|
43
|
+
/** Deterministic graduation floor: a crystallization candidate graduates when
|
|
44
|
+
* its members together carry at least this many confirmations. Layered on top
|
|
45
|
+
* of findCrystallizationCandidates' own minCluster/minTotalConfirm gates so the
|
|
46
|
+
* rule is purely numeric — NO LLM judgement. Overridable via the runSafety
|
|
47
|
+
* opt, the AGENT_RECALL_GRADUATION_MIN_CONFIRMATIONS env var, or config.json
|
|
48
|
+
* `graduation_min_confirmations` (resolved in that order by
|
|
49
|
+
* resolveGraduationMinConfirmations). */
|
|
50
|
+
export declare const DEFAULT_GRADUATION_MIN_CONFIRMATIONS = 8;
|
|
51
|
+
export interface SafetyDecayResult {
|
|
52
|
+
ran: boolean;
|
|
53
|
+
/** Skills + rooms scanned by the decay pass (0 when it could not run). */
|
|
54
|
+
scanned: number;
|
|
55
|
+
/** Objects flagged archived this pass (or that WOULD be, when dryRun). */
|
|
56
|
+
archived: number;
|
|
57
|
+
error?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface SafetyPruneResult {
|
|
60
|
+
ran: boolean;
|
|
61
|
+
scanned: number;
|
|
62
|
+
/** Aged + distilled segments gzipped (0 in dryRun). */
|
|
63
|
+
gzipped: number;
|
|
64
|
+
/** Segments removed outright (only when mode === "remove"). */
|
|
65
|
+
removed: number;
|
|
66
|
+
/** Candidates matching BOTH gates (old AND consumed). */
|
|
67
|
+
eligible: number;
|
|
68
|
+
/** `lastConsumedAt` the marker was advanced TO (or would be, in dryRun). */
|
|
69
|
+
consumedThrough: string | null;
|
|
70
|
+
error?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface SafetyGraduateResult {
|
|
73
|
+
ran: boolean;
|
|
74
|
+
/** Crystallization candidates surfaced this pass. */
|
|
75
|
+
candidates: number;
|
|
76
|
+
/** Candidates that crossed the deterministic threshold and graduated (or
|
|
77
|
+
* would, in dryRun). */
|
|
78
|
+
graduated: number;
|
|
79
|
+
/** Titles graduated this pass (for traceability). */
|
|
80
|
+
graduatedTitles: string[];
|
|
81
|
+
error?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface SafetyConsolidationResult {
|
|
84
|
+
project: string;
|
|
85
|
+
dryRun: boolean;
|
|
86
|
+
decay: SafetyDecayResult;
|
|
87
|
+
pruned: SafetyPruneResult;
|
|
88
|
+
graduated: SafetyGraduateResult;
|
|
89
|
+
}
|
|
90
|
+
export interface SafetyConsolidationOptions {
|
|
91
|
+
/** When true, compute counts but write nothing. Default false. */
|
|
92
|
+
dryRun?: boolean;
|
|
93
|
+
/** Override the raw-archive retention window (days). */
|
|
94
|
+
olderThanDays?: number;
|
|
95
|
+
/** Override the deterministic graduation confirmation floor. */
|
|
96
|
+
minConfirmations?: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Run the three best-effort, LOGIN-FREE, LLM-FREE safety-consolidation steps
|
|
100
|
+
* for a project. Each step is isolated in its own try/catch: one throwing never
|
|
101
|
+
* aborts the others. dryRun computes counts but writes nothing.
|
|
102
|
+
*/
|
|
103
|
+
export declare function runSafetyConsolidation(project: string, opts?: SafetyConsolidationOptions): Promise<SafetyConsolidationResult>;
|
|
104
|
+
//# sourceMappingURL=safety-consolidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety-consolidation.d.ts","sourceRoot":"","sources":["../../src/tools-logic/safety-consolidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAoBH,OAAO,EACL,8BAA8B,EAE/B,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAAE,8BAA8B,EAAE,CAAC;AAE1C;;;;;;0CAM0C;AAC1C,eAAO,MAAM,oCAAoC,IAAI,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,OAAO,CAAC;IACb,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB;6BACyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,oBAAoB,CAAC;CACjC;AAED,MAAM,WAAW,0BAA0B;IACzC,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwID;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,0BAA+B,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAmFpC"}
|