total-recall-brain 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +1 -1
  2. package/bin/antigravity.mjs +19 -8
  3. package/extension/background.js +13 -1
  4. package/extension/content-script.js +18 -1
  5. package/extension/lib/brain-client.js +18 -5
  6. package/extension/options/options.js +9 -4
  7. package/frontend/index.html +8 -0
  8. package/frontend/src/api.ts +20 -1
  9. package/frontend/src/pages/ChatPage.tsx +9 -6
  10. package/frontend/src/pages/HealthPage.tsx +179 -7
  11. package/frontend/src/pages/IntegrationsPage.tsx +4 -2
  12. package/frontend/src/pages/SettingsPage.tsx +197 -2
  13. package/frontend/src/types.ts +16 -0
  14. package/package.json +2 -2
  15. package/scaffold/.agent/skills/total-recall/SKILL.md +55 -6
  16. package/scaffold/.agent/skills/total-recall/memory-vault/invariants/operating-instructions.md +2 -2
  17. package/scaffold/.agent/skills/total-recall/research-queue.jsonl +1 -0
  18. package/scaffold/.agent/skills/total-recall/skills/cli-agents/agents.yml +1 -6
  19. package/scaffold/.agent/skills/total-recall/skills/ssss/SKILL.md +19 -0
  20. package/scaffold/.agent/skills/total-recall/skills/ssss/references/ssss-spec.md +33 -5
  21. package/src/cli/forget.mjs +18 -12
  22. package/src/cli/ingest/index.mjs +3 -2
  23. package/src/cli/map.mjs +2 -2
  24. package/src/cli/rebuild.mjs +1 -1
  25. package/src/cli/remember.mjs +21 -11
  26. package/src/cli/share.mjs +7 -2
  27. package/src/core/append-log.mjs +131 -0
  28. package/src/core/clarity-rewriter.mjs +10 -6
  29. package/src/core/conclusion-writer.mjs +3 -2
  30. package/src/core/config.mjs +6 -0
  31. package/src/core/conflict-detector.mjs +4 -2
  32. package/src/core/context-compiler.mjs +412 -0
  33. package/src/core/daemon-loop.mjs +15 -0
  34. package/src/core/dream.mjs +4 -4
  35. package/src/core/drift-detector.mjs +3 -3
  36. package/src/core/embeddings.mjs +60 -10
  37. package/src/core/fact-seeker.mjs +70 -44
  38. package/src/core/import-rules.mjs +3 -2
  39. package/src/core/inference-engine.mjs +5 -4
  40. package/src/core/migrate.mjs +4 -3
  41. package/src/core/optimizer.mjs +6 -5
  42. package/src/core/parallel-context.mjs +288 -0
  43. package/src/core/post-mortem.mjs +4 -3
  44. package/src/core/research-queue.mjs +4 -3
  45. package/src/core/runtime.mjs +30 -7
  46. package/src/core/sandbox.mjs +56 -26
  47. package/src/core/scheduler.mjs +6 -5
  48. package/src/core/schema.mjs +483 -2
  49. package/src/core/search.mjs +167 -101
  50. package/src/core/surface.mjs +203 -53
  51. package/src/core/validated-write.mjs +100 -0
  52. package/src/core/vault-cache.mjs +46 -18
  53. package/src/core/vault.mjs +17 -29
  54. package/src/core/vector-field.mjs +659 -0
  55. package/src/core/vector-store.mjs +85 -0
  56. package/src/server/api.mjs +4 -3
  57. package/src/server/index.mjs +13 -61
  58. package/src/server/rest.mjs +341 -63
  59. package/src/server/route-manifest.json +352 -77
  60. package/src/server/routes/memory.mjs +85 -39
  61. package/src/server/routes/sessions.mjs +6 -2
  62. package/src/server/routes/share.mjs +9 -2
@@ -35,6 +35,7 @@ export default function SettingsPage() {
35
35
  if (!data.budget.budget) data.budget.budget = { daily_cap_usd: 5.0, weekly_cap_usd: 25.0, enabled: true };
36
36
  if (!data.brain) data.brain = {};
37
37
  if (!data.brain.preferred_agent) data.brain.preferred_agent = 'auto';
38
+ if (!data.secrets) data.secrets = {};
38
39
 
39
40
  setConfigData(data);
40
41
  } catch (err: unknown) {
@@ -152,6 +153,17 @@ export default function SettingsPage() {
152
153
  });
153
154
  };
154
155
 
