skillscript-runtime 0.13.7 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +13 -12
  2. package/dist/bootstrap.d.ts +13 -13
  3. package/dist/bootstrap.d.ts.map +1 -1
  4. package/dist/bootstrap.js +31 -31
  5. package/dist/bootstrap.js.map +1 -1
  6. package/dist/cli.js +6 -6
  7. package/dist/cli.js.map +1 -1
  8. package/dist/compile.js +2 -2
  9. package/dist/compile.js.map +1 -1
  10. package/dist/connectors/config.d.ts +4 -4
  11. package/dist/connectors/config.d.ts.map +1 -1
  12. package/dist/connectors/config.js +7 -7
  13. package/dist/connectors/config.js.map +1 -1
  14. package/dist/connectors/{memory-store-mcp.d.ts → data-store-mcp.d.ts} +8 -8
  15. package/dist/connectors/data-store-mcp.d.ts.map +1 -0
  16. package/dist/connectors/{memory-store-mcp.js → data-store-mcp.js} +31 -31
  17. package/dist/connectors/data-store-mcp.js.map +1 -0
  18. package/dist/connectors/{memory-store.d.ts → data-store.d.ts} +12 -11
  19. package/dist/connectors/data-store.d.ts.map +1 -0
  20. package/dist/connectors/{memory-store.js → data-store.js} +15 -6
  21. package/dist/connectors/data-store.js.map +1 -0
  22. package/dist/connectors/index.d.ts +5 -5
  23. package/dist/connectors/index.d.ts.map +1 -1
  24. package/dist/connectors/index.js +7 -7
  25. package/dist/connectors/index.js.map +1 -1
  26. package/dist/connectors/local-model-mcp.js +1 -1
  27. package/dist/connectors/local-model-mcp.js.map +1 -1
  28. package/dist/connectors/registry.d.ts +10 -10
  29. package/dist/connectors/registry.d.ts.map +1 -1
  30. package/dist/connectors/registry.js +11 -11
  31. package/dist/connectors/registry.js.map +1 -1
  32. package/dist/connectors/sqlite-skill-store.js +1 -1
  33. package/dist/connectors/sqlite-skill-store.js.map +1 -1
  34. package/dist/connectors/types.d.ts +30 -20
  35. package/dist/connectors/types.d.ts.map +1 -1
  36. package/dist/connectors/types.js +2 -2
  37. package/dist/connectors/types.js.map +1 -1
  38. package/dist/dashboard/spa/app.js +2 -2
  39. package/dist/errors.d.ts +1 -1
  40. package/dist/errors.js +4 -4
  41. package/dist/errors.js.map +1 -1
  42. package/dist/help-content.js +27 -27
  43. package/dist/help-content.js.map +1 -1
  44. package/dist/index.d.ts +4 -4
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +3 -3
  47. package/dist/index.js.map +1 -1
  48. package/dist/lint.js +18 -18
  49. package/dist/lint.js.map +1 -1
  50. package/dist/mcp-server.d.ts +1 -0
  51. package/dist/mcp-server.d.ts.map +1 -1
  52. package/dist/mcp-server.js +24 -3
  53. package/dist/mcp-server.js.map +1 -1
  54. package/dist/runtime-config.d.ts +2 -2
  55. package/dist/runtime-config.d.ts.map +1 -1
  56. package/dist/runtime-config.js +1 -1
  57. package/dist/runtime-config.js.map +1 -1
  58. package/dist/runtime.js +6 -6
  59. package/dist/runtime.js.map +1 -1
  60. package/dist/skill-manager.js +1 -1
  61. package/dist/skill-manager.js.map +1 -1
  62. package/dist/testing/conformance.d.ts +8 -8
  63. package/dist/testing/conformance.d.ts.map +1 -1
  64. package/dist/testing/conformance.js +8 -8
  65. package/dist/testing/conformance.js.map +1 -1
  66. package/dist/testing/index.d.ts +2 -2
  67. package/dist/testing/index.d.ts.map +1 -1
  68. package/dist/testing/index.js +1 -1
  69. package/dist/testing/index.js.map +1 -1
  70. package/dist/trace.d.ts +3 -3
  71. package/docs/adopter-playbook.md +18 -15
  72. package/docs/configuration.md +8 -8
  73. package/docs/connector-contract-reference.md +44 -2
  74. package/docs/language-reference.md +38 -63
  75. package/docs/sqlite-skill-store.md +1 -1
  76. package/examples/README.md +5 -5
  77. package/examples/connectors/{MemoryStoreTemplate/MemoryStoreTemplate.ts → DataStoreTemplate/DataStoreTemplate.ts} +34 -34
  78. package/examples/connectors/{MemoryStoreTemplate → DataStoreTemplate}/README.md +36 -36
  79. package/examples/connectors/LocalModelTemplate/README.md +1 -1
  80. package/examples/connectors/McpConnectorTemplate/McpConnectorTemplate.ts +2 -2
  81. package/examples/connectors/McpConnectorTemplate/README.md +5 -5
  82. package/examples/connectors/README.md +3 -3
  83. package/examples/connectors/SkillStoreTemplate/README.md +1 -1
  84. package/examples/connectors/SkillStoreTemplate/SkillStoreTemplate.ts +1 -1
  85. package/examples/custom-bootstrap.example.ts +8 -8
  86. package/examples/onboarding-scaffold/README.md +7 -7
  87. package/examples/onboarding-scaffold/bootstrap.ts +10 -10
  88. package/examples/onboarding-scaffold/{file-memory-store.ts → file-data-store.ts} +18 -18
  89. package/examples/skillscripts/classify-support-ticket.skill.md +4 -4
  90. package/examples/skillscripts/doc-qa-with-citations.skill.md +1 -1
  91. package/examples/skillscripts/feedback-sentiment-scan.skill.md +3 -3
  92. package/examples/skillscripts/hello.skill.provenance.json +1 -1
  93. package/examples/skillscripts/morning-brief.skill.md +3 -3
  94. package/examples/skillscripts/service-health-watch.skill.md +1 -1
  95. package/package.json +6 -2
  96. package/scaffold/config.toml +2 -2
  97. package/scaffold/connectors.json +3 -3
  98. package/dist/connectors/memory-store-mcp.d.ts.map +0 -1
  99. package/dist/connectors/memory-store-mcp.js.map +0 -1
  100. package/dist/connectors/memory-store.d.ts.map +0 -1
  101. package/dist/connectors/memory-store.js.map +0 -1
  102. package/docs/ERD.md +0 -1139
@@ -1,10 +1,10 @@
1
- # MemoryStoreTemplate — fork-me skeleton
1
+ # DataStoreTemplate — fork-me skeleton
2
2
 
