total-recall-brain 3.13.2 → 3.14.3
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/bin/total-recall.mjs +3 -0
- package/frontend/src/App.tsx +8 -7
- package/frontend/src/api.ts +25 -0
- package/frontend/src/components/UsageChart.tsx +1 -1
- package/frontend/src/pages/ApiKeysPage.tsx +118 -42
- package/frontend/src/pages/ChatPage.tsx +1 -1
- package/frontend/src/pages/DesignDocsPage.tsx +28 -21
- package/frontend/src/pages/FilesPage.tsx +6 -1
- package/frontend/src/pages/GraphPage.tsx +5 -1
- package/frontend/src/pages/HealthPage.tsx +1 -1
- package/frontend/src/pages/InboxPage.tsx +2 -1
- package/frontend/src/pages/InstructionsPage.tsx +2 -2
- package/frontend/src/pages/IntegrationsPage.tsx +11 -5
- package/frontend/src/pages/MemoryPage.tsx +27 -118
- package/frontend/src/pages/ModelsPage.tsx +2 -50
- package/frontend/src/pages/OnboardingPage.tsx +5 -10
- package/frontend/src/pages/OpenWikiPage.tsx +1 -0
- package/frontend/src/pages/SettingsPage.tsx +136 -131
- package/frontend/src/pages/SkillsPage.tsx +102 -46
- package/frontend/src/pages/TasksPage.tsx +60 -25
- package/frontend/src/pages/UsagePage.tsx +206 -95
- package/frontend/src/types.ts +17 -11
- package/frontend/src/utils/onboarding.ts +10 -0
- package/package.json +3 -2
- package/scaffold/.agent/skills/ssss/SKILL.md +235 -0
- package/scaffold/.agent/skills/ssss/evals/evals.json +37 -0
- package/scaffold/.agent/skills/ssss/references/contract-reference.md +95 -0
- package/scaffold/.agent/skills/ssss/scripts/validate-schema.mjs +215 -0
- package/scaffold/.agent/skills/ssss/subagents/audit-ssss-contract.md +22 -0
- package/scaffold/.agent/skills/total-recall/SKILL.md +1 -0
- package/src/cli/backup.mjs +3 -3
- package/src/cli/chat.mjs +2 -2
- package/src/cli/config.mjs +2 -9
- package/src/cli/connect.mjs +1 -1
- package/src/cli/deploy-ui.mjs +1 -1
- package/src/cli/deploy.mjs +2 -2
- package/src/cli/doctor.mjs +1 -1
- package/src/cli/help.mjs +1 -1
- package/src/cli/init.mjs +19 -1
- package/src/cli/key.mjs +150 -0
- package/src/cli/secret.mjs +30 -1
- package/src/cli/skill.mjs +0 -2
- package/src/cli/sync.mjs +19 -0
- package/src/cli/upgrade.mjs +1 -1
- package/src/cli/wizard.html +5 -5
- package/src/core/crons.mjs +11 -0
- package/src/core/daemon-loop.mjs +11 -0
- package/src/core/import-rules.mjs +4 -3
- package/src/core/okf-adapter.mjs +10 -10
- package/src/core/runtime.mjs +0 -2
- package/src/core/secrets-store.mjs +16 -0
- package/src/core/skills-registry.mjs +38 -0
- package/src/core/surface.mjs +1 -1
- package/src/core/task_runner.mjs +6 -0
- package/src/core/usage-tracker.mjs +16 -3
- package/src/core/vault-watcher.mjs +92 -0
- package/src/core/vault.mjs +0 -2
- package/src/server/api.mjs +1 -1
- package/src/server/rest.mjs +69 -57
- package/src/server/route-manifest.json +8 -0
- package/src/server/routes/_shared.mjs +1 -1
- package/src/server/routes/secrets.mjs +4 -4
- package/src/server/routes/skills.mjs +92 -10
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ssss
|
|
3
|
+
description: "Inspect, validate, implement, or change SSSS primitives, registries, kernel commands, VFS/security adapters, events, projections, multilingual semantic runtime, generative UI, bundles, and host adapters. MANDATORY: Read this file before editing SSSS files or code."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SSSS — Structured Semantic Syntax System Manager
|
|
7
|
+
|
|
8
|
+
SSSS is a vendor-neutral, Markdown-first state and mutation contract. Canonical
|
|
9
|
+
state is typed Markdown plus append-only events. Databases, indexes, queues,
|
|
10
|
+
dashboards, and search stores are host projections unless explicitly documented
|
|
11
|
+
as external resources.
|
|
12
|
+
|
|
13
|
+
## Establish Ground Truth First
|
|
14
|
+
|
|
15
|
+
Do not infer the contract from an installed skill snapshot.
|
|
16
|
+
|
|
17
|
+
1. Find the repository root and inspect `package.json`, `VERSION`,
|
|
18
|
+
`registry/core.json`, and `docs/ssss-spec.md` when they exist.
|
|
19
|
+
2. Treat `registry/core.json` as the machine-readable primitive contract and
|
|
20
|
+
`docs/ssss-spec.md` as the normative explanation.
|
|
21
|
+
3. Treat `src/engine.mjs`, `src/runtime.mjs`, `src/semantic.mjs`,
|
|
22
|
+
`src/bundle.mjs`, `src/registry.mjs`, and `src/frontmatter.mjs` as the
|
|
23
|
+
reference behavior.
|
|
24
|
+
4. Treat host schemas and services as adapters or extension registries. Never
|
|
25
|
+
promote host-only fields into the core standard without an explicit spec and
|
|
26
|
+
registry change.
|
|
27
|
+
5. Read the current package name and version instead of hard-coding an alias.
|
|
28
|
+
In this checkout the published package is `@gregiteen/ssss-cli`; the CLI is
|
|
29
|
+
`ssss`.
|
|
30
|
+
|
|
31
|
+
If those files are absent, inspect the installed
|
|
32
|
+
`@gregiteen/ssss-cli/registry/core.json` export. Use the bundled reference only
|
|
33
|
+
as a fallback and report that the result is snapshot-based.
|
|
34
|
+
|
|
35
|
+
## Authority Order
|
|
36
|
+
|
|
37
|
+
When sources disagree, resolve drift in this order:
|
|
38
|
+
|
|
39
|
+
1. Conformance fixtures and tests for observed executable behavior.
|
|
40
|
+
2. `registry/core.json` for required fields, enums, append behavior, and
|
|
41
|
+
portability.
|
|
42
|
+
3. `docs/ssss-spec.md` for normative semantics.
|
|
43
|
+
4. Reference engine/runtime/bundle code.
|
|
44
|
+
5. Host extension registry and host adapter documentation.
|
|
45
|
+
6. Skills, examples, README prose, and copied mirrors.
|
|
46
|
+
|
|
47
|
+
Do not silently pick one side. Identify the mismatch, decide whether code or
|
|
48
|
+
canon is wrong, update every affected source, and add a regression check.
|
|
49
|
+
|
|
50
|
+
## Document Contract
|
|
51
|
+
|
|
52
|
+
Every SSSS document has YAML frontmatter and a Markdown body. SSSS-managed
|
|
53
|
+
documents require the universal fields:
|
|
54
|
+
|
|
55
|
+
- `type`
|
|
56
|
+
- `title`
|
|
57
|
+
- `description`
|
|
58
|
+
- `timestamp`
|
|
59
|
+
|
|
60
|
+
Primitive-specific required fields are additive. An SSSS-managed skill also
|
|
61
|
+
requires `name`; a schema-v2 memory has knowledge-graph fields; a workflow
|
|
62
|
+
requires `name`.
|
|
63
|
+
|
|
64
|
+
Unknown frontmatter fields must be preserved for forward compatibility. Never
|
|
65
|
+
drop a nested map, array, or unknown field during parse/serialize or patch.
|
|
66
|
+
|
|
67
|
+
Registry declarations are executable contract. Enforce `required_fields`,
|
|
68
|
+
`required_when`, `enums`, `patterns`, `immutable_fields`, `references`,
|
|
69
|
+
`append_only`, and `portability`. Reject malformed extension definitions,
|
|
70
|
+
symlinked registry files, and core or sibling type collisions during load.
|
|
71
|
+
|
|
72
|
+
## Mutation Contract
|
|
73
|
+
|
|
74
|
+
**Package `@gregiteen/ssss-cli@0.9` is the shared mutation authority.** Hosts inject
|
|
75
|
+
VFS/lease/idempotency/event adapters and call `createKernel` → `kernel.execute`
|
|
76
|
+
(or host bridges that wrap it). Do not re-implement the Operation Contract pipeline
|
|
77
|
+
in a host, and do not use raw file/DB writes for agent-generated vault mutations.
|
|
78
|
+
|
|
79
|
+
Agent-generated mutations flow through the Operation Contract:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
validate envelope
|
|
83
|
+
-> verify safe workspace/idempotency/actor identifiers
|
|
84
|
+
-> resolve and contain the target path
|
|
85
|
+
-> replay or reject the idempotency key + request hash
|
|
86
|
+
-> authorize with verified actor identity (fail closed)
|
|
87
|
+
-> validate any active lease (fail closed)
|
|
88
|
+
-> validate universal + primitive-specific content
|
|
89
|
+
-> commit atomically
|
|
90
|
+
-> append the audit event
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The mutation envelopes are:
|
|
94
|
+
|
|
95
|
+
- `operation` — create or fully replace a replace-type document.
|
|
96
|
+
- `patch` — merge an existing replace-type document without changing `type`.
|
|
97
|
+
- `event` — append an immutable event record.
|
|
98
|
+
- `delete` — remove a replace-type document and emit an audit event; reject
|
|
99
|
+
append-type targets.
|
|
100
|
+
|
|
101
|
+
Use `dry_run: true` for model-generated preflight. Idempotency is scoped by the
|
|
102
|
+
effective request, not the key alone: the same request replays, while the same
|
|
103
|
+
workspace/key with a different request hash is a conflict.
|
|
104
|
+
|
|
105
|
+
### Host cutover status (0.9.0)
|
|
106
|
+
|
|
107
|
+
| Host | Default | Notes |
|
|
108
|
+
|------|---------|--------|
|
|
109
|
+
| Total Recall | `kernel-core` | Local legacy pipeline removed |
|
|
110
|
+
| Festech | `kernel` | `processLegacy` removed |
|
|
111
|
+
| UltraChat | `kernel` | `processOperationLegacy` removed |
|
|
112
|
+
|
|
113
|
+
Host-copied validators may remain as **read-side** helpers only. Mutation validation
|
|
114
|
+
uses package `createValidator` + host extension registries.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## Append, Lease, and Path Safety
|
|
118
|
+
|
|
119
|
+
- `conversation` and `run` are append-only. Preserve prior bytes and append new
|
|
120
|
+
records; never rewrite or delete them.
|
|
121
|
+
- Events are immutable.
|
|
122
|
+
- Paths must be relative, contained vault paths. Reject absolute paths,
|
|
123
|
+
backslashes, null bytes, empty segments, `.`/`..`, directory targets, and
|
|
124
|
+
symlink escapes.
|
|
125
|
+
- Leases are actor-owned, operation-linked, expiring locks. Missing, mismatched,
|
|
126
|
+
malformed, or unreadable lease state fails closed.
|
|
127
|
+
- Hosts must overwrite caller-supplied actor data with verified session identity
|
|
128
|
+
before authorization.
|
|
129
|
+
|
|
130
|
+
## Workflow Runtime
|
|
131
|
+
|
|
132
|
+
Workflow frontmatter owns the schedule. Cron, daemon, webhook, file watcher, and
|
|
133
|
+
event-loop processes are wake-up mechanisms, not a second scheduling database.
|
|
134
|
+
|
|
135
|
+
Use `@gregiteen/ssss-cli/runtime` to deterministically derive the trigger event,
|
|
136
|
+
task, and run envelopes. Duplicate ticks must replay idempotently. Queues and
|
|
137
|
+
task dashboards are disposable projections over workflow state and events.
|
|
138
|
+
|
|
139
|
+
## Bundles and Portability
|
|
140
|
+
|
|
141
|
+
Every document primitive resolves to one portability class:
|
|
142
|
+
|
|
143
|
+
- `structural` — reusable model shipped in templates and sale bundles.
|
|
144
|
+
- `tenant_private` — operator/customer runtime data; excluded from template and
|
|
145
|
+
sale exports.
|
|
146
|
+
- `resource_bound` — exported only as a requirement declaration; never leak the
|
|
147
|
+
seller's bound resource value.
|
|
148
|
+
|
|
149
|
+
Bundle paths must be unique, safe, and symlink-free. Validate content hashes,
|
|
150
|
+
required extensions, primitive inventory, core version, parameters, and link
|
|
151
|
+
integrity before import. Preflight the complete plan before the first commit so a
|
|
152
|
+
late invalid envelope cannot leave a partial install. Provisioning produces
|
|
153
|
+
deterministic Operation Contract envelopes; re-import must be a no-op.
|
|
154
|
+
|
|
155
|
+
## Multilingual Semantic Runtime
|
|
156
|
+
|
|
157
|
+
Treat semantic indexes and rendered text/UI as disposable projections. Canonical
|
|
158
|
+
documents are authored once in any language; do not create translation documents or
|
|
159
|
+
localized canonical trees.
|
|
160
|
+
|
|
161
|
+
- Index only `structural` documents by default. Include `tenant_private` and
|
|
162
|
+
`resource_bound` sources only after an explicit authorized opt-in.
|
|
163
|
+
- Derive stable identity from `semantic_id`, then `resource`, then source path.
|
|
164
|
+
- Build edges from explicit `relations`, wiki links, and Markdown links.
|
|
165
|
+
- Record embedding model identity and vector dimensions and report lexical and
|
|
166
|
+
semantic evidence separately.
|
|
167
|
+
- Render language at runtime through an injected adapter. Preserve primitive IDs,
|
|
168
|
+
field IDs, enum codes, actions, permissions, paths, versions, hashes, and relations.
|
|
169
|
+
|
|
170
|
+
## Scope and Host Adapters
|
|
171
|
+
|
|
172
|
+
The core standard does not collapse host ownership layers. A host may implement
|
|
173
|
+
global/project or system/account/workspace overlays, but must document precedence
|
|
174
|
+
and preserve isolation. Shared system skills should be inherited through an
|
|
175
|
+
overlay rather than copied into every workspace.
|
|
176
|
+
|
|
177
|
+
When working in Total Recall, use its validated-write and memory-validator
|
|
178
|
+
adapter if those modules exist. In another host, locate its extension registry
|
|
179
|
+
and conformance bridge. Do not quote Total Recall paths as universal SSSS
|
|
180
|
+
architecture.
|
|
181
|
+
|
|
182
|
+
## Procedure for Changes
|
|
183
|
+
|
|
184
|
+
1. Classify the change: core primitive, contract behavior, runtime behavior,
|
|
185
|
+
semantic/runtime-rendering behavior, bundle/provisioning behavior, projection, or
|
|
186
|
+
host extension.
|
|
187
|
+
2. Inspect the registry, spec section, implementation, fixtures, and host bridge
|
|
188
|
+
for that surface.
|
|
189
|
+
3. Make the smallest coherent change across code and canon.
|
|
190
|
+
4. Add positive, negative, replay, and invalid-path cases where applicable.
|
|
191
|
+
5. Run focused validation, then the full conformance gate.
|
|
192
|
+
6. Update skill/reference mirrors only after the executable contract is green.
|
|
193
|
+
|
|
194
|
+
## Validation
|
|
195
|
+
|
|
196
|
+
Validate a Markdown document with the dependency-free skill helper:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
node skills/ssss/scripts/validate-schema.mjs path/to/document.md
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
In the SSSS reference repository, the required gate is:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm test
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
It covers registry/engine parity, shipped-skill conformance, Operation Contract
|
|
209
|
+
fixtures, workflow runtime behavior, lease/frontmatter regressions,
|
|
210
|
+
extension-registry hardening, multilingual semantic behavior,
|
|
211
|
+
bundle/provisioning round trips, and CLI smoke tests.
|
|
212
|
+
|
|
213
|
+
For host adapters, run the host's named SSSS conformance command as well. Do not
|
|
214
|
+
substitute a loose YAML parse or a generic typecheck for the SSSS gate.
|
|
215
|
+
|
|
216
|
+
## Do Not
|
|
217
|
+
|
|
218
|
+
- Do not treat an installed skill, copied spec, or README as newer than the live
|
|
219
|
+
registry and conformance suite.
|
|
220
|
+
- Do not use raw file writes for agent-generated vault mutations.
|
|
221
|
+
- Do not make a derived database/index/queue the canonical record.
|
|
222
|
+
- Do not add a primitive in prose without registry and fixture coverage.
|
|
223
|
+
- Do not translate symbolic control fields or index private content by default.
|
|
224
|
+
- Do not materialize a projection inside its source vault.
|
|
225
|
+
- Do not mix document primitives with contract envelopes.
|
|
226
|
+
- Do not claim conformance from HTTP success or file creation alone.
|
|
227
|
+
- Do not publish package names, versions, or exporter identities without reading
|
|
228
|
+
them from current package metadata.
|
|
229
|
+
|
|
230
|
+
## References
|
|
231
|
+
|
|
232
|
+
Read `references/contract-reference.md` for the compact topology, primitive
|
|
233
|
+
families, package entry points, and drift checklist. For normative detail, read
|
|
234
|
+
the exact linked section of `docs/ssss-spec.md` rather than loading a stale
|
|
235
|
+
vendored copy.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "ssss-skill-validates-as-primitive",
|
|
4
|
+
"assertion": "SKILL.md includes universal SSSS frontmatter plus type: skill, name: ssss, and a trigger-optimized description.",
|
|
5
|
+
"severity": "error"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"name": "ssss-canon-is-evidence-first",
|
|
9
|
+
"assertion": "The skill tells agents to inspect package metadata, registry, spec, implementation, and conformance instead of trusting a copied snapshot.",
|
|
10
|
+
"severity": "error"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "ssss-validator-is-dependency-free",
|
|
14
|
+
"assertion": "scripts/validate-schema.mjs runs with Node built-ins and validates universal plus primitive-specific fields.",
|
|
15
|
+
"severity": "error"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "ssss-host-boundaries-are-explicit",
|
|
19
|
+
"assertion": "The skill distinguishes the vendor-neutral reference kernel from Total Recall and other host adapters.",
|
|
20
|
+
"severity": "error"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "ssss-full-gate-is-named",
|
|
24
|
+
"assertion": "The skill requires npm test in the reference repository and the host-specific SSSS conformance gate for adapters.",
|
|
25
|
+
"severity": "error"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "ssss-semantic-default-is-private",
|
|
29
|
+
"assertion": "The skill requires structural-only semantic projections by default, with explicit authorization before private or resource-bound indexing.",
|
|
30
|
+
"severity": "error"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "ssss-runtime-rendering-preserves-controls",
|
|
34
|
+
"assertion": "The skill requires runtime multilingual rendering and preserves all symbolic control fields.",
|
|
35
|
+
"severity": "error"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# SSSS Contract Reference
|
|
2
|
+
|
|
3
|
+
This is an operational map. The normative source is the current
|
|
4
|
+
`docs/ssss-spec.md`; the machine-readable source is `registry/core.json`.
|
|
5
|
+
|
|
6
|
+
## Reference-kernel topology
|
|
7
|
+
|
|
8
|
+
| Surface | Responsibility |
|
|
9
|
+
| --- | --- |
|
|
10
|
+
| `registry/core.json` | Core document/contract primitives, universal fields, enums, portability, bundle/runtime vocabularies. |
|
|
11
|
+
| `registry/extensions/*.json` | Host/application types that cannot redefine core primitives. |
|
|
12
|
+
| `src/engine.mjs` | Operation Contract, validation, authorization, leases, idempotency, atomic commit, audit. |
|
|
13
|
+
| `src/runtime.mjs` | Workflow trigger planning and deterministic event/task/run envelopes. |
|
|
14
|
+
| `src/semantic.mjs` | Deterministic records/edges, multilingual embeddings, hybrid retrieval, and invariant rendering. |
|
|
15
|
+
| `src/bundle.mjs` | Export, validate, provision, import, portability filtering, link/hash integrity. |
|
|
16
|
+
| `src/registry.mjs` | Registry loading and type/portability resolution. |
|
|
17
|
+
| `src/frontmatter.mjs` | Dependency-free parse/serialize with unknown-field preservation. |
|
|
18
|
+
| `conformance/fixtures.json` | Canonical mutation examples and negative cases. |
|
|
19
|
+
| `scripts/conformance.mjs` | Full executable contract gate. |
|
|
20
|
+
|
|
21
|
+
## Package entry points
|
|
22
|
+
|
|
23
|
+
Read the npm package name from `package.json`. The current reference checkout
|
|
24
|
+
uses `@gregiteen/ssss-cli` and exposes `/engine`, `/runtime`, `/semantic`, `/bundle`,
|
|
25
|
+
`/registry`, `/frontmatter`, `/registry/core.json`,
|
|
26
|
+
`/conformance/fixtures.json`, and `/conformance/reference-bundle.ucw.json`.
|
|
27
|
+
The executable command is `ssss`.
|
|
28
|
+
|
|
29
|
+
## Document versus contract primitives
|
|
30
|
+
|
|
31
|
+
Document primitives persist as Markdown and carry universal frontmatter.
|
|
32
|
+
Contract primitives are mutation/concurrency envelopes and are not Markdown
|
|
33
|
+
document types.
|
|
34
|
+
|
|
35
|
+
Current core document families include knowledge (`memory`), capability
|
|
36
|
+
(`skill`, `page`), governance (`rule`, `security_role`), work (`task`,
|
|
37
|
+
`workflow`), actors/catalog (`assistant`, `model`), transcripts (`conversation`,
|
|
38
|
+
`run`), and lifecycle/meta (`conflict`, `migration`, `release`, `primitive`).
|
|
39
|
+
|
|
40
|
+
The contract primitives are `operation`, `patch`, `event`, `delete`, and
|
|
41
|
+
`lease`.
|
|
42
|
+
|
|
43
|
+
## Required validation dimensions
|
|
44
|
+
|
|
45
|
+
For a document:
|
|
46
|
+
|
|
47
|
+
1. Frontmatter exists and parses.
|
|
48
|
+
2. Universal fields are present and non-empty.
|
|
49
|
+
3. `type` exists in the core or a loaded extension registry.
|
|
50
|
+
4. Primitive-specific required/conditional fields are present.
|
|
51
|
+
5. Enum values are valid.
|
|
52
|
+
6. Pattern constraints match and document references resolve safely.
|
|
53
|
+
7. Immutable fields do not change during replacement or patch.
|
|
54
|
+
8. Append-only behavior is preserved.
|
|
55
|
+
9. Unknown fields survive parse/serialize and patch.
|
|
56
|
+
10. Path and canonical filename rules hold where applicable.
|
|
57
|
+
|
|
58
|
+
For an envelope:
|
|
59
|
+
|
|
60
|
+
1. Envelope type and identifiers are valid.
|
|
61
|
+
2. Target path is relative and contained.
|
|
62
|
+
3. Idempotency replay is bound to the request hash.
|
|
63
|
+
4. Actor identity is verified and authorization fails closed.
|
|
64
|
+
5. Lease state is valid or the write is rejected.
|
|
65
|
+
6. Content validates against universal plus primitive-specific rules.
|
|
66
|
+
7. Commit is atomic and emits an audit event.
|
|
67
|
+
|
|
68
|
+
For a bundle:
|
|
69
|
+
|
|
70
|
+
1. Manifest shape and core version are supported.
|
|
71
|
+
2. Required extensions are loaded.
|
|
72
|
+
3. Paths are safe, unique, and sorted.
|
|
73
|
+
4. Content hash and primitive inventory match.
|
|
74
|
+
5. Portability prevents tenant-private and resource-value leakage.
|
|
75
|
+
6. Parameters/provisioning use registry vocabularies.
|
|
76
|
+
7. Internal links resolve after remapping.
|
|
77
|
+
8. Re-import replays without new commits.
|
|
78
|
+
|
|
79
|
+
For a multilingual semantic projection:
|
|
80
|
+
|
|
81
|
+
1. Records and index hashes are deterministic for identical inputs.
|
|
82
|
+
2. Stable identity, tokens, content hashes, portability, and graph edges are retained.
|
|
83
|
+
3. Private and resource-bound documents are excluded unless explicitly authorized.
|
|
84
|
+
4. Embedding records retain model identity and vector dimensions.
|
|
85
|
+
5. Lexical and semantic evidence remain separately inspectable.
|
|
86
|
+
6. Runtime rendering preserves all symbolic control fields.
|
|
87
|
+
7. Language selection never widens authorization or portability scope.
|
|
88
|
+
|
|
89
|
+
## Drift checklist
|
|
90
|
+
|
|
91
|
+
Compare package/version metadata, spec and registry versions, registry fields
|
|
92
|
+
against engine consumption, `spec_ref` headings, docs/skills against package
|
|
93
|
+
exports, reference-bundle provenance, host extensions against core ownership,
|
|
94
|
+
and generated/symlinked skill copies against tracked sources. Add a deterministic
|
|
95
|
+
check for every drift class that has occurred once.
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const FALLBACK_UNIVERSAL = ['type', 'title', 'description', 'timestamp'];
|
|
7
|
+
const FALLBACK_REQUIRED = {
|
|
8
|
+
memory: ['slug', 'category', 'status', 'schema_version'],
|
|
9
|
+
skill: ['name'],
|
|
10
|
+
rule: ['name'],
|
|
11
|
+
security_role: ['name', 'permissions'],
|
|
12
|
+
task: ['priority', 'category', 'status'],
|
|
13
|
+
assistant: ['name'],
|
|
14
|
+
workflow: ['name'],
|
|
15
|
+
model: ['model_id', 'provider'],
|
|
16
|
+
conversation: ['thread_id'],
|
|
17
|
+
run: ['run_id', 'workflow_id'],
|
|
18
|
+
conflict: ['conflict_id', 'status', 'new_slug', 'existing_slug', 'detected_at'],
|
|
19
|
+
page: ['slug', 'name', 'sandbox_entry'],
|
|
20
|
+
migration: ['migration_id', 'from_version', 'to_version', 'status'],
|
|
21
|
+
release: ['release_id', 'version', 'schema_version', 'summary', 'released_at'],
|
|
22
|
+
primitive: ['primitive_id', 'namespace', 'version', 'name', 'mutation', 'portability', 'scopes', 'fields'],
|
|
23
|
+
};
|
|
24
|
+
const CONTRACT_TYPES = new Set(['operation', 'patch', 'event', 'delete', 'lease']);
|
|
25
|
+
const APPEND_TYPES = new Set(['conversation', 'run']);
|
|
26
|
+
|
|
27
|
+
function findUp(start, predicate) {
|
|
28
|
+
let dir = path.resolve(start);
|
|
29
|
+
while (true) {
|
|
30
|
+
if (predicate(dir)) return dir;
|
|
31
|
+
const parent = path.dirname(dir);
|
|
32
|
+
if (parent === dir) return null;
|
|
33
|
+
dir = parent;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function findKernelRoot(start) {
|
|
38
|
+
return findUp(start, (dir) =>
|
|
39
|
+
fs.existsSync(path.join(dir, 'registry', 'core.json')) &&
|
|
40
|
+
fs.existsSync(path.join(dir, 'src', 'frontmatter.mjs'))
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseScalar(value) {
|
|
45
|
+
const text = value.trim();
|
|
46
|
+
if (!text) return '';
|
|
47
|
+
if ((text.startsWith('"') && text.endsWith('"')) ||
|
|
48
|
+
(text.startsWith("'") && text.endsWith("'"))) return text.slice(1, -1);
|
|
49
|
+
if (text === 'true') return true;
|
|
50
|
+
if (text === 'false') return false;
|
|
51
|
+
if (text === 'null' || text === '~') return null;
|
|
52
|
+
if (/^-?\d+(?:\.\d+)?$/.test(text)) return Number(text);
|
|
53
|
+
if (text.startsWith('[') && text.endsWith(']')) {
|
|
54
|
+
return text.slice(1, -1).split(',').map((item) => parseScalar(item)).filter((item) => item !== '');
|
|
55
|
+
}
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function parseFallback(raw) {
|
|
60
|
+
const lines = raw.replace(/\r\n/g, '\n').split('\n');
|
|
61
|
+
if (lines[0]?.trim() !== '---') throw new Error('Missing YAML frontmatter block.');
|
|
62
|
+
const close = lines.findIndex((line, index) => index > 0 && line.trim() === '---');
|
|
63
|
+
if (close < 0) throw new Error('Unclosed YAML frontmatter block.');
|
|
64
|
+
const data = {};
|
|
65
|
+
let collectionKey = null;
|
|
66
|
+
for (const line of lines.slice(1, close)) {
|
|
67
|
+
if (!line.trim() || line.trimStart().startsWith('#')) continue;
|
|
68
|
+
const listMatch = line.match(/^\s+-\s+(.+)$/);
|
|
69
|
+
if (listMatch && collectionKey) {
|
|
70
|
+
if (!Array.isArray(data[collectionKey])) data[collectionKey] = [];
|
|
71
|
+
data[collectionKey].push(parseScalar(listMatch[1]));
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (/^\s/.test(line)) continue;
|
|
75
|
+
const match = line.match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);
|
|
76
|
+
if (!match) continue;
|
|
77
|
+
collectionKey = match[1];
|
|
78
|
+
data[collectionKey] = parseScalar(match[2]);
|
|
79
|
+
}
|
|
80
|
+
return { data, body: lines.slice(close + 1).join('\n') };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function parseDocument(raw, kernelRoot) {
|
|
84
|
+
if (!kernelRoot) return parseFallback(raw);
|
|
85
|
+
try {
|
|
86
|
+
const module = await import(pathToFileURL(path.join(kernelRoot, 'src', 'frontmatter.mjs')).href);
|
|
87
|
+
return module.parseDocument(raw);
|
|
88
|
+
} catch {
|
|
89
|
+
return parseFallback(raw);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function loadRegistry(kernelRoot) {
|
|
94
|
+
if (!kernelRoot) return null;
|
|
95
|
+
try {
|
|
96
|
+
return JSON.parse(fs.readFileSync(path.join(kernelRoot, 'registry', 'core.json'), 'utf8'));
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isEmpty(value) {
|
|
103
|
+
return value === undefined || value === null || value === '' ||
|
|
104
|
+
(Array.isArray(value) && value.length === 0);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function requiredWhenFields(definition, data) {
|
|
108
|
+
const fields = [];
|
|
109
|
+
for (const [condition, required] of Object.entries(definition?.required_when || {})) {
|
|
110
|
+
const match = condition.match(/^([A-Za-z_][A-Za-z0-9_-]*)==(.+)$/);
|
|
111
|
+
if (match && String(data[match[1]]) === match[2]) fields.push(...required);
|
|
112
|
+
}
|
|
113
|
+
return fields;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function isSafeReferencePath(value) {
|
|
117
|
+
return typeof value === 'string' && value.length > 0 && value.endsWith('.md') &&
|
|
118
|
+
!path.isAbsolute(value) && !value.includes('\\') && !value.includes('\0') &&
|
|
119
|
+
value.split('/').every((segment) => segment && segment !== '.' && segment !== '..');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function validateNode(filePath) {
|
|
123
|
+
const target = path.resolve(filePath);
|
|
124
|
+
const kernelRoot = findKernelRoot(path.dirname(target)) || findKernelRoot(process.cwd());
|
|
125
|
+
const registry = loadRegistry(kernelRoot);
|
|
126
|
+
const raw = fs.readFileSync(target, 'utf8');
|
|
127
|
+
const { data, body } = await parseDocument(raw, kernelRoot);
|
|
128
|
+
const errors = [];
|
|
129
|
+
const warnings = [];
|
|
130
|
+
|
|
131
|
+
if (isEmpty(data.type)) {
|
|
132
|
+
errors.push("Missing required field 'type'.");
|
|
133
|
+
return { valid: false, errors, warnings, file: target, type: null, kernelRoot };
|
|
134
|
+
}
|
|
135
|
+
if (CONTRACT_TYPES.has(data.type)) {
|
|
136
|
+
errors.push(`Type '${data.type}' is a contract envelope, not a Markdown document primitive.`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const definition = registry?.document_primitives?.[data.type] || null;
|
|
140
|
+
if (registry && !definition) errors.push(`Unknown document primitive '${data.type}'.`);
|
|
141
|
+
if (!registry && !FALLBACK_REQUIRED[data.type]) {
|
|
142
|
+
warnings.push(`No live core registry found and no fallback schema exists for '${data.type}'.`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const required = new Set([
|
|
146
|
+
...(registry?.universal_frontmatter?.required || FALLBACK_UNIVERSAL),
|
|
147
|
+
...(definition?.required_fields || FALLBACK_REQUIRED[data.type] || []),
|
|
148
|
+
...requiredWhenFields(definition, data),
|
|
149
|
+
]);
|
|
150
|
+
for (const field of required) {
|
|
151
|
+
if (isEmpty(data[field])) errors.push(`Missing required field '${field}'.`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for (const [field, allowed] of Object.entries(definition?.enums || {})) {
|
|
155
|
+
const values = Array.isArray(data[field]) ? data[field] : [data[field]];
|
|
156
|
+
if (!isEmpty(data[field]) && values.some((value) => !allowed.includes(value))) {
|
|
157
|
+
errors.push(`Field '${field}' must contain only: ${allowed.join(', ')}.`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
for (const [field, source] of Object.entries(definition?.patterns || {})) {
|
|
162
|
+
if (isEmpty(data[field])) continue;
|
|
163
|
+
try {
|
|
164
|
+
if (!(new RegExp(source, 'u')).test(String(data[field]))) {
|
|
165
|
+
errors.push(`Field '${field}' does not match required pattern ${source}.`);
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
errors.push(`Registry pattern for '${field}' is invalid.`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (APPEND_TYPES.has(data.type) && body.trim() === '') {
|
|
173
|
+
warnings.push(`Append-only primitive '${data.type}' has an empty body.`);
|
|
174
|
+
}
|
|
175
|
+
if (data.type === 'memory' && target.split(path.sep).includes('memory-vault')) {
|
|
176
|
+
const parent = path.basename(path.dirname(target));
|
|
177
|
+
if (data.category && data.category !== parent) {
|
|
178
|
+
errors.push(`Memory category '${data.category}' does not match parent directory '${parent}'.`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
valid: errors.length === 0,
|
|
184
|
+
errors,
|
|
185
|
+
warnings,
|
|
186
|
+
file: target,
|
|
187
|
+
type: data.type,
|
|
188
|
+
kernelRoot,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function realpath(value) {
|
|
193
|
+
try { return fs.realpathSync(value); } catch { return value; }
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const invoked = process.argv[1] ? realpath(path.resolve(process.argv[1])) : null;
|
|
197
|
+
if (invoked === realpath(fileURLToPath(import.meta.url))) {
|
|
198
|
+
const target = process.argv[2];
|
|
199
|
+
if (!target) {
|
|
200
|
+
console.error('Usage: node validate-schema.mjs <path-to-ssss-document.md>');
|
|
201
|
+
process.exit(2);
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const result = await validateNode(target);
|
|
205
|
+
for (const warning of result.warnings) console.warn(`WARN: ${warning}`);
|
|
206
|
+
if (!result.valid) {
|
|
207
|
+
for (const error of result.errors) console.error(`ERROR: ${error}`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
console.log(`OK: ${path.basename(result.file)} is a valid '${result.type}' document.`);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error(`ERROR: ${error.message}`);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Role: SSSS Contract Auditor
|
|
2
|
+
|
|
3
|
+
Audit one bounded SSSS surface without editing it.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
- Repository root
|
|
8
|
+
- Surface: primitive, envelope, runtime, bundle, projection, or host adapter
|
|
9
|
+
- Files or symbols in scope
|
|
10
|
+
|
|
11
|
+
## Procedure
|
|
12
|
+
|
|
13
|
+
1. Read the relevant registry entry and exact spec section.
|
|
14
|
+
2. Trace the implementation and every related conformance fixture.
|
|
15
|
+
3. Compare required fields, enums, append behavior, authorization, path safety,
|
|
16
|
+
idempotency, portability, and package identity where relevant.
|
|
17
|
+
4. Report only evidence-backed mismatches with file paths and a proposed test.
|
|
18
|
+
|
|
19
|
+
## Output
|
|
20
|
+
|
|
21
|
+
Return a compact table with `severity`, `contract`, `implementation`, `evidence`,
|
|
22
|
+
and `recommended regression`. Do not modify files.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: total-recall
|
|
3
3
|
provenance: total-recall
|
|
4
4
|
description: "Use this skill to operate Total Recall — portable memory, instructions, openwiki, skill deploy, and secrets. MANDATORY: Read this file before changing TR setup. Nested packages under modules/ are NOT agent skills."
|
|
5
|
+
version: 3.14.3
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Total Recall — Master Agent Skill
|
package/src/cli/backup.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* total-recall backup
|
|
3
3
|
*
|
|
4
4
|
* Back up the meta-skill folder (the user's brain) to:
|
|
5
|
-
* - GitHub repo (diff-based,
|
|
5
|
+
* - GitHub repo (diff-based, persistent)
|
|
6
6
|
* - Encrypted/plain tarball
|
|
7
7
|
* - Obsidian vault (rsync)
|
|
8
8
|
*
|
|
@@ -92,7 +92,7 @@ function printHelp() {
|
|
|
92
92
|
Options:
|
|
93
93
|
--output, -o <path> Destination archive path (tarball mode)
|
|
94
94
|
--no-encrypt Write a plain .tar.gz archive (default: gpg-encrypted)
|
|
95
|
-
--push-git <remote> Commit brain to a git remote (
|
|
95
|
+
--push-git <remote> Commit brain to a git remote (persistent, diff-based)
|
|
96
96
|
e.g. git@github.com:you/total-recall-brain.git
|
|
97
97
|
Initialises the skill folder as a git repo on first run.
|
|
98
98
|
--obsidian <path> Rsync brain snapshot into an Obsidian vault folder.
|
|
@@ -431,7 +431,7 @@ export default async function backup(args) {
|
|
|
431
431
|
return;
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
// Git-push mode:
|
|
434
|
+
// Git-push mode: persistent diff-based backup
|
|
435
435
|
if (opts.pushGit) {
|
|
436
436
|
await pushGitBackup(opts.pushGit, opts.layer);
|
|
437
437
|
return;
|
package/src/cli/chat.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { callLocalRuntime, loadRuntimeConfig, checkRuntimeHealth } from '../core
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Total Recall CLI Chat Interface
|
|
8
|
-
* Allows direct conversation with the
|
|
8
|
+
* Allows direct conversation with the Total Recall System kernel from the terminal.
|
|
9
9
|
*/
|
|
10
10
|
export default async function runChat(args) {
|
|
11
11
|
console.log('🤖 Total Recall CLI Chat initialized. Type "exit" to quit.\n');
|
|
@@ -34,7 +34,7 @@ export default async function runChat(args) {
|
|
|
34
34
|
prompt: 'You: '
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
const systemMessage = 'You are the Total Recall
|
|
37
|
+
const systemMessage = 'You are the Total Recall Total Recall System kernel. Keep responses concise and direct.';
|
|
38
38
|
const messages = [];
|
|
39
39
|
|
|
40
40
|
rl.prompt();
|