156
+ const updateSecretsProp = (prop: string, value: string) => {
157
+ if (!configData) return;
158
+ setConfigData({
159
+ ...configData,
160
+ secrets: {
161
+ ...configData.secrets,
162
+ [prop]: value
163
+ }
164
+ });
165
+ };
166
+
155
167
  return (
156
168
  <div className="page" style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
157
169
  <div className="page-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 16 }}>
@@ -209,7 +221,7 @@ export default function SettingsPage() {
209
221
  </div>
210
222
  ) : viewMode === 'visual' && configData ? (
211
223
  /* ==================== VISUAL CONTROL PANEL UI ==================== */
212
- <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))', gap: 24, flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 24 }}>
224
+ <form onSubmit={(e) => { e.preventDefault(); handleSaveVisual(); }} style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))', gap: 24, flex: 1, minHeight: 0, overflowY: 'auto', paddingBottom: 24 }}>
213
225
 
214
226
  {/* Card 1: AI Reasoning & Autonomy */}
215
227
  <div className="card" style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20, background: 'rgba(18, 18, 26, 0.6)', backdropFilter: 'blur(8px)', border: '1px solid var(--border)' }}>
@@ -537,7 +549,190 @@ export default function SettingsPage() {
537
549
  </div>
538
550
  </div>
539
551
 
540
- </div>
552
+ {/* Card 5: API Keys & Integrations */}
553
+ <div className="card" style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20, background: 'rgba(18, 18, 26, 0.6)', backdropFilter: 'blur(8px)', border: '1px solid var(--border)' }}>
554
+ <div style={{ display: 'flex', alignItems: 'center', gap: 10, borderBottom: '1px solid var(--border)', paddingBottom: 12 }}>
555
+ <span style={{ fontSize: 20 }}>🔑</span>
556
+ <div>
557
+ <h3 style={{ fontSize: 15, fontWeight: 600 }}>API Keys & Integrations</h3>
558
+ <p style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>Manage access keys and tokens for AI models and search providers</p>
559
+ </div>
560
+ </div>
561
+
562
+ {/* Google Gemini API Key */}
563
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
564
+ <label htmlFor="google_api_key" style={{ fontSize: 13, fontWeight: 500 }}>Google Gemini API Key</label>
565
+ <input
566
+ id="google_api_key"
567
+ type="password"
568
+ placeholder="AIzaSy..."
569
+ value={configData.secrets?.google_api_key || ''}
570
+ onChange={(e) => updateSecretsProp('google_api_key', e.target.value)}
571
+ style={{
572
+ background: 'var(--bg-tertiary)',
573
+ color: 'var(--text-primary)',
574
+ border: '1px solid var(--border)',
575
+ padding: '8px 12px',
576
+ borderRadius: 6,
577
+ outline: 'none',
578
+ fontSize: 13
579
+ }}
580
+ />
581
+ </div>
582
+
583
+ {/* Anthropic API Key */}
584
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
585
+ <label htmlFor="anthropic_api_key" style={{ fontSize: 13, fontWeight: 500 }}>Anthropic API Key (Claude Code)</label>
586
+ <input
587
+ id="anthropic_api_key"
588
+ type="password"
589
+ placeholder="sk-ant-..."
590
+ value={configData.secrets?.anthropic_api_key || ''}
591
+ onChange={(e) => updateSecretsProp('anthropic_api_key', e.target.value)}
592
+ style={{
593
+ background: 'var(--bg-tertiary)',
594
+ color: 'var(--text-primary)',
595
+ border: '1px solid var(--border)',
596
+ padding: '8px 12px',
597
+ borderRadius: 6,
598
+ outline: 'none',
599
+ fontSize: 13
600
+ }}
601
+ />
602
+ <span style={{ fontSize: 10, color: 'var(--text-tertiary)' }}>Configuring this allows Claude Code CLI to run without prompting for OAuth login.</span>
603
+ </div>
604
+
605
+ {/* OpenAI API Key */}
606
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
607
+ <label htmlFor="openai_api_key" style={{ fontSize: 13, fontWeight: 500 }}>OpenAI API Key (Codex)</label>
608
+ <input
609
+ id="openai_api_key"
610
+ type="password"
611
+ placeholder="sk-proj-..."
612
+ value={configData.secrets?.openai_api_key || ''}
613
+ onChange={(e) => updateSecretsProp('openai_api_key', e.target.value)}
614
+ style={{
615
+ background: 'var(--bg-tertiary)',
616
+ color: 'var(--text-primary)',
617
+ border: '1px solid var(--border)',
618
+ padding: '8px 12px',
619
+ borderRadius: 6,
620
+ outline: 'none',
621
+ fontSize: 13
622
+ }}
623
+ />
624
+ </div>
625
+
626
+ {/* Tavily API Key */}
627
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
628
+ <label htmlFor="tavily_api_key" style={{ fontSize: 13, fontWeight: 500 }}>Tavily Search API Key</label>
629
+ <input
630
+ id="tavily_api_key"
631
+ type="password"
632
+ placeholder="tvly-..."
633
+ value={configData.secrets?.tavily_api_key || ''}
634
+ onChange={(e) => updateSecretsProp('tavily_api_key', e.target.value)}
635
+ style={{
636
+ background: 'var(--bg-tertiary)',
637
+ color: 'var(--text-primary)',
638
+ border: '1px solid var(--border)',
639
+ padding: '8px 12px',
640
+ borderRadius: 6,
641
+ outline: 'none',
642
+ fontSize: 13
643
+ }}
644
+ />
645
+ </div>
646
+
647
+ {/* Other Search Keys (Brave, Exa, Serper) */}
648
+ <details style={{ fontSize: 13, color: 'var(--text-secondary)' }}>
649
+ <summary style={{ cursor: 'pointer', fontWeight: 500, outline: 'none', padding: '4px 0' }}>More Provider Keys (Brave, Exa, Serper, GitHub)</summary>
650
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 12, paddingLeft: 8, borderLeft: '2px solid var(--border)' }}>
651
+ {/* Brave Search Key */}
652
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
653
+ <label htmlFor="brave_api_key" style={{ fontSize: 12, fontWeight: 500 }}>Brave Search API Key</label>
654
+ <input
655
+ id="brave_api_key"
656
+ type="password"
657
+ value={configData.secrets?.brave_api_key || ''}
658
+ onChange={(e) => updateSecretsProp('brave_api_key', e.target.value)}
659
+ style={{
660
+ background: 'var(--bg-tertiary)',
661
+ color: 'var(--text-primary)',
662
+ border: '1px solid var(--border)',
663
+ padding: '8px 12px',
664
+ borderRadius: 6,
665
+ outline: 'none',
666
+ fontSize: 13
667
+ }}
668
+ />
669
+ </div>
670
+
671
+ {/* Exa Search Key */}
672
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
673
+ <label htmlFor="exa_api_key" style={{ fontSize: 12, fontWeight: 500 }}>Exa API Key</label>
674
+ <input
675
+ id="exa_api_key"
676
+ type="password"
677
+ value={configData.secrets?.exa_api_key || ''}
678
+ onChange={(e) => updateSecretsProp('exa_api_key', e.target.value)}
679
+ style={{
680
+ background: 'var(--bg-tertiary)',
681
+ color: 'var(--text-primary)',
682
+ border: '1px solid var(--border)',
683
+ padding: '8px 12px',
684
+ borderRadius: 6,
685
+ outline: 'none',
686
+ fontSize: 13
687
+ }}
688
+ />
689
+ </div>
690
+
691
+ {/* Serper API Key */}
692
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
693
+ <label htmlFor="serper_api_key" style={{ fontSize: 12, fontWeight: 500 }}>Serper (Google Search API) Key</label>
694
+ <input
695
+ id="serper_api_key"
696
+ type="password"
697
+ value={configData.secrets?.serper_api_key || ''}
698
+ onChange={(e) => updateSecretsProp('serper_api_key', e.target.value)}
699
+ style={{
700
+ background: 'var(--bg-tertiary)',
701
+ color: 'var(--text-primary)',
702
+ border: '1px solid var(--border)',
703
+ padding: '8px 12px',
704
+ borderRadius: 6,
705
+ outline: 'none',
706
+ fontSize: 13
707
+ }}
708
+ />
709
+ </div>
710
+
711
+ {/* GitHub Token */}
712
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
713
+ <label htmlFor="github_token" style={{ fontSize: 12, fontWeight: 500 }}>GitHub Personal Access Token</label>
714
+ <input
715
+ id="github_token"
716
+ type="password"
717
+ placeholder="ghp_..."
718
+ value={configData.secrets?.github_token || ''}
719
+ onChange={(e) => updateSecretsProp('github_token', e.target.value)}
720
+ style={{
721
+ background: 'var(--bg-tertiary)',
722
+ color: 'var(--text-primary)',
723
+ border: '1px solid var(--border)',
724
+ padding: '8px 12px',
725
+ borderRadius: 6,
726
+ outline: 'none',
727
+ fontSize: 13
728
+ }}
729
+ />
730
+ </div>
731
+ </div>
732
+ </details>
733
+ </div>
734
+
735
+ </form>
541
736
  ) : (
542
737
  /* ==================== RAW YAML EDITOR UI ==================== */
543
738
  <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }}>