3
- A skeleton `MemoryStore` implementation for adopters writing their own. Not runnable; every method throws a `TODO` error. Copy this directory, rename, fill in the substrate-specific work.
3
+ A skeleton `DataStore` implementation for adopters writing their own. Not runnable; every method throws a `TODO` error. Copy this directory, rename, fill in the substrate-specific work.
4
4
 
5
5
  Use this when you want skillscript memories backed by:
6
6
  - A vector database (Pinecone, Weaviate, Qdrant, Chroma)
7
- - A memory system (AMP, hosted memory API)
7
+ - A data store backing (memory broker like AMP, hosted memory API, vector DB, etc.)
8
8
  - A different SQL flavor (Postgres + pgvector, MySQL)
9
9
  - An HTTP CRUD service
10
10
  - Anything else with query + write semantics
@@ -12,32 +12,32 @@ Use this when you want skillscript memories backed by:
12
12
  ## The three legs
13
13
 
14
14
  ```
15
- MemoryStore (choose which connector)
16
- ├── SqliteMemoryStore (bundled, SQLite + FTS5 — src/connectors/memory-store.ts)
15
+ DataStore (choose which connector)
16
+ ├── SqliteDataStore (bundled, SQLite + FTS5 — src/connectors/data-store.ts)
17
17
  ├── (no other bundled impl — vector DBs and remote services are adopter-side)
18
18
  └── Your fork from this template
19
19
  ```
20
20
 
21
- The runtime is substrate-agnostic. Memories don't know which backend they're stored against — the contract is the `MemoryStore` interface, and any class implementing it works.
21
+ The runtime is substrate-agnostic. Memories don't know which backend they're stored against — the contract is the `DataStore` interface, and any class implementing it works.
22
22
 
23
23
  ## Forking workflow
24
24
 
25
25
  ```bash
26
- cp -r examples/connectors/MemoryStoreTemplate examples/connectors/MyMemoryStore
26
+ cp -r examples/connectors/DataStoreTemplate examples/connectors/MyDataStore
27
27
  ```
28
28
 
29
- 1. **Rename the class.** Convention: `<Substrate>MemoryStore` (e.g., `PineconeMemoryStore`, `PostgresMemoryStore`, `AmpMemoryStore`).
30
- 2. **Define your config interface.** Edit `MemoryStoreTemplateConfig` to declare what your substrate needs (connection URL, API key, vault name, index name, etc.).
29
+ 1. **Rename the class.** Convention: `<Substrate>DataStore` (e.g., `PineconeDataStore`, `PostgresDataStore`, `AmpDataStore`).
30
+ 2. **Define your config interface.** Edit `DataStoreTemplateConfig` to declare what your substrate needs (connection URL, API key, vault name, index name, etc.).
31
31
  3. **Implement each method.** Three methods + `staticCapabilities()`. Each has a TODO comment in the skeleton explaining what to do.
32
32
  4. **Update `staticCapabilities()`** to declare what your impl actually supports. The runtime + lint consult these flags before exercising features.
33
33
  5. **Wire from your adopter bootstrap:**
34
34
 
35
35
  ```typescript
36
36
  import { Registry } from "skillscript-runtime";
37
- import { MyMemoryStore } from "./MyMemoryStore.js";
37
+ import { MyDataStore } from "./MyDataStore.js";
38
38
 
39
39
  const registry = new Registry();
40
- registry.registerMemoryStore("primary", new MyMemoryStore({
40
+ registry.registerDataStore("primary", new MyDataStore({
41
41
  // your config
42
42
  }));
43
43
  ```
@@ -46,37 +46,37 @@ cp -r examples/connectors/MemoryStoreTemplate examples/connectors/MyMemoryStore
46
46
 
47
47
  ```typescript
48
48
  import { describe, it } from "vitest";
49
- import { MemoryStoreConformance } from "skillscript-runtime/testing";
50
- import { MyMemoryStore } from "./MyMemoryStore.js";
49
+ import { DataStoreConformance } from "skillscript-runtime/testing";
50
+ import { MyDataStore } from "./MyDataStore.js";
51
51
 
52
- describe("MyMemoryStore conformance", () => {
53
- const tests = MemoryStoreConformance.buildTests({
54
- build: () => new MyMemoryStore({ /* test config */ }),
55
- ctor: MyMemoryStore,
52
+ describe("MyDataStore conformance", () => {
53
+ const tests = DataStoreConformance.buildTests({
54
+ build: () => new MyDataStore({ /* test config */ }),
55
+ ctor: MyDataStore,
56
56
  });
57
57
  for (const t of tests) it(`[${t.category}] ${t.name}`, t.run);
58
58
  });
59
59
  ```
60
60
 
61
- The conformance suite verifies your impl honors the contract: method presence, return-type shape, capability flag self-consistency. Passes → runtime treats your impl interchangeably with `SqliteMemoryStore`.
61
+ The conformance suite verifies your impl honors the contract: method presence, return-type shape, capability flag self-consistency. Passes → runtime treats your impl interchangeably with `SqliteDataStore`.
62
62
 
63
63
  ## Reference implementation
64
64
 
65
65
  When in doubt about semantics, read the bundled impl:
66
66
 
67
- - **`src/connectors/memory-store.ts`** — `SqliteMemoryStore`, SQLite + FTS5-backed. Schema lives in `bootstrap()` (memories table + FTS virtual table + AFTER INSERT/UPDATE/DELETE triggers). Single-process. Capability flags: `supports_writes: true`, `supports_tag_filter: true`, FTS only (semantic / rerank false).
67
+ - **`src/connectors/data-store.ts`** — `SqliteDataStore`, SQLite + FTS5-backed. Schema lives in `bootstrap()` (memories table + FTS virtual table + AFTER INSERT/UPDATE/DELETE triggers). Single-process. Capability flags: `supports_writes: true`, `supports_tag_filter: true`, FTS only (semantic / rerank false).
68
68
 
69
69
  ## Contract surface (3 methods)
70
70
 
71
- The MemoryStore contract is narrower than SkillStore. Three methods + `staticCapabilities()`:
71
+ The DataStore contract is narrower than SkillStore. Three methods + `staticCapabilities()`:
72
72
 
73
73
  | Method | What it does | When called |
74
74
  |---|---|---|
75
- | `query(filters)` | Read memories by mode + filter; return `PortableMemory[]` | Every `$ memory mode=... query=...` op |
76
- | `write(entry)` | Persist a new memory; return `{id, created_at}` | Every `$ memory_write content=... -> R` op + `memory_write` skill notify routes |
75
+ | `query(filters)` | Read memories by mode + filter; return `PortableData[]` | Every `$ data_read mode=... query=...` op |
76
+ | `write(entry)` | Persist a new memory; return `{id, created_at}` | Every `$ data_write content=... -> R` op + `data_write` skill notify routes |
77
77
  | `manifest()` | Capability snapshot for `runtime_capabilities` discovery | At startup + on-demand from MCP clients |
