@deepstrike/sdk 0.2.50 → 0.2.51

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 (39) hide show
  1. package/README.md +83 -60
  2. package/dist/index.d.ts +5 -7
  3. package/dist/index.js +3 -3
  4. package/dist/kernel.d.ts +61 -31
  5. package/dist/runtime/canonical-kernel-step.d.ts +143 -0
  6. package/dist/runtime/canonical-kernel-step.js +1444 -0
  7. package/dist/runtime/execution-plane.d.ts +0 -3
  8. package/dist/runtime/execution-plane.js +0 -24
  9. package/dist/runtime/facade.js +3 -0
  10. package/dist/runtime/kernel-event-log.js +7 -13
  11. package/dist/runtime/kernel-journal.d.ts +264 -0
  12. package/dist/runtime/kernel-journal.js +741 -0
  13. package/dist/runtime/kernel-primitives-dashboard.d.ts +0 -2
  14. package/dist/runtime/kernel-primitives-dashboard.js +1 -8
  15. package/dist/runtime/kernel-step.d.ts +29 -109
  16. package/dist/runtime/kernel-step.js +47 -317
  17. package/dist/runtime/os-snapshot.d.ts +2 -2
  18. package/dist/runtime/os-snapshot.js +2 -6
  19. package/dist/runtime/payload-store.d.ts +16 -0
  20. package/dist/runtime/payload-store.js +80 -0
  21. package/dist/runtime/runner.d.ts +31 -114
  22. package/dist/runtime/runner.js +689 -774
  23. package/dist/runtime/session-log.d.ts +34 -32
  24. package/dist/runtime/session-log.js +21 -131
  25. package/dist/runtime/session-repair.d.ts +2 -36
  26. package/dist/runtime/session-repair.js +2 -47
  27. package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
  28. package/dist/runtime/sub-agent-orchestrator.js +42 -40
  29. package/dist/types/agent.d.ts +22 -19
  30. package/dist/types/agent.js +26 -42
  31. package/dist/workflow/public.d.ts +1 -1
  32. package/dist/workflow/public.js +1 -1
  33. package/package.json +2 -2
  34. package/dist/runtime/kernel-rebuild.d.ts +0 -13
  35. package/dist/runtime/kernel-rebuild.js +0 -75
  36. package/dist/runtime/kernel-transaction-log.d.ts +0 -61
  37. package/dist/runtime/kernel-transaction-log.js +0 -149
  38. package/dist/runtime/large-result-spool.d.ts +0 -93
  39. package/dist/runtime/large-result-spool.js +0 -214