@@ -159,5 +159,21 @@ export interface ConfigJson {
159
159
  brain?: {
160
160
  preferred_agent?: string
161
161
  }
162
+ secrets?: {
163
+ google_api_key?: string
164
+ anthropic_api_key?: string
165
+ openai_api_key?: string
166
+ tavily_api_key?: string
167
+ brave_api_key?: string
168
+ exa_api_key?: string
169
+ serper_api_key?: string
170
+ github_token?: string
171
+ }
172
+ }
173
+
174
+ export interface UpdateCheckResult {
175
+ currentVersion: string
176
+ latestVersion: string
177
+ updateAvailable: boolean
162
178
  }
163
179
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total-recall-brain",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "Sovereign AI system — database-free, SSSS-powered personal intelligence engine deployable to any POSIX host.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -50,7 +50,7 @@
50
50
  "local-llm"
51
51
  ],
52
52
  "author": "gregiteen",
53
- "license": "ISC",
53
+ "license": "MIT",
54
54
  "bugs": {
55
55
  "url": "https://github.com/gregiteen/total-recall/issues"
56
56
  },
@@ -26,9 +26,10 @@ You MUST actively reference and apply this skill under the following specific ru
26
26
 
27
27
  ### 3. When searching for complex domain knowledge or general facts
28
28
  * **Trigger**: When you need to retrieve deep factual information (e.g. from the `facts/` category) or conceptual domain structures (e.g. from `concepts/`) that are not present in your active instruction files.