78
78
 
79
- Per the curated-subset framing in `src/connectors/types.ts`, `PortableMemory` has a 4-tier field model:
79
+ Per the curated-subset framing in `src/connectors/types.ts`, `PortableData` has a 4-tier field model:
80
80
 
81
81
  1. **Core fields** — `id`, `summary`, `detail`, `score` (always-meaningful)
82
82
  2. **Curated substrate subset** — top-level fields with portable concepts: `domain_tags`, `payload_type`, `knowledge_type`, `pinned`, `confidence`, `thread_status`, `recipients`, `expires_at`, `agent_id`, `vault`
@@ -89,8 +89,8 @@ Per the curated-subset framing in `src/connectors/types.ts`, `PortableMemory` ha
89
89
 
90
90
  `QueryFilters.mode` is the dispatch axis:
91
91
 
92
- - **`"fts"`** — full-text search; substrate-defined (BM25, BM25F, etc.). `SqliteMemoryStore` supports this via FTS5.
93
- - **`"semantic"`** — embedding-based similarity. Vector-DB substrates support this; `SqliteMemoryStore` does not.
92
+ - **`"fts"`** — full-text search; substrate-defined (BM25, BM25F, etc.). `SqliteDataStore` supports this via FTS5.
93
+ - **`"semantic"`** — embedding-based similarity. Vector-DB substrates support this; `SqliteDataStore` does not.
94
94
  - **`"rerank"`** — substrate-defined hybrid (e.g., FTS retrieve + embedding rerank). Optional.
95
95
  - **substrate-specific strings** — your fork can define its own modes; document them in `manifest().manifest.supported_modes`.
96
96
 
@@ -111,7 +111,7 @@ Honor what your substrate supports; ignore the rest. Document the supported set
111
111
 
112
112
  ## `write()` semantics
113
113
 
114
- The `MemoryWrite` shape:
114
+ The `DataWrite` shape:
115
115
 
116
116
  - **`content`** (required) — the memory body
117
117
  - **`tags`** (optional) — routed to your substrate's tag mechanism
@@ -125,18 +125,18 @@ If your substrate doesn't support writes (read-only memory like a search index o
125
125
 
126
126
  ## Wiring against the dashboard / MCP
127
127
 
128
- Runtime hosts honor whichever MemoryStore impl your registry has. To make your fork visible through `skillfile dashboard`:
128
+ Runtime hosts honor whichever DataStore impl your registry has. To make your fork visible through `skillfile dashboard`:
129
129
 
130
- - Write a custom bootstrap that constructs the runtime with your MemoryStore (see `src/bootstrap.ts` for the reference shape)
130
+ - Write a custom bootstrap that constructs the runtime with your DataStore (see `src/bootstrap.ts` for the reference shape)
131
131
  - OR (planned future) declare in `~/.skillscript/connectors.json`:
132
132
 
133
133
  ```json
134
134
  {
135
135
  "substrate": {
136
- "memory_store": {
136
+ "data_store": {
137
137
  "type": "custom",
138
- "module": "./my-memory-store.js",
139
- "export": "MyMemoryStore",
138
+ "module": "./my-data-store.js",
139
+ "export": "MyDataStore",
140
140
  "config": { "pineconeApiKey": "${PINECONE_KEY}" }
141
141
  }
142
142
  }
@@ -145,11 +145,11 @@ Runtime hosts honor whichever MemoryStore impl your registry has. To make your f
145
145
 
146
146
  Current limitation: sync `bootstrap()` can't dynamic-import, so the `custom` form surfaces an error today. Programmatic bootstrap is the path until async-bootstrap support lands.
147
147
 
148
- ## MemoryStore vs SkillStore differences
148
+ ## DataStore vs SkillStore differences
149
149
 
150
150
  Both are substrate-agnostic, but they differ in shape:
151
151
 
152
- | Aspect | SkillStore | MemoryStore |
152
+ | Aspect | SkillStore | DataStore |
153
153
  |---|---|---|
154
154
  | Methods | 8 (load, query, metadata, versions, store, delete, update_status, manifest) | 3 (query, write, manifest) |
155
155
  | Versioning | First-class (`versions()`, `load(name, version)`) | Substrate-side (e.g., `supersededById` in AMP); not in contract |
@@ -158,12 +158,12 @@ Both are substrate-agnostic, but they differ in shape:
158
158
  | Curated-subset fields | None | Many (`domain_tags`, `pinned`, `confidence`, `recipients`, etc.) |
159
159
  | Forking complexity | Higher (multi-method state machine) | Lower (three methods, simpler semantics) |
160
160
 
161
- The narrower contract is why MemoryStoreTemplate ships sooner + smaller than SkillStoreTemplate.
161
+ The narrower contract is why DataStoreTemplate ships sooner + smaller than SkillStoreTemplate.
162
162
 
163
163
  ## Further reading
164
164
 
165
165
  - **[`../../../docs/configuration.md`](../../../docs/configuration.md)** — substrate selection via `connectors.json`
166
166
  - **[`../../../docs/adopter-playbook.md`](../../../docs/adopter-playbook.md)** — programmatic-bootstrap patterns; two-instance posture
167
- - **`src/connectors/types.ts`** — authoritative `MemoryStore` interface, `PortableMemory`, `QueryFilters`, `MemoryWrite` types
167
+ - **`src/connectors/types.ts`** — authoritative `DataStore` interface, `PortableData`, `QueryFilters`, `DataWrite` types
168
168
  - **`src/testing/conformance.ts`** — the per-contract conformance test suites
169
- - **`src/connectors/memory-store.ts`** — `SqliteMemoryStore` reference impl + schema
169
+ - **`src/connectors/data-store.ts`** — `SqliteDataStore` reference impl + schema
@@ -113,7 +113,7 @@ Adopters wire their custom LocalModel **programmatically** from their bootstrap:
113
113
  registry.registerLocalModel("default", new MyLocalModel({ /* config */ }));
114
114
  ```
115
115
 
116
- Declarative custom-LocalModel via `connectors.json` `substrate.local_model: {type: "custom", module, export, config}` form is **deferred** until async-bootstrap support lands. Same limitation applies to `SkillStore` and `MemoryStore` custom forms — sync `bootstrap()` can't `await import()`. Not LocalModel-specific.
116
+ Declarative custom-LocalModel via `connectors.json` `substrate.local_model: {type: "custom", module, export, config}` form is **deferred** until async-bootstrap support lands. Same limitation applies to `SkillStore` and `DataStore` custom forms — sync `bootstrap()` can't `await import()`. Not LocalModel-specific.
117
117
 
