total-recall-brain 3.10.0 → 3.11.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.
- package/bin/antigravity.mjs +62 -183
- package/package.json +2 -2
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/SKILL.md +75 -17
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/references/CHANGELOG.md +122 -7
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/references/ssss-spec.md +474 -43
- package/src/cli/ingest-openwiki.mjs +122 -0
- package/src/cli/ingest.mjs +9 -0
- package/src/core/operation-validator.mjs +66 -8
- package/src/core/schema.mjs +62 -12
package/bin/antigravity.mjs
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// Antigravity CLI Agent Wrapper — routes through the running Antigravity IDE
|
|
3
|
+
// via agentapi, using the user's logged-in Google account.
|
|
2
4
|
|
|
3
5
|
import fs from 'node:fs';
|
|
4
6
|
import path from 'node:path';
|
|
5
7
|
import os from 'node:os';
|
|
8
|
+
import { spawnSync } from 'node:child_process';
|
|
6
9
|
|
|
7
10
|
const args = process.argv.slice(2);
|
|
8
11
|
let prompt = '';
|
|
9
12
|
let outputJson = false;
|
|
10
|
-
let requestedModel = process.env.TR_CLI_MODEL || '
|
|
13
|
+
let requestedModel = process.env.TR_CLI_MODEL || 'flash';
|
|
11
14
|
|
|
12
15
|
if (args.includes('-h') || args.includes('--help')) {
|
|
13
16
|
console.log(`
|
|
14
|
-
Antigravity CLI Agent Wrapper — Headless
|
|
17
|
+
Antigravity CLI Agent Wrapper — Headless via agentapi (logged-in account)
|
|
15
18
|
|
|
16
19
|
Usage:
|
|
17
20
|
antigravity [options] [prompt]
|
|
@@ -19,39 +22,30 @@ Usage:
|
|
|
19
22
|
|
|
20
23
|
Options:
|
|
21
24
|
-p, --prompt The text prompt to generate content for
|
|
22
|
-
-m, --model
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- pro / gemini-pro / 3.1-pro -> dynamically resolves best Pro model
|
|
26
|
-
-o, --json Output dynamic JSON response payload (choices: stream/json/default)
|
|
27
|
-
--json Output dynamic JSON response payload
|
|
25
|
+
-m, --model Model: flash_lite, flash, pro (default: flash)
|
|
26
|
+
-o json Output JSON response payload
|
|
27
|
+
--json Output JSON response payload
|
|
28
28
|
-h, --help Show this help information
|
|
29
|
-
|
|
30
|
-
Examples:
|
|
31
|
-
antigravity "Say hello"
|
|
32
|
-
antigravity -p "Write an essay about AI" -m pro
|
|
33
|
-
antigravity -p "Get system stats" --json
|
|
34
29
|
`);
|
|
35
30
|
process.exit(0);
|
|
36
31
|
}
|
|
37
32
|
|
|
33
|
+
// Ignored flags for compatibility with tr-cli-agents dispatch
|
|
34
|
+
const IGNORED = new Set(['--sandbox=false', '--yolo']);
|
|
35
|
+
|
|
38
36
|
for (let i = 0; i < args.length; i++) {
|
|
39
|
-
if (args[i]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
i++;
|
|
45
|
-
} else if (args[i] === '--json') {
|
|
46
|
-
outputJson = true;
|
|
47
|
-
} else if (args[i] === '-m' || args[i] === '--model') {
|
|
48
|
-
requestedModel = args[i + 1] || requestedModel;
|
|
49
|
-
i++;
|
|
50
|
-
}
|
|
37
|
+
if (IGNORED.has(args[i])) continue;
|
|
38
|
+
if (args[i] === '-p' || args[i] === '--prompt') { prompt = args[i + 1] || ''; i++; }
|
|
39
|
+
else if (args[i] === '-o' && args[i + 1] === 'json') { outputJson = true; i++; }
|
|
40
|
+
else if (args[i] === '--json') { outputJson = true; }
|
|
41
|
+
else if (args[i] === '-m' || args[i] === '--model') { requestedModel = args[i + 1] || requestedModel; i++; }
|
|
51
42
|
}
|
|
52
43
|
|
|
53
44
|
if (!prompt && args.length > 0) {
|
|
54
|
-
|
|
45
|
+
// Last non-flag arg is the prompt
|
|
46
|
+
for (let i = args.length - 1; i >= 0; i--) {
|
|
47
|
+
if (!args[i].startsWith('-') && !IGNORED.has(args[i])) { prompt = args[i]; break; }
|
|
48
|
+
}
|
|
55
49
|
}
|
|
56
50
|
|
|
57
51
|
if (!prompt) {
|
|
@@ -59,165 +53,50 @@ if (!prompt) {
|
|
|
59
53
|
process.exit(1);
|
|
60
54
|
}
|
|
61
55
|
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
56
|
+
// Map model aliases
|
|
57
|
+
const modelMap = {
|
|
58
|
+
default: 'flash', gemini: 'flash', 'gemini-flash': 'flash',
|
|
59
|
+
'gemini-3.5-flash': 'flash', '3.5-flash': 'flash',
|
|
60
|
+
pro: 'pro', 'gemini-pro': 'pro', '3.1-pro': 'pro',
|
|
61
|
+
lite: 'flash_lite', 'flash-lite': 'flash_lite',
|
|
62
|
+
};
|
|
63
|
+
const model = modelMap[requestedModel] || requestedModel;
|
|
64
|
+
|
|
65
|
+
// Spawn agentapi new-conversation and capture the response
|
|
66
|
+
const result = spawnSync('agentapi', [
|
|
67
|
+
'new-conversation',
|
|
68
|
+
`--model=${model}`,
|
|
69
|
+
'--title=antigravity-cli',
|
|
70
|
+
prompt,
|
|
71
|
+
], {
|
|
72
|
+
encoding: 'utf8',
|
|
73
|
+
timeout: 300_000,
|
|
74
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
75
|
+
env: process.env,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (result.status !== 0) {
|
|
79
|
+
const err = result.stderr || result.stdout || 'agentapi failed';
|
|
80
|
+
console.error('Error:', err);
|
|
81
|
+
process.exit(1);
|
|
84
82
|
}
|
|
85
83
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
const raw = result.stdout?.trim() || '';
|
|
85
|
+
|
|
86
|
+
// Parse agentapi response
|
|
87
|
+
let text = raw;
|
|
88
|
+
try {
|
|
89
|
+
const parsed = JSON.parse(raw);
|
|
90
|
+
// agentapi returns { response: { conversationId, content } }
|
|
91
|
+
if (parsed.response?.content) text = parsed.response.content;
|
|
92
|
+
else if (parsed.content) text = parsed.content;
|
|
93
|
+
else if (parsed.response) text = typeof parsed.response === 'string' ? parsed.response : JSON.stringify(parsed.response);
|
|
94
|
+
} catch {
|
|
95
|
+
// Not JSON, use raw output
|
|
89
96
|
}
|
|
90
97
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
default: 'flash',
|
|
96
|
-
flash: 'flash',
|
|
97
|
-
'gemini-flash': 'flash',
|
|
98
|
-
'3.5-flash': 'flash',
|
|
99
|
-
pro: 'pro',
|
|
100
|
-
'gemini-pro': 'pro',
|
|
101
|
-
'3.1-pro': 'pro'
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const category = aliases[selectedModel];
|
|
105
|
-
if (!category) {
|
|
106
|
-
// If it's a full model string, use it directly
|
|
107
|
-
return selectedModel;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
const keyParam = apiKey ? `key=${apiKey}` : '';
|
|
112
|
-
const headers = {};
|
|
113
|
-
if (!apiKey && process.env.GCLOUD_TOKEN) {
|
|
114
|
-
headers['Authorization'] = `Bearer ${process.env.GCLOUD_TOKEN}`;
|
|
115
|
-
}
|
|
116
|
-
const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?${keyParam}`, {
|
|
117
|
-
headers,
|
|
118
|
-
signal: AbortSignal.timeout(5000)
|
|
119
|
-
});
|
|
120
|
-
if (res.ok) {
|
|
121
|
-
const data = await res.json();
|
|
122
|
-
const models = data.models || [];
|
|
123
|
-
|
|
124
|
-
if (category === 'pro') {
|
|
125
|
-
const proPreferences = [
|
|
126
|
-
'gemini-3.1-pro-preview',
|
|
127
|
-
'gemini-2.5-pro',
|
|
128
|
-
'gemini-1.5-pro',
|
|
129
|
-
'gemini-pro-latest'
|
|
130
|
-
];
|
|
131
|
-
for (const p of proPreferences) {
|
|
132
|
-
if (models.some(m => m.name === `models/${p}`)) {
|
|
133
|
-
return p;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
} else {
|
|
137
|
-
const flashPreferences = [
|
|
138
|
-
'gemini-3.5-flash',
|
|
139
|
-
'gemini-3.1-flash-lite',
|
|
140
|
-
'gemini-2.5-flash',
|
|
141
|
-
'gemini-2.0-flash-lite',
|
|
142
|
-
'gemini-flash-latest'
|
|
143
|
-
];
|
|
144
|
-
for (const p of flashPreferences) {
|
|
145
|
-
if (models.some(m => m.name === `models/${p}`)) {
|
|
146
|
-
return p;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
} catch {
|
|
152
|
-
// Silent failover to hardcoded default targets
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Ultimate fallback
|
|
156
|
-
return category === 'pro' ? 'gemini-3.1-pro-preview' : 'gemini-3.5-flash';
|
|
98
|
+
if (outputJson) {
|
|
99
|
+
console.log(JSON.stringify({ response: text }));
|
|
100
|
+
} else {
|
|
101
|
+
console.log(text);
|
|
157
102
|
}
|
|
158
|
-
|
|
159
|
-
async function main() {
|
|
160
|
-
try {
|
|
161
|
-
const resolvedModel = await resolveGenerativeModel(requestedModel);
|
|
162
|
-
const keyParam = apiKey ? `?key=${apiKey}` : '';
|
|
163
|
-
const url = `https://generativelanguage.googleapis.com/v1beta/models/${resolvedModel}:generateContent${keyParam}`;
|
|
164
|
-
|
|
165
|
-
const headers = {
|
|
166
|
-
'Content-Type': 'application/json',
|
|
167
|
-
};
|
|
168
|
-
if (!apiKey && process.env.GCLOUD_TOKEN) {
|
|
169
|
-
headers['Authorization'] = `Bearer ${process.env.GCLOUD_TOKEN}`;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const res = await fetch(url, {
|
|
173
|
-
method: 'POST',
|
|
174
|
-
headers,
|
|
175
|
-
body: JSON.stringify({
|
|
176
|
-
contents: [{
|
|
177
|
-
parts: [{ text: prompt }]
|
|
178
|
-
}]
|
|
179
|
-
})
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
if (!res.ok) {
|
|
183
|
-
const errText = await res.text();
|
|
184
|
-
throw new Error(`Gemini API returned status ${res.status}: ${errText}`);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const data = await res.json();
|
|
188
|
-
const text = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
189
|
-
|
|
190
|
-
// Save usage data for token monitoring/budget safety
|
|
191
|
-
try {
|
|
192
|
-
const promptTokens = data.usageMetadata?.promptTokenCount || 0;
|
|
193
|
-
const candidatesTokens = data.usageMetadata?.candidatesTokenCount || 0;
|
|
194
|
-
if (promptTokens > 0 || candidatesTokens > 0) {
|
|
195
|
-
const tmpDir = path.join(os.homedir(), '.gemini', 'tmp', 'antigravity', 'chats');
|
|
196
|
-
if (!fs.existsSync(tmpDir)) {
|
|
197
|
-
fs.mkdirSync(tmpDir, { recursive: true });
|
|
198
|
-
}
|
|
199
|
-
const usageLine = JSON.stringify({
|
|
200
|
-
timestamp: new Date().toISOString(),
|
|
201
|
-
tokens: {
|
|
202
|
-
input: promptTokens,
|
|
203
|
-
output: candidatesTokens
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
fs.appendFileSync(path.join(tmpDir, 'usage.jsonl'), usageLine + '\n', 'utf8');
|
|
207
|
-
}
|
|
208
|
-
} catch {
|
|
209
|
-
// Silent ignore
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (outputJson) {
|
|
213
|
-
console.log(JSON.stringify({ response: text }));
|
|
214
|
-
} else {
|
|
215
|
-
console.log(text);
|
|
216
|
-
}
|
|
217
|
-
} catch (err) {
|
|
218
|
-
console.error('Error calling Gemini API:', err.message);
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "total-recall-brain",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.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": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"homepage": "https://github.com/gregiteen/total-recall#readme",
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@ssss/cli": "github:gregiteen/ssss#v0.
|
|
59
|
+
"@ssss/cli": "github:gregiteen/ssss#v0.7.0",
|
|
60
60
|
"bcrypt": "^6.0.0",
|
|
61
61
|
"cookie-parser": "^1.4.7",
|
|
62
62
|
"cors": "^2.8.6",
|
|
@@ -14,15 +14,17 @@ schema/reference files.
|
|
|
14
14
|
## Ground Truth
|
|
15
15
|
|
|
16
16
|
The vendor-neutral contract is now a published package, **`@ssss/cli`** (pinned to
|
|
17
|
-
**`v0.
|
|
17
|
+
**`v0.7.0`**, spec v0.6 draft; source <https://github.com/gregiteen/ssss>), declared in
|
|
18
18
|
`package.json`. `references/ssss-spec.md` is the local mirror. The canon owns the
|
|
19
|
-
spec (§5.5 portability, §6 Operation
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
spec (§4.2 universal OKF-compatible frontmatter, §5.5 portability, §6 Operation
|
|
20
|
+
Contract incl. `event` and `delete`, §11.8 workflow runtime daemon contract, §16
|
|
21
|
+
the `.ucw` bundle format, §17 provisioning), the core
|
|
22
|
+
registry (`@ssss/cli/registry/core.json`: 14 document + 5 contract primitives),
|
|
23
|
+
the reference engine, runtime helpers, and the v1.4.0 conformance fixtures. Total
|
|
24
|
+
Recall's kernel was the engine the canon's reference implementation was harvested
|
|
25
|
+
from; keep them aligned. If this skill conflicts with the canon, correct this
|
|
26
|
+
skill unless the implementation has intentionally advanced beyond it and the
|
|
27
|
+
difference is documented here.
|
|
26
28
|
|
|
27
29
|
Current local implementation entry points:
|
|
28
30
|
|
|
@@ -41,7 +43,8 @@ Current local implementation entry points:
|
|
|
41
43
|
It operates on a **vault directory** of Markdown files and `.ucw` bundles, using
|
|
42
44
|
the canon's own reference engine — separate from this kernel's `processOperation`.
|
|
43
45
|
Use it for bundle/tenant tooling and conformance; for in-kernel memory writes keep
|
|
44
|
-
using `writeNodeValidated()` / `processOperation()`.
|
|
46
|
+
using `writeNodeValidated()` / `processOperation()`. Use `@ssss/cli/runtime` when
|
|
47
|
+
building daemon, cron, webhook, event, file-change, or agent-host wake-up loops.
|
|
45
48
|
|
|
46
49
|
```bash
|
|
47
50
|
npx ssss help # list doc topics; e.g. `ssss help portability|bundle|provisioning`
|
|
@@ -68,7 +71,7 @@ All agent-generated mutations must flow through the SSSS operation pipeline:
|
|
|
68
71
|
```text
|
|
69
72
|
processOperation(envelope, vaultRoot, options)
|
|
70
73
|
-> envelope validation
|
|
71
|
-
-> idempotency check
|
|
74
|
+
-> idempotency replay/conflict check
|
|
72
75
|
-> authorization
|
|
73
76
|
-> lease validation
|
|
74
77
|
-> deterministic schema validation
|
|
@@ -93,6 +96,52 @@ Total Recall implements all four canonical envelope types in
|
|
|
93
96
|
Use `dry_run: true` for preflight validation when constructing writes from model
|
|
94
97
|
output.
|
|
95
98
|
|
|
99
|
+
## Universal Frontmatter / OKF
|
|
100
|
+
|
|
101
|
+
SSSS v0.7.0 / spec v0.6 is an OKF-compatible Markdown contract. Every SSSS
|
|
102
|
+
document primitive, including skills, memory, workflows, assistants, pages,
|
|
103
|
+
models, migrations, and releases, MUST carry non-empty universal frontmatter:
|
|
104
|
+
|
|
105
|
+
- `type`
|
|
106
|
+
- `title`
|
|
107
|
+
- `description`
|
|
108
|
+
- `timestamp`
|
|
109
|
+
|
|
110
|
+
Recommended OKF-compatible fields are:
|
|
111
|
+
|
|
112
|
+
- `resource`
|
|
113
|
+
- `tags`
|
|
114
|
+
- `aliases`
|
|
115
|
+
|
|
116
|
+
Primitive-specific required fields still apply on top of the universal fields.
|
|
117
|
+
For example, a `workflow` still needs its workflow identity fields, and
|
|
118
|
+
`schema_version: 2` memory nodes still need the knowledge-graph fields below.
|
|
119
|
+
Do not "fix" OKF compatibility by weakening primitive validation; add the
|
|
120
|
+
universal metadata and keep the primitive registry strict.
|
|
121
|
+
|
|
122
|
+
## Security Contract
|
|
123
|
+
|
|
124
|
+
The reference engine now treats path and replay safety as part of the standard:
|
|
125
|
+
|
|
126
|
+
- `workspace_id`, `idempotency_key`, and `actor.role` must be safe identifiers:
|
|
127
|
+
ASCII alphanumeric start, then ASCII letters, digits, `.`, `_`, or `-`, max
|
|
128
|
+
128 characters.
|
|
129
|
+
- Operation paths must be relative vault paths. Reject empty/root paths, `.`,
|
|
130
|
+
`..`, absolute paths, backslashes, null bytes, empty segments, and directory
|
|
131
|
+
targets.
|
|
132
|
+
- `type` is immutable after creation. An operation or patch must not rewrite an
|
|
133
|
+
existing file from one primitive type to another.
|
|
134
|
+
- Append-only primitives may only preserve existing content exactly or append
|
|
135
|
+
after the existing body plus a newline. Prefix tricks are not enough.
|
|
136
|
+
- Idempotency is scoped by `workspace_id + idempotency_key + request_hash`.
|
|
137
|
+
Replaying the same effective request returns the original result; reusing the
|
|
138
|
+
same key/workspace with a different effective request is an idempotency
|
|
139
|
+
conflict and must fail.
|
|
140
|
+
- Leases fail closed. Corrupt or unreadable lease state does not authorize a
|
|
141
|
+
write, and lease storage must not expose the VFS path directly.
|
|
142
|
+
- Bundle import/export must reject unsafe or duplicate file paths, and exporters
|
|
143
|
+
must not follow symlinked vault entries into files outside the vault.
|
|
144
|
+
|
|
96
145
|
## Canonical State
|
|
97
146
|
|
|
98
147
|
The vault is source-of-truth. Derived files, embeddings, search indexes,
|
|
@@ -158,9 +207,6 @@ SSSS schema v2. Required schema v2 knowledge-graph fields are:
|
|
|
158
207
|
|
|
159
208
|
Invariants additionally use `priority: absolute` and `immutable: true`.
|
|
160
209
|
|
|
161
|
-
### OKF Compatibility Note
|
|
162
|
-
SSSS v0.2 is a strict superset of the Open Knowledge Format (OKF v0.1 Draft). SSSS memory nodes are fully OKF-compatible, as they are Markdown files containing a YAML frontmatter block with a `type` field (which maps to SSSS `category` via the OKF adapter). To bridge the format seamlessly, SSSS v0.2 extends `MemoryNodeSchema` with two optional OKF-standard fields: `description` and `resource` (supporting non-HTTP URIs such as `gs://` or `s3://`).
|
|
163
|
-
|
|
164
210
|
Memory validation is owned by `TotalRecallMemoryValidator`, not by generic loose
|
|
165
211
|
frontmatter checks. No memory path may be committed with zero validation.
|
|
166
212
|
|
|
@@ -174,6 +220,13 @@ frontmatter checks. No memory path may be committed with zero validation.
|
|
|
174
220
|
body records but must not rewrite prior records.
|
|
175
221
|
- Events are immutable. Do not update or delete event records.
|
|
176
222
|
- Leases must be time-bound, actor-owned, operation-linked, and recoverable.
|
|
223
|
+
- Workflow daemons, crons, webhook workers, and agent hosts must treat workflow
|
|
224
|
+
frontmatter triggers as canonical and use deterministic runtime planning
|
|
225
|
+
(`@ssss/cli/runtime`) to derive event/task/run envelopes.
|
|
226
|
+
- Bundle exporters/importers must use the canon's path, content hash,
|
|
227
|
+
portability, and provisioning validation. `template` and `sale` profiles must
|
|
228
|
+
drop every `tenant_private` primitive and reduce `resource_bound` values to
|
|
229
|
+
requirement declarations.
|
|
177
230
|
|
|
178
231
|
## Projections And Indexes
|
|
179
232
|
|
|
@@ -208,9 +261,9 @@ npx vitest run \
|
|
|
208
261
|
The **conformance bridge** (`src/core/ssss-conformance.bridge.spec.mjs`) runs the
|
|
209
262
|
canonical fixtures from `@ssss/cli` through this kernel's `processOperation` and
|
|
210
263
|
asserts every canonical core primitive is present in `SSSS_SCHEMAS`. It proves the
|
|
211
|
-
kernel implements the *same* standard as the
|
|
212
|
-
change the operation contract or the registry, keep this green; to adopt a
|
|
213
|
-
standard, bump the `@ssss/cli` pin and re-run it.
|
|
264
|
+
kernel implements the *same* standard as the SSSS reference engine and host apps.
|
|
265
|
+
If you change the operation contract or the registry, keep this green; to adopt a
|
|
266
|
+
newer standard, bump the `@ssss/cli` pin and re-run it.
|
|
214
267
|
|
|
215
268
|
## Do Not
|
|
216
269
|
|
|
@@ -223,13 +276,18 @@ standard, bump the `@ssss/cli` pin and re-run it.
|
|
|
223
276
|
- Do not delete append-type documents (`conversation`, `run`); they are immutable.
|
|
224
277
|
- Do not add host-specific required fields to the vendor-neutral spec unless they
|
|
225
278
|
are being standardized.
|
|
279
|
+
- Do not claim OKF compliance unless `type`, `title`, `description`, and
|
|
280
|
+
`timestamp` are present and non-empty.
|
|
281
|
+
- Do not replay idempotency keys without comparing `request_hash`.
|
|
282
|
+
- Do not export symlinked vault entries or accept unsafe bundle paths.
|
|
226
283
|
|
|
227
284
|
## References
|
|
228
285
|
|
|
229
286
|
| For | Read |
|
|
230
287
|
| --- | --- |
|
|
231
|
-
| Upstream canon (package) | `@ssss/cli` (`v0.
|
|
288
|
+
| Upstream canon (package) | `@ssss/cli` (`v0.7.0`, spec v0.6 draft, github:gregiteen/ssss) |
|
|
232
289
|
| Canonical core registry | `@ssss/cli/registry/core.json` |
|
|
290
|
+
| Runtime helpers | `@ssss/cli/runtime` |
|
|
233
291
|
| Conformance bridge | `src/core/ssss-conformance.bridge.spec.mjs` |
|
|
234
292
|
| SSSS standard (local mirror) | `references/ssss-spec.md` |
|
|
235
293
|
| Implemented schemas | `src/core/schema.mjs` |
|
|
@@ -1,9 +1,124 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- **Changed**: Stripped product-specific primitives (`meeting`, `event`, `crm`, etc.) from the core specification to enforce vendor-neutrality. Product primitives must now live strictly in host-level registries.
|
|
5
|
-
- **Added**: Upgraded Total Recall, UltraChat, and MUSE to v0.2.0 alignment.
|
|
3
|
+
All notable changes to the SSSS (Structured Semantic Syntax System) spec will be documented in this file.
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.7.0] - 2026-07-02
|
|
9
|
+
### Changed
|
|
10
|
+
- **BREAKING: universal frontmatter enforcement** — every SSSS document primitive
|
|
11
|
+
now requires `type`, `title`, `description`, and `timestamp`. Primitive-specific
|
|
12
|
+
required fields still apply after these universal fields.
|
|
13
|
+
- Registry `spec_version` -> `0.6`; spec header -> v0.6 draft. Reference bundle
|
|
14
|
+
metadata now targets SSSS core `0.6`.
|
|
15
|
+
- The reference engine, bundle validator, skill validator, runtime helpers,
|
|
16
|
+
scaffold output, conformance fixtures, shipped skills, and reference bundle now
|
|
17
|
+
share the universal metadata requirement.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- OKF compatibility guidance documenting `resource`, `tags`, and `aliases` as
|
|
21
|
+
recommended discovery enrichment fields while keeping the mandatory universal
|
|
22
|
+
metadata minimal and deterministic.
|
|
23
|
+
- Security hardening for the reference engine and CLI:
|
|
24
|
+
- VFS paths now reject absolute, root, dot-segment, empty-segment, backslash,
|
|
25
|
+
and directory targets.
|
|
26
|
+
- `workspace_id`, `idempotency_key`, and role names are constrained to safe
|
|
27
|
+
filesystem identifiers.
|
|
28
|
+
- Idempotency replay is bound to a request hash; same-key/different-payload
|
|
29
|
+
requests now fail as conflicts.
|
|
30
|
+
- Leases fail closed when unreadable and no longer derive filenames directly
|
|
31
|
+
from raw VFS paths.
|
|
32
|
+
- Bundle validation rejects unsafe and duplicate file paths, and export refuses
|
|
33
|
+
symlinked vault entries.
|
|
34
|
+
- Autolink skips symlinked Markdown targets before `--write`.
|
|
35
|
+
- Repo-local skill utility scripts avoid shell-string execution and validate
|
|
36
|
+
write-target names.
|
|
37
|
+
|
|
38
|
+
## [0.6.0] - 2026-07-02
|
|
39
|
+
### Added
|
|
40
|
+
- **Workflow Runtime & Daemon Contract (spec §11.8)** — standardizes workflow
|
|
41
|
+
trigger evaluation across daemon, cron, webhook, file-change, event, condition,
|
|
42
|
+
and manual runtimes. Workflows own `triggers[]`; external schedulers are only
|
|
43
|
+
wake-up mechanisms.
|
|
44
|
+
- **`@ssss/cli/runtime` helpers** — deterministic `planWorkflowTrigger()` and
|
|
45
|
+
`createRunEnvelope()` helpers derive `workflow_triggered` events, task
|
|
46
|
+
documents, and run documents through the Operation Contract.
|
|
47
|
+
- **Runtime conformance metadata/checks** — `conformance/fixtures.json` v1.3.0
|
|
48
|
+
declares trigger/misfire/concurrency vocabularies and proves duplicate daemon
|
|
49
|
+
ticks replay idempotently.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Registry `spec_version` -> `0.5`; spec header -> v0.5 draft. Reference bundle
|
|
53
|
+
metadata now targets SSSS core `0.5`.
|
|
54
|
+
|
|
55
|
+
## [0.5.0] - 2026-06-25
|
|
56
|
+
### Added
|
|
57
|
+
- **`ssss new <dir>` scaffolder** — bootstrap a fresh SSSS-native repo in one command:
|
|
58
|
+
a starter `vault/` of core primitives (incl. a `tenant_private` task to demonstrate
|
|
59
|
+
the sale-drop), a dependency-free conformance test (`node --test`) that replays the
|
|
60
|
+
canonical fixtures through the engine and round-trips the vault as a `sale` bundle,
|
|
61
|
+
plus `package.json` (pinned to the matching `@ssss/cli` tag), `CLAUDE.md`, `README`,
|
|
62
|
+
and `.gitignore`. Flags: `--with-total-recall` (wire the Total Recall memory OS),
|
|
63
|
+
`--install` (npm install + Total Recall init + verify), `--ref`, `--name`, `--force`,
|
|
64
|
+
`--no-git`. All shelling-out uses `execFileSync` with fixed argv (no shell). Docs:
|
|
65
|
+
`ssss help scaffold`.
|
|
66
|
+
|
|
67
|
+
## [0.4.0] - 2026-06-24
|
|
68
|
+
### Added
|
|
69
|
+
- **The `.ucw` bundle format (spec §16, registry `bundle`)** — the canonical transportable
|
|
70
|
+
package of a vault: a manifest plus path-sorted files, content-hashed for integrity. The
|
|
71
|
+
manifest declares `ssss_core_version`, `required_extensions`, `export_profile`,
|
|
72
|
+
`primitive_inventory` (registry-driven, replacing ultrachat's closed `categories` enum),
|
|
73
|
+
`provisioning[]`, `parameters[]`, and `provenance{content_hash, exporter, signature?}`.
|
|
74
|
+
Harvested from ultrachat's `WorkspaceVfsPackageService` and generalized to be portability-
|
|
75
|
+
and registry-driven.
|
|
76
|
+
- **The provisioning contract (spec §17, registry `provisioning`)** — three deterministic,
|
|
77
|
+
idempotent verbs: `export` (pure, profile-filtered), `provision` (params + link-integrity
|
|
78
|
+
+ id-remap → replayable envelope plan), `import` (engine replay, idempotent via
|
|
79
|
+
idempotency_key). Adopts ultrachat's `WorkspaceProvisioningStep.mode`/`system` and
|
|
80
|
+
`WorkspaceGraphEdge.relation` as the canonical binding/dependency vocabularies, plus
|
|
81
|
+
`installMode` composition and structural-only `migration`+`patch` upgrades.
|
|
82
|
+
- **Reference engine for bundles (`src/bundle.mjs`)** — dependency-free `exportBundle`,
|
|
83
|
+
`validateBundle`, `provisionBundle`, `importBundle` over the registry bundle schema.
|
|
84
|
+
- **Reference bundle (`conformance/reference-bundle.ucw.json`, "Festival in a Box")** — a
|
|
85
|
+
real `sale`-profile bundle, built deterministically by `scripts/build-reference-bundle.mjs`.
|
|
86
|
+
Proves the §5.5 keystone: structural + resource_bound files ship, the `tenant_private`
|
|
87
|
+
ticket record is dropped. Round-tripped (validate → provision → import → re-import) by
|
|
88
|
+
`ssss conformance --engine`; 6/6 bundle/provisioning checks pass alongside the 9 fixtures.
|
|
89
|
+
- **`language_convention` documented (spec §11.7)** — the festech-shipped, `structural`
|
|
90
|
+
presentation-overlay primitive, formally placed in the semantic layer.
|
|
91
|
+
- **CLI command surface for the full lifecycle** — `ssss export`, `validate`, `inspect`,
|
|
92
|
+
`provision`, and `import` wire the bundle/provisioning verbs to the command line, plus
|
|
93
|
+
`ssss help [topic]` serving offline docs from `docs/help/` and `ssss version`. Each
|
|
94
|
+
command has its own `--help`. Shared parsing/formatting in `scripts/lib/cli.mjs`.
|
|
95
|
+
- **Open-source packaging** — `README.md`, `LICENSE` (ISC), `.gitignore`, and
|
|
96
|
+
`package.json` metadata (`engines`, `repository`, `files`) so `@ssss/cli` is
|
|
97
|
+
publishable and the runtime-read paths (`VERSION`, `docs/help`) ship in the tarball.
|
|
98
|
+
|
|
99
|
+
### Changed
|
|
100
|
+
- Registry `spec_version` → `0.4`; spec header + §14 → v0.4. Engine exports add `./bundle`.
|
|
101
|
+
|
|
102
|
+
## [0.3.0] - 2026-06-24
|
|
103
|
+
### Added
|
|
104
|
+
- **Portability classification (spec §5.5, registry `portability`)** — every document
|
|
105
|
+
primitive now declares a portability class: `structural` (the sellable business model),
|
|
106
|
+
`tenant_private` (the operator's private data, never sold), or `resource_bound` (needs a
|
|
107
|
+
real resource bound at provision). Export profiles `backup | template | sale` are filters
|
|
108
|
+
over these classes; `template`/`sale` exports MUST drop all `tenant_private` primitives.
|
|
109
|
+
Files MAY override their type default with `x_portability`. Lifted and generalized from
|
|
110
|
+
ultrachat's ad-hoc export filter in `WorkspaceVfsPackageService`.
|
|
111
|
+
- **`delete` envelope (spec §6.2)** — promoted from festech's `SsssOperationService` into
|
|
112
|
+
the canonical Operation Contract as the fourth envelope type. Removes a replace-type file,
|
|
113
|
+
rejects append-type targets, and emits a deletion event for audit. Idempotent.
|
|
114
|
+
- **Reference engine (`src/engine.mjs`, `src/registry.mjs`, `src/frontmatter.mjs`)** — the
|
|
115
|
+
canonical, dependency-free `@ssss/cli` Operation Contract engine. Harvested from total-recall
|
|
116
|
+
(§6.3 pipeline, idempotency replay from the audit log, `buildRepair`/§9 repair blocks) and
|
|
117
|
+
festech (`delete` envelope, `resolveContainedPath` path-traversal guard, registry-driven
|
|
118
|
+
content validation). Validates content against `registry/core.json` + `registry/extensions/*`
|
|
119
|
+
with no per-type code and no Zod/YAML dependency. Runs all 9 conformance fixtures in-process
|
|
120
|
+
via `ssss conformance --engine` (now wired into `npm test`).
|
|
121
|
+
|
|
122
|
+
### Changed
|
|
123
|
+
- Registry now defines **5 contract primitives** (added `delete`); `spec_version` → `0.3`.
|
|
124
|
+
- §5.1 Document Primitives table gains a **Portability** column.
|