29
- * **Action**: Use the two complementary search modes:
30
- * **Regular Text Search** (e.g. filesystem grep / literal matching): Use this when searching for specific literal keywords, exact config keys, exact filenames, or exact slugs.
31
- * **Semantic Search (REST API POST `/api/memory/search/semantic`)**: Use this when searching for conceptual matching, high-level intent, design patterns, or user preferences. Do NOT rely on only one search mode; combine both to ensure absolute coverage.
29
+ * **Action**: Use the semantic/lexical hybrid search engine (via the local `recall` command, or `/api/memory/search/semantic` endpoint) along with regular text search (e.g., grep):
30
+ * **Hybrid Search**: Blends cosine-similarity vector search and lexical density TF-IDF keyword matching using Reciprocal Rank Fusion (RRF). This blends intent-based semantic matching with exact keyword accuracy.
31
+ * **Hierarchical Parent-Child Search**: Memory node bodies are chunked and indexed as children. The vector store searches both the parent node and child chunks, returning matches based on maximum similarity.
32
+ * **Regular Text Search**: Use grep to locate exact configurations, literal keys, or symbols.
32
33
 
33
34
  ### 4. When a topic requires deep, structured domain learning and mastery
34
35
  * **Trigger**: When you encounter a complex architectural topic, a deep conceptual system, or a technical domain where you need to acquire deep mastery to proceed effectively.
@@ -37,7 +38,7 @@ You MUST actively reference and apply this skill under the following specific ru
37
38
 
38
39
  ### 5. When you modify, add, or delete files in the memory vault
39
40
  * **Trigger**: Immediately after performing any memory node writes.
40
- * **Action**: Rebuild the instruction shims by sending a POST request to `/api/vault/compile`.
41
+ * **Action**: Rebuild the instruction shims. If using CLI commands (`npx total-recall remember` / `forget`), recompilation runs automatically in the background (asynchronously via detached subprocesses) to minimize latency. If editing vault files directly, trigger manual compilation by sending a POST request to `/api/vault/compile` or running `npx total-recall compile`.
41
42
 
42
43
  ### 6. When troubleshooting connections, port blocks, or sync errors
43
44
  * **Trigger**: If the REST server is unreachable, ports are blocked, or the upstream sync tool encounters errors.
@@ -48,12 +49,12 @@ You MUST actively reference and apply this skill under the following specific ru
48
49
  ## ⚡ Core Directives for IDE Agents
49
50
 
50
51
  ### 1. Zero-Database Sovereign Integrity
51
- Total Recall operates **entirely database-free**. The local filesystem is the source of truth. Every rule, pattern, decision, concept, preference, and fact exists as a plain Markdown file with semantic YAML frontmatter. Derived indexes are disposable caches. Do not look for PostgreSQL or SQLite databases.
52
+ Total Recall operates **entirely database-free**. The local filesystem is the source of truth. Every rule, pattern, decision, concept, preference, and fact exists as a plain Markdown file with semantic YAML frontmatter. Derived indexes are disposable caches. While the internal Vector Store engine is pluggable and ready for native drop-in indexing engines (such as SQLite-VSS or HNSWLib), the canonical source of truth remains filesystem flat files. Do not look for PostgreSQL or traditional SQL databases.
52
53
 
53
54
  ### 2. Precise Tool & API Selection Heuristics
54
55
  When interacting with the system, choose your interfaces based on the following:
55
56
  * **Local Skills**: Use local skill packages (located in `.agent/skills/`) for complex workspace tasks, testing, and formatting. If a local skill has custom helper scripts, ALWAYS invoke them via your shell command tool instead of running raw standard commands.