118
118
  ## Wiring against the dashboard / MCP
119
119
 
@@ -15,8 +15,8 @@
15
15
  * - `LocalModelMcpConnector` — bridges a registered LocalModel as
16
16
  * `$ llm prompt=...` MCP dispatch. Auto-wired when LocalModel substrate
17
17
  * is configured.
18
- * - `MemoryStoreMcpConnector` — bridges a registered MemoryStore as
19
- * `$ memory mode=...` MCP dispatch. Auto-wired when MemoryStore substrate
18
+ * - `DataStoreMcpConnector` — bridges a registered DataStore as
19
+ * `$ data_read mode=...` MCP dispatch. Auto-wired when DataStore substrate
20
20
  * is configured.
21
21
  *
22
22
  * Fork from this template when none of those fit — e.g.:
@@ -9,7 +9,7 @@ A skeleton `McpConnector` implementation for adopters writing their own. Not run
9
9
  | `RemoteMcpConnector` | Stdio bridging to remote MCP servers (`npx mcp-remote ...`). YouTrack, GitHub, Linear, most adopter MCP wiring goes through this. JSON-configurable via `connectors.json`. |
10
10
  | `CallbackMcpConnector` | Wraps a JS function. Test rigs + embedder-wired transports where the dispatch is local code. |
11
11
  | `LocalModelMcpConnector` | Bridges a registered `LocalModel` as `$ llm prompt=...`. Auto-wired when `substrate.local_model` is set. |
12
- | `MemoryStoreMcpConnector` | Bridges a registered `MemoryStore` as `$ memory mode=...`. Auto-wired when `substrate.memory_store` is set. |
12
+ | `DataStoreMcpConnector` | Bridges a registered `DataStore` as `$ data_read mode=...`. Auto-wired when `substrate.data_store` is set. |
13
13
 
14
14
  **Fork this template only when none of those fit** — e.g.:
15
15
 
@@ -72,7 +72,7 @@ The bundled impls are the canonical reference:
72
72
  - **`src/connectors/mcp-remote.ts`** — `RemoteMcpConnector`. Most comprehensive: stdio framing (LSP and newline), child process lifecycle (spawn → initialize → tools/list cache → SIGTERM/SIGKILL on dispose), `fromConfig` factory with strict validation, per-message timeout discipline. The closest reference for any transport that needs robust lifecycle management.
73
73
  - **`src/connectors/mcp.ts`** — `CallbackMcpConnector`. Minimal reference: 60 LOC. The closest reference for embedder-wired transports.
74
74
 
75
- When in doubt, read both + the bridge classes (`local-model-mcp.ts`, `memory-store-mcp.ts`) for how single-substrate bridges work.
75
+ When in doubt, read both + the bridge classes (`local-model-mcp.ts`, `data-store-mcp.ts`) for how single-substrate bridges work.
76
76
 
77
77
  ## Contract surface (2 methods)
78
78
 
@@ -131,15 +131,15 @@ Two registration paths:
131
131
 
132
132
  The declarative path is the canonical adopter pattern for stdio-bridged remote MCPs. Your fork is for transports the declarative path can't express.
133
133
 
134
- ## McpConnector vs. SkillStore / MemoryStore differences
134
+ ## McpConnector vs. SkillStore / DataStore differences
135
135
 
136
- | Aspect | McpConnector | SkillStore / MemoryStore |
136
+ | Aspect | McpConnector | SkillStore / DataStore |
137
137
  |---|---|---|
138
138
  | Methods | 2 (call, manifest) | 3-8 (more state machine) |
139
139
  | Cardinality | Many instances per deployment | One singleton per slot |
140
140
  | Substrate config | Per-instance via top-level keys | `substrate` section short/object/custom |
141
141
  | Class extensibility | `registerConnectorClass()` for adopter-custom classes | Programmatic bootstrap (or `substrate.skill_store: {type: "custom", ...}` once async-bootstrap lands) |
142
- | Auto-wired bridges | `llm` + `memory` + `memory_write` (LocalModel + MemoryStore exposed via bridge connectors) | n/a (these ARE the substrates being bridged) |
142
+ | Auto-wired bridges | `llm` + `memory` + `data_write` (LocalModel + DataStore exposed via bridge connectors) | n/a (these ARE the substrates being bridged) |
143
143
 
144
144
  McpConnector is fundamentally the "dispatch to external tools" surface — narrowest contract, broadest range of impls.
145
145
 
@@ -7,9 +7,9 @@ Worked examples + fork-me templates for adopter-written connectors. The bundled
7
7
  | Contract | Bundled defaults | Worked example | Fork template |
8
8
  |---|---|---|---|
9
9
  | `SkillStore` | `FilesystemSkillStore`, `SqliteSkillStore` (in `src/connectors/`) | — | **[SkillStoreTemplate/](./SkillStoreTemplate/)** |
10
- | `MemoryStore` | `SqliteMemoryStore` (in `src/connectors/`) | — | **[MemoryStoreTemplate/](./MemoryStoreTemplate/)** |
10
+ | `DataStore` | `SqliteDataStore` (in `src/connectors/`) | — | **[DataStoreTemplate/](./DataStoreTemplate/)** |
11
11
  | `LocalModel` | `OllamaLocalModel` (in `src/connectors/`; opt-in via substrate config) | — | **[LocalModelTemplate/](./LocalModelTemplate/)** |
12
- | `McpConnector` | `RemoteMcpConnector`, `CallbackMcpConnector`, `LocalModelMcpConnector`, `MemoryStoreMcpConnector` (in `src/connectors/`) | — | **[McpConnectorTemplate/](./McpConnectorTemplate/)** |
12
+ | `McpConnector` | `RemoteMcpConnector`, `CallbackMcpConnector`, `LocalModelMcpConnector`, `DataStoreMcpConnector` (in `src/connectors/`) | — | **[McpConnectorTemplate/](./McpConnectorTemplate/)** |
13
13
  | `AgentConnector` | `NoOpAgentConnector` (in `src/connectors/`) | **[HttpWebhookAgentConnector/](./HttpWebhookAgentConnector/)** | — |
14
14
 
15
15
  **Bundled defaults** are runnable out of the box — wired through `connectors.json` substrate config or programmatic bootstrap.
@@ -35,7 +35,7 @@ Worked examples + fork-me templates for adopter-written connectors. The bundled
35
35
  - **[`docs/configuration.md`](../../docs/configuration.md)** — substrate selection via `connectors.json`; programmatic-bootstrap vs declarative patterns
