total-recall-brain 3.13.0 → 3.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -108
- package/bin/antigravity.mjs +81 -52
- package/bin/total-recall.mjs +32 -57
- package/extension/background.js +1 -1
- package/extension/options/options.js +9 -3
- package/extension/sidepanel/sidepanel.js +0 -2
- package/frontend/index.html +4 -3
- package/frontend/package.json +1 -0
- package/frontend/src/App.tsx +109 -152
- package/frontend/src/api.ts +605 -23
- package/frontend/src/components/BrainSelector.tsx +211 -199
- package/frontend/src/components/DocumentEditorModal.tsx +57 -0
- package/frontend/src/components/DocumentTable.tsx +47 -0
- package/frontend/src/components/Graph3D.tsx +120 -71
- package/frontend/src/components/UsageChart.tsx +3 -3
- package/frontend/src/components/brand/BrandMark.tsx +95 -0
- package/frontend/src/index.css +286 -86
- package/frontend/src/pages/ApiKeysPage.tsx +1878 -215
- package/frontend/src/pages/ChatPage.tsx +103 -45
- package/frontend/src/pages/DesignDocsPage.tsx +5 -5
- package/frontend/src/pages/FilesPage.tsx +10 -6
- package/frontend/src/pages/GraphPage.tsx +5 -3
- package/frontend/src/pages/HelpPage.tsx +2 -2
- package/frontend/src/pages/InboxPage.tsx +82 -0
- package/frontend/src/pages/InstructionsPage.tsx +1 -1
- package/frontend/src/pages/IntegrationsPage.tsx +21 -10
- package/frontend/src/pages/LoginPage.tsx +95 -77
- package/frontend/src/pages/MemoryPage.tsx +31 -8
- package/frontend/src/pages/OnboardingPage.tsx +690 -0
- package/frontend/src/pages/OpenWikiPage.tsx +412 -323
- package/frontend/src/pages/SettingsPage.tsx +825 -922
- package/frontend/src/pages/SkillsPage.tsx +272 -147
- package/frontend/src/pages/UsagePage.tsx +23 -31
- package/frontend/src/pages/VaultPage.tsx +223 -0
- package/frontend/src/types.ts +13 -0
- package/package.json +4 -4
- package/scaffold/.agent/skills/total-recall/SKILL.md +43 -4
- package/scaffold/.agent/skills/total-recall/modules/README.md +10 -0
- package/scaffold/.agent/skills/total-recall/modules/agents/README.md +5 -0
- package/scaffold/.agent/skills/total-recall/{skills/tr-cli-agents → modules/agents}/agents.yml +8 -0
- package/scaffold/.agent/skills/total-recall/modules/skill-deploy/README.md +9 -0
- package/scaffold/.agent/skills/total-recall/openwiki/README.md +10 -0
- package/scaffold/.agent/skills/total-recall/openwiki/architecture.md +5 -0
- package/scaffold/.agent/skills/total-recall/openwiki/ide.md +10 -0
- package/scaffold/.agent/skills/total-recall/openwiki/memory.md +11 -0
- package/scaffold/.agent/skills/total-recall/openwiki/secrets.md +7 -0
- package/scaffold/.agent/skills/total-recall/openwiki/skills.md +7 -0
- package/src/cli/brain.mjs +63 -5
- package/src/cli/connect.mjs +11 -19
- package/src/cli/daemon.mjs +5 -4
- package/src/cli/deploy-ui.mjs +8 -3
- package/src/cli/deploy.mjs +84 -27
- package/src/cli/ingest/index.mjs +1 -1
- package/src/cli/init.mjs +63 -34
- package/src/cli/remember.mjs +3 -3
- package/src/cli/secret.mjs +812 -0
- package/src/cli/setup.mjs +34 -7
- package/src/cli/share.mjs +2 -2
- package/src/cli/skill.mjs +396 -35
- package/src/cli/sync.mjs +4 -4
- package/src/cli/task.mjs +287 -0
- package/src/core/clarity-rewriter.mjs +5 -5
- package/src/core/config.mjs +44 -2
- package/src/core/conflict-detector.mjs +5 -5
- package/src/core/crons.mjs +54 -0
- package/src/core/daemon-loop.mjs +87 -235
- package/src/core/dream.mjs +170 -10
- package/src/core/env-import.mjs +456 -0
- package/src/core/fact-seeker.mjs +14 -14
- package/src/core/import-rules.mjs +20 -7
- package/src/core/inference-engine.mjs +3 -3
- package/src/core/migrate.mjs +14 -8
- package/src/core/okf-adapter.mjs +2 -2
- package/src/core/operation-validator.mjs +39 -331
- package/src/core/optimizer.mjs +7 -0
- package/src/core/post-mortem.mjs +2 -2
- package/src/core/project-brain.mjs +349 -0
- package/src/core/provider-catalog.mjs +296 -0
- package/src/core/quick-capture.mjs +1 -1
- package/src/core/remote-vault-sync.mjs +194 -0
- package/src/core/research-queue.mjs +7 -11
- package/src/core/runtime.mjs +33 -9
- package/src/core/scheduler.mjs +59 -5
- package/src/core/schema.mjs +14 -0
- package/src/core/search.mjs +1 -1
- package/src/core/secrets-env-export.mjs +323 -0
- package/src/core/secrets-rotate.mjs +245 -0
- package/src/core/secrets-store.mjs +645 -0
- package/src/core/semantic-index.mjs +3 -3
- package/src/core/skills-registry.mjs +1062 -0
- package/src/core/source-adapters.mjs +4 -1
- package/src/core/ssss-host-extension.mjs +94 -0
- package/src/core/ssss-kernel-bridge.mjs +530 -0
- package/src/core/surface.mjs +14 -0
- package/src/core/task-envelope.mjs +298 -0
- package/src/core/task-executors.mjs +600 -0
- package/src/core/validated-write.mjs +124 -56
- package/src/core/vault.mjs +21 -34
- package/src/core/webauthn-store.mjs +272 -0
- package/src/server/api.mjs +26 -16
- package/src/server/auth.mjs +51 -0
- package/src/server/index.mjs +3 -3
- package/src/server/keys.mjs +30 -4
- package/src/server/rest.mjs +198 -25
- package/src/server/route-manifest.json +156 -0
- package/src/server/routes/_shared.mjs +40 -1
- package/src/server/routes/docs.mjs +260 -0
- package/src/server/routes/memory.mjs +145 -32
- package/src/server/routes/research.mjs +30 -0
- package/src/server/routes/secrets.mjs +470 -0
- package/src/server/routes/share.mjs +2 -2
- package/src/server/routes/skills.mjs +452 -54
- package/src/server/routes/sync.mjs +48 -0
- package/src/server/routes/webauthn.mjs +184 -0
- package/src/server/update-route-manifest.mjs +39 -0
- package/templates/onboarding-interview.md +32 -22
- package/templates/openwiki/README.md +10 -0
- package/templates/openwiki/architecture.md +5 -0
- package/templates/openwiki/ide.md +10 -0
- package/templates/openwiki/memory.md +11 -0
- package/templates/openwiki/secrets.md +7 -0
- package/templates/openwiki/skills.md +7 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/SKILL.md +0 -121
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/antigravity.txt +0 -20
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/claude.txt +0 -58
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/codex.txt +0 -81
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/references/gemini.txt +0 -44
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/scripts/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-cli-agents/subagents/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-research/SKILL.md +0 -338
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/SKILL.md +0 -282
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/assets/skill-template/SKILL.md +0 -20
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/evals/evals.json +0 -20
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/hooks/on-skill-add.sh +0 -14
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/hooks/on-skill-delete.sh +0 -14
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/learnings/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/references/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/.gitkeep +0 -0
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/create-skill.sh +0 -65
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/enforce-skill-optimization.mjs +0 -135
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/scripts/skill-watcher.mjs +0 -64
- package/scaffold/.agent/skills/total-recall/skills/tr-skill/subagents/audit-all-skills.md +0 -62
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/SKILL.md +0 -298
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/evals/evals.json +0 -17
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/references/CHANGELOG.md +0 -124
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/references/ssss-spec.md +0 -1325
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/scripts/validate-schema.mjs +0 -232
- package/scaffold/.agent/skills/total-recall/skills/tr-ssss/subagents/audit-ssss-node.md +0 -9
- /package/scaffold/.agent/skills/total-recall/{skills/tr-cli-agents/evals → modules/skill-deploy/scripts}/.gitkeep +0 -0
- /package/scaffold/.agent/skills/total-recall/{skills/tr-skill → modules/skill-deploy}/scripts/find-skills.mjs +0 -0
- /package/scaffold/.agent/skills/total-recall/{skills/tr-skill → modules/skill-deploy}/scripts/install-skill.mjs +0 -0
- /package/scaffold/.agent/skills/total-recall/{skills/tr-skill → modules/skill-deploy}/scripts/scan-skill.mjs +0 -0
|
@@ -1,1325 +0,0 @@
|
|
|
1
|
-
# SSSS — Structured Semantic Syntax System
|
|
2
|
-
|
|
3
|
-
**Specification v0.6 — Draft**
|
|
4
|
-
|
|
5
|
-
> This is the canonical, vendor-neutral specification for SSSS. It is the ground
|
|
6
|
-
> truth on which all SSSS implementations are built. It is intended to be vendored
|
|
7
|
-
> byte-for-byte into any repository that implements SSSS (e.g. the UltraChat
|
|
8
|
-
> Sovereign AI OS, the Total Recall reference kernel).
|
|
9
|
-
>
|
|
10
|
-
> Status: **Draft**. The format, type registry, and conformance contract are under
|
|
11
|
-
> active development. Expect breaking changes until v1.0.
|
|
12
|
-
>
|
|
13
|
-
> Implementation-specific detail (routes, services, storage backends, deployment)
|
|
14
|
-
> does **not** belong in this document — it belongs in each implementation's own
|
|
15
|
-
> `SKILL.md`. This file describes *what SSSS is*, never *how one product wires it up*.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 1. Abstract
|
|
20
|
-
|
|
21
|
-
SSSS — the Structured Semantic Syntax System — is a **database-free, Markdown-first
|
|
22
|
-
schema and mutation contract for AI agent state**.
|
|
23
|
-
|
|
24
|
-
Every unit of agent-relevant state — a memory, a skill, a conversation, a workflow
|
|
25
|
-
run, an assistant definition, a runtime task — is a plain Markdown file with YAML
|
|
26
|
-
frontmatter. There is no relational database of record, no binary format, and no
|
|
27
|
-
proprietary container. A relational store MAY exist, but only as a *disposable
|
|
28
|
-
projection* rebuildable from the Markdown.
|
|
29
|
-
|
|
30
|
-
SSSS additionally defines the **Operation Contract**: a single, validated, idempotent
|
|
31
|
-
envelope through which all agent-generated mutations must flow. This makes
|
|
32
|
-
AI-generated state changes deterministic, replayable, conflict-safe, and auditable.
|
|
33
|
-
|
|
34
|
-
Any tool, IDE, agent framework, daemon, or CLI that can read Markdown can
|
|
35
|
-
interoperate with an SSSS vault. The only thing that distinguishes a memory engine,
|
|
36
|
-
a chat runtime, and a workflow orchestrator is *which primitive types they read and
|
|
37
|
-
write* — the underlying file format and mutation contract are identical.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 2. Conformance Terminology
|
|
42
|
-
|
|
43
|
-
The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**,
|
|
44
|
-
**SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **MAY**, and **OPTIONAL** in this
|
|
45
|
-
document are to be interpreted as described in RFC 2119.
|
|
46
|
-
|
|
47
|
-
Defined terms used throughout:
|
|
48
|
-
|
|
49
|
-
| Term | Meaning |
|
|
50
|
-
|------|---------|
|
|
51
|
-
| **Host** | A system that implements SSSS — stores SSSS files and/or processes the Operation Contract. |
|
|
52
|
-
| **Vault** | The version-controlled directory tree of SSSS files. The source of truth. |
|
|
53
|
-
| **VFS** | Virtual File System — the addressable namespace of paths within a vault. |
|
|
54
|
-
| **Primitive** | A defined `type` of SSSS file or contract structure (see §5). |
|
|
55
|
-
| **Document primitive** | A primitive that exists as an addressable Markdown file. |
|
|
56
|
-
| **Contract primitive** | A primitive that exists only as a protocol structure (envelope, lease, event). |
|
|
57
|
-
| **Projection** | A derived, disposable representation of vault state (e.g. an SQL table, a search index). Never source-of-truth. |
|
|
58
|
-
| **Agent** | Any human or AI actor issuing operations. |
|
|
59
|
-
|
|
60
|
-
A host is **conformant** if it satisfies every MUST in this document and passes the
|
|
61
|
-
conformance fixtures of §12.
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 3. Design Principles
|
|
66
|
-
|
|
67
|
-
| Principle | Rule |
|
|
68
|
-
|-----------|------|
|
|
69
|
-
| **No database of record** | Product-meaningful state MUST live in Markdown files, not in a relational database. A database MAY hold projections only. |
|
|
70
|
-
| **Markdown is law** | Every state primitive exists as a `.md` file (document primitives) or as a JSON envelope over the contract (contract primitives). |
|
|
71
|
-
| **Semantic frontmatter** | Every SSSS file MUST carry YAML frontmatter with a `type` field that identifies how engines interpret it. |
|
|
72
|
-
| **One mutation contract** | All agent-generated mutations MUST flow through the Operation Contract (§6). Direct, unvalidated writes by agents are forbidden. |
|
|
73
|
-
| **Deterministic validation** | Every mutation MUST be validated against the primitive's schema before commit. Validation MUST be deterministic — same input, same verdict. |
|
|
74
|
-
| **Idempotent by key** | Every operation carries an idempotency key. Replays MUST NOT double-apply. |
|
|
75
|
-
| **Append-only history** | The event log is immutable. Events are never updated or deleted. |
|
|
76
|
-
| **Disposable indexes** | Derived indexes and projections are ephemeral caches, fully rebuildable from the vault. They may be deleted at any time. |
|
|
77
|
-
| **Git-versioned** | The vault is version-controlled. History is provenance. |
|
|
78
|
-
| **Portable** | A vault is interpretable by any Markdown-capable tool. No host is privileged. |
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## 4. The SSSS File
|
|
83
|
-
|
|
84
|
-
### 4.1 Anatomy
|
|
85
|
-
|
|
86
|
-
A document primitive is a UTF-8 Markdown file with two regions:
|
|
87
|
-
|
|
88
|
-
```markdown
|
|
89
|
-
---
|
|
90
|
-
type: <primitive-type>
|
|
91
|
-
<frontmatter fields...>
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
<Markdown body>
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
1. **Frontmatter** — a YAML block delimited by a leading `---` line and a closing
|
|
98
|
-
`---` line. It MUST be the first content in the file. It is machine-readable
|
|
99
|
-
structured data.
|
|
100
|
-
2. **Body** — everything after the closing `---`. It is human-readable Markdown
|
|
101
|
-
prose, and for append-type primitives (§5.3) it carries the ordered records.
|
|
102
|
-
|
|
103
|
-
A Markdown file with no frontmatter, or with frontmatter that omits `type`, is **not
|
|
104
|
-
an SSSS file** — it is an ordinary Markdown file (e.g. a `README`) and is out of SSSS
|
|
105
|
-
scope. Where a context *requires* an SSSS file — a write through the Operation
|
|
106
|
-
Contract (§6) to an SSSS path — a missing or unrecognized `type` MUST be rejected.
|
|
107
|
-
|
|
108
|
-
### 4.2 Universal Frontmatter Fields
|
|
109
|
-
|
|
110
|
-
Every SSSS document primitive MUST include:
|
|
111
|
-
|
|
112
|
-
| Field | Type | Description |
|
|
113
|
-
|-------|------|-------------|
|
|
114
|
-
| `type` | string | The primitive type. MUST match an entry in the Type Registry (§5). |
|
|
115
|
-
| `title` | string | Human-readable title of the document. |
|
|
116
|
-
| `description` | string | One-sentence summary of the document's purpose. |
|
|
117
|
-
| `timestamp` | string | ISO 8601 timestamp of last modification. |
|
|
118
|
-
|
|
119
|
-
For OKF-compatible discovery, SSSS document primitives SHOULD also include:
|
|
120
|
-
|
|
121
|
-
| Field | Type | Description |
|
|
122
|
-
|-------|------|-------------|
|
|
123
|
-
| `resource` | string | Canonical URI for the underlying asset, when the primitive describes one. |
|
|
124
|
-
| `tags` | array | Array of string tags for categorization and routing. |
|
|
125
|
-
| `aliases` | array | Array of alternative names for this concept, used for wiki autolinking. |
|
|
126
|
-
|
|
127
|
-
Every primitive type defines its own additional REQUIRED and OPTIONAL fields
|
|
128
|
-
(§5.4). To maintain forward compatibility and allow agents scratchpad space, hosts MUST NOT reject documents containing unknown frontmatter keys. Unknown fields MUST be preserved.
|
|
129
|
-
|
|
130
|
-
### 4.3 Linking & Progressive Disclosure
|
|
131
|
-
|
|
132
|
-
SSSS adopts the OKF standards for hyperlinking and directory indices:
|
|
133
|
-
|
|
134
|
-
1. **Absolute Bundle-Relative Links**: Links to other primitives SHOULD be absolute paths starting from the vault root (e.g., `[Customer Assistant](/assistants/support.md)`).
|
|
135
|
-
2. **The `# Citations` Section**: If a primitive's body makes claims sourced from other primitives or external data, it SHOULD include a `# Citations` heading at the bottom with numbered reference links.
|
|
136
|
-
3. **Index Files (`index.md`)**: A host MAY generate `index.md` files in directories to provide progressive disclosure of the vault's contents. These files contain no frontmatter and exist solely to serve as a table of contents for agents traversing the VFS.
|
|
137
|
-
|
|
138
|
-
### 4.4 Canonical Filenames
|
|
139
|
-
|
|
140
|
-
Document primitives that have a fixed role in a directory use an **uppercase
|
|
141
|
-
canonical filename** that signals the primitive at a glance:
|
|
142
|
-
|
|
143
|
-
| Filename | Primitive |
|
|
144
|
-
|----------|-----------|
|
|
145
|
-
| `SKILL.md` | `skill` |
|
|
146
|
-
| `ASSISTANT.md` | `assistant` |
|
|
147
|
-
| `WORKFLOW.md` | `workflow` |
|
|
148
|
-
| `MODEL.md` | `model` |
|
|
149
|
-
| `CONVERSATION.md` | `conversation` |
|
|
150
|
-
| `RUN.md` | `run` |
|
|
151
|
-
|
|
152
|
-
Free-standing primitives (e.g. `memory`, `task`) instead use a `kebab-case` slug
|
|
153
|
-
filename matching their `slug` field. The frontmatter `type` is always
|
|
154
|
-
authoritative; the filename is a convention, not a substitute for validation.
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## 5. Primitive Type Registry
|
|
159
|
-
|
|
160
|
-
SSSS defines two families of primitive: **document primitives** (addressable files)
|
|
161
|
-
and **contract primitives** (protocol structures). A host need not implement every
|
|
162
|
-
primitive — it implements the subset its product requires — but any primitive it
|
|
163
|
-
*does* implement MUST conform to the schema below.
|
|
164
|
-
|
|
165
|
-
### 5.1 Document Primitives
|
|
166
|
-
|
|
167
|
-
| `type` | Family | Portability | Purpose |
|
|
168
|
-
|--------|--------|-------------|---------|
|
|
169
|
-
| `memory` | knowledge | structural | A single unit of agent knowledge (rule, pattern, fact, preference). |
|
|
170
|
-
| `skill` | capability | structural | A skill package manifest. |
|
|
171
|
-
| `rule` | governance | structural | A workspace-scoped behavior rule applied to assistants/agents. |
|
|
172
|
-
| `security_role` | governance | structural | A security role definition for role-based access control (RBAC). |
|
|
173
|
-
| `task` | work | tenant_private | A unit of submitted work — one step or many. The universal work primitive. |
|
|
174
|
-
| `assistant` | actor | structural | The definition of an AI assistant/persona. |
|
|
175
|
-
| `workflow` | work | structural | A reusable **task template**: a defined procedure plus triggers. Firing a workflow submits a `task`. |
|
|
176
|
-
| `model` | catalog | structural | The definition of an inference model. |
|
|
177
|
-
| `conversation` | transcript | tenant_private | An append-only chat transcript. |
|
|
178
|
-
| `run` | transcript | tenant_private | An append-only workflow execution record. |
|
|
179
|
-
| `conflict` | meta | tenant_private | A record of two contradicting primitives, blocking promotion. |
|
|
180
|
-
| `page` | capability | structural | A VFS-native sandboxed custom workspace page. |
|
|
181
|
-
| `migration` | meta | structural | An SSSS schema migration state record. |
|
|
182
|
-
| `release` | meta | structural | An SSSS system schema version release record. |
|
|
183
|
-
|
|
184
|
-
The **Portability** column is the primitive's default portability class (§5.5); a host
|
|
185
|
-
resolves it from `registry/core.json`. Extension registries assign their own primitives a
|
|
186
|
-
class — notably `resource_bound` for things like domains and phone numbers.
|
|
187
|
-
|
|
188
|
-
### 5.2 Contract Primitives
|
|
189
|
-
|
|
190
|
-
| `type` | Purpose |
|
|
191
|
-
|--------|---------|
|
|
192
|
-
| `operation` | A full atomic file write (create or full replace) — see §6. |
|
|
193
|
-
| `patch` | A partial merge into an existing file — see §6. |
|
|
194
|
-
| `event` | An append-only immutable log entry — see §6, §8. |
|
|
195
|
-
| `delete` | A tombstoning removal of a replace-type file — see §6. |
|
|
196
|
-
| `lease` | A file-level write lock — see §7. |
|
|
197
|
-
|
|
198
|
-
### 5.3 Append-Type vs. Replace-Type Documents
|
|
199
|
-
|
|
200
|
-
Document primitives are either:
|
|
201
|
-
|
|
202
|
-
- **Replace-type** — the whole file represents current state; a write replaces it
|
|
203
|
-
entirely (`memory`, `skill`, `assistant`, `workflow`, `model`, `task`,
|
|
204
|
-
`conflict`).
|
|
205
|
-
- **Append-type** — the file is an ordered, append-only log; writes add records to
|
|
206
|
-
the body and MUST NOT rewrite prior records (`conversation`, `run`).
|
|
207
|
-
|
|
208
|
-
Append-type documents MUST be mutated only by appending. A host MUST reject an
|
|
209
|
-
operation that would rewrite or remove existing records of an append-type document.
|
|
210
|
-
|
|
211
|
-
### 5.4 Per-Type Schemas
|
|
212
|
-
|
|
213
|
-
Each schema lists REQUIRED fields. All other fields are OPTIONAL. Examples are
|
|
214
|
-
minimal and illustrative.
|
|
215
|
-
|
|
216
|
-
#### `memory`
|
|
217
|
-
|
|
218
|
-
The knowledge primitive. Categories: `invariants`, `patterns`, `anti-patterns`,
|
|
219
|
-
`preferences`, `decisions`, `concepts`, `facts`, `lore`.
|
|
220
|
-
|
|
221
|
-
REQUIRED: `type`, `slug`, `category`, `title`, `status`, `schema_version`.
|
|
222
|
-
|
|
223
|
-
Knowledge-graph fields, REQUIRED when `schema_version: 2`: `confidence` (0..1),
|
|
224
|
-
`importance` (1..5), `modality` (`must|must_not|should|should_not|descriptive|preference`),
|
|
225
|
-
`subject`, `predicate`, `object`, `sentiment_polarity`
|
|
226
|
-
(`directive_must|directive_must_not|descriptive|preference`).
|
|
227
|
-
|
|
228
|
-
The `subject`/`predicate`/`object` triple SHOULD use stable, language-neutral
|
|
229
|
-
concept identifiers (not localized prose), so the triple is a semantic anchor
|
|
230
|
-
independent of the document's authoring language — see §11.
|
|
231
|
-
|
|
232
|
-
```markdown
|
|
233
|
-
---
|
|
234
|
-
type: memory
|
|
235
|
-
slug: prefer-atomic-writes
|
|
236
|
-
category: patterns
|
|
237
|
-
title: "Always write files atomically (write-then-rename)"
|
|
238
|
-
status: active
|
|
239
|
-
schema_version: 2
|
|
240
|
-
confidence: 0.92
|
|
241
|
-
importance: 4
|
|
242
|
-
modality: must
|
|
243
|
-
subject: agent
|
|
244
|
-
predicate: use_atomic_write
|
|
245
|
-
object: file_system
|
|
246
|
-
sentiment_polarity: directive_must
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
Write to a temporary file, then `rename()` to the target. `rename()` is atomic on
|
|
250
|
-
POSIX filesystems; direct writes risk partial-file corruption on crash.
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
Memory nodes in the `invariants` category additionally carry `priority: absolute`
|
|
254
|
-
and `immutable: true`. The full `priority` enum is `absolute|high|normal|low`;
|
|
255
|
-
`priority` is OPTIONAL on non-invariant categories (defaults to `normal`).
|
|
256
|
-
|
|
257
|
-
#### `skill`
|
|
258
|
-
|
|
259
|
-
A capability package manifest. SSSS skill manifests are compatible with the open
|
|
260
|
-
Agent Skills standard: the minimal REQUIRED frontmatter is `name` and `description`.
|
|
261
|
-
The `type: skill` discriminator is REQUIRED for SSSS-managed manifests so the
|
|
262
|
-
registry can route them.
|
|
263
|
-
|
|
264
|
-
REQUIRED: `type`, `name`, `description`.
|
|
265
|
-
|
|
266
|
-
```markdown
|
|
267
|
-
---
|
|
268
|
-
type: skill
|
|
269
|
-
name: deploy
|
|
270
|
-
description: >-
|
|
271
|
-
Deploy services with zero downtime. Use when the user mentions deploy,
|
|
272
|
-
release, ship, or production push.
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
# Deploy
|
|
276
|
-
...
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
#### `task`
|
|
280
|
-
|
|
281
|
-
A unit of submitted work — the universal work primitive. A `task` MAY be ad-hoc or
|
|
282
|
-
instantiated from a `workflow` template; either way it executes as a `run`.
|
|
283
|
-
|
|
284
|
-
REQUIRED: `type`, `priority` (integer), `category`, `status`
|
|
285
|
-
(`pending|in_progress|done|failed`). A task instantiated from a template carries an
|
|
286
|
-
OPTIONAL `workflow_id` referencing it.
|
|
287
|
-
|
|
288
|
-
Runtime-created tasks SHOULD additionally carry `workflow_path`, `trigger_id`,
|
|
289
|
-
`trigger_type`, `trigger_event_id`, `scheduled_for`, and `dedupe_key`. These fields
|
|
290
|
-
make the task reconstructible from the workflow definition plus the trigger event
|
|
291
|
-
and prevent duplicate daemon ticks from creating duplicate work (§11.8).
|
|
292
|
-
|
|
293
|
-
```markdown
|
|
294
|
-
---
|
|
295
|
-
type: task
|
|
296
|
-
priority: 85
|
|
297
|
-
category: skill-engineering
|
|
298
|
-
status: pending
|
|
299
|
-
workflow_id: "research-skill"
|
|
300
|
-
trigger_id: "manual"
|
|
301
|
-
scheduled_for: 2026-05-16T08:00:00Z
|
|
302
|
-
dedupe_key: "runtime:abc123"
|
|
303
|
-
---
|
|
304
|
-
|
|
305
|
-
## Objective
|
|
306
|
-
Research the payments API and write a reference skill.
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
#### `assistant`
|
|
310
|
-
|
|
311
|
-
The definition of an AI assistant.
|
|
312
|
-
|
|
313
|
-
REQUIRED: `type`, `name`.
|
|
314
|
-
|
|
315
|
-
```markdown
|
|
316
|
-
---
|
|
317
|
-
type: assistant
|
|
318
|
-
name: "Support Bot"
|
|
319
|
-
description: "Front-line customer support assistant."
|
|
320
|
-
model: "anthropic/claude-opus-4-5"
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## Instructions
|
|
324
|
-
You are a helpful support assistant.
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
#### `workflow`
|
|
328
|
-
|
|
329
|
-
A reusable **task template** — a defined multi-step procedure plus triggers. A
|
|
330
|
-
workflow is not executed directly: when a trigger fires (or it is invoked), the host
|
|
331
|
-
**submits a `task`** from the template, and that task executes as a `run`. Workflow
|
|
332
|
-
and task are one work model — the workflow is the reusable definition, the task is
|
|
333
|
-
the submitted instance.
|
|
334
|
-
|
|
335
|
-
REQUIRED: `type`, `name`. `triggers` (array) is OPTIONAL — a workflow with no
|
|
336
|
-
triggers is valid and may be invoked manually or by another workflow.
|
|
337
|
-
|
|
338
|
-
When present, `triggers[]` is the canonical schedule source. OS cron, hosted
|
|
339
|
-
schedulers, queues, and daemon timers are wake-up mechanisms only; they MUST NOT
|
|
340
|
-
become the record of what the workflow schedule means. A trigger entry SHOULD
|
|
341
|
-
include:
|
|
342
|
-
|
|
343
|
-
| Field | Description |
|
|
344
|
-
|-------|-------------|
|
|
345
|
-
| `type` | `manual`, `cron`, `interval`, `event`, `webhook`, `file_change`, or `condition`. |
|
|
346
|
-
| `id` / `trigger_id` | Stable trigger identity within the workflow. |
|
|
347
|
-
| `cron` / `interval` / `event_type` | Type-specific selector. |
|
|
348
|
-
| `timezone` | Required for wall-clock schedules; UTC is implied if omitted. |
|
|
349
|
-
| `misfire_policy` | `skip`, `run_once`, or `catch_up`; default `run_once`. |
|
|
350
|
-
| `concurrency` | `allow_parallel`, `skip_if_running`, `enqueue`, or `replace`; default `skip_if_running`. |
|
|
351
|
-
|
|
352
|
-
```markdown
|
|
353
|
-
---
|
|
354
|
-
type: workflow
|
|
355
|
-
name: "Daily Digest"
|
|
356
|
-
description: "Sends a daily summary email."
|
|
357
|
-
triggers:
|
|
358
|
-
- type: cron
|
|
359
|
-
id: daily-0800
|
|
360
|
-
cron: "0 8 * * *"
|
|
361
|
-
timezone: "America/Denver"
|
|
362
|
-
misfire_policy: run_once
|
|
363
|
-
concurrency: skip_if_running
|
|
364
|
-
isActive: true
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
## Steps
|
|
368
|
-
1. Gather unread messages.
|
|
369
|
-
2. Summarize.
|
|
370
|
-
3. Send digest.
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
#### `rule`
|
|
374
|
-
|
|
375
|
-
A workspace-scoped behavior rule that constrains how assistants/agents act.
|
|
376
|
-
Distinct from `memory` (which is agent-private knowledge): a `rule` is workspace
|
|
377
|
-
governance, authored deliberately.
|
|
378
|
-
|
|
379
|
-
REQUIRED: `type`, `name`. OPTIONAL: `description`, `scope`.
|
|
380
|
-
|
|
381
|
-
```markdown
|
|
382
|
-
---
|
|
383
|
-
type: rule
|
|
384
|
-
name: "No external links in replies"
|
|
385
|
-
description: "Customer-facing replies must not contain outbound URLs."
|
|
386
|
-
scope: support
|
|
387
|
-
---
|
|
388
|
-
|
|
389
|
-
Outbound links are stripped from any assistant reply on a support thread.
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
#### `security_role`
|
|
393
|
-
|
|
394
|
-
A definition of a security role used for role-based access control (RBAC).
|
|
395
|
-
It maps a role name to a set of permissions that dictate what an agent or user
|
|
396
|
-
can do within the workspace.
|
|
397
|
-
|
|
398
|
-
REQUIRED: `type`, `name`, `permissions` (array). OPTIONAL: `description`.
|
|
399
|
-
|
|
400
|
-
```markdown
|
|
401
|
-
---
|
|
402
|
-
type: security_role
|
|
403
|
-
name: "admin"
|
|
404
|
-
description: "Administrator with full access to all workspace primitives."
|
|
405
|
-
permissions:
|
|
406
|
-
- "read:*"
|
|
407
|
-
- "write:*"
|
|
408
|
-
---
|
|
409
|
-
|
|
410
|
-
Full administrative access to the workspace.
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
#### `model`
|
|
414
|
-
|
|
415
|
-
The definition of an inference model.
|
|
416
|
-
|
|
417
|
-
REQUIRED: `type`, `model_id`, `provider`.
|
|
418
|
-
|
|
419
|
-
```markdown
|
|
420
|
-
---
|
|
421
|
-
type: model
|
|
422
|
-
model_id: "anthropic/claude-opus-4-5"
|
|
423
|
-
provider: anthropic
|
|
424
|
-
display_name: "Claude Opus 4.5"
|
|
425
|
-
---
|
|
426
|
-
|
|
427
|
-
## Capabilities
|
|
428
|
-
Long-context reasoning, tool use, vision.
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
#### `conversation`
|
|
432
|
-
|
|
433
|
-
An append-only chat transcript. Append-type.
|
|
434
|
-
|
|
435
|
-
REQUIRED: `type`, `thread_id`. Typical fields: `workspace_id`, `user_id`, `status`,
|
|
436
|
-
`turn_count`, `created_at`.
|
|
437
|
-
|
|
438
|
-
```markdown
|
|
439
|
-
---
|
|
440
|
-
type: conversation
|
|
441
|
-
thread_id: "7f3a2b1c-..."
|
|
442
|
-
workspace_id: "..."
|
|
443
|
-
user_id: "..."
|
|
444
|
-
status: active
|
|
445
|
-
created_at: 2026-05-16T14:00:00Z
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
### turn 1 — user — 2026-05-16T14:00:00Z
|
|
449
|
-
Hello.
|
|
450
|
-
|
|
451
|
-
### turn 2 — assistant — 2026-05-16T14:00:05Z
|
|
452
|
-
Hi — how can I help?
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
#### `run`
|
|
456
|
-
|
|
457
|
-
An append-only workflow execution record. Append-type.
|
|
458
|
-
|
|
459
|
-
REQUIRED: `type`, `run_id`, `workflow_id`. Typical fields: `workspace_id`, `status`,
|
|
460
|
-
`task_id`, `task_path`, `step_count`, `started_at`.
|
|
461
|
-
|
|
462
|
-
`status` SHOULD be one of: `queued`, `claimed`, `running`, `waiting_for_human`,
|
|
463
|
-
`succeeded`, `failed`, `canceled`, `retrying`, `dead_letter`.
|
|
464
|
-
|
|
465
|
-
```markdown
|
|
466
|
-
---
|
|
467
|
-
type: run
|
|
468
|
-
run_id: "run-001"
|
|
469
|
-
workflow_id: "daily-digest"
|
|
470
|
-
task_path: "tasks/daily-digest/daily-0800-20260516T080000Z.md"
|
|
471
|
-
status: queued
|
|
472
|
-
started_at: 2026-05-16T08:00:00Z
|
|
473
|
-
---
|
|
474
|
-
|
|
475
|
-
### step 1 — gather — 2026-05-16T08:00:01Z — ok
|
|
476
|
-
Collected 12 messages.
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
#### `conflict`
|
|
480
|
-
|
|
481
|
-
A record of two contradicting primitives. Blocks promotion until resolved.
|
|
482
|
-
|
|
483
|
-
REQUIRED: `type`, `conflict_id`, `status` (`pending|resolved`), `new_slug`,
|
|
484
|
-
`existing_slug`, `detected_at`.
|
|
485
|
-
|
|
486
|
-
```markdown
|
|
487
|
-
---
|
|
488
|
-
type: conflict
|
|
489
|
-
conflict_id: conflict-2026-05-16-001
|
|
490
|
-
status: pending
|
|
491
|
-
new_slug: use-html-email
|
|
492
|
-
existing_slug: use-plaintext-email
|
|
493
|
-
detected_at: 2026-05-16T18:30:00Z
|
|
494
|
-
---
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
#### `page`
|
|
498
|
-
|
|
499
|
-
A VFS-native sandboxed custom workspace page.
|
|
500
|
-
|
|
501
|
-
REQUIRED: `type`, `slug`, `name`, `sandbox_entry`.
|
|
502
|
-
|
|
503
|
-
```markdown
|
|
504
|
-
---
|
|
505
|
-
type: page
|
|
506
|
-
slug: "leads-portal"
|
|
507
|
-
name: "Leads Dashboard"
|
|
508
|
-
icon: "users"
|
|
509
|
-
layout: "split-chat"
|
|
510
|
-
sandbox_entry: "index.html"
|
|
511
|
-
---
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
#### `migration`
|
|
515
|
-
|
|
516
|
-
An SSSS schema migration record.
|
|
517
|
-
|
|
518
|
-
REQUIRED: `type`, `migration_id`, `from_version`, `to_version`, `status`, `description`.
|
|
519
|
-
|
|
520
|
-
```markdown
|
|
521
|
-
---
|
|
522
|
-
type: migration
|
|
523
|
-
migration_id: "mig-v2-to-v3"
|
|
524
|
-
from_version: 2
|
|
525
|
-
to_version: 3
|
|
526
|
-
status: pending
|
|
527
|
-
description: "Add vector_embedding field"
|
|
528
|
-
---
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
#### `release`
|
|
532
|
-
|
|
533
|
-
An SSSS system schema version release.
|
|
534
|
-
|
|
535
|
-
REQUIRED: `type`, `release_id`, `version`, `schema_version`, `summary`, `released_at`.
|
|
536
|
-
|
|
537
|
-
```markdown
|
|
538
|
-
---
|
|
539
|
-
type: release
|
|
540
|
-
release_id: "rel-3.1.0"
|
|
541
|
-
version: "3.1.0"
|
|
542
|
-
schema_version: 3
|
|
543
|
-
summary: "Added proposal and migration file types"
|
|
544
|
-
released_at: 2026-05-16T12:00:00Z
|
|
545
|
-
---
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
### 5.5 Portability Classification
|
|
549
|
-
|
|
550
|
-
A workspace is not one undifferentiated blob. Some of it is the **reusable business
|
|
551
|
-
model** (the workflows, assistants, pages, and rules that make the business run); some is
|
|
552
|
-
the operator's **private operational data** (customer transcripts, runtime work); and some
|
|
553
|
-
is **bound to a real external resource** (a domain, a phone number, a mailbox). Selling,
|
|
554
|
-
templating, and backing up a workspace each need a different slice. SSSS makes that slice
|
|
555
|
-
declarable instead of ad-hoc.
|
|
556
|
-
|
|
557
|
-
Every **document** primitive declares one **portability class** in its registry entry.
|
|
558
|
-
(Contract primitives — `operation`/`patch`/`event`/`lease` — are protocol envelopes, not
|
|
559
|
-
stored documents, and have no portability class.)
|
|
560
|
-
|
|
561
|
-
| Class | Meaning | May appear in template/sale? |
|
|
562
|
-
|-------|---------|------------------------------|
|
|
563
|
-
| `structural` | The reusable business model — carries no operator- or customer-specific data. | ✅ verbatim |
|
|
564
|
-
| `tenant_private` | The operator's private operational data (customers, transcripts, runtime work). | ❌ never — backup only, encrypted at rest |
|
|
565
|
-
| `resource_bound` | Requires a real external resource bound at provision time. | ⚠️ as a **requirement declaration** only — the seller's resource value is stripped |
|
|
566
|
-
|
|
567
|
-
A file MAY override its type's default with an `x_portability` frontmatter field. A host
|
|
568
|
-
MUST honor the **most restrictive** of (type default, instance override) — a file may make
|
|
569
|
-
itself more private than its type, never less.
|
|
570
|
-
|
|
571
|
-
An **export profile** is simply a filter over portability classes:
|
|
572
|
-
|
|
573
|
-
- **`backup`** — all three classes. `tenant_private` MUST be encrypted at rest.
|
|
574
|
-
- **`template`** / **`sale`** — `structural` verbatim; `resource_bound` reduced to a
|
|
575
|
-
requirement declaration (seller's bound value stripped); `tenant_private` **dropped
|
|
576
|
-
entirely**.
|
|
577
|
-
|
|
578
|
-
A host MUST reject a `template`/`sale` export that would emit a `tenant_private` primitive.
|
|
579
|
-
This single rule is what lets an operator sell a proven business model without ever
|
|
580
|
-
shipping a customer's data — the data is `tenant_private` by classification, so it
|
|
581
|
-
physically cannot enter a sale bundle.
|
|
582
|
-
|
|
583
|
-
---
|
|
584
|
-
|
|
585
|
-
## 6. The Operation Contract
|
|
586
|
-
|
|
587
|
-
All agent-generated mutations to a vault MUST flow through the Operation Contract.
|
|
588
|
-
An agent MUST NOT write vault files directly.
|
|
589
|
-
|
|
590
|
-
### 6.1 The Operation Envelope
|
|
591
|
-
|
|
592
|
-
An operation is a JSON envelope:
|
|
593
|
-
|
|
594
|
-
```jsonc
|
|
595
|
-
{
|
|
596
|
-
"type": "operation", // "operation" | "patch" | "event" | "delete"
|
|
597
|
-
"idempotency_key": "uuid-v4", // see §6.4
|
|
598
|
-
"path": "assistants/bot/ASSISTANT.md", // relative VFS path, no leading "/"
|
|
599
|
-
"workspace_id": "uuid", // the vault/workspace scope
|
|
600
|
-
"content": "---\ntype: ...", // full file content (operation, event)
|
|
601
|
-
"patches": { }, // partial merge (patch only)
|
|
602
|
-
"lease_id": "uuid", // OPTIONAL — see §7
|
|
603
|
-
"intent": "human description", // OPTIONAL — audit annotation
|
|
604
|
-
"dry_run": false, // OPTIONAL — validate without committing
|
|
605
|
-
"actor": { // OPTIONAL — the cryptographically verified identity.
|
|
606
|
-
"type": "human", // "human" | "ai" | "system"
|
|
607
|
-
"role": "admin" // role-based access control hook for the host
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
### 6.2 Envelope Types
|
|
613
|
-
|
|
614
|
-
| `type` | Semantics | Body field | Required envelope fields |
|
|
615
|
-
|--------|-----------|------------|--------------------------|
|
|
616
|
-
| `operation` | Full atomic write — creates or fully replaces a file. | `content` | `type`, `idempotency_key`, `path`, `workspace_id`, `content` |
|
|
617
|
-
| `patch` | Partial merge into an existing file's frontmatter and/or body. | `patches` | `type`, `idempotency_key`, `path`, `workspace_id`, `patches` |
|
|
618
|
-
| `event` | Append-only immutable log entry. Never overwrites. | `content` | `type`, `idempotency_key`, `path`, `workspace_id`, `content` |
|
|
619
|
-
| `delete` | Removes a replace-type file from the vault. | — | `type`, `idempotency_key`, `path`, `workspace_id` |
|
|
620
|
-
|
|
621
|
-
For `patch`, the `patches` object merges into frontmatter keys; the reserved key
|
|
622
|
-
`__body__` replaces or (for append-type documents) appends the Markdown body. For
|
|
623
|
-
`event`, `content` MUST be a valid JSON string carrying the event payload.
|
|
624
|
-
|
|
625
|
-
For `delete`, the host removes the file at `path` and appends a deletion event to the log
|
|
626
|
-
(§8) — the removal is itself an auditable, append-only record, so history is never lost. A
|
|
627
|
-
host MUST reject a `delete` targeting an **append-type** document (`conversation`, `run`)
|
|
628
|
-
or a non-existent path. A `delete` of an already-deleted path is an idempotent no-op that
|
|
629
|
-
returns the original result (§6.4). `delete` is the only contract type that removes vault
|
|
630
|
-
state; export and provision (§16) never delete — only a live workspace edit or a migration
|
|
631
|
-
(§5.4 `migration`) does.
|
|
632
|
-
|
|
633
|
-
### 6.3 The Processing Pipeline
|
|
634
|
-
|
|
635
|
-
A host MUST process every operation through these ordered stages. Any stage's
|
|
636
|
-
failure aborts the operation with no commit.
|
|
637
|
-
|
|
638
|
-
1. **Envelope validation** — `type` is one of the four envelope types
|
|
639
|
-
(`operation`/`patch`/`event`/`delete`); required envelope fields present and
|
|
640
|
-
well-formed.
|
|
641
|
-
2. **Idempotency check** — if this `idempotency_key` + `workspace_id` +
|
|
642
|
-
request hash was already committed within the TTL, return the original result
|
|
643
|
-
as a replay (§6.4). If the key and workspace match but the request hash
|
|
644
|
-
differs, reject the request with `idempotency_conflict`. Stop.
|
|
645
|
-
3. **Authorization & Actor Identity** — the agent has write access to `workspace_id`.
|
|
646
|
-
*Security Mandate*: If a host exposes the Operation Contract directly to untrusted clients (e.g., a `POST /api/ssss` REST endpoint), the host **MUST** irreversibly overwrite the `actor` payload with the user's cryptographically verified session identity. Hosts MUST use this `actor` field to enforce Role-Based Access Control (RBAC) over sensitive or `resource_bound` primitives.
|
|
647
|
-
4. **Lease check** — if the target path is leased, the operation MUST carry a
|
|
648
|
-
matching, unexpired `lease_id` (§7).
|
|
649
|
-
5. **Content validation** — for `operation`/`patch`, the resulting file is validated
|
|
650
|
-
against its primitive schema (§9). Append-type rewrite attempts are rejected. For
|
|
651
|
-
`delete`, the host verifies the target exists and is a replace-type document (append-type
|
|
652
|
-
deletes are rejected).
|
|
653
|
-
5.5. **Granular Authorization (RBAC)** — evaluated only if stage 5 passed. Resolve
|
|
654
|
-
`actor.role` from the (by now host-verified, per stage 3) envelope. `role: "system"`
|
|
655
|
-
is an unconditional bypass (used by trusted internal callers such as the provisioning
|
|
656
|
-
pipeline, §17). `role: "admin"` is granted `write:*`/`read:*` unconditionally. Any
|
|
657
|
-
other named role's permissions are read from that role's `security_role` document
|
|
658
|
-
(canonical location `roles/<role>/ROLE.md`) and checked against the required
|
|
659
|
-
permission — `write:<type>` for `operation`/`patch`/`delete` (using the type resolved
|
|
660
|
-
in stage 5), or the fixed `write:event` for `event` envelopes (which have no resolved
|
|
661
|
-
document type). A permission list satisfies the requirement via an exact match,
|
|
662
|
-
`*:<type>`, `write:*`, or `*:*`. **A MISSING `actor.role` MUST be denied, not treated
|
|
663
|
-
as any default role** — this is the fail-closed complement to stage 3's mandate: a
|
|
664
|
-
host that forgets to overwrite `actor` gets every write rejected, not silently
|
|
665
|
-
promoted to admin.
|
|
666
|
-
6. **Commit** — the mutation is applied to the vault atomically. For `delete`, the file is
|
|
667
|
-
removed.
|
|
668
|
-
7. **Audit** — an audit entry is appended to the event log (§8).
|
|
669
|
-
|
|
670
|
-
A `dry_run` operation runs stages 1–5.5 and then stops: it MUST return the validation
|
|
671
|
-
verdict with `success` reflecting validity, and MUST NOT commit (`committed_at` is
|
|
672
|
-
`null`).
|
|
673
|
-
|
|
674
|
-
### 6.4 The Operation Response
|
|
675
|
-
|
|
676
|
-
```jsonc
|
|
677
|
-
{
|
|
678
|
-
"success": true,
|
|
679
|
-
"type": "operation",
|
|
680
|
-
"operation_id": "uuid",
|
|
681
|
-
"path": "assistants/bot/ASSISTANT.md",
|
|
682
|
-
"committed_at": "2026-05-16T14:00:00Z", // null for dry_run / failure
|
|
683
|
-
"dry_run": false,
|
|
684
|
-
"validation": {
|
|
685
|
-
"valid": true,
|
|
686
|
-
"type": "assistant", // resolved primitive type
|
|
687
|
-
"errors": [],
|
|
688
|
-
"warnings": []
|
|
689
|
-
},
|
|
690
|
-
"replay": { }, // present only on an idempotent replay
|
|
691
|
-
"repair": { } // present only on validation failure — see §9
|
|
692
|
-
}
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
### 6.5 Error Codes
|
|
696
|
-
|
|
697
|
-
| Code | Meaning |
|
|
698
|
-
|------|---------|
|
|
699
|
-
| `400` | Invalid request — malformed envelope, or a path that fails the traversal guard. |
|
|
700
|
-
| `401` | Authentication required. |
|
|
701
|
-
| `403` | Agent lacks write access to the workspace. |
|
|
702
|
-
| `404` | The `patch`/`delete` target does not exist. |
|
|
703
|
-
| `409` | Lease conflict, version conflict, or idempotency conflict — path is locked, the supplied lease is invalid/expired, or the same idempotency key was reused for a different request hash. |
|
|
704
|
-
| `422` | Validation failure — see `validation.errors` and `repair`. |
|
|
705
|
-
| `500` | Internal error — the operation was not committed. |
|
|
706
|
-
|
|
707
|
-
A host need not use HTTP; if it does, these are the canonical status codes.
|
|
708
|
-
|
|
709
|
-
---
|
|
710
|
-
|
|
711
|
-
## 7. Leases — Concurrency Control
|
|
712
|
-
|
|
713
|
-
A **lease** is a file-level write lock that prevents two agents from racing on the
|
|
714
|
-
same path.
|
|
715
|
-
|
|
716
|
-
- A lease is identified by a `lease_id` and scoped to a `(workspace_id, path)` pair.
|
|
717
|
-
- At most one active lease MAY exist per `(workspace_id, path)`.
|
|
718
|
-
- While a path is leased, an operation targeting it MUST present the matching,
|
|
719
|
-
unexpired `lease_id` or be rejected with `409`.
|
|
720
|
-
- A lease MUST carry an expiry. An expired lease is treated as absent.
|
|
721
|
-
- An agent that acquires a lease MUST release it after its operation completes. A
|
|
722
|
-
host SHOULD reclaim expired leases automatically.
|
|
723
|
-
|
|
724
|
-
Leases are advisory coordination, not security. Authorization (§6.3 stage 3) is the
|
|
725
|
-
security boundary.
|
|
726
|
-
|
|
727
|
-
---
|
|
728
|
-
|
|
729
|
-
## 8. The Event Log
|
|
730
|
-
|
|
731
|
-
The event log is an **append-only, immutable** record. It is two things at once: a
|
|
732
|
-
flat physical *log*, and a relational *event graph* layered on top of it.
|
|
733
|
-
|
|
734
|
-
### 8.1 The Log
|
|
735
|
-
|
|
736
|
-
- Events are written via `type: event` operations (§6.2).
|
|
737
|
-
- An entry, once written, MUST NOT be updated or deleted. There is no UPDATE and no
|
|
738
|
-
DELETE. Ordering is arrival order; adjacency in the log is purely temporal.
|
|
739
|
-
- Audit entries (pipeline stage 7) are themselves events.
|
|
740
|
-
- The event log is the canonical history of *what happened*; the vault is the
|
|
741
|
-
canonical state of *what is true now*. Both are source-of-truth; projections are
|
|
742
|
-
not.
|
|
743
|
-
|
|
744
|
-
### 8.2 The Event Record
|
|
745
|
-
|
|
746
|
-
An event is a typed record — **not** a document primitive. There is no `EVENT.md`;
|
|
747
|
-
events exist only in the log. Each event carries:
|
|
748
|
-
|
|
749
|
-
| Field | Description |
|
|
750
|
-
|-------|-------------|
|
|
751
|
-
| `event_id` | Stable unique identity — makes the event addressable. |
|
|
752
|
-
| `event_type` | The kind of event (e.g. `feedback`, `audit`, `spawn`). |
|
|
753
|
-
| `correlation_id` | Groups every event of one logical flow ("saga"), however far apart in the log. |
|
|
754
|
-
| `caused_by` | Zero or more `event_id`s of the event(s) that directly caused this one (causation). |
|
|
755
|
-
| `subject` | The vault path / record the event is about. |
|
|
756
|
-
| `payload` | The event-type-specific body. |
|
|
757
|
-
| `ts` | ISO 8601 timestamp. |
|
|
758
|
-
|
|
759
|
-
### 8.3 The Event Graph
|
|
760
|
-
|
|
761
|
-
Events relate to **non-adjacent** events: a feedback event refers to the completion
|
|
762
|
-
it rated, an investigation to the feedback that triggered it, a fix to the
|
|
763
|
-
investigation. These references form a causal **graph** over the flat log.
|
|
764
|
-
|
|
765
|
-
The graph is preserved without violating append-only because **edges point backward
|
|
766
|
-
only**: a new event records its `caused_by` parents; an existing event is never
|
|
767
|
-
mutated to record a child. The forward view (an event's children, a full saga tree)
|
|
768
|
-
is reconstructed by scanning — so the **event graph is a derived artifact** (§10),
|
|
769
|
-
disposable and rebuildable. Relationships are canonical (backward `event_id`
|
|
770
|
-
references stored in the log); the graph index is only a cache.
|
|
771
|
-
|
|
772
|
-
A **session** is not a separate primitive — it is a named, `correlation_id`-scoped
|
|
773
|
-
slice of the event graph: the saga tree of one coherent unit of work.
|
|
774
|
-
|
|
775
|
-
---
|
|
776
|
-
|
|
777
|
-
## 9. Validation & Repair
|
|
778
|
-
|
|
779
|
-
Validation is **deterministic**: identical input always yields an identical verdict.
|
|
780
|
-
|
|
781
|
-
A file is valid if and only if:
|
|
782
|
-
|
|
783
|
-
1. It has well-formed YAML frontmatter.
|
|
784
|
-
2. The frontmatter `type` matches a primitive in the registry (§5).
|
|
785
|
-
3. Every REQUIRED field for that primitive is present and non-empty.
|
|
786
|
-
4. For append-type documents, the operation does not rewrite existing records.
|
|
787
|
-
|
|
788
|
-
Hosts MUST NOT reject a file due to the presence of unknown or unrecognized frontmatter keys. Unrecognized keys MUST be silently preserved to support agent scratchpads and forward compatibility with OKF extensions.
|
|
789
|
-
|
|
790
|
-
On failure, the host MUST return structured **repair feedback** so an agent can
|
|
791
|
-
self-correct without guesswork:
|
|
792
|
-
|
|
793
|
-
```jsonc
|
|
794
|
-
{
|
|
795
|
-
"repair": {
|
|
796
|
-
"field_errors": [
|
|
797
|
-
{ "field": "name", "issue": "Missing required field 'name' for type 'assistant'." }
|
|
798
|
-
]
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
A host MAY additionally emit non-blocking `warnings` (e.g. deprecated fields,
|
|
804
|
-
low-confidence content). Warnings MUST NOT block a commit.
|
|
805
|
-
|
|
806
|
-
---
|
|
807
|
-
|
|
808
|
-
## 10. Derived Artifacts
|
|
809
|
-
|
|
810
|
-
Hosts MAY maintain derived artifacts for performance: search indexes, embedding
|
|
811
|
-
indexes, graph indexes, the **event-graph index** (the forward/causal view of the
|
|
812
|
-
event log — see §8.3), routing logs, and relational **projections** of vault data.
|
|
813
|
-
|
|
814
|
-
All derived artifacts are **disposable**:
|
|
815
|
-
|
|
816
|
-
- They MUST be fully rebuildable from the vault alone.
|
|
817
|
-
- They MUST NOT be treated as source-of-truth for product meaning.
|
|
818
|
-
- Deleting them MUST NOT lose information — only force a rebuild.
|
|
819
|
-
|
|
820
|
-
A host that maintains projections MUST provide a means to (a) rebuild a projection
|
|
821
|
-
from a vault scan, and (b) detect and repair drift between a projection and the
|
|
822
|
-
vault.
|
|
823
|
-
|
|
824
|
-
### 10.1 Projection Manifest
|
|
825
|
-
|
|
826
|
-
A host SHOULD maintain a `MANIFEST.json` (or equivalent) in the derived-artifacts
|
|
827
|
-
directory declaring each projection as disposable and recording provenance:
|
|
828
|
-
|
|
829
|
-
```jsonc
|
|
830
|
-
{
|
|
831
|
-
"type": "projection-manifest",
|
|
832
|
-
"generated_at": "2026-05-30T06:35:00Z",
|
|
833
|
-
"vault_hash": "sha256:abc123...", // content hash of the vault at build time
|
|
834
|
-
"projections": [
|
|
835
|
-
{ "file": "graph-index.jsonl", "disposable": true },
|
|
836
|
-
{ "file": "memory-layers.jsonl", "disposable": true },
|
|
837
|
-
{ "file": "embeddings.json", "disposable": true }
|
|
838
|
-
],
|
|
839
|
-
"rebuild_command": "npx total-recall compile"
|
|
840
|
-
}
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
The `vault_hash` field enables **staleness detection**: if the current vault hash
|
|
844
|
-
differs from the manifest's hash, the projections are stale and SHOULD be rebuilt.
|
|
845
|
-
This supports **incremental compilation** — a host MAY skip recompilation when the
|
|
846
|
-
hash matches, avoiding redundant I/O on unchanged vaults.
|
|
847
|
-
|
|
848
|
-
---
|
|
849
|
-
|
|
850
|
-
## 11. The Semantic Layer
|
|
851
|
-
|
|
852
|
-
SSSS operates as two layers with deliberately opposite requirements. A conformant
|
|
853
|
-
host MUST keep them separate.
|
|
854
|
-
|
|
855
|
-
### 11.1 The Two Layers
|
|
856
|
-
|
|
857
|
-
**The deterministic layer** — the file format (§4), type registry (§5), Operation
|
|
858
|
-
Contract (§6), leases (§7), event log (§8), and validation (§9). It is exact and
|
|
859
|
-
reproducible: identical input yields an identical verdict. It is language-independent
|
|
860
|
-
*by construction*: its control vocabulary — every frontmatter **key** and every
|
|
861
|
-
enumerated **value** (`type`, `modality`, `status`, the primitive type names, …) —
|
|
862
|
-
consists of **stable symbolic identifiers**, never localized words. They are never
|
|
863
|
-
translated, exactly as a JSON key or an HTTP method is never translated. Only
|
|
864
|
-
natural-language *content* (§11.2) carries language. A host MUST NOT make this layer
|
|
865
|
-
fuzzy.
|
|
866
|
-
|
|
867
|
-
**The semantic layer** — retrieval, routing, deduplication, conflict detection, and
|
|
868
|
-
memory surfacing. It operates on **meaning**, not on shared surface tokens. This is
|
|
869
|
-
where natural-language content lives, and where SSSS becomes genuinely
|
|
870
|
-
language-independent. A host MUST NOT make this layer depend on lexical token overlap
|
|
871
|
-
alone.
|
|
872
|
-
|
|
873
|
-
### 11.2 Language Independence
|
|
874
|
-
|
|
875
|
-
Natural-language fields — `title`, `description`, document bodies, feedback comments —
|
|
876
|
-
MAY be authored in ANY language. The semantic layer MUST treat documents by meaning,
|
|
877
|
-
so a node authored in one language remains retrievable, routable, and
|
|
878
|
-
conflict-checkable against a query or node in any other. Implementations SHOULD use a
|
|
879
|
-
multilingual embedding model so that all languages share a single vector space.
|
|
880
|
-
|
|
881
|
-
### 11.3 The Embedding Index
|
|
882
|
-
|
|
883
|
-
The semantic layer is backed by an **embedding index** — a derived artifact (§10):
|
|
884
|
-
disposable, never source-of-truth, fully rebuildable from the vault.
|
|
885
|
-
|
|
886
|
-
- It MUST record the `embedding_model` and vector `dim` that produced it. Embeddings
|
|
887
|
-
are not comparable across models; a model change REQUIRES a full reindex.
|
|
888
|
-
- A host MUST maintain exactly **one canonical embedding implementation**. Parallel
|
|
889
|
-
or duplicate embedding systems (e.g. one in JSON format and another in JSONL)
|
|
890
|
-
create consistency risks where a node is indexed in one but not the other.
|
|
891
|
-
- Retrieval SHOULD be **hybrid**: an exact/lexical pass (strong for slugs,
|
|
892
|
-
identifiers, and code) fused with a dense semantic pass (strong for meaning and
|
|
893
|
-
cross-lingual matches).
|
|
894
|
-
|
|
895
|
-
### 11.4 Provenance
|
|
896
|
-
|
|
897
|
-
So that outcomes can be attributed to their causes, append-type records (conversation
|
|
898
|
-
turns, run steps) SHOULD capture **provenance**: the set of primitives that produced
|
|
899
|
-
the record — e.g. the assistant, model, skills, and memory nodes in play. Provenance
|
|
900
|
-
is what lets a quality signal on an outcome propagate back to the primitives
|
|
901
|
-
responsible for it.
|
|
902
|
-
|
|
903
|
-
### 11.5 The `feedback` Block
|
|
904
|
-
|
|
905
|
-
Any document primitive MAY carry an OPTIONAL `feedback` frontmatter block — a
|
|
906
|
-
derived, language-neutral rollup of feedback signal:
|
|
907
|
-
|
|
908
|
-
```yaml
|
|
909
|
-
feedback:
|
|
910
|
-
score: 0.82 # 0..1, normalized
|
|
911
|
-
positive: 14
|
|
912
|
-
negative: 3
|
|
913
|
-
samples: 17
|
|
914
|
-
last_feedback: 2026-05-16T09:00:00Z
|
|
915
|
-
```
|
|
916
|
-
|
|
917
|
-
- Raw feedback MUST be recorded as `type: event` entries in the append-only event
|
|
918
|
-
log (§8) — never written as raw events directly into a document's frontmatter.
|
|
919
|
-
- The `feedback` block is a **rollup** of those events, recomputed periodically — the
|
|
920
|
-
same derived-cache pattern as `confidence`. It lives in the canonical file but is a
|
|
921
|
-
deliberately-lagged projection of the log.
|
|
922
|
-
- The block MUST be language-neutral structured signal (scores, counts, polarity),
|
|
923
|
-
never prose. Free-text feedback lives in the event payload and the embedding index.
|
|
924
|
-
|
|
925
|
-
### 11.6 Feedback as an Enhancement Layer
|
|
926
|
-
|
|
927
|
-
A host MAY use feedback to adjust `confidence`, routing weight, and to trigger
|
|
928
|
-
investigation of low-scored outcomes. Feedback is strictly an **enhancement** layer:
|
|
929
|
-
a host MUST remain fully functional with feedback collection disabled, and the
|
|
930
|
-
semantic layer MUST degrade gracefully to its other signals (access frequency, decay,
|
|
931
|
-
embedding similarity).
|
|
932
|
-
|
|
933
|
-
### 11.7 The `language_convention` Primitive
|
|
934
|
-
|
|
935
|
-
Because the control vocabulary is symbolic and never translated (§11.1), a workspace
|
|
936
|
-
that wishes to *present* itself in a given human language does so with data, not by
|
|
937
|
-
translating keys. The `language_convention` primitive (a `structural`, extension-owned
|
|
938
|
-
type — festech ships it) records a workspace's presentation conventions: its default
|
|
939
|
-
language/locale, formality, date and currency formatting, and terminology preferences.
|
|
940
|
-
|
|
941
|
-
It is `structural` and therefore travels in `template`/`sale` bundles (§5.5): a sold
|
|
942
|
-
business carries its voice and locale conventions, but never the operator's private
|
|
943
|
-
content. A host applies a `language_convention` as a **presentation overlay** at the
|
|
944
|
-
semantic/rendering layer; it MUST NOT alter the deterministic layer's symbolic keys or
|
|
945
|
-
enumerated values.
|
|
946
|
-
|
|
947
|
-
### 11.8 Workflow Runtime & Daemon Contract
|
|
948
|
-
|
|
949
|
-
SSSS defines the source of truth for workflow runtime behavior, but it does not
|
|
950
|
-
mandate one resident process manager. A host MAY use OS cron, systemd timers,
|
|
951
|
-
serverless schedules, webhooks, message queues, browser alarms, or an always-on
|
|
952
|
-
daemon to wake the runtime. Those systems are **wake-up mechanisms** only. They MUST
|
|
953
|
-
NOT become the canonical schedule, queue, or task history.
|
|
954
|
-
|
|
955
|
-
The canonical runtime sources are:
|
|
956
|
-
|
|
957
|
-
| Concern | Source of truth |
|
|
958
|
-
|---------|-----------------|
|
|
959
|
-
| Schedule and trigger meaning | `workflow` frontmatter `triggers[]`. |
|
|
960
|
-
| Submitted work | `task` documents. |
|
|
961
|
-
| Execution transcript | append-only `run` documents. |
|
|
962
|
-
| What happened | append-only event log (§8). |
|
|
963
|
-
| Claim/concurrency safety | leases (§7) plus deterministic idempotency keys (§6.4). |
|
|
964
|
-
| Dashboards, task queues, cursors | projections (§10), rebuildable from the vault and event log. |
|
|
965
|
-
|
|
966
|
-
A conformant daemon loop is:
|
|
967
|
-
|
|
968
|
-
1. **Scan** active `workflow` primitives whose `triggers[]` might fire.
|
|
969
|
-
2. **Evaluate** the trigger against wall-clock time, incoming event, webhook, file
|
|
970
|
-
change, condition, or explicit manual invocation.
|
|
971
|
-
3. **Append** a `workflow_triggered` event via an `event` envelope.
|
|
972
|
-
4. **Instantiate** one `task` via an `operation` envelope.
|
|
973
|
-
5. **Claim** the task using a time-bound lease before execution.
|
|
974
|
-
6. **Create or append** a `run` record for execution steps.
|
|
975
|
-
7. **Patch** task status to `done` or `failed`, or to `pending` with retry metadata.
|
|
976
|
-
8. **Rebuild** derived task queues, run timelines, graph indexes, or UI projections
|
|
977
|
-
as needed.
|
|
978
|
-
|
|
979
|
-
Every step that mutates vault state MUST use the Operation Contract (§6). A daemon
|
|
980
|
-
MUST NOT write task, run, cursor, or workflow files directly.
|
|
981
|
-
|
|
982
|
-
#### Trigger Types
|
|
983
|
-
|
|
984
|
-
Core trigger types are:
|
|
985
|
-
|
|
986
|
-
| Type | Fires when |
|
|
987
|
-
|------|------------|
|
|
988
|
-
| `manual` | A human, agent, or another workflow invokes it. |
|
|
989
|
-
| `cron` | A wall-clock cron expression reaches a scheduled instant. |
|
|
990
|
-
| `interval` | A fixed duration elapses after the previous scheduled instant. |
|
|
991
|
-
| `event` | A matching event-log entry appears. |
|
|
992
|
-
| `webhook` | A verified external request arrives. |
|
|
993
|
-
| `file_change` | A matching vault path is created, patched, or deleted. |
|
|
994
|
-
| `condition` | A host-defined predicate over vault/projection state becomes true. |
|
|
995
|
-
|
|
996
|
-
Trigger entries SHOULD use the fields documented in §5.4 `workflow`. Hosts MAY add
|
|
997
|
-
type-specific `x_` fields, but MUST preserve unknown fields when rewriting the
|
|
998
|
-
workflow document (§4.2).
|
|
999
|
-
|
|
1000
|
-
#### Idempotency & Duplicate Daemons
|
|
1001
|
-
|
|
1002
|
-
The idempotency basis for runtime-created work is:
|
|
1003
|
-
|
|
1004
|
-
```text
|
|
1005
|
-
workspace_id + workflow_id + trigger_id + scheduled_for
|
|
1006
|
-
```
|
|
1007
|
-
|
|
1008
|
-
Two daemon ticks evaluating the same trigger for the same scheduled instant MUST
|
|
1009
|
-
produce the same task idempotency key. Replaying the same envelope MUST NOT create a
|
|
1010
|
-
second task. This rule is what lets an SSSS host run multiple scheduler processes
|
|
1011
|
-
without a scheduler database becoming the source of truth.
|
|
1012
|
-
|
|
1013
|
-
For `event`, `webhook`, and `file_change` triggers, `scheduled_for` SHOULD be the
|
|
1014
|
-
canonical event timestamp or the host's normalized receipt timestamp, and the task
|
|
1015
|
-
SHOULD also record `trigger_event_id` when one exists.
|
|
1016
|
-
|
|
1017
|
-
#### Concurrency, Misfires & Retries
|
|
1018
|
-
|
|
1019
|
-
`misfire_policy` determines what happens when a daemon wakes after one or more missed
|
|
1020
|
-
schedule instants:
|
|
1021
|
-
|
|
1022
|
-
| Policy | Meaning |
|
|
1023
|
-
|--------|---------|
|
|
1024
|
-
| `skip` | Do not create work for missed instants. |
|
|
1025
|
-
| `run_once` | Create one task for the most recent missed instant. |
|
|
1026
|
-
| `catch_up` | Create one task per missed instant, each with its own idempotency key. |
|
|
1027
|
-
|
|
1028
|
-
`concurrency` determines what happens when a trigger fires while earlier work from
|
|
1029
|
-
the same workflow/trigger is still active:
|
|
1030
|
-
|
|
1031
|
-
| Policy | Meaning |
|
|
1032
|
-
|--------|---------|
|
|
1033
|
-
| `allow_parallel` | Create the new task regardless of active runs. |
|
|
1034
|
-
| `skip_if_running` | Do not create a new task while a prior run is active. |
|
|
1035
|
-
| `enqueue` | Create a pending task, but allow a worker to claim it only after prior work finishes. |
|
|
1036
|
-
| `replace` | Cancel or fail the previous task/run before creating the replacement. |
|
|
1037
|
-
|
|
1038
|
-
Retries MUST be represented on the `task` and/or `run` (`attempts`,
|
|
1039
|
-
`next_attempt_at`, `status: retrying`) and by events. A dead-letter outcome SHOULD be
|
|
1040
|
-
represented as `status: failed` on the task and `status: dead_letter` on the final
|
|
1041
|
-
run, plus an event explaining the terminal failure.
|
|
1042
|
-
|
|
1043
|
-
#### Runtime Helpers
|
|
1044
|
-
|
|
1045
|
-
The reference package exposes `@ssss/cli/runtime`, including deterministic helpers
|
|
1046
|
-
for planning a workflow trigger into a `workflow_triggered` event envelope and a
|
|
1047
|
-
task `operation` envelope. Hosts MAY implement their own daemon, but SHOULD pass the
|
|
1048
|
-
runtime conformance checks to prove the same source-of-truth and idempotency rules.
|
|
1049
|
-
|
|
1050
|
-
---
|
|
1051
|
-
|
|
1052
|
-
## 12. Conformance
|
|
1053
|
-
|
|
1054
|
-
Conformance is defined by a shared set of **fixtures** — canonical
|
|
1055
|
-
request/response pairs for the Operation Contract. A host is conformant if, for
|
|
1056
|
-
every fixture, it produces the expected response and status code.
|
|
1057
|
-
|
|
1058
|
-
Fixtures are distributed as a JSON document carrying:
|
|
1059
|
-
|
|
1060
|
-
- `operation_types` — the envelope-type schemas.
|
|
1061
|
-
- `idempotency` — TTL and replay behavior.
|
|
1062
|
-
- `validation_rules` — envelope and content rules.
|
|
1063
|
-
- `runtime_contract` — trigger vocabulary and daemon idempotency rules (§11.8).
|
|
1064
|
-
- `fixtures[]` — each with a `request`, an `expected_response`, and an
|
|
1065
|
-
OPTIONAL `expected_http_status`.
|
|
1066
|
-
- `error_codes` — the canonical code table.
|
|
1067
|
-
|
|
1068
|
-
The conformance fixture set is the shared test contract between all SSSS
|
|
1069
|
-
implementations. A host MUST NOT claim SSSS conformance without passing the current
|
|
1070
|
-
fixture set. Hosts implementing workflow daemons SHOULD also run the reference
|
|
1071
|
-
runtime checks exposed by `@ssss/cli/runtime`.
|
|
1072
|
-
|
|
1073
|
-
---
|
|
1074
|
-
|
|
1075
|
-
## 13. Naming Conventions
|
|
1076
|
-
|
|
1077
|
-
| Thing | Convention | Example |
|
|
1078
|
-
|-------|-----------|---------|
|
|
1079
|
-
| Memory / task slug | `kebab-case`, unique, matches filename | `prefer-atomic-writes` |
|
|
1080
|
-
| Memory category | lowercase, matches directory | `patterns` |
|
|
1081
|
-
| Skill name | `kebab-case`, matches directory | `deploy` |
|
|
1082
|
-
| Canonical filename | `UPPERCASE.md` | `ASSISTANT.md` |
|
|
1083
|
-
| VFS path | relative, no leading `/`, `/`-separated | `assistants/bot/ASSISTANT.md` |
|
|
1084
|
-
| Conflict ID | `conflict-YYYY-MM-DD-NNN` | `conflict-2026-05-16-001` |
|
|
1085
|
-
| Idempotency key | UUID v4, min 8 chars | `11111111-1111-...` |
|
|
1086
|
-
| Timestamp | ISO 8601, `Z` suffix (UTC) | `2026-05-16T14:03:00Z` |
|
|
1087
|
-
|
|
1088
|
-
Slugs and names MAY contain non-ASCII Unicode letters so that non-Latin scripts are
|
|
1089
|
-
first-class; they remain lowercase and hyphen-separated. A host MAY instead use an
|
|
1090
|
-
opaque ID as the slug and keep the human-readable label in `title` / `name`.
|
|
1091
|
-
|
|
1092
|
-
---
|
|
1093
|
-
|
|
1094
|
-
## 14. Spec Versioning
|
|
1095
|
-
|
|
1096
|
-
This document is versioned independently of any host and of the conformance
|
|
1097
|
-
fixture set.
|
|
1098
|
-
|
|
1099
|
-
- The spec version is stated in the document header (currently **v0.6 — Draft**).
|
|
1100
|
-
- Breaking changes to the file format, the type registry, or the Operation
|
|
1101
|
-
Contract increment the spec version.
|
|
1102
|
-
- Until **v1.0**, any version MAY introduce breaking changes.
|
|
1103
|
-
- A host SHOULD declare which spec version it targets.
|
|
1104
|
-
|
|
1105
|
-
---
|
|
1106
|
-
|
|
1107
|
-
## 15. Schema Evolution
|
|
1108
|
-
|
|
1109
|
-
SSSS is **self-describing and self-mutable**. The type registry (§5), the field
|
|
1110
|
-
schemas, and the contract rules are themselves SSSS-governed data — not a frozen
|
|
1111
|
-
external artifact. The protocol can evolve. But evolution is **governed**, never
|
|
1112
|
-
ad-hoc, so the deterministic layer (§11.1) stays exact at every moment.
|
|
1113
|
-
|
|
1114
|
-
### 15.1 Plain-Language Proposals
|
|
1115
|
-
|
|
1116
|
-
A change to SSSS is proposed in **plain natural language**, in any language — e.g.
|
|
1117
|
-
*"add an optional `priority` field to the task primitive."* A proposal is an ordinary
|
|
1118
|
-
SSSS work item (a `task`); authoring one does NOT require writing formal schema
|
|
1119
|
-
syntax by hand.
|
|
1120
|
-
|
|
1121
|
-
The host interprets the proposal **semantically** (§11), so a proposal written in any
|
|
1122
|
-
language is understood identically. The plain-language text is the *authoring
|
|
1123
|
-
interface* — it is not itself the schema.
|
|
1124
|
-
|
|
1125
|
-
### 15.2 The Governed Path
|
|
1126
|
-
|
|
1127
|
-
A proposal becomes part of SSSS only through a fixed pipeline:
|
|
1128
|
-
|
|
1129
|
-
1. **Interpret** — the plain-language proposal is resolved into a formal schema delta.
|
|
1130
|
-
2. **Validate** — the delta is checked against the current spec for consistency
|
|
1131
|
-
(no contradiction; no existing REQUIRED field removed without a migration).
|
|
1132
|
-
3. **Review** — acceptance is gated by human/admin approval and/or eval gates.
|
|
1133
|
-
4. **Version** — on acceptance the spec version (§14) is incremented.
|
|
1134
|
-
5. **Migrate** — a migration is recorded so existing vault data conforms to the new
|
|
1135
|
-
version.
|
|
1136
|
-
|
|
1137
|
-
### 15.3 Mutability Without Fuzziness
|
|
1138
|
-
|
|
1139
|
-
At any instant the *active* schema is a single, fixed, exact, versioned artifact —
|
|
1140
|
-
validation never becomes fuzzy. Mutability happens **between** versions, through the
|
|
1141
|
-
gate of §15.2. SSSS is therefore a *sequence of exact schemas*, not a fluid one. The
|
|
1142
|
-
plain-language interface lowers the authoring barrier; the governed path preserves
|
|
1143
|
-
the determinism the contract layer depends on.
|
|
1144
|
-
|
|
1145
|
-
---
|
|
1146
|
-
|
|
1147
|
-
## 16. The `.ucw` Bundle Format
|
|
1148
|
-
|
|
1149
|
-
A **bundle** is a single transportable file that packages a portion of a vault — its
|
|
1150
|
-
files plus a manifest describing what they are and what they need to run. A bundle is
|
|
1151
|
-
how an SSSS business or template is **backed up, shared, sold, and re-provisioned**. The
|
|
1152
|
-
canonical container is `package.ucw.json` (a "universal containerized workspace"); a host
|
|
1153
|
-
MAY additionally wrap it in a `.ucw` archive (the JSON plus any binary branding assets),
|
|
1154
|
-
but the JSON document is the normative artifact and is self-contained.
|
|
1155
|
-
|
|
1156
|
-
A bundle is produced by an **export** (§17) under one of the export profiles of §5.5
|
|
1157
|
-
(`backup | template | sale`). The profile a bundle was built under is recorded in its
|
|
1158
|
-
manifest and governs which portability classes (§5.5) its files may contain. A conformant
|
|
1159
|
-
exporter MUST NOT emit a `tenant_private` file into a `template` or `sale` bundle.
|
|
1160
|
-
|
|
1161
|
-
### 16.1 Structure
|
|
1162
|
-
|
|
1163
|
-
A bundle is a JSON object with three top-level members:
|
|
1164
|
-
|
|
1165
|
-
```jsonc
|
|
1166
|
-
{
|
|
1167
|
-
"manifest": { /* §16.2 — what this bundle is and needs */ },
|
|
1168
|
-
"branding": { /* OPTIONAL — binary assets, base64 (logo, favicon, colors, fonts) */ },
|
|
1169
|
-
"files": [ /* §16.4 — the SSSS files, in deterministic path order */ ]
|
|
1170
|
-
}
|
|
1171
|
-
```
|
|
1172
|
-
|
|
1173
|
-
`files` MUST be sorted by `path` (byte order) so that two exports of the same vault state
|
|
1174
|
-
are identical and content-hashable (§16.3, `provenance.content_hash`).
|
|
1175
|
-
|
|
1176
|
-
### 16.2 The Manifest
|
|
1177
|
-
|
|
1178
|
-
The manifest is the bundle's contract. It declares the bundle's identity, the SSSS version
|
|
1179
|
-
and extensions a host needs to consume it, the export profile, an inventory of what is
|
|
1180
|
-
inside, the resources it must bind at provision time, and provenance.
|
|
1181
|
-
|
|
1182
|
-
| Field | Required | Meaning |
|
|
1183
|
-
|-------|----------|---------|
|
|
1184
|
-
| `name` | yes | Human name of the bundle. |
|
|
1185
|
-
| `description` | yes | One-line summary. |
|
|
1186
|
-
| `version` | yes | The bundle's own semver, independent of the spec. |
|
|
1187
|
-
| `exported_at` | yes | ISO-8601 timestamp of export. |
|
|
1188
|
-
| `ssss_core_version` | yes | The `registry/core.json` `spec_version` the bundle targets (e.g. `"0.3"`). A host MUST refuse a bundle whose core version it does not support. |
|
|
1189
|
-
| `required_extensions` | yes | Array of extension registry ids the files rely on (e.g. `["festech"]`). Empty array if the bundle uses only core primitives. A host MUST refuse a bundle naming an extension it has not loaded. |
|
|
1190
|
-
| `export_profile` | yes | `backup` \| `template` \| `sale` — the §5.5 profile this bundle was built under. Determines the allowed portability classes. |
|
|
1191
|
-
| `primitive_inventory` | yes | Map of primitive `type` → count, over every file in the bundle (replaces ultrachat's hard-coded `categories`; it is registry-driven, so extension types appear automatically). |
|
|
1192
|
-
| `provisioning` | yes | Array of provisioning steps (§17.2) — the ordered, declarative plan for binding this bundle into a live workspace. Empty for a pure `backup` that is restored in place. |
|
|
1193
|
-
| `parameters` | no | Array of parameter definitions (§16.5) the importer must resolve (e.g. business name, domain). |
|
|
1194
|
-
| `source_workspace_id` | no | Origin workspace; OMITTED or nulled in `template`/`sale` profiles (it is operator-identifying). |
|
|
1195
|
-
| `file_count` | yes | Length of `files`; a cheap integrity check. |
|
|
1196
|
-
| `provenance` | yes | `{ content_hash, exporter, signature? }` (§16.3). |
|
|
1197
|
-
|
|
1198
|
-
`primitive_inventory` supersedes ultrachat's fixed `categories` object and `provisioning`
|
|
1199
|
-
supersedes its `capabilities` booleans: both are now open and registry-driven rather than a
|
|
1200
|
-
closed enum, so a bundle full of `festech` extension primitives inventories and provisions
|
|
1201
|
-
them without a spec change.
|
|
1202
|
-
|
|
1203
|
-
### 16.3 Provenance & Integrity
|
|
1204
|
-
|
|
1205
|
-
`provenance` makes a bundle verifiable and attributable:
|
|
1206
|
-
|
|
1207
|
-
- `content_hash` — a hash (SHA-256, hex, prefixed `sha256:`) over the canonical
|
|
1208
|
-
serialization of `files` (path-sorted, §16.1). An importer MUST recompute it and reject
|
|
1209
|
-
a bundle whose files do not match. This is what makes a bundle tamper-evident and what a
|
|
1210
|
-
marketplace lists against.
|
|
1211
|
-
- `exporter` — an identifier for the tool/host that produced the bundle (`"@ssss/cli@0.3.0"`).
|
|
1212
|
-
- `signature` — OPTIONAL detached signature over `content_hash` for a sold bundle, so a
|
|
1213
|
-
buyer can verify authorship. Unsigned bundles are valid; signing is a marketplace concern.
|
|
1214
|
-
|
|
1215
|
-
### 16.4 Files
|
|
1216
|
-
|
|
1217
|
-
Each entry of `files` is `{ path, content }`, where `content` is the full SSSS file text
|
|
1218
|
-
(frontmatter + body, §4). A host MAY also carry a parsed `frontmatter` object for
|
|
1219
|
-
convenience, but `content` is normative — on import the host re-parses `content`, so a
|
|
1220
|
-
divergent cached `frontmatter` is ignored. Every file's resolved portability class (§5.5,
|
|
1221
|
-
honoring `x_portability`) MUST be permitted by `export_profile`.
|
|
1222
|
-
|
|
1223
|
-
### 16.5 Parameters
|
|
1224
|
-
|
|
1225
|
-
`parameters` are the values an importer must supply to turn a template into a running
|
|
1226
|
-
instance — the difference between "a festival in a box" and "*this* festival." The schema is
|
|
1227
|
-
adopted verbatim from ultrachat's `WorkspaceTemplateVariableDefinition`:
|
|
1228
|
-
|
|
1229
|
-
| Field | Meaning |
|
|
1230
|
-
|-------|---------|
|
|
1231
|
-
| `key` | Stable identifier, referenced by provisioning steps and link rewriting. |
|
|
1232
|
-
| `label` | Human prompt. |
|
|
1233
|
-
| `type` | Value type (`string`, `boolean`, `surfaces`, …). |
|
|
1234
|
-
| `scope` | Where the value applies (`workspace`, `automation`, `data`, …). |
|
|
1235
|
-
| `source` | Who supplies it: `user` \| `llm` \| `graph` \| `system`. |
|
|
1236
|
-
| `required` | Whether provisioning may proceed without it. |
|
|
1237
|
-
| `defaultValue`, `options`, `dependsOn` | Optional default, enumerated choices, and dependency keys. |
|
|
1238
|
-
|
|
1239
|
-
A `sale`/`template` bundle declares its `resource_bound` requirements (§5.5) as `parameters`
|
|
1240
|
-
of `source: user` or `source: system` — e.g. the phone number, domain, and mailbox a buyer
|
|
1241
|
-
must bind. This is how the standard guarantees a sold business says exactly what real-world
|
|
1242
|
-
resources it needs without shipping the seller's own.
|
|
1243
|
-
|
|
1244
|
-
---
|
|
1245
|
-
|
|
1246
|
-
## 17. The Provisioning Contract
|
|
1247
|
-
|
|
1248
|
-
Export, provision, and import are the three verbs that move a bundle (§16) between vaults.
|
|
1249
|
-
They are specified to be **deterministic** and **idempotent** so that selling, cloning, and
|
|
1250
|
-
restoring an SSSS business are reliable operations rather than bespoke migrations.
|
|
1251
|
-
|
|
1252
|
-
### 17.1 The Three Verbs
|
|
1253
|
-
|
|
1254
|
-
- **export(vault, profile) → bundle** — Walk the vault, filter by the §5.5 portability rules
|
|
1255
|
-
for `profile`, sort files by path, compute `provenance.content_hash`, and emit a §16
|
|
1256
|
-
bundle. Export is **pure**: the same vault state and profile yield a byte-identical bundle.
|
|
1257
|
-
- **provision(bundle, parameters, target) → plan** — Resolve `parameters` (§16.5), bind the
|
|
1258
|
-
bundle's `resource_bound` requirements to real resources in `target`, and produce an
|
|
1259
|
-
ordered, replayable plan of Operation Contract envelopes (§6) plus resource bindings. A
|
|
1260
|
-
`dry_run` provision (mirroring §6 `dry_run`) validates and plans without committing.
|
|
1261
|
-
- **import(plan, target)** — Replay the plan's envelopes through the target's engine (§6.3).
|
|
1262
|
-
Because each envelope carries an `idempotency_key`, a re-run is a safe no-op: import is
|
|
1263
|
-
idempotent.
|
|
1264
|
-
|
|
1265
|
-
### 17.2 Provisioning Steps & Binding Vocabulary
|
|
1266
|
-
|
|
1267
|
-
A manifest's `provisioning` array is an ordered list of steps. The step schema and its
|
|
1268
|
-
controlled vocabularies are adopted from ultrachat's `WorkspaceProvisioningStep` and
|
|
1269
|
-
`WorkspaceGraphEdge`:
|
|
1270
|
-
|
|
1271
|
-
A **step** is `{ id, label, system, mode, required, notes? }`:
|
|
1272
|
-
|
|
1273
|
-
- `system` — the subsystem the step acts on: `workspace | branding | email | phone |
|
|
1274
|
-
domains | accounts | deployments | marketplace | tabs | automation`.
|
|
1275
|
-
- `mode` — the canonical **binding verb**: `existing` (bind to a resource the target
|
|
1276
|
-
already has), `provision` (allocate a new real resource — a domain, a phone number),
|
|
1277
|
-
`install` (add a dependency bundle), `generate` (synthesize content), `configure` (set
|
|
1278
|
-
values). `mode` is how a bundle distinguishes "needs a *new* phone number" from "route to
|
|
1279
|
-
the operator's existing line."
|
|
1280
|
-
|
|
1281
|
-
Dependency and resource relationships between primitives are expressed with the canonical
|
|
1282
|
-
**edge relations**: `uses_brand | owns_domain | routes_calls_to | deploys_to | has_surface
|
|
1283
|
-
| contains_page | installs_pack | authenticates_account | runs_workflow`. The
|
|
1284
|
-
`resource_bound` primitives of §5.5 each declare which relation binds them (festech's
|
|
1285
|
-
`domain` → `owns_domain`, `phone_number` → `routes_calls_to`, `integration_connection` →
|
|
1286
|
-
`connects_to`), so an importer knows exactly what real-world binding each requires.
|
|
1287
|
-
|
|
1288
|
-
### 17.3 Determinism, Id-Remap & Link Integrity
|
|
1289
|
-
|
|
1290
|
-
When a bundle is provisioned into a target vault, identifiers (slugs, workspace ids,
|
|
1291
|
-
cross-file links) are **remapped** so the imported business is a fresh, self-consistent
|
|
1292
|
-
instance rather than a clone aliasing the seller's ids. Remapping MUST preserve link
|
|
1293
|
-
integrity: every internal `[[link]]` / relative reference that resolved in the source bundle
|
|
1294
|
-
MUST resolve to the remapped target after import. This is the same rewrite engine the
|
|
1295
|
-
semantic layer's autolink (§11) uses, run with a bundle-relative id map. An importer that
|
|
1296
|
-
cannot resolve a link MUST fail the provision rather than emit a dangling reference.
|
|
1297
|
-
|
|
1298
|
-
### 17.4 Composition & Upgrade
|
|
1299
|
-
|
|
1300
|
-
- **Composition** — a bundle MAY depend on other bundles. A dependency carries an
|
|
1301
|
-
`installMode` of `optional | recommended | required` (adopted from ultrachat's
|
|
1302
|
-
`WorkspaceMarketplaceRecommendation`). `provision` installs `required` dependencies before
|
|
1303
|
-
the bundle itself; `optional`/`recommended` are surfaced to the operator.
|
|
1304
|
-
- **Upgrade** — moving an installed bundle from `v2` to a `v1`-conformant shape (or any
|
|
1305
|
-
version step) is performed through a `migration` primitive (§5) plus **structural-only**
|
|
1306
|
-
`patch` envelopes (§6.2). An upgrade MUST NOT touch `tenant_private` data: it rewrites the
|
|
1307
|
-
structural model, never the operator's private records. This is what lets a sold business
|
|
1308
|
-
receive standard updates without the vendor reaching into customer data.
|
|
1309
|
-
|
|
1310
|
-
---
|
|
1311
|
-
|
|
1312
|
-
## Appendix A — Reserved Frontmatter Keys
|
|
1313
|
-
|
|
1314
|
-
The following frontmatter keys are reserved by this spec across all primitives and
|
|
1315
|
-
MUST NOT be repurposed by hosts: `type`, `slug`, `schema_version`, `status`,
|
|
1316
|
-
`feedback`, `confidence`.
|
|
1317
|
-
|
|
1318
|
-
Hosts adding their own frontmatter fields SHOULD prefix them `x_` to remain
|
|
1319
|
-
forward-compatible with future spec revisions.
|
|
1320
|
-
|
|
1321
|
-
---
|
|
1322
|
-
|
|
1323
|
-
*SSSS is a portable standard. This specification is the ground truth; every SSSS
|
|
1324
|
-
implementation is a conformant consumer of it. To learn how a specific product
|
|
1325
|
-
implements SSSS, read that product's `SKILL.md`, not this file.*
|