56
- * **Total Recall Brain (MANDATORY)**: For all semantic searches, memory retrieval, memory writes, and derived index recompilation, **ALWAYS use shell `curl` commands** targeting the REST API endpoints documented below.
57
+ * **Total Recall Brain (MANDATORY)**: For all semantic searches, memory retrieval, memory writes, and derived index recompilation, **use either the local CLI suite (`npx total-recall`) or shell `curl` commands** targeting the REST API endpoints documented below.
57
58
 
58
59
  ### 3. Non-Destructive Code Modifications
59
60
  When modifying existing rule surfaces or IDE shims (such as `.cursorrules`, `CLAUDE.md`, `GEMINI.md`, etc.), **NEVER** overwrite the developer's custom pre-existing rules. Instead, write compiled absolute invariants inside the managed comment block:
@@ -81,6 +82,54 @@ This spins up a secure local Express server (port 3000, increments dynamically i
81
82
 
82
83
  ---
83
84
 
85
+ ## 🛠️ LOCAL CLI SUITE REFERENCE
86
+
87
+ For local workstation and terminal-based agent workflows, Total Recall provides a CLI command suite:
88
+
89
+ ### 1. Save Memory Node
90
+ ```bash
91
+ npx total-recall remember <category> "<content>" [options]
92
+ ```
93
+ Save rules, preferences, corrections, and facts.
94
+ * **Categories**: `invariant`, `preference`, `correction`, `fact`, `concept`, `pattern`, `anti-pattern`, `decision`, `lore`.
95
+ * **Options**:
96
+ * `--global` / `--project`: Target scope. Global writes propagate to all registered projects.
97
+ * `--importance <1-5>`: Define relative importance.
98
+ * `--priority <level>`: Set priority level (`absolute`, `high`, `normal`, `low`).
99
+ * `--modality <type>`: Modality constraints (`must`, `must_not`, `should`, `should_not`, `descriptive`).
100
+ * `--slug <custom-slug>` / `--title "<custom-title>"`: Override automatic identifiers.
101
+ * `--expires <duration>`: Set expiration lifespan (e.g. `7d`, `2w`, `6h`, `3m`).
102
+ * *Note*: Spawns an asynchronous background surface compile process immediately on execution to avoid synchronous blockages.
103
+
104
+ ### 2. Delete Memory Node
105
+ ```bash
106
+ npx total-recall forget <slug> [options]
107
+ ```
108
+ Delete a memory node by slug.
109
+ * **Options**:
110
+ * `--global` / `--project`: Scope layers. If omitted, checks project first, then global.
111
+ * `--no-compile`: Skip automatic background recompilation.
112
+ * *Note*: Spawns an asynchronous background surface compile process immediately on execution.
113
+
114
+ ### 3. Recall / Hybrid Search
115
+ ```bash
116
+ npx total-recall recall "<query>" [options]
117
+ ```
118
+ Perform semantic/lexical hybrid search across rules, facts, and session history using Reciprocal Rank Fusion (RRF).
119
+ * **Options**:
120
+ * `--top-k, -k <number>`: Number of results (default: 5).
121
+ * `--category, -cat <name>`: Filter by SSSS category.
122
+ * `--tags, -t <list>`: Filter by tags.
123
+ * `--global` / `--project`: Search specific layer.
124
+
125
+ ### 4. Build Memory Vault (Recompile)
126
+ ```bash
127
+ npx total-recall compile
128
+ ```
129
+ Synchronously rebuild the entire memory index (derived embeddings) and regenerate prompt instruction shims (such as `INSTRUCTIONS.md`, `GEMINI.md`, `AGENTS.md`, etc.).
130
+
131
+ ---
132
+
84
133
  ## 🌐 DIRECT REST API REFERENCE
85
134
 
86
135
  All requests to the Total Recall REST API must include the Bearer token in the `Authorization` header.
@@ -15,7 +15,7 @@ predicate: operate
15
15
  object: memory_system
16
16
  created: 2026-05-01T00:00:00.000Z
17
17
  updated: 2026-05-15T00:00:00.000Z
18
- last_accessed: 2026-05-15T00:00:00.000Z
18
+ last_accessed: 2026-06-01T06:07:11.601Z
19
19
  source:
20
20
  type: scaffold
21
21
  session_id: scaffold-seed
@@ -36,7 +36,7 @@ sentiment_polarity: directive_must
36
36
  sentiment_target: memory_system
37
37
  decay:
38
38
  half_life_days: 365
39
- access_count: 1
39
+ access_count: 3
40
40
  x_temporal_context: 2026-05-26T23:05:06.525Z
41
41
  ---
42
42
  # Total Recall Operating Protocol
@@ -0,0 +1 @@
1
+ {"id":"0efa65c2-0231-4267-a304-e0285e50011e","topic":"Total Recall repository improvement research: SSSS validated write pipeline, filesystem-native memory engines, local-first semantic indexing, Express 5 API hardening, 2026 agent memory architecture patterns","status":"pending","priority":"high","notes":"Queued from repo-wide analysis request on 2026-06-01. Focus on current best practices and meta-patterns for filesystem-native memory OS, validated operation envelopes, append-only logs, cache invalidation, research queue architecture, and secure local-first AI tools.","node_slug":null,"research_phase":"acquisition","created_at":"2026-06-01T06:07:40.102Z","updated_at":"2026-06-01T06:07:40.126Z","completed_at":null,"summary":{"id":"0efa65c2-0231-4267-a304-e0285e50011e","topic":"Total Recall repository improvement research: SSSS validated write pipeline, filesystem-native memory engines, local-first semantic indexing, Express 5 API hardening, 2026 agent memory architecture patterns","status":"pending","phase":"acquisition","last_updated":"2026-06-01T06:07:40.126Z","conclusions":[],"ongoing_directions":["Research project is enqueued / in progress in phase: acquisition"],"sources_count":0}}
@@ -5,12 +5,7 @@ agents:
5
5
  priority: 1
6
6
  enabled: true
7
7
  exec: flag
8
- - name: gemini
9
- binary: gemini
10
- flags: --sandbox=false --yolo -o json
11
- priority: 2
12
- enabled: true
13
- exec: flag
8
+
14
9
  - name: claude
15
10
  binary: claude
16
11
  flags: --output-format json --permission-mode bypassPermissions
@@ -9,11 +9,23 @@ schema_version: 2
9
9
 
10
10
  Structured Semantic Syntax System (ssss) is the core operational substrate of the Total Recall Virtual File System (VFS). This skill guides agents in inspecting, reading, and constructing SSSS-compliant memory nodes, conflict models, and derived indices.
11
11
 
12
+ ## Spec Version
13
+
14
+ Current specification: **v0.2 — Draft** (see `references/ssss-spec.md`)
15
+
16
+ ### v0.2 Changes (2026-05-30)
17
+ - Expanded `modality` enum: `must|must_not|should|should_not|descriptive|preference`
18
+ - Expanded `priority` enum: `absolute|high|normal|low` (OPTIONAL, defaults to `normal`)
19
+ - Added §10.1: Projection Manifest requirement with vault-hash staleness detection
20
+ - Added §11.3: Single canonical embedding implementation (no dual systems)
21
+
12
22
  ## Core Directives
13
23
 
14
24
  1. **Schema Integrity:** Every SSSS node must strictly adhere to the frontmatter schema definitions (Modality, Category, Sentiment).
15
25
  2. **Zero-Database Persistence:** Do not look for Postgres or SQLite. Everything lives as a git-versioned Markdown file.
16
26
  3. **Decay and Drift Monitoring:** Use decay indicators to manage node half-lives dynamically in background ticks.
27
+ 4. **Cached Reads:** All vault reads MUST go through `vault-cache.mjs` (`getNodes()`) — never call `loadNodes()` directly. The cache supports multi-directory (global + project) with per-directory `fs.watch` invalidation.
28
+ 5. **Operation Contract:** All agent-generated mutations MUST flow through `processOperation()` (§6). Direct `writeNode()` calls bypass validation, idempotency, authorization, lease protection, and audit logging.
17
29
 
18
30
  ## Progressive Memory Disclosure
19
31
 
@@ -22,6 +34,13 @@ Memory flows through a 3-tier progressive hierarchy:
22
34
  * **Tier 2 (Warm):** SKILL.md injects (Category-routed warm capsules).
23
35
  * **Tier 3 (Cold):** Full memory vault (Search index files on demand).
24
36
 
37
+ ## Performance Invariants
38
+
39
+ * `vault-cache.mjs` is the **single import point** for all node reads. The cache uses `fs.watch` auto-invalidation and supports multiple vault directories simultaneously.
40
+ * `walkMd()` uses `{ withFileTypes: true }` to eliminate per-file `stat()` syscalls.
41
+ * `deleteNode()` scans category directories directly — O(categories) not O(nodes).
42
+ * Surface recompilation (`triggerMutation()`) is debounced with a 2-second quiet period for batch writes.
43
+
25
44
  ## References
26
45
 
27
46
  * Core SSSS specification: `references/ssss-spec.md`
@@ -1,6 +1,6 @@
1
1
  # SSSS — Structured Semantic Syntax System
2
2
 
3
- **Specification v0.1 — Draft**
3
+ **Specification v0.2 — Draft**
4
4
 
5
5
  > This is the canonical, vendor-neutral specification for SSSS. It is the ground
6
6
  > truth on which all SSSS implementations are built. It is intended to be vendored
@@ -198,8 +198,8 @@ The knowledge primitive. Categories: `invariants`, `patterns`, `anti-patterns`,
198
198
  REQUIRED: `type`, `slug`, `category`, `title`, `status`, `schema_version`.
199
199
 
200
200
  Knowledge-graph fields, REQUIRED when `schema_version: 2`: `confidence` (0..1),
201
- `importance` (1..5), `modality` (`must|must_not|should|should_not`), `subject`,
202
- `predicate`, `object`, `sentiment_polarity`
201
+ `importance` (1..5), `modality` (`must|must_not|should|should_not|descriptive|preference`),
202
+ `subject`, `predicate`, `object`, `sentiment_polarity`
203
203
  (`directive_must|directive_must_not|descriptive|preference`).
204
204
 
205
205
  The `subject`/`predicate`/`object` triple SHOULD use stable, language-neutral
@@ -228,7 +228,8 @@ POSIX filesystems; direct writes risk partial-file corruption on crash.
228
228
  ```
229
229
 
230
230
  Memory nodes in the `invariants` category additionally carry `priority: absolute`
231
- and `immutable: true`.
231
+ and `immutable: true`. The full `priority` enum is `absolute|high|normal|low`;
232
+ `priority` is OPTIONAL on non-invariant categories (defaults to `normal`).
232
233
 
233
234
  #### `skill`
234
235
 
@@ -673,6 +674,30 @@ A host that maintains projections MUST provide a means to (a) rebuild a projecti
673
674
  from a vault scan, and (b) detect and repair drift between a projection and the
674
675
  vault.
675
676
 
677
+ ### 10.1 Projection Manifest
678
+
679
+ A host SHOULD maintain a `MANIFEST.json` (or equivalent) in the derived-artifacts
680
+ directory declaring each projection as disposable and recording provenance:
681
+
682
+ ```jsonc
683
+ {
684
+ "type": "projection-manifest",
685
+ "generated_at": "2026-05-30T06:35:00Z",
686
+ "vault_hash": "sha256:abc123...", // content hash of the vault at build time
687
+ "projections": [
688
+ { "file": "graph-index.jsonl", "disposable": true },
689
+ { "file": "memory-layers.jsonl", "disposable": true },
690
+ { "file": "embeddings.json", "disposable": true }
691
+ ],
692
+ "rebuild_command": "npx total-recall compile"
693
+ }
694
+ ```
695
+
696
+ The `vault_hash` field enables **staleness detection**: if the current vault hash
697
+ differs from the manifest's hash, the projections are stale and SHOULD be rebuilt.
698
+ This supports **incremental compilation** — a host MAY skip recompilation when the
699
+ hash matches, avoiding redundant I/O on unchanged vaults.
700
+
676
701
  ---
677
702
 
678
703
  ## 11. The Semantic Layer
@@ -713,6 +738,9 @@ disposable, never source-of-truth, fully rebuildable from the vault.
713
738
 
714
739
  - It MUST record the `embedding_model` and vector `dim` that produced it. Embeddings
715
740
  are not comparable across models; a model change REQUIRES a full reindex.
741
+ - A host MUST maintain exactly **one canonical embedding implementation**. Parallel
742
+ or duplicate embedding systems (e.g. one in JSON format and another in JSONL)
743
+ create consistency risks where a node is indexed in one but not the other.
716
744
  - Retrieval SHOULD be **hybrid**: an exact/lexical pass (strong for slugs,
717
745
  identifiers, and code) fused with a dense semantic pass (strong for meaning and
718
746
  cross-lingual matches).
@@ -802,7 +830,7 @@ opaque ID as the slug and keep the human-readable label in `title` / `name`.
802
830
  This document is versioned independently of any host and of the conformance
803
831
  fixture set.
804
832
 
805
- - The spec version is stated in the document header (currently **v0.1 — Draft**).
833
+ - The spec version is stated in the document header (currently **v0.2 — Draft**).
806
834
  - Breaking changes to the file format, the type registry, or the Operation
807
835
  Contract increment the spec version.
808
836
  - Until **v1.0**, any version MAY introduce breaking changes.
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { resolveAgentDir, resolveBrainDir, parseLayerFlag, getBothBrains } from './agent-dir.mjs';
4
4
  import { compileSurface } from '../core/surface.mjs';
5
- import { deleteNode, loadNodes } from '../core/vault.mjs';
5
+ import { deleteNode } from '../core/vault.mjs';
6
6
 
7
7
  function printHelp() {
8
8
  console.log(`
@@ -46,9 +46,15 @@ export default async function forget(args) {
46
46
  // Check project first, then global
47
47
  if (brains.project) {
48
48
  const projVaultDir = path.join(brains.project.brainDir, 'memory-vault');
49
- const projNodes = loadNodes(projVaultDir);
50
- if (projNodes.some(n => n.slug === slug)) {
51
- layer = 'project';
49
+ // Direct category scan instead of full vault load
50
+ if (fs.existsSync(projVaultDir)) {
51
+ const cats = fs.readdirSync(projVaultDir, { withFileTypes: true });
52
+ for (const cat of cats) {
53
+ if (cat.isDirectory() && fs.existsSync(path.join(projVaultDir, cat.name, `${slug}.md`))) {
54
+ layer = 'project';
55
+ break;
56
+ }
57
+ }
52
58
  }
53
59
  }
54
60
  if (layer === 'auto') {
@@ -76,17 +82,17 @@ export default async function forget(args) {
76
82
 
77
83
  // Recompile unless --no-compile
78
84
  if (!noCompile) {
79
- console.log(' ⏳ Recompiling active memory surfaces and indexes...');
85
+ console.log(' ⏳ Recompiling active memory surfaces and indexes in the background...');
80
86
  try {
81
- const compileResult = await compileSurface({
82
- vaultDir,
83
- skillsDir,
84
- derivedDir,
85
- instructionsFile
87
+ const { spawn } = await import('node:child_process');
88
+ const child = spawn(process.argv[0], [process.argv[1], 'compile'], {
89
+ detached: true,
90
+ stdio: 'ignore'
86
91
  });
87
- console.log(` ✅ Recompilation successful! Processed ${compileResult.nodesProcessed} SSSS nodes.`);
92
+ child.unref();
93
+ console.log(' ✅ Background compilation started.');
88
94
  } catch (err) {
89
- console.warn(` ⚠️ Node deleted, but surface recompilation failed: ${err.message}`);
95
+ console.warn(` ⚠️ Node deleted, but background recompilation spawn failed: ${err.message}`);
90
96
  }
91
97
  }
92
98
  }
@@ -24,7 +24,8 @@ import { parseSearchHistory } from './parsers/search-history.mjs';
24
24
  import { parseChromeBookmarks } from './parsers/chrome-bookmarks.mjs';
25
25
  import { parseGoogleKeep } from './parsers/google-keep.mjs';
26
26
  import { parseYoutubeHistory } from './parsers/youtube-history.mjs';
27
- import { writeNode, loadNodes } from '../../core/vault.mjs';
27
+ import { writeNode } from '../../core/vault.mjs';
28
+ import { getNodes } from '../../core/vault-cache.mjs';
28
29
  import { resolveBrainDir, parseLayerFlag, getBothBrains, defaultLayerForCategory } from '../../cli/agent-dir.mjs';
29
30
 
30
31
  /**
@@ -204,7 +205,7 @@ export async function ingestGoogleTakeout(takeoutPath, options = {}) {
204
205
  // Load existing vault nodes for dedup
205
206
  let existingNodes = [];
206
207
  if (fs.existsSync(vaultDir)) {
207
- existingNodes = loadNodes(vaultDir);
208
+ existingNodes = getNodes(vaultDir);
208
209
  }
209
210
 
210
211
  // Run parsers for each detected type
package/src/cli/map.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { resolveBrainDir, parseLayerFlag, getBothBrains } from './agent-dir.mjs';
4
- import { loadNodes } from '../core/vault.mjs';
4
+ import { getNodes } from '../core/vault-cache.mjs';
5
5
 
6
6
  function printHelp() {
7
7
  console.log(`
@@ -68,7 +68,7 @@ export default async function map(args) {
68
68
  const vaultDir = path.join(l.path, 'memory-vault');
69
69
  if (!fs.existsSync(vaultDir)) continue;
70
70
 
71
- const nodes = loadNodes(vaultDir).map(n => ({ ...n, _layer: l.name }));
71
+ const nodes = getNodes(vaultDir).map(n => ({ ...n, _layer: l.name }));
72
72
  loadedLayers.push({ name: l.name, nodes });
73
73
  totalNodesCount += nodes.length;
74
74
  }
@@ -59,7 +59,7 @@ export async function runRebuild(options = {}) {
59
59
 
60
60
  console.log('🏗️ Recompiling surface from canonical vault...');
61
61
  try {
62
- const stats = await compileSurface({ vaultDir, skillsDir, derivedDir, instructionsFile });
62
+ const stats = await compileSurface({ vaultDir, skillsDir, derivedDir, instructionsFile, force: true });
63
63
  console.log(`✅ Processed ${stats.nodesProcessed} canonical memory nodes.`);
64
64
  console.log(`✅ Injected memory into ${stats.skillsInjected} skill files.`);
65
65
  console.log(`✅ Rebuilt graph-index.jsonl, memory-layers.jsonl, and skill-routes.jsonl.`);