36
36
  - **[`docs/adopter-playbook.md`](../../docs/adopter-playbook.md)** — Case 1 vs Case 2 wiring decisions; two-instance posture; upstream-merge-friendly conventions
37
37
  - **[`docs/connector-contract-reference.md`](../../docs/connector-contract-reference.md)** — interface contracts for adopter agents writing connector impls
38
- - **`src/connectors/types.ts`** — authoritative contract interfaces (SkillStore, MemoryStore, LocalModel, McpConnector)
38
+ - **`src/connectors/types.ts`** — authoritative contract interfaces (SkillStore, DataStore, LocalModel, McpConnector)
39
39
  - **`src/testing/conformance.ts`** — the per-contract conformance test suites
40
40
 
41
41
  ## Naming convention
@@ -5,7 +5,7 @@ A skeleton `SkillStore` implementation for adopters writing their own. Not runna
5
5
  Use this when you want skillscript skills backed by:
6
6
  - A database the bundled impls don't cover (Postgres, MySQL, MongoDB, etc.)
7
7
  - A vector store (Pinecone, Weaviate, Qdrant)
8
- - A memory system (AMP, hosted memory API)
8
+ - A data store backing (memory broker like AMP, hosted memory API, vector DB, etc.)
9
9
  - An HTTP CRUD service
10
10
  - Anything else with a query/write interface
11
11
 