package/README.md CHANGED
@@ -82,7 +82,7 @@ const reply = await collectText(runner.run({ sessionId: "chat-1", goal: "What is
82
82
 
83
83
  Use `InMemorySessionLog` for process-local sessions or `FileSessionLog` when replay should survive restarts. `wake(sessionId)` resumes from the event log without inserting a duplicate `run_started` event.
84
84
 
85
- ### Package layout (v0.2.30)
85
+ ### Package layout (v0.2.50)
86
86
 
87
87
  The root export is the **intent layer** — what you reach for to run an agent, run a workflow, author a tool, or pick a provider (~30 symbols). Advanced machinery lives behind subpaths, so the common surface stays small and tree-shakeable:
88
88
 
@@ -96,7 +96,7 @@ The root export is the **intent layer** — what you reach for to run an agent,
96
96
  | `@deepstrike/sdk/harness` | `AttemptLoop`, body/judge/carry policies, `judge` |
97
97
  | `@deepstrike/sdk/os` | profiles, `KernelPrimitivesDashboard`, `primitiveForKind` / `KernelPrimitive`, signals, `PermissionManager`, replay-testing utilities |
98
98
 
99
- > **Migration from 0.2.x:** the kernel-lowering converters (`*ToKernel`), low-level prompt/eval builders, and the `OpenAIChatProvider` alias are no longer exported from root; backend providers, planes, memory, harness, and OS utilities moved to the subpaths above. See [`MIGRATION-v0.2.300.md`](./MIGRATION-v0.2.300.md).
99
+ > **Migration from 0.2.x:** the kernel-lowering converters (`*ToKernel`), low-level prompt/eval builders, and the `OpenAIChatProvider` alias are no longer exported from root; backend providers, planes, memory, harness, and OS utilities moved to the subpaths above. See [`MIGRATION-v0.2.30.md`](./MIGRATION-v0.2.30.md).
100
100
 
101
101
  ### Recipes — the canonical entry points
102
102
 
@@ -163,19 +163,19 @@ for await (const event of runner.run({ sessionId: "readme-1", goal: "Summarize R
163
163
  │ RuntimeRunner (Layer 1.5) │
164
164
  │ LLMProvider · ExecutionPlane · SessionLog · DreamStore │
165
165
  └───────────────────────────┬─────────────────────────────┘
166
- step(JSON event) actions / observations
166
+ durable prepare / append / commit
167
167
  ┌───────────────────────────▼─────────────────────────────┐
168
- │ @deepstrike/core KernelRuntime
168
+ │ @deepstrike/core Canonical Kernel ABI
169
169
  │ P1 Syscall · P2 Sched · P3 MM · Proc · IPC │
170
170
  └─────────────────────────────────────────────────────────┘
171
171
  ```
172
172
 
173
- The runner drives a single loop:
173
+ The runner drives one durable operation loop:
174
174
 
175
- 1. Kernel returns an **action** `call_provider`, `execute_tool`, `evaluate_milestone`, or `done`.
176
- 2. SDK executes the action (stream LLM, run tools, call milestone verifier).
177
- 3. SDK feeds the result back as a kernel **event** (`provider_result`, `tool_results`, …).
178
- 4. Kernel **observations** (compression, page-out, spool, signals, …) are drained into `SessionLog`.
175
+ 1. The host prepares one canonical envelope and durably appends the exact core-produced record.
176
+ 2. After commit, the kernel publishes typed **effects** such as provider, tool, or task work.
177
+ 3. The SDK executes those effects and returns each outcome through the single `resolve_effect` input.
178
+ 4. Typed observations and the terminal disposition are projected into `SessionLog` and the public stream.
179
179
 
180
180
  Kernel session events carry an optional `category` tag (`syscall` · `sched` · `mm` · `proc` · `ipc`) for diagnostics and OS snapshot rebuilds.
181
181
 
@@ -186,26 +186,26 @@ The mechanisms above are not internal refactors — they change what you can bui
186
186
  **Kernel-mediated runtime (M0–M4)**
187
187
  Tool calls, spawns, compression, and signals pass through one kernel gate with an explicit lifecycle (Ready / Running / Blocked / Suspended). You implement I/O; the kernel decides *when* and *whether*. Node, Python, and Rust share the same decision path, so `wake(sessionId)` and cross-language tooling see consistent behavior.
188
188
 
189
- **Longer, sturdier sessions (Layer-1 spool + semantic page-out)**
190
- Oversized tool results (> 50 KB) stay in context as a preview plus a `.spool/` reference the model reads the full payload on demand via ordinary file tools. When pressure triggers semantic eviction, the SDK summarizes archived content into `DreamStore`. Long tasks survive token pressure instead of failing mid-run.
189
+ **Longer, sturdier sessions (external payloads + semantic page-out)**
190
+ The host atomically persists oversized tool results before submitting an `External` result. Core journals only the opaque locator, digest, size, and preview; `read_result` becomes a correlated `LoadPayload` effect. When pressure triggers semantic eviction, the SDK summarizes archived content into `DreamStore`.
191
191
 
192
192
  **Safety and governance by default (OS native profile)**
193
193
  Every run loads declarative `governancePolicy` (deny / ask_user / rate-limit / param rules) and in-kernel signal routing (`signalPolicy`, default queue 64). Dangerous tools, external interrupts, and approval flows are policy — not ad-hoc `if` checks in your handlers.
194
194
 
195
195
  **Long-term memory as syscalls (Phase-7)**
196
- `writeMemory` and `queryMemory` run outside the main tool loop: kernel validation before `DreamStore.commit`, search `selectMemories` `memory_retrieval_result` on query. Failed writes emit `memory_validation_failed` for audit; good memory is durable without polluting history.
196
+ `writeMemory` and `queryMemory` run outside the main tool loop: kernel validation happens before `DreamStore.upsert`, while queries call `DreamStore.search` and journal `memory_retrieval_result`. Failed writes emit `memory_validation_failed` for audit; good memory is durable without polluting history.
197
197
 
198
198
  **Multi-agent and multi-signal orchestration**
199
199
  Sub-agents register in the kernel process table (`agent_process_changed`); parent runs suspend explicitly until `sub_agent_completed`. Signals get disposition (Interrupt / Queue / Observe / Dropped) in-kernel, so gateways, cron, and heartbeats compose with the main loop instead of racing it.
200
200
 
201
201
  **Observable like an OS log**
202
- Spool, page-out, signals, processes, budgets, and memory events land in `SessionLog` with categories. Rebuild an OS snapshot (`pageOutCount`, `spoolCount`, `processByAgent`, memory counters) from one event stream replay still strips audit events when reconstructing LLM messages.
202
+ Page-out, signals, processes, budgets, and memory events land in `SessionLog` with categories. Rebuild an OS snapshot (`pageOutCount`, `processByAgent`, memory counters) from one event stream; payload residency stays in the canonical journal.
203
203
 
204
204
  | You need… | Use… |
205
205
  |---|---|
206
206
  | Policy before tools run | `governancePolicy` (default: allow-all native profile) |
207
207
  | External interrupts | `signalSource` + in-kernel `signalPolicy` |
208
- | Huge tool output | Automatic Layer-1 spool; optional custom `resultSpool` |
208
+ | Huge tool output | Canonical external payload; optional custom `payloadStore` |
209
209
  | Durable recall across runs | `DreamStore` + semantic `page_out` via `dreamSummarizer` |
210
210
  | Programmatic memory I/O | `runner.writeMemory()` / `runner.queryMemory()` |
211
211
  | Debug / compliance | `SessionLog` events + OS snapshot helpers |
@@ -228,27 +228,56 @@ const outcome = await runner.runWorkflow({
228
228
  { task: "Skeptic: which flags are real violations?", role: "verify", dependsOn: [0, 1, 2] },
229
229
  ],
230
230
  })
231
- // → { completed: ["wf-node0", ], failed: [], outputs: { "wf-node3": "…" } }
231
+ const completed = outcome.nodeOutcomes.filter(node => node.status === "completed")
232
+ const partial = outcome.nodeOutcomes.filter(node => node.status === "completed_partial")
233
+ const failed = outcome.nodeOutcomes.filter(node => node.status === "failed")
234
+ // outcome.outputs["wf-node3"] contains the skeptic's final text.
235
+ // outcome.rejection is present only when the whole workflow was rejected before any node ran.
232
236
  ```
233
237
 
234
- `runWorkflow` works **standalone** — call it on a freshly-constructed runner (e.g. inside a stateless HTTP handler) and it auto-bootstraps a kernel that owns the DAG, drives it under the same governance/quota/attention policies a full `run()` gets, and tears it down on completion. Called *during* a `run()`, it instead drives the workflow on the active kernel. Either way every node's final text comes back in `outputs`, keyed by node agent-id. To resume an interrupted standalone run, pass the prior session id: `runner.resumeWorkflow(spec, { sessionId })`.
238
+ `runWorkflow` works **standalone** — call it on a freshly-constructed runner (e.g. inside a stateless HTTP handler) and it auto-bootstraps a kernel that owns the DAG, drives it under the same governance/quota/attention policies a full `run()` gets, and tears it down on completion. Called *during* a `run()`, it instead drives the workflow on the active kernel. Either way every node's final text comes back in `outputs`, keyed by node agent-id.
235
239
 
236
- A node's `kind` selects the control-flow shape; the same executor drives them all, every spawn passing the syscall gate:
240
+ A workflow node has no public `kind` field. Its control-flow shape is selected by one of four
241
+ mutually exclusive fields; omit all four for a normal spawn. The same executor drives every shape,
242
+ and every spawn passes the syscall gate:
237
243
 
238
- | Node `kind` | Behavior |
244
+ | Public `WorkflowNodeSpec` field | Behavior |
239
245
  |---|---|
240
- | `{ type: "spawn" }` (default) | Run the node's agent once |
241
- | `{ type: "loop", maxIters }` | Re-run until the agent signals it's done, capped at `maxIters` |
242
- | `{ type: "classify", branches }` | The classifier's result selects one branch; the rest are pruned |
243
- | `{ type: "tournament", entrants }` | Generate N entrants, then a pairwise-judge bracket to one winner |
244
- | `{ type: "reduce", reducer }` | **Tokenless host-compute** — a pure function (`dedupe_lines` / `merge_json_arrays` / `concat` / `count`, or your own via the `reducers` runner option) over the node's dependency outputs |
246
+ | none (default) | Run the node's agent once |
247
+ | `loop: { maxIters }` | Re-run until the agent signals it's done, capped at `maxIters` |
248
+ | `classify: { branches }` | The classifier's result selects one branch; the rest are pruned |
249
+ | `tournament: { entrants }` | Generate N entrants, then a pairwise-judge bracket to one winner |
250
+ | `reducer: "concat"` | **Tokenless host-compute** — a pure function (`dedupe_lines` / `merge_json_arrays` / `concat` / `count`, or your own via the `reducers` runner option) over the node's `dependsOn` outputs |
245
251
 
246
- ### 0.2.11 capabilities
252
+ Dependencies use `dependsOn: number[]`, where each number is a node index, and `depPolicy` controls
253
+ how upstream terminal states gate the node (`all_success` by default, plus `accept_partial`,
254
+ `all_terminal`, and `optional`).
247
255
 
248
- - **Runtime fan-out** — give a node the `submitWorkflowNodesTool` and its agent can append nodes to the live DAG mid-run (true loop-until-done; one verifier per claim it discovers). Recorded and replayed on `resumeWorkflow`. Governance rejection fails the submitting node instead of acknowledging work that was never appended.
256
+ ### Workflow capabilities (v0.2.50)
257
+
258
+ - **Runtime fan-out** — register `submitWorkflowNodesTool` on the parent execution plane and a trusted node can append nodes to the live DAG mid-run (true loop-until-done; one verifier per discovered claim). The tool schema is exported from `@deepstrike/sdk/workflow`, not the package root. Submission events remain audit projections; checkpoint state owns recovery. Governance rejection fails the submitting node instead of acknowledging work that was never appended.
249
259
  - **Quarantine, no escape** — set `trust: "quarantined"` on a node that reads untrusted content; it's denied write-capable isolation in-kernel, and any nodes it submits are coerced to quarantined too (no privilege escalation).
250
260
  - **Structured output** — set `outputSchema` on a node; the runner instructs the agent, validates the result against the JSON-Schema subset, and re-runs once with the errors on mismatch. A node that never conforms fails (its dependents starve).
251
- - **Budget as signal** — with a `maxWorkflowNodes` / `maxConcurrentSubagents` quota installed, each spawned node's goal carries its remaining headroom so a coordinator can size its fan-out to fit.
261
+ - **Budget as signal** — set `resourceQuota.maxWorkflowNodes` and/or `resourceQuota.maxConcurrentSubagents`; each spawned node's goal carries its remaining headroom so a coordinator can size its fan-out to fit.
262
+
263
+ `submitWorkflowNodesTool` is a `ToolSchema`, while execution planes register `RegisteredTool`
264
+ instances. Adapt it once on the parent plane; the runner intercepts the call before the placeholder
265
+ handler executes:
266
+
267
+ ```typescript
268
+ import { tool } from "@deepstrike/sdk"
269
+ import { submitWorkflowNodesTool } from "@deepstrike/sdk/workflow"
270
+
271
+ plane.register(tool(
272
+ submitWorkflowNodesTool.name,
273
+ submitWorkflowNodesTool.description,
274
+ JSON.parse(submitWorkflowNodesTool.parameters),
275
+ async () => "", // intercepted by RuntimeRunner
276
+ ))
277
+ ```
278
+
279
+ Trusted workflow nodes inherit the parent plane, so the tool is visible to all of them. There is no
280
+ per-node tool allowlist on `WorkflowNodeSpec`; quarantined nodes use a filtered, deny-all plane.
252
281
 
253
282
  ---
254
283
 
@@ -337,7 +366,7 @@ Full reference: [docs/concepts/context-slots-compression.md](../docs/concepts/co
337
366
  import {
338
367
  DEFAULT_NATIVE_GOVERNANCE_POLICY,
339
368
  DEFAULT_NATIVE_SIGNAL_POLICY,
340
- } from "@deepstrike/sdk"
369
+ } from "@deepstrike/sdk/os"
341
370
 
342
371
  const runner = new RuntimeRunner({
343
372
  provider,
@@ -359,14 +388,15 @@ const runner = new RuntimeRunner({
359
388
  // Resource quotas (M2) — enforced at the kernel syscall trap. Opt-in; omit for unbounded.
360
389
  resourceQuota: {
361
390
  maxConcurrentSubagents: 4, // deny spawn while at cap
391
+ maxTotalSubagents: 20, // cumulative cap across the RunGroup
362
392
  maxSpawnDepth: 2, // deny spawn past nesting depth
393
+ maxWorkflowNodes: 32, // cap one live DAG, including submitted nodes
363
394
  memoryWritesPerWindow: { maxWrites: 20, windowMs: 60_000 }, // rate-limit writeMemory
364
395
  },
365
396
 
366
- // Long-term memory policy (set_memory_policy) — opt-in, kernel-enforced; omit for defaults.
397
+ // Canonical long-term memory policy — opt-in, kernel-enforced; omit for defaults.
367
398
  memoryPolicy: {
368
- memoryPath: "./.memory", // where the SDK persists/scans memories (SDK-consumed)
369
- staleWarningDays: 30, // flag recalled memories older than this (SDK-consumed)
399
+ staleWarningDays: 30, // flag recalled memories older than this
370
400
  retrievalTopK: 5, // kernel caps query_memory requested_k to this
371
401
  validationEnabled: true, // false → admit writes without validation
372
402
  maxContentBytes: 10_000, // override write_memory content-size limit
@@ -414,13 +444,14 @@ const runner = new RuntimeRunner({
414
444
 
415
445
  | Option | Purpose |
416
446
  |--------|---------|
417
- | `governancePolicy` | Declarative deny / ask_user / rate-limit / param rules loaded into the kernel before `start_run` |
447
+ | `governancePolicy` | Declarative deny / ask_user / rate-limit / param rules installed before canonical root start |
418
448
  | `signalPolicy` | Versioned in-kernel signal queue/TTL policy (default queue 64) |
419
449
  | `promptBudget` | Provider-envelope overhead, output reserve, and safety margin deducted from the context window |
420
- | `resourceQuota` | M2 declarative limits — `maxConcurrentSubagents` / `maxSpawnDepth` / `memoryWritesPerWindow` — enforced at the kernel syscall trap (`set_resource_quota`); over-quota spawns roll back, over-rate writes surface as `memory_validation_failed` |
421
- | `memoryPolicy` | Long-term memory config sent as `set_memory_policy` and **kernel-enforced**: `validationEnabled: false` admits writes without validation, `maxContentBytes` / `maxNameLength` override validation limits, `retrievalTopK` caps `query_memory` breadth; `memoryPath` / `staleWarningDays` are SDK-consumed (requires `dreamStore` + `agentId` to enable memory) |
450
+ | `resourceQuota` | M2 declarative limits — `maxConcurrentSubagents` / `maxTotalSubagents` / `maxSpawnDepth` / `maxWorkflowNodes` / `memoryWritesPerWindow` — enforced at the kernel syscall trap (`set_resource_quota`); over-quota spawns roll back, over-rate writes surface as `memory_validation_failed` |
451
+ | `memoryPolicy` | Canonical long-term memory policy: `validationEnabled: false` admits writes without validation, `maxContentBytes` / `maxNameLength` override validation limits, `retrievalTopK` caps `query_memory` breadth, and `staleWarningDays` controls stale recall policy. Storage belongs to the configured `dreamStore`. |
422
452
  | `onPermissionRequest` | Resolves `tool_gated` + `suspended` → kernel `resume` with approved/denied call IDs |
423
453
  | `compressionStore` | Writes archived messages on `compressed` observations |
454
+ | `payloadStore` | Resolves canonical opaque payload locators (default: `.payloads/`) |
424
455
  | `asyncSummarizer` | Background LLM summary after compression; stored as `summary_upgraded` |
425
456
  | `dreamSummarizer` | Summarizes `page_out { tier_hint: "semantic" }` into `DreamStore` during a run |
426
457
  | `dreamProvider` | Separate LLM for `dream()` idle consolidation (falls back to `provider`) |
@@ -428,37 +459,33 @@ const runner = new RuntimeRunner({
428
459
  Rebuild an OS diagnostics snapshot from session events:
429
460
 
430
461
  ```typescript
431
- import { rebuildOsSnapshotFromSessionEvents } from "@deepstrike/sdk"
462
+ import { rebuildOsSnapshotFromSessionEvents } from "@deepstrike/sdk/os"
432
463
 
433
464
  const events = (await sessionLog.read(sessionId)).map(e => e.event)
434
465
  const snap = rebuildOsSnapshotFromSessionEvents(events)
435
- // snap.pageOutCount, snap.spoolCount, snap.signals, snap.processByAgent, …
466
+ // snap.pageOutCount, snap.signals, snap.processByAgent, …
436
467
  ```
437
468
 
438
469
  ---
439
470
 
440
- ## Large result spool (Layer 1)
471
+ ## External tool payloads
441
472
 
442
- When a single tool result exceeds **50 KB**, the kernel keeps a short preview in context and emits `large_result_spooled`. The SDK writes the full payload to `.spool/` under the process cwd (SHA-256 keyed files) and logs `spool_ref` in the session.
473
+ When a tool result exceeds the configured inline threshold, the SDK persists the full body before sending the canonical `External` result. The kernel receives only `payload_ref`, `digest`, `original_size`, and a bounded preview.
443
474
 
444
- The model can retrieve full content via ordinary read tools `LocalExecutionPlane` transparently resolves paths under `.spool/`:
475
+ The locator is opaque and never passed to ordinary file tools. The model calls `read_result`; core authorizes the reachable handle and emits `LoadPayload`, which the runner resolves through `PayloadStore`.
445
476
 
446
- ```typescript
447
- // Kernel context shows a preview + spool reference.
448
- // LLM calls read_file({ path: ".spool/abc123…" }) → full content returned.
449
- ```
450
-
451
- No configuration is required; customize the directory by passing a `resultSpool` instance when constructing `RuntimeRunner` (see tests under `tests/runtime/large-result-spool.test.ts`).
477
+ No configuration is required. Pass a `PayloadStore` through `RuntimeOptions.payloadStore` to use a different filesystem root or storage adapter.
452
478
 
453
479
  ---
454
480
 
455
481
  ## Tools
456
482
 
457
483
  ```typescript
458
- import { tool, readFile } from "@deepstrike/sdk"
484
+ import { tool } from "@deepstrike/sdk"
485
+ import { readFile } from "@deepstrike/sdk/workflow"
459
486
 
460
487
  plane.register(tool("search", "Search.", schema, async (args) => ...))
461
- plane.register(readFile) // built-in: read files from disk (also resolves .spool/ refs)
488
+ plane.register(readFile) // built-in: read files explicitly named by the caller
462
489
  plane.unregister("search")
463
490
  ```
464
491
 
@@ -553,35 +580,31 @@ mem.clear()
553
580
  import type { DreamStore } from "@deepstrike/sdk/memory"
554
581
 
555
582
  class MyStore implements DreamStore {
556
- async loadSessions(agentId) { ... }
557
- async loadMemories(agentId) { ... }
558
- async commit(agentId, result, existing) { ... }
559
- async search(agentId, query) { ... } // Promise<MemoryRecall[]>
583
+ async upsert(agentId, record) { ... } // the only durable memory mutation
584
+ async search(agentId, query) { ... } // Promise<MemoryRecall[]>
585
+ async saveSession(session) { ... } // completed transcript for extraction
560
586
  }
561
587
 
588
+ const memoryScope = { tenant_id: "acme", namespace: "assistant" }
562
589
  const runner = new RuntimeRunner({
563
590
  provider,
564
591
  executionPlane: plane,
565
592
  sessionLog: new FileSessionLog(".deepstrike/sessions"),
566
593
  maxTokens: 4096,
567
594
  dreamStore: new MyStore(),
568
- agentId: "my-agent", // enables `memory` meta-tool + semantic page-out archival
595
+ agentId: "my-agent",
596
+ memoryScope, // scopes run-start recall, queries, extraction, and semantic page-out
569
597
  })
570
598
  ```
571
599
 
572
- Three memory paths:
600
+ Four memory paths:
573
601
 
574
602
  | Path | When | What happens |
575
603
  |------|------|--------------|
576
604
  | In-session `memory(query)` | LLM calls meta-tool | `DreamStore.search()` → history tool result |
577
605
  | `initialMemory` | Run start | Injected into Slot 2 (`systemKnowledge`) |
578
- | Semantic `page_out` | Kernel evicts with `tier_hint: "semantic"` | SDK summarizes via `dreamSummarizer` / `dreamProvider` → `DreamStore.commit()` |
579
- | `dream(agentId)` | Explicit idle call | `IdlePipeline` batch-consolidates past sessions |
580
-
581
- ```typescript
582
- // Post-session batch consolidation
583
- const result = await runner.dream("my-agent", Date.now())
584
- ```
606
+ | `writeMemory(record)` | Host writes a durable record | Kernel validation / quota / dedup → `DreamStore.upsert()` |
607
+ | Semantic `page_out` | Kernel evicts with `tier_hint: "semantic"` | SDK summarizes via `dreamSummarizer` / `dreamProvider` gated `writeMemory()` |
585
608
 
586
609
  ### Phase-7 memory syscalls (`writeMemory` / `queryMemory`)
587
610
 
@@ -682,7 +705,7 @@ Inbound signals are routed by the in-kernel attention policy (default queue size
682
705
  | queue full | `dropped` |
683
706
 
684
707
  ```typescript
685
- import { SignalGateway, ScheduledPrompt } from "@deepstrike/sdk"
708
+ import { SignalGateway, ScheduledPrompt } from "@deepstrike/sdk/os"
686
709
 
687
710
  const gw = new SignalGateway()
688
711
  gw.schedule(new ScheduledPrompt("standup", Date.now() + 3600_000))
package/dist/index.d.ts CHANGED
@@ -4,20 +4,18 @@ export type { LoopSpec, LoopOutcome } from "./runtime/loop-driver.js";
4
4
  export type { RunAgentOptions, RunFanoutOptions } from "./runtime/facade.js";
5
5
  export { RuntimeRunner, collectText } from "./runtime/runner.js";
6
6
  export type { RuntimeOptions, KernelReliabilityOptions, OperationCancellationReason, PromptBudget, SchedulerPolicy } from "./runtime/runner.js";
7
+ export { PayloadStore } from "./runtime/payload-store.js";
8
+ export type { PayloadStoreConfig } from "./runtime/payload-store.js";
7
9
  export type { InstructionProfile, NudgeRule, NudgeTrigger } from "./harness/public.js";
8
10
  export type { SignalPolicy } from "./runtime/os-profile.js";
9
- export { readKernelDiagnostics, restoreKernelRuntime, snapshotKernelRuntime } from "./runtime/kernel-step.js";
10
- export type { KernelDiagnostics, KernelSnapshot } from "./runtime/kernel-step.js";
11
- export { rebuildKernelRuntime } from "./runtime/kernel-rebuild.js";
12
- export type { KernelRebuildResult } from "./runtime/kernel-rebuild.js";
13
11
  export { CONTEXT_POLICY_VERSION, DEFAULT_CONTEXT_POLICY_V1, PPM_SCALE, contextPolicyV1, normalizeContextPolicyV1, ratioToPpm, } from "./runtime/context-policy.js";
14
12
  export type { ContextPolicyOverridesV1, ContextPolicyV1, ContextPolicyWireV1, ContextPressureThresholdsV1, } from "./runtime/context-policy.js";
15
13
  export { LocalExecutionPlane } from "./runtime/execution-plane.js";
16
14
  export type { ExecutionPlane, RunContext } from "./runtime/execution-plane.js";
17
15
  export { InMemorySessionLog, FileSessionLog } from "./runtime/session-log.js";
18
- export type { KernelTransactionEntry, SessionLog, SessionEvent } from "./runtime/session-log.js";
19
- export { KERNEL_LOG_RECORD_VERSION, KernelLogConflictError, KernelLogIntegrityError, canonicalKernelJson, createKernelOperationGenesis, createKernelTransaction, kernelRecordDigest, verifyKernelOperationGenesis, verifyKernelTransaction, verifyKernelTransactionStream, verifyKernelTransactionSuccessor, } from "./runtime/kernel-transaction-log.js";
20
- export type { DurableAppendReceipt, KernelGenesisReceipt, KernelOperationCursor, KernelOperationGenesis, KernelOperationGenesisBody, KernelTransaction, KernelTransactionBody, } from "./runtime/kernel-transaction-log.js";
16
+ export type { SessionLog, SessionEvent } from "./runtime/session-log.js";
17
+ export { FileKernelJournal, InMemoryKernelJournal, JournalCasConflictError, JournalIntegrityError, JournalIoError, } from "./runtime/kernel-journal.js";
18
+ export type { CheckpointCandidate, InstalledCheckpoint, JournalAppendReceipt, JournalEntry, JournalHead, JournalPruneReceipt, JournalRecordInput, KernelJournal, } from "./runtime/kernel-journal.js";
21
19
  export { InMemoryGroupBudgetStore, GroupBudgetScope } from "./runtime/run-group.js";
22
20
  export type { RunGroup, GroupBudgetStore, GroupLedger, GroupCharge, GroupMember, GroupBudgetRequest, GroupBudgetReservation, } from "./runtime/run-group.js";
23
21
  export { InMemoryEventStream, isVisibleTo } from "./runtime/event-stream.js";
package/dist/index.js CHANGED
@@ -15,13 +15,13 @@ export { runAgent, runFanout } from "./runtime/facade.js";
15
15
  // ③ dynamic loop agents: self-pacing rounds over the kernel pacing trap.
16
16
  export { runLoop, LoopDriver, foldLoopState } from "./runtime/loop-driver.js";
17
17
  export { RuntimeRunner, collectText } from "./runtime/runner.js";
18
- export { readKernelDiagnostics, restoreKernelRuntime, snapshotKernelRuntime } from "./runtime/kernel-step.js";
19
- export { rebuildKernelRuntime } from "./runtime/kernel-rebuild.js";
18
+ export { PayloadStore } from "./runtime/payload-store.js";
20
19
  export { CONTEXT_POLICY_VERSION, DEFAULT_CONTEXT_POLICY_V1, PPM_SCALE, contextPolicyV1, normalizeContextPolicyV1, ratioToPpm, } from "./runtime/context-policy.js";
21
20
  // ── Execution plane + session log (the defaults) ────────────────────────────
22
21
  export { LocalExecutionPlane } from "./runtime/execution-plane.js";
23
22
  export { InMemorySessionLog, FileSessionLog } from "./runtime/session-log.js";
24
- export { KERNEL_LOG_RECORD_VERSION, KernelLogConflictError, KernelLogIntegrityError, canonicalKernelJson, createKernelOperationGenesis, createKernelTransaction, kernelRecordDigest, verifyKernelOperationGenesis, verifyKernelTransaction, verifyKernelTransactionStream, verifyKernelTransactionSuccessor, } from "./runtime/kernel-transaction-log.js";
23
+ // ── Durable transaction capability (Canonical Kernel ABI §9.1) ──────────────
24
+ export { FileKernelJournal, InMemoryKernelJournal, JournalCasConflictError, JournalIntegrityError, JournalIoError, } from "./runtime/kernel-journal.js";
25
25
  export { InMemoryGroupBudgetStore, GroupBudgetScope } from "./runtime/run-group.js";
26
26
  export { InMemoryEventStream, isVisibleTo } from "./runtime/event-stream.js";
27
27
  export { ManagedTaskScope, operationAbortSignal } from "./runtime/reliability.js";
package/dist/kernel.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Message, RenderedContext } from "./types.js";
1
+ import type { Message } from "./types.js";
2
2
  export interface GovernanceVerdict {
3
3
  kind: "allow" | "deny" | "rate_limited" | "ask_user";
4
4
  reason?: string;
@@ -33,16 +33,12 @@ export interface ResourceQuota {
33
33
  /**
34
34
  * Long-term memory policy — declarative knobs for the kernel's memory subsystem.
35
35
  *
36
- * Installed through the versioned JSON event ABI (`set_memory_policy`), the same channel as
37
- * governance / scheduler / quota config, so memory configuration is replayable and
38
- * session-loggable rather than a side-channel setter. Installing the policy is opt-in and
39
- * kernel-enforced; omitted fields fall back to the kernel defaults (empty path, 2-day stale
40
- * warning, top-5 retrieval, validation on). Enabling memory is still `dreamStore` + `agentId`.
36
+ * Included in canonical operation configuration, so memory policy is replayable and
37
+ * kernel-enforced. Omitted fields retain the canonical defaults. Host storage belongs to the
38
+ * configured `DreamStore`, never to this contract.
41
39
  */
42
40
  export interface MemoryPolicy {
43
- /** Filesystem root the SDK uses to persist/scan memories; carried for SDK recall I/O. */
44
- memoryPath?: string;
45
- /** Age after which a recalled memory is flagged stale (days); consumed SDK-side. */
41
+ /** Age after which a recalled memory is flagged stale (days). */
46
42
  staleWarningDays?: number;
47
43
  /** Upper bound on retrieval breadth: the kernel clamps `query_memory` top-k to this. */
48
44
  retrievalTopK?: number;
@@ -108,31 +104,65 @@ export interface Verdict {
108
104
  content: string;
109
105
  };
110
106
  }
111
- export interface KernelRuntimeInstance {
112
- step(inputJson: string): string;
113
- prepareStep(inputJson: string): string;
114
- commitPrepared(prepareToken: string): string;
115
- abortPrepared(prepareToken: string): void;
116
- snapshot(): string;
117
- restore(snapshotJson: string): void;
118
- diagnostics(): string;
119
- isTerminal(): boolean;
120
- turn(): number;
121
- /** L1 (RunGroup): cumulative sub-agent spawns this run, for charging the group ledger at run end. */
122
- localSubagentsSpawned(): number;
123
- recoveryContentBytes(): number;
124
- render(): RenderedContext;
125
- drainNewMessages(): Message[];
126
- preservedRefs(): string[];
107
+ export interface CanonicalPrepared {
108
+ status: "prepared";
109
+ prepareToken: string;
110
+ stepSeq: string;
111
+ expectedHead?: string;
112
+ recordDigest: string;
113
+ recordBytes: Buffer;
114
+ plannedStepJson: string;
115
+ }
116
+ export interface CanonicalReplayed {
117
+ status: "replayed";
118
+ stepSeq: string;
119
+ expectedHead?: string;
120
+ recordDigest: string;
121
+ recordBytes?: Buffer;
122
+ plannedStepJson?: string;
123
+ }
124
+ export interface CanonicalRejected {
125
+ status: "rejected";
126
+ faultJson: string;
127
+ }
128
+ /** Closed §7.13 result; only `prepared` carries a token that may be committed or aborted. */
129
+ export type CanonicalPreparation = CanonicalPrepared | CanonicalReplayed | CanonicalRejected;
130
+ export interface CanonicalCommit {
131
+ stepSeq: string;
132
+ recordDigest: string;
133
+ plannedStepJson: string;
134
+ checkpointAdviceJson?: string;
135
+ }
136
+ export interface CanonicalCheckpoint {
137
+ checkpointBytes: Buffer;
138
+ throughStepSeq: string;
139
+ coveredHead: string;
140
+ stateDigest: string;
141
+ ackToken: string;
142
+ }
143
+ export interface CanonicalRestoreCost {
144
+ recordsBeforeCheckpoint: string;
145
+ tailInputsReplayed: string;
146
+ recordsAfterCheckpoint: string;
147
+ bytesRead: string;
148
+ }
149
+ export interface CanonicalKernelInstance {
150
+ prepare(inputJson: string): CanonicalPreparation;
151
+ commit(prepareToken: string, appendedHead: string): CanonicalCommit;
152
+ abort(prepareToken: string): void;
153
+ checkpointCandidate(): CanonicalCheckpoint;
154
+ checkpointRebase(checkpointBytes: Buffer): CanonicalCheckpoint;
155
+ ackCheckpoint(throughStepSeq: string, coveredHead: string): void;
156
+ /** Replaces native state in place; the JavaScript handle retains its identity. */
157
+ restore(checkpointBytes: Buffer | undefined, recordBytes: Buffer[]): CanonicalRestoreCost;
158
+ lifecycle(): "created" | "configured" | "running" | "suspended" | "completed" | "cancelled" | "failed";
159
+ pendingEffectsJson(): string;
160
+ terminalJson(): string | undefined;
127
161
  }
128
162
  interface KernelModule {
129
163
  Governance: new (defaultAction?: "allow" | "deny" | "ask_user") => GovernanceInstance;
130
- KernelRuntime: new (policy: {
131
- maxTokens: number;
132
- maxTurns?: number;
133
- maxTotalTokens?: bigint;
134
- timeoutMs?: bigint;
135
- }) => KernelRuntimeInstance;
164
+ CanonicalKernel: new () => CanonicalKernelInstance;
165
+ kernelAbiVersion(): number;
136
166
  SignalRouter: new (maxQueueSize: number) => SignalRouterInstance;
137
167
  buildEvalMessages(goal: string, criteria: NativeCriterion[], result: string, attempt: number, extractSkillOnPass: boolean): Message[];
138
168
  parseVerdict(content: string): Verdict;
@@ -0,0 +1,143 @@
1
+ import type { CanonicalKernelInstance, CanonicalRestoreCost } from "../kernel.js";
2
+ import type { Message } from "../types.js";
3
+ import { type InstalledCheckpoint, type KernelJournal } from "./kernel-journal.js";
4
+ import { type KernelObservation, type KernelRunnerAction } from "./kernel-step.js";
5
+ export declare const MAX_CHAIN_POSITION = 1000000000000;
6
+ export type CanonicalKernelInput = Record<string, unknown> & {
7
+ kind: string;
8
+ };
9
+ export interface CanonicalPlannedStep {
10
+ root_kind?: "agent" | "workflow";
11
+ focus?: Record<string, unknown>;
12
+ observations?: Array<Record<string, unknown>>;
13
+ disposition: {
14
+ kind: "effects";
15
+ effects?: Array<Record<string, unknown>>;
16
+ } | {
17
+ kind: "terminal";
18
+ terminal: Record<string, unknown>;
19
+ };
20
+ }
21
+ export interface CanonicalTransitionOptions {
22
+ /** Caller-stable idempotency key. Generated once when omitted. */
23
+ inputId?: string;
24
+ /** Decimal-u64 host observation. Captured once when omitted and preserved across every retry. */
25
+ observedAtMs?: string;
26
+ }
27
+ export interface CanonicalTransition {
28
+ inputJson: string;
29
+ stepSeq: number;
30
+ recordDigest: string;
31
+ plannedStep: CanonicalPlannedStep;
32
+ checkpointAdvice?: Record<string, unknown>;
33
+ replayed: boolean;
34
+ }
35
+ export declare function canonicalUnsupportedEffectResolution(effectId: string, effectKind: string): CanonicalKernelInput;
36
+ /** The only ABI-v3 planned-step → Node host-action projection. */
37
+ export declare function canonicalActionFromPlannedStep(plannedStep: CanonicalPlannedStep): KernelRunnerAction | null;
38
+ export declare class CanonicalKernelRejectedError extends Error {
39
+ readonly fault: Record<string, unknown>;
40
+ constructor(faultJson: string);
41
+ }
42
+ /**
43
+ * A record is already authoritative once the journal append returns. A later native commit failure
44
+ * is therefore a rebuild boundary, never an abort boundary.
45
+ */
46
+ export declare class CanonicalKernelRebuildRequiredError extends Error {
47
+ constructor(message: string, options?: {
48
+ cause?: unknown;
49
+ });
50
+ }
51
+ /**
52
+ * Node's canonical durable staged-transition host.
53
+ *
54
+ * It owns no scheduler truth. Core prepares opaque record bytes; `KernelJournal` makes those bytes
55
+ * authoritative; only then may core commit and expose the planned effects/terminal to the runner.
56
+ */
57
+ export declare class CanonicalKernelHost {
58
+ readonly kernel: CanonicalKernelInstance;
59
+ readonly journal: KernelJournal;
60
+ readonly operationId: string;
61
+ constructor(kernel: CanonicalKernelInstance, journal: KernelJournal, operationId: string);
62
+ transition(input: CanonicalKernelInput, options?: CanonicalTransitionOptions): Promise<CanonicalTransition>;
63
+ /** Restore the latest installed checkpoint and its authoritative record tail in place. */
64
+ restore(): Promise<CanonicalRestoreCost>;
65
+ /**
66
+ * Replay a crash-window outbound envelope with identical bytes (adjudication 5e.3).
67
+ * No-op when nothing is staged. Clears the stage after commit/replay/reject.
68
+ */
69
+ drainOutboundEnvelope(): Promise<CanonicalTransition | undefined>;
70
+ /** Execute the full §12.3 install/ack/reclaim boundary. */
71
+ checkpoint(): Promise<InstalledCheckpoint>;
72
+ private transitionEnvelope;
73
+ }
74
+ export interface CanonicalRunnerRuntimeOptions {
75
+ maxContextTokens: number;
76
+ maxTurns?: number;
77
+ maxTotalTokens?: number;
78
+ maxWallMs?: number;
79
+ memoryBindingId?: string;
80
+ persistPayload?: (callId: string, content: string, previewBytes: number) => Promise<{
81
+ payloadRef: string;
82
+ digest: string;
83
+ originalSize: string;
84
+ preview: string;
85
+ }>;
86
+ }
87
+ /**
88
+ * Canonical operation runtime used by the Node host.
89
+ * Every durable transition below is one of the canonical ABI's five input classes; no legacy
90
+ * envelope or synthesized host transaction reaches core or storage.
91
+ */
92
+ export declare class CanonicalRunnerRuntime {
93
+ private readonly options;
94
+ private readonly host;
95
+ private readonly config;
96
+ private readonly initialContext;
97
+ private configured;
98
+ private started;
99
+ private turns;
100
+ private lastAction;
101
+ private readonly newMessages;
102
+ private readonly hostObservations;
103
+ private spawnedTasks;
104
+ private readonly memoryBindingId;
105
+ private payloadInlineThreshold;
106
+ private payloadPreviewBytes;
107
+ constructor(kernel: CanonicalKernelInstance, journal: KernelJournal, operationId: string, options: CanonicalRunnerRuntimeOptions);
108
+ get operationId(): string;
109
+ get journal(): KernelJournal;
110
+ turn(): number;
111
+ isTerminal(): boolean;
112
+ recoveryContentBytes(): number;
113
+ preservedRefs(): string[];
114
+ drainNewMessages(): Message[];
115
+ drainHostObservations(): KernelObservationLike[];
116
+ terminal(): Record<string, unknown> | undefined;
117
+ localSubagentsSpawned(): number;
118
+ restore(): Promise<void>;
119
+ resumeAction(): KernelRunnerAction | null;
120
+ startAgent(taskValue: Record<string, unknown>, runSpecValue?: Record<string, unknown>): Promise<KernelRunnerAction | null>;
121
+ startWorkflow(specValue: Record<string, unknown>): Promise<KernelRunnerAction | null>;
122
+ applyHostEvent(event: Record<string, unknown>): Promise<KernelRunnerAction | null>;
123
+ private ensureConfigured;
124
+ private commit;
125
+ private currentAction;
126
+ private pendingEffects;
127
+ private succeededEffect;
128
+ private failedEffect;
129
+ private pageOutResolution;
130
+ private canonicalSignal;
131
+ private canonicalCapabilityCommand;
132
+ private applyBootstrapEvent;
133
+ private featurePolicy;
134
+ private executionPolicy;
135
+ private mergeHostConfig;
136
+ }
137
+ export declare function canonicalKernelApply(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], event: Record<string, unknown>): Promise<KernelObservationLike[]>;
138
+ export declare function canonicalKernelMaybeAction(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], event: Record<string, unknown>): Promise<KernelRunnerAction | null>;
139
+ export declare function canonicalKernelAction(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], event: Record<string, unknown>): Promise<KernelRunnerAction>;
140
+ export declare function canonicalStartAgent(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], task: Record<string, unknown>, runSpec?: Record<string, unknown>): Promise<KernelRunnerAction>;
141
+ export declare function canonicalStartWorkflow(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], spec: Record<string, unknown>): Promise<KernelRunnerAction | null>;
142
+ type KernelObservationLike = KernelObservation;
143
+ export {};