@@ -138,7 +138,7 @@ export class SkillStoreTemplate implements SkillStore {
138
138
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
139
139
  async versions(_name: string): Promise<VersionInfo[]> {
140
140
  // TODO — return version chain. SQL substrates: SELECT FROM skill_versions
141
- // ORDER BY changed_at. MemoryStore-style: query memories with the right tag.
141
+ // ORDER BY changed_at. DataStore-style: query memories with the right tag.
142
142
  throw new Error("TODO: versions() — return VersionInfo[] chronologically.");
143
143
  }
144
144
 
@@ -3,8 +3,8 @@
3
3
  //
4
4
  // **When to write your own bootstrap.** The bundled `bootstrap()` from
5
5
  // `skillscript-runtime` wires `FilesystemSkillStore` + `OllamaLocalModel` +
6
- // `SqliteMemoryStore` + the v0.7.2 bridges. If your deployment uses
7
- // different substrates (your own memory system, a hosted LLM API, an MCP
6
+ // `SqliteDataStore` + the v0.7.2 bridges. If your deployment uses
7
+ // different substrates (your own data store, a hosted LLM API, an MCP
8
8
  // server for agent delivery, etc.), write your own bootstrap rather than
9
9
  // modifying the bundled one. Prevents merge conflicts on every upstream
10
10
  // release that touches `src/bootstrap.ts`.
@@ -83,17 +83,17 @@ const registry = new Registry();
83
83
  const skillStore = new FilesystemSkillStore(config.skillsDir ?? `${HOME}/skills`);
84
84
  registry.registerSkillStore("primary", skillStore);
85
85
 
86
- // Wire your own LocalModel, MemoryStore, AgentConnector here. For typed-
86
+ // Wire your own LocalModel, DataStore, AgentConnector here. For typed-
87
87
  // contract impls, this is the "case 1" wiring — substrate-portable.
88
88
  // registry.registerLocalModel("default", new MyHostedLlmAdapter(...));
89
- // registry.registerMemoryStore("primary", new MyMemoryAdapter(...));
89
+ // registry.registerDataStore("primary", new MyMemoryAdapter(...));
90
90
  // registry.registerAgentConnector("primary", new MyAgentHarnessAdapter(...));
91
91
 
92
- // Then wire bridges if you want the canonical `$ llm` / `$ memory` surfaces:
93
- // import { LocalModelMcpConnector, MemoryStoreMcpConnector } from "skillscript-runtime";
92
+ // Then wire bridges if you want the canonical `$ llm` / `$ data_read` surfaces:
93
+ // import { LocalModelMcpConnector, DataStoreMcpConnector } from "skillscript-runtime";
94
94
  // registry.registerMcpConnector("llm", new LocalModelMcpConnector(registry.getLocalModel("default")));
95
- // const ms = registry.listMemoryStores().find((e) => e.name === "primary");
96
- // if (ms !== undefined) registry.registerMcpConnector("memory", new MemoryStoreMcpConnector(ms.instance));
95
+ // const ms = registry.listDataStores().find((e) => e.name === "primary");
96
+ // if (ms !== undefined) registry.registerMcpConnector("data_read", new DataStoreMcpConnector(ms.instance));
97
97
 
98
98
  // Wire any connectors.json instances.
99
99
  for (const c of connectors) {
@@ -6,11 +6,11 @@ A complete adopter-deployment example demonstrating substrate-portable wiring fo
6
6
 
7
7
  Skillscript's substrate-portability story is conditional: **typed-contract wiring (Case 1)** keeps skills portable across substrates; **MCP-tools wiring (Case 2)** locks skills to a specific substrate. This scaffold is Case 1 end-to-end.
8
8
 
9
- - **MemoryStore** → `FileMemoryStore` (JSON file with simple substring FTS)
9
+ - **DataStore** → `FileDataStore` (JSON file with simple substring FTS)
10
10
  - **LocalModel** → `OpenAILocalModel` (HTTP to Chat Completions API)
11
11
  - **AgentConnector** → `TmuxShellAgentConnector` (delivers to tmux sessions via `send-keys`)
12
12
 
13
- Each impl conforms to the typed contract from `skillscript-runtime/connectors`. Skills authored against this scaffold use the canonical `$ llm prompt=...` and `$ memory mode=fts query=...` surfaces — *the same calls would work against any other Case-1-wired substrate* (Pinecone, Ollama, Anthropic API, etc.).
13
+ Each impl conforms to the typed contract from `skillscript-runtime/connectors`. Skills authored against this scaffold use the canonical `$ llm prompt=...` and `$ data_read mode=fts query=...` surfaces — *the same calls would work against any other Case-1-wired substrate* (Pinecone, Ollama, Anthropic API, etc.).
14
14
 
15
15
  ## Quick start
16
16
 
@@ -44,7 +44,7 @@ node --loader ts-node/esm bootstrap.ts
44
44
 
45
45
  | File | Purpose | LOC |
46
46
  |---|---|---|
47
- | `file-memory-store.ts` | `MemoryStore` impl — JSON file substrate | ~95 |
47
+ | `file-data-store.ts` | `DataStore` impl — JSON file substrate | ~95 |
48
48
  | `openai-local-model.ts` | `LocalModel` impl — Chat Completions API | ~85 |
49
49
  | `tmux-shell-agent-connector.ts` | `AgentConnector` impl — tmux send-keys | ~75 |
50
50
  | `bootstrap.ts` | Wiring — Registry, bridges, scheduler, MCP server | ~75 |
@@ -53,7 +53,7 @@ node --loader ts-node/esm bootstrap.ts
53
53
 
54
54
  ## Two-instance posture
55
55
 
56
- To run this scaffold *alongside* an existing skillscript dev instance, just copy the scaffold to a separate directory with its own `skillscript.config.json` pointing at different `dashboard.port` + `skillsDir` + `memoryDbPath` etc. The `--config <path>` CLI flag selects which config to use; no two instances will collide on disk or port.
56
+ To run this scaffold *alongside* an existing skillscript dev instance, just copy the scaffold to a separate directory with its own `skillscript.config.json` pointing at different `dashboard.port` + `skillsDir` + `dataDbPath` etc. The `--config <path>` CLI flag selects which config to use; no two instances will collide on disk or port.
57
57
 
58
58
  ```bash
59
59
  # dev instance on default port
@@ -67,14 +67,14 @@ skillfile dashboard --config ./adopter.config.json # contains "dashboard": { "p
67
67
 
68
68
  For your real deployment, swap each adapter:
69
69
 
70
- - `FileMemoryStore` → your actual memory system (Pinecone, Postgres-pgvector, Obsidian-backed, your in-house store, etc.)
70
+ - `FileDataStore` → your actual data store (Pinecone, Postgres-pgvector, Obsidian-backed, in-house store, memory broker, etc.)
71
71
  - `OpenAILocalModel` → your actual LLM (Ollama via the bundled `OllamaLocalModel`, Anthropic via your own adapter, hosted-OpenAI as shown, etc.)
72
72
  - `TmuxShellAgentConnector` → your actual agent delivery (webhook POST, named-pipe write, your harness's API, etc.)
73
73
 
74
- The skill bodies don't need to change. `$ llm prompt=...` keeps working; `$ memory mode=fts query=...` keeps working. That's the substrate-portability claim, validated by you wiring different substrates against the same typed contracts.
74
+ The skill bodies don't need to change. `$ llm prompt=...` keeps working; `$ data_read mode=fts query=...` keeps working. That's the substrate-portability claim, validated by you wiring different substrates against the same typed contracts.
75
75
 
76
76
  ## Where to go next
77
77
 
78
78
  - **Adopter playbook** — `docs/adopter-playbook.md` walks through Case 1 vs Case 2 wiring patterns
79
79
  - **Custom bootstrap walkthrough** — `examples/custom-bootstrap.example.ts` shows registering custom McpConnector classes via `registerConnectorClass`
80
- - **v0.8.x roadmap** — `$ memory_write` ships in v0.8.x bundled with the auth model. When that lands, extend `FileMemoryStore` with the corresponding `write()` method.
80
+ - **v0.8.x roadmap** — `$ data_write` ships in v0.8.x bundled with the auth model. When that lands, extend `FileDataStore` with the corresponding `write()` method.
@@ -4,8 +4,8 @@
4
4
  // Copy this file into your deployment and modify substrate choices to
5
5
  // match your environment. The shape is:
6
6
  // 1. Construct a Registry
7
- // 2. Register your substrate impls (SkillStore + LocalModel + MemoryStore + AgentConnector)
8
- // 3. Wire bridges so canonical `$ llm` / `$ memory` dispatch works
7
+ // 2. Register your substrate impls (SkillStore + LocalModel + DataStore + AgentConnector)
8
+ // 3. Wire bridges so canonical `$ llm` / `$ data_read` dispatch works
9
9
  // 4. Load connectors.json + skillscript.config.json
10
10
  // 5. Wire scheduler + MCP server
11
11
  // 6. Start
@@ -20,15 +20,15 @@ import {
20
20
  import { Scheduler } from "skillscript-runtime/scheduler";
21
21
  import { FilesystemTraceStore } from "skillscript-runtime/trace";
22
22
  import { McpServer } from "skillscript-runtime/mcp-server";
23
- // Note: LocalModelMcpConnector + MemoryStoreMcpConnector are bridge classes
23
+ // Note: LocalModelMcpConnector + DataStoreMcpConnector are bridge classes
24
24
  // already exported from skillscript-runtime/connectors. They wrap any
25
25
  // typed-contract impl as an MCP-dispatchable connector.
26
26
  import {
27
27
  LocalModelMcpConnector,
28
- MemoryStoreMcpConnector,
28
+ DataStoreMcpConnector,
29
29
  } from "skillscript-runtime/connectors";
30
30
 
31
- import { FileMemoryStore } from "./file-memory-store.js";
31
+ import { FileDataStore } from "./file-data-store.js";
32
32
  import { OpenAILocalModel } from "./openai-local-model.js";
33
33
  import { TmuxShellAgentConnector } from "./tmux-shell-agent-connector.js";
34
34
 
@@ -44,10 +44,10 @@ const skillStore = new FilesystemSkillStore(config.skillsDir ?? `${HOME}/skills`
44
44
  registry.registerSkillStore("primary", skillStore);
45
45
 
46
46
  // File-backed memory at $SKILLSCRIPT_HOME/memory.json
47
- const memoryStore = new FileMemoryStore({
48
- filePath: config.memoryDbPath ?? `${HOME}/memory.json`,
47
+ const dataStore = new FileDataStore({
48
+ filePath: config.dataDbPath ?? `${HOME}/memory.json`,
49
49
  });
50
- registry.registerMemoryStore("primary", memoryStore);
50
+ registry.registerDataStore("primary", dataStore);
51
51
 
52
52
  // OpenAI LLM — reads OPENAI_API_KEY from env.
53
53
  const openai = new OpenAILocalModel({ defaultModel: "gpt-4o-mini" });
@@ -63,10 +63,10 @@ const agentConnector = new TmuxShellAgentConnector({
63
63
  });
64
64
  registry.registerAgentConnector("primary", agentConnector);
65
65
 
66
- // Step 3: wire bridges so `$ llm` / `$ memory` dispatch through the
66
+ // Step 3: wire bridges so `$ llm` / `$ data_read` dispatch through the
67
67
  // adopter substrates above (case 1 typed-contract wiring — portable).
68
68
  registry.registerMcpConnector("llm", new LocalModelMcpConnector(openai));
69
- registry.registerMcpConnector("memory", new MemoryStoreMcpConnector(memoryStore));
69
+ registry.registerMcpConnector("data_read", new DataStoreMcpConnector(dataStore));
70
70
 
71
71
  // Step 4: wire connectors.json instances (adopter-defined MCP servers).
72
72
  for (const c of connectors) {
@@ -1,40 +1,40 @@
1
- // Onboarding scaffold: file-backed MemoryStore. v0.7.3.
1
+ // Onboarding scaffold: file-backed DataStore. v0.7.3.
2
2
  //
3
3
  // JSON file as the substrate; simple JS substring + token match for "fts"
4
4
  // queries; reranks by recency. Adopters copy this file and modify for
5
5
  // their concrete substrate (e.g., swap the JSON file for a Postgres
6
6
  // table, the substring match for actual full-text search, etc.).
7
7
  //
8
- // **Scope.** Read-only `query()` per the v0.7.2 MemoryStore contract.
8
+ // **Scope.** Read-only `query()` per the v0.7.2 DataStore contract.
9
9
  // `write()` is deferred to v0.8.x bundled with the auth model — when
10
10
  // that lands, extend this file with the matching `write()` method.
11
11
 
12
12
  import { readFileSync, existsSync, writeFileSync } from "node:fs";
13
13
  import { randomUUID } from "node:crypto";
14
14
  import type {
15
- MemoryStore,
16
- MemoryWrite,
17
- MemoryWriteRecord,
18
- PortableMemory,
15
+ DataStore,
16
+ DataWrite,
17
+ DataWriteRecord,
18
+ PortableData,
19
19
  QueryFilters,
20
20
  ManifestInfo,
21
21
  StaticCapabilities,
22
22
  } from "skillscript-runtime/connectors";
23
23
 
24
- export interface FileMemoryStoreConfig {
24
+ export interface FileDataStoreConfig {
25
25
  /** Absolute path to the JSON file holding the memory array. */
26
26
  filePath: string;
27
27
  }
28
28
 
29
- interface FileMemoryRecord extends PortableMemory {
30
- /** Optional substrate-specific fields go in `metadata`; everything top-level matches PortableMemory. */
29
+ interface FileMemoryRecord extends PortableData {
30
+ /** Optional substrate-specific fields go in `metadata`; everything top-level matches PortableData. */
31
31
  }
32
32
 
33
- export class FileMemoryStore implements MemoryStore {
33
+ export class FileDataStore implements DataStore {
34
34
  static staticCapabilities(): StaticCapabilities {
35
35
  return {
36
- connector_type: "memory_store",
37
- implementation: "FileMemoryStore",
36
+ connector_type: "data_store",
37
+ implementation: "FileDataStore",
38
38
  contract_version: "1.0.0",
39
39
  features: {
40
40
  supports_fts: true,
@@ -44,9 +44,9 @@ export class FileMemoryStore implements MemoryStore {
44
44
  };
45
45
  }
46
46
 
47
- constructor(private readonly config: FileMemoryStoreConfig) {}
47
+ constructor(private readonly config: FileDataStoreConfig) {}
48
48
 
49
- async query(filters: QueryFilters): Promise<PortableMemory[]> {
49
+ async query(filters: QueryFilters): Promise<PortableData[]> {
50
50
  const records = this.loadFile();
51
51
  const queryTerms = filters.query.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
52
52
 
@@ -71,7 +71,7 @@ export class FileMemoryStore implements MemoryStore {
71
71
  return scored.slice(0, filters.limit).map((s) => s.record);
72
72
  }
73
73
 
74
- async write(entry: MemoryWrite): Promise<MemoryWriteRecord> {
74
+ async write(entry: DataWrite): Promise<DataWriteRecord> {
75
75
  const records = this.loadFile();
76
76
  const id = randomUUID();
77
77
  const created_at = Math.floor(Date.now() / 1000);
@@ -102,7 +102,7 @@ export class FileMemoryStore implements MemoryStore {
102
102
  return {
103
103
  capabilities_version: "1",
104
104
  manifest: {
105
- kind: "file-memory-store",
105
+ kind: "file-data-store",
106
106
  file_path: this.config.filePath,
107
107
  record_count: this.loadFile().length,
108
108
  supports_write: true,
@@ -116,11 +116,11 @@ export class FileMemoryStore implements MemoryStore {
116
116
  const raw = readFileSync(this.config.filePath, "utf8");
117
117
  const parsed: unknown = JSON.parse(raw);
118
118
  if (!Array.isArray(parsed)) {
119
- throw new Error(`FileMemoryStore: '${this.config.filePath}' top-level must be an array of memory records.`);
119
+ throw new Error(`FileDataStore: '${this.config.filePath}' top-level must be an array of memory records.`);
120
120
  }
121
121
  return parsed as FileMemoryRecord[];
122
122
  } catch (err) {
123
- throw new Error(`FileMemoryStore: failed to read '${this.config.filePath}': ${(err as Error).message}`);
123
+ throw new Error(`FileDataStore: failed to read '${this.config.filePath}': ${(err as Error).message}`);
124
124
  }
125
125
  }
126
126
  }
@@ -15,16 +15,16 @@ route:
15
15
  needs: severity_check
16
16
  if ${CATEGORY|trim} == "sev-1":
17
17
  emit(text="PAGE: sev-1 ticket ${TICKET_ID} - ${TICKET_TEXT}")
18
- $ memorystore.write summary="sev-1 ticket ${TICKET_ID}" detail="${TICKET_TEXT}" knowledge_type=hard_won vault=private domain_tags=["support","sev-1","page"]
18
+ $ datastore.write summary="sev-1 ticket ${TICKET_ID}" detail="${TICKET_TEXT}" knowledge_type=hard_won vault=private domain_tags=["support","sev-1","page"]
19
19
  elif ${IS_SEV1|trim} == "yes":
20
20
  emit(text="PAGE: classifier said ${CATEGORY|trim} but severity-check flagged this as sev-1: ${TICKET_ID}")
21
- $ memorystore.write summary="sev-1 escalation ${TICKET_ID}" detail="category=${CATEGORY|trim} but severity-check=yes" knowledge_type=hard_won vault=private domain_tags=["support","sev-1","disagreement"]
21
+ $ datastore.write summary="sev-1 escalation ${TICKET_ID}" detail="category=${CATEGORY|trim} but severity-check=yes" knowledge_type=hard_won vault=private domain_tags=["support","sev-1","disagreement"]
22
22
  elif ${CATEGORY|trim} == "billing":
23
23
  $set TAG_FOR = "finance"
24
24
  emit(text="Tagged for ${TAG_FOR} review: ${TICKET_ID}")
25
- $ memorystore.write summary="billing ticket ${TICKET_ID}" detail="${TICKET_TEXT}" knowledge_type=common vault=private domain_tags=["support","billing"]
25
+ $ datastore.write summary="billing ticket ${TICKET_ID}" detail="${TICKET_TEXT}" knowledge_type=common vault=private domain_tags=["support","billing"]
26
26
  else:
27
27
  $ llm prompt="Draft a polite acknowledgment reply for this support ticket. Two short sentences. No greeting, no sign-off.\n\n${TICKET_TEXT}" model=qwen maxTokens=150 -> DRAFT
28
- $ memorystore.write summary="support draft ${TICKET_ID}" detail="${DRAFT|trim}" knowledge_type=common vault=private domain_tags=["support","draft"]
28
+ $ datastore.write summary="support draft ${TICKET_ID}" detail="${DRAFT|trim}" knowledge_type=common vault=private domain_tags=["support","draft"]
29
29
 
30
30
  default: route
@@ -5,7 +5,7 @@
5
5
  # Output: text
6
6
 
7
7
  answer:
8
- $ memory mode=rerank query="${QUESTION}" limit=${K} -> HITS (fallback: [])
8
+ $ data_read mode=rerank query="${QUESTION}" limit=${K} -> HITS (fallback: [])
9
9
  $ llm prompt="Answer the question using ONLY the supplied passages. Cite each claim inline as [id:<memory-id>]. Question: ${QUESTION}. Passages: ${HITS|json}" maxTokens=900 -> RESPONSE
10
10
  emit(text="${RESPONSE}")
11
11
 
@@ -6,10 +6,10 @@
6
6
  # Output: agent: support-lead
7
7
 
8
8
  fetch_new:
9
- $ memory mode=fts query="customer feedback" limit=${SCAN_LIMIT} created_after=${EVENT.fired_at_unix} -> FEEDBACK
9
+ $ data_read mode=fts query="customer feedback" limit=${SCAN_LIMIT} created_after=${EVENT.fired_at_unix} -> FEEDBACK
10
10
 
11
11
  fetch_seen:
12
- $ memory mode=fts query="sentiment-scan seen marker" limit=200 domain_tags=["sentiment-scan-seen"] -> SEEN_MARKERS
12
+ $ data_read mode=fts query="sentiment-scan seen marker" limit=200 domain_tags=["sentiment-scan-seen"] -> SEEN_MARKERS
13
13
 
14
14
  classify_and_emit:
15
15
  needs: fetch_new, fetch_seen
@@ -23,6 +23,6 @@ classify_and_emit:
23
23
  emit(text="- FRUSTRATED [${F.id|trim}] ${F.summary}")
24
24
  elif ${VERDICT|trim} == "blocking":
25
25
  emit(text="- BLOCKING [${F.id|trim}] ${F.summary}")
26
- $ memorystore.write summary="sentiment-scan seen ${F.id|trim}" detail="verdict=${VERDICT|trim} on ${EVENT.fired_at_unix}" knowledge_type=common vault=private domain_tags=["sentiment-scan-seen"] expires_at=${EVENT.fired_at_plus_7d_unix}
26
+ $ datastore.write summary="sentiment-scan seen ${F.id|trim}" detail="verdict=${VERDICT|trim} on ${EVENT.fired_at_unix}" knowledge_type=common vault=private domain_tags=["sentiment-scan-seen"] expires_at=${EVENT.fired_at_plus_7d_unix}
27
27
 
28
28
  default: classify_and_emit
@@ -2,7 +2,7 @@
2
2
  "provenance_version": "1.0",
3
3
  "language_version": "1.0",
4
4
  "compiler_version": "0.1.0-dev",
5
- "compiled_at": "2026-05-29T21:43:48.999Z",
5
+ "compiled_at": "2026-05-30T14:28:14.260Z",
6
6
  "source_skill": {
7
7
  "name": "hello"
8
8
  },
@@ -1,6 +1,6 @@
1
1
  # Skill: morning-brief
2
2
  # Status: Approved v1:037c18af
3
- # Description: Compose a daily morning brief from calendar, mailbox, and overnight memory writes when the cron trigger fires at 7am. Delivers via the agent: lifecycle hook to the receiving agent, who decides whether to surface to Slack / Discord / etc.
3
+ # Description: Compose a daily morning brief from calendar, mailbox, and overnight data writes when the cron trigger fires at 7am. Delivers via the agent: lifecycle hook to the receiving agent, who decides whether to surface to Slack / Discord / etc.
4
4
  # Vars: AGENT, BRIEF_HORIZON_HOURS=24
5
5
  # Triggers: cron: 0 7 * * *
6
6
  # OnError: morning-brief-degraded
@@ -10,10 +10,10 @@ calendar:
10
10
  $ calendar.list_events horizon_hours=${BRIEF_HORIZON_HOURS} -> EVENTS
11
11
 
12
12
  mailbox:
13
- $ memory mode=fts query="addressed:${AGENT} created_after:${EVENT.fired_at_unix}" limit=10 -> MAIL
13
+ $ data_read mode=fts query="addressed:${AGENT} created_after:${EVENT.fired_at_unix}" limit=10 -> MAIL
14
14
 
15
15
  overnight:
16
- $ memory mode=rerank query="overnight writes since:${EVENT.fired_at_plus_1d_unix}" limit=15 -> NOTES
16
+ $ data_read mode=rerank query="overnight writes since:${EVENT.fired_at_plus_1d_unix}" limit=15 -> NOTES
17
17
 
18
18
  compose: needs: calendar, mailbox, overnight
19
19
  $ llm prompt="Compose a concise morning brief. Calendar: ${EVENTS|json}. Mailbox: ${MAIL|json}. Overnight notes: ${NOTES|json}. Three sections, six bullets max each." model=qwen maxTokens=1200 -> BRIEF
@@ -10,7 +10,7 @@ probe:
10
10
  shell(command="curl -s -o /dev/null -w \"%{http_code} %{time_total}\" https://status.internal/${SVC|url}") -> RAW
11
11
  $ llm prompt="From the line '${RAW|trim}' (http_code time_seconds), and budget ${LATENCY_BUDGET_MS} ms, answer ok or degraded only." -> STATUS
12
12
  if ${STATUS|trim} == "degraded":
13
- $ memorystore.write summary="service degradation: ${SVC}" detail="probe at ${NOW}: ${RAW|trim}" domain_tags=[ops, service-health, degraded:${SVC}] vault=private knowledge_type=common expires_at=${EVENT.fired_at_plus_1d_unix} -> ACK
13
+ $ datastore.write summary="service degradation: ${SVC}" detail="probe at ${NOW}: ${RAW|trim}" domain_tags=[ops, service-health, degraded:${SVC}] vault=private knowledge_type=common expires_at=${EVENT.fired_at_plus_1d_unix} -> ACK
14
14
  emit(text="${SVC} degraded — wrote signal")
15
15
  else:
16
16
  emit(text="${SVC} ok")