chore: Also format scripts and skills.

This commit is contained in:
cpojer
2026-01-31 21:21:09 +09:00
parent a767c584c7
commit 76b5208b11
95 changed files with 2250 additions and 1239 deletions
@@ -104,12 +104,13 @@ The execution state file shows the program's current position using **annotated
**Only the VM writes this file.** Subagents never modify `state.md`.
The format shows:
- **Full history** of executed code with inline annotations
- **Current position** clearly marked with status
- **~5-10 lines ahead** of current position (what's coming next)
- **Index** of all bindings and agents with file paths
```markdown
````markdown
# Execution State
run: 20260115-143052-a7b3c9
@@ -144,6 +145,7 @@ resume: captain # [...next...]
prompt: "Review the synthesis"
context: synthesis
```
````
## Active Constructs
@@ -162,26 +164,27 @@ resume: captain # [...next...]
### Bindings
| Name | Kind | Path | Execution ID |
|------|------|------|--------------|
| research | let | bindings/research.md | (root) |
| a | let | bindings/a.md | (root) |
| result | let | bindings/result__43.md | 43 |
| Name | Kind | Path | Execution ID |
| -------- | ---- | ------------------------ | ------------ |
| research | let | bindings/research.md | (root) |
| a | let | bindings/a.md | (root) |
| result | let | bindings/result\_\_43.md | 43 |
### Agents
| Name | Scope | Path |
|------|-------|------|
| Name | Scope | Path |
| ------- | --------- | --------------- |
| captain | execution | agents/captain/ |
## Call Stack
| execution_id | block | depth | status |
|--------------|-------|-------|--------|
| 43 | process | 3 | executing |
| 42 | process | 2 | waiting |
| 41 | process | 1 | waiting |
```
| execution_id | block | depth | status |
| ------------ | ------- | ----- | --------- |
| 43 | process | 3 | executing |
| 42 | process | 2 | waiting |
| 41 | process | 1 | waiting |
````
**Status annotations:**
@@ -209,14 +212,15 @@ source:
```prose
let research = session: researcher
prompt: "Research AI safety"
```
````
---
AI safety research covers several key areas including alignment,
robustness, and interpretability. The field has grown significantly
since 2020 with major contributions from...
```
````
**Structure:**
- Header with binding name
@@ -240,7 +244,7 @@ Sessions without explicit output capture still produce results:
```prose
session "Analyze the codebase" # No `let x = ...` capture
```
````
These get auto-generated names with an `anon_` prefix:
@@ -259,25 +263,29 @@ When a binding is created inside a block invocation, it's scoped to that executi
**Naming convention:** `{name}__{execution_id}.md`
Examples:
- `bindings/result__43.md` — binding `result` in execution_id 43
- `bindings/parts__44.md` — binding `parts` in execution_id 44
**File format with execution scope:**
```markdown
````markdown
# result
kind: let
execution_id: 43
source:
```prose
let result = session "Process chunk"
```
````
---
Processed chunk into 3 sub-parts...
```
**Scope resolution:** The VM resolves variable references by checking:
@@ -291,15 +299,17 @@ The first match wins.
**Example directory for recursive calls:**
```
bindings/
├── data.md # Root scope input
├── result__1.md # First process() invocation
├── parts__1.md # Parts from first invocation
├── result__2.md # Recursive call (depth 2)
├── parts__2.md # Parts from depth 2
├── result__3.md # Recursive call (depth 3)
├── data.md # Root scope input
├── result**1.md # First process() invocation
├── parts**1.md # Parts from first invocation
├── result**2.md # Recursive call (depth 2)
├── parts**2.md # Parts from depth 2
├── result\_\_3.md # Recursive call (depth 3)
└── ...
```
````
---
@@ -326,7 +336,7 @@ Architecture uses Express + PostgreSQL. Test coverage target is 80%.
- Rate limiting not yet implemented on login endpoint
- Need to verify OAuth flow works with new token format
```
````
#### `agents/{name}/{name}-NNN.md` (Segments)
@@ -350,11 +360,11 @@ prompt: "Review the research findings"
## Who Writes What
| File | Written By |
|------|------------|
| `state.md` | VM only |
| `bindings/{name}.md` | Subagent |
| `agents/{name}/memory.md` | Persistent agent |
| File | Written By |
| ----------------------------- | ---------------- |
| `state.md` | VM only |
| `bindings/{name}.md` | Subagent |
| `agents/{name}/memory.md` | Persistent agent |
| `agents/{name}/{name}-NNN.md` | Persistent agent |
The VM orchestrates; subagents write their own outputs directly to the filesystem. **The VM never holds full binding values—it tracks file paths.**
@@ -367,7 +377,7 @@ When the VM spawns a session, it tells the subagent where to write output.
### For Regular Sessions
```
````
When you complete this task, write your output to:
.prose/runs/20260115-143052-a7b3c9/bindings/research.md
@@ -380,24 +390,27 @@ source:
```prose
let research = session: researcher
prompt: "Research AI safety"
```
````
---
[Your output here]
```
### For Persistent Agents (resume:)
```
Your memory is at:
.prose/runs/20260115-143052-a7b3c9/agents/captain/memory.md
.prose/runs/20260115-143052-a7b3c9/agents/captain/memory.md
Read it first to understand your prior context. When done, update it
with your compacted state following the guidelines in primitives/session.md.
Also write your segment record to:
.prose/runs/20260115-143052-a7b3c9/agents/captain/captain-003.md
.prose/runs/20260115-143052-a7b3c9/agents/captain/captain-003.md
```
### What Subagents Return to the VM
@@ -406,17 +419,21 @@ After writing output, the subagent returns a **confirmation message**—not the
**Root scope (outside block invocations):**
```
Binding written: research
Location: .prose/runs/20260115-143052-a7b3c9/bindings/research.md
Summary: AI safety research covering alignment, robustness, and interpretability with 15 citations.
```
**Inside block invocation (include execution_id):**
```
Binding written: result
Location: .prose/runs/20260115-143052-a7b3c9/bindings/result__43.md
Location: .prose/runs/20260115-143052-a7b3c9/bindings/result\_\_43.md
Execution ID: 43
Summary: Processed chunk into 3 sub-parts for recursive processing.
```
The VM records the location and continues. It does NOT read the file—it passes the reference to subsequent sessions that need the context.
@@ -428,16 +445,18 @@ The VM records the location and continues. It does NOT read the file—it passes
Imported programs use the **same unified structure recursively**:
```
.prose/runs/{id}/imports/{handle}--{slug}/
├── program.prose
├── state.md
├── bindings/
└── {name}.md
├── imports/ # Nested imports go here
└── {handle2}--{slug2}/
└── ...
│ └── {name}.md
├── imports/ # Nested imports go here
│ └── {handle2}--{slug2}/
│ └── ...
└── agents/
└── {name}/
└── {name}/
```
This allows unlimited nesting depth while maintaining consistent structure at every level.
@@ -476,3 +495,4 @@ If execution is interrupted, resume by:
3. Continuing from the marked position
The `state.md` file contains everything needed to understand where execution stopped and what has been accomplished.
```
@@ -28,13 +28,13 @@ In-context state uses text-prefixed markers to persist state within the conversa
In-context state is appropriate for:
| Factor | In-Context | Use File-Based Instead |
|--------|------------|------------------------|
| Statement count | < 30 statements | >= 30 statements |
| Parallel branches | < 5 concurrent | >= 5 concurrent |
| Imported programs | 0-2 imports | >= 3 imports |
| Nested depth | <= 2 levels | > 2 levels |
| Expected duration | < 5 minutes | >= 5 minutes |
| Factor | In-Context | Use File-Based Instead |
| ----------------- | --------------- | ---------------------- |
| Statement count | < 30 statements | >= 30 statements |
| Parallel branches | < 5 concurrent | >= 5 concurrent |
| Imported programs | 0-2 imports | >= 3 imports |
| Nested depth | <= 2 levels | > 2 levels |
| Expected duration | < 5 minutes | >= 5 minutes |
Announce your state mode at program start:
@@ -49,23 +49,23 @@ OpenProse Program Start
Use text-prefixed markers for each state change:
| Marker | Category | Usage |
|--------|----------|-------|
| [Program] | Program | Start, end, definition collection |
| [Position] | Position | Current statement being executed |
| [Binding] | Binding | Variable assignment or update |
| [Input] | Input | Receiving inputs from caller |
| [Output] | Output | Producing outputs for caller |
| [Import] | Import | Fetching and invoking imported programs |
| [Success] | Success | Session or block completion |
| [Warning] | Error | Failures and exceptions |
| [Parallel] | Parallel | Entering, branch status, joining |
| [Loop] | Loop | Iteration, condition evaluation |
| [Pipeline] | Pipeline | Stage progress |
| [Try] | Error handling | Try/catch/finally |
| [Flow] | Flow | Condition evaluation results |
| [Frame+] | Call Stack | Push new frame (block invocation) |
| [Frame-] | Call Stack | Pop frame (block completion) |
| Marker | Category | Usage |
| ---------- | -------------- | --------------------------------------- |
| [Program] | Program | Start, end, definition collection |
| [Position] | Position | Current statement being executed |
| [Binding] | Binding | Variable assignment or update |
| [Input] | Input | Receiving inputs from caller |
| [Output] | Output | Producing outputs for caller |
| [Import] | Import | Fetching and invoking imported programs |
| [Success] | Success | Session or block completion |
| [Warning] | Error | Failures and exceptions |
| [Parallel] | Parallel | Entering, branch status, joining |
| [Loop] | Loop | Iteration, condition evaluation |
| [Pipeline] | Pipeline | Stage progress |
| [Try] | Error handling | Try/catch/finally |
| [Flow] | Flow | Condition evaluation results |
| [Frame+] | Call Stack | Push new frame (block invocation) |
| [Frame-] | Call Stack | Pop frame (block completion) |
---
@@ -185,6 +185,7 @@ Track block invocations with frame markers:
```
**Key points:**
- Each `[Frame+]` must have a matching `[Frame-]`
- `execution_id` uniquely identifies each invocation
- `depth` shows call stack depth (1 = first level)
@@ -236,13 +237,14 @@ For variable resolution across scopes:
When passing context to sessions, format appropriately:
| Context Size | Strategy |
|--------------|----------|
| < 2000 chars | Pass verbatim |
| Context Size | Strategy |
| --------------- | ----------------------- |
| < 2000 chars | Pass verbatim |
| 2000-8000 chars | Summarize to key points |
| > 8000 chars | Extract essentials only |
| > 8000 chars | Extract essentials only |
**Format:**
```
Context provided:
---
@@ -274,6 +276,7 @@ loop until **analysis complete** (max: 3):
```
**Narration:**
```
[Program] Program Start
Collecting definitions...
@@ -322,20 +325,20 @@ loop until **analysis complete** (max: 3):
The VM must track these state categories in narration:
| Category | What to Track | Example |
|----------|---------------|---------|
| **Import Registry** | Imported programs and aliases | `research: @alice/research` |
| **Agent Registry** | All agent definitions | `researcher: {model: sonnet, prompt: "..."}` |
| **Block Registry** | All block definitions (hoisted) | `review: {params: [topic], body: [...]}` |
| **Input Bindings** | Inputs received from caller | `topic = "quantum computing"` |
| **Output Bindings** | Outputs to return to caller | `findings = "Research shows..."` |
| **Variable Bindings** | Name -> value mapping (with execution_id) | `result = "..." (execution_id: 3)` |
| **Variable Mutability** | Which are `let` vs `const` vs `output` | `research: let, findings: output` |
| **Execution Position** | Current statement index | Statement 3 of 7 |
| **Loop State** | Counter, max, condition | Iteration 2 of max 5 |
| **Parallel State** | Branches, results, strategy | `{a: complete, b: pending}` |
| **Error State** | Exception, retry count | Retry 2 of 3, error: "timeout" |
| **Call Stack** | Stack of execution frames | See below |
| Category | What to Track | Example |
| ----------------------- | ----------------------------------------- | -------------------------------------------- |
| **Import Registry** | Imported programs and aliases | `research: @alice/research` |
| **Agent Registry** | All agent definitions | `researcher: {model: sonnet, prompt: "..."}` |
| **Block Registry** | All block definitions (hoisted) | `review: {params: [topic], body: [...]}` |
| **Input Bindings** | Inputs received from caller | `topic = "quantum computing"` |
| **Output Bindings** | Outputs to return to caller | `findings = "Research shows..."` |
| **Variable Bindings** | Name -> value mapping (with execution_id) | `result = "..." (execution_id: 3)` |
| **Variable Mutability** | Which are `let` vs `const` vs `output` | `research: let, findings: output` |
| **Execution Position** | Current statement index | Statement 3 of 7 |
| **Loop State** | Counter, max, condition | Iteration 2 of max 5 |
| **Parallel State** | Branches, results, strategy | `{a: complete, b: pending}` |
| **Error State** | Exception, retry count | Retry 2 of 3, error: "timeout" |
| **Call Stack** | Stack of execution frames | See below |
### Call Stack State
@@ -349,6 +352,7 @@ For block invocations, track the full call stack:
```
Each frame tracks:
- `execution_id`: Unique ID for this invocation
- `block`: Name of the block
- `depth`: Position in call stack
@@ -21,19 +21,20 @@ This document describes how the OpenProse VM tracks execution state using a **Po
## Prerequisites
**Requires:**
1. The `psql` command-line tool must be available in your PATH
2. A running PostgreSQL server (local, Docker, or cloud)
### Installing psql
| Platform | Command | Notes |
|----------|---------|-------|
| macOS (Homebrew) | `brew install libpq && brew link --force libpq` | Client-only; no server |
| macOS (Postgres.app) | Download from https://postgresapp.com | Full install with GUI |
| Debian/Ubuntu | `apt install postgresql-client` | Client-only |
| Fedora/RHEL | `dnf install postgresql` | Client-only |
| Arch Linux | `pacman -S postgresql-libs` | Client-only |
| Windows | `winget install PostgreSQL.PostgreSQL` | Full installer |
| Platform | Command | Notes |
| -------------------- | ----------------------------------------------- | ---------------------- |
| macOS (Homebrew) | `brew install libpq && brew link --force libpq` | Client-only; no server |
| macOS (Postgres.app) | Download from https://postgresapp.com | Full install with GUI |
| Debian/Ubuntu | `apt install postgresql-client` | Client-only |
| Fedora/RHEL | `dnf install postgresql` | Client-only |
| Arch Linux | `pacman -S postgresql-libs` | Client-only |
| Windows | `winget install PostgreSQL.PostgreSQL` | Full installer |
After installation, verify:
@@ -70,6 +71,7 @@ PostgreSQL state provides:
- Create a **limited-privilege user** with access only to the `openprose` schema
**Recommended setup:**
```sql
-- Create dedicated user with minimal privileges
CREATE USER openprose_agent WITH PASSWORD 'changeme';
@@ -84,13 +86,13 @@ GRANT ALL ON SCHEMA openprose TO openprose_agent;
PostgreSQL state is for **power users** with specific scale or collaboration needs:
| Need | PostgreSQL Helps |
|------|------------------|
| >5 parallel branches writing simultaneously | SQLite locks; PostgreSQL doesn't |
| External dashboards querying state | PostgreSQL is designed for concurrent readers |
| Team collaboration on long workflows | Shared network access; no file sync needed |
| Outputs exceeding 1GB | Bulk ingestion; no single-file bottleneck |
| Mission-critical workflows (hours/days) | Robust durability; point-in-time recovery |
| Need | PostgreSQL Helps |
| ------------------------------------------- | --------------------------------------------- |
| >5 parallel branches writing simultaneously | SQLite locks; PostgreSQL doesn't |
| External dashboards querying state | PostgreSQL is designed for concurrent readers |
| Team collaboration on long workflows | Shared network access; no file sync needed |
| Outputs exceeding 1GB | Bulk ingestion; no single-file bottleneck |
| Mission-critical workflows (hours/days) | Robust durability; point-in-time recovery |
**If none of these apply, use filesystem or SQLite state.** They're simpler and sufficient for 99% of programs.
@@ -187,11 +189,11 @@ echo "OPENPROSE_POSTGRES_URL=postgresql:///myproject" >> .prose/.env
For team collaboration or production:
| Provider | Free Tier | Cold Start | Best For |
|----------|-----------|------------|----------|
| **Neon** | 0.5GB, auto-suspend | 1-3s | Development, testing |
| **Supabase** | 500MB, no auto-suspend | None | Projects needing auth/storage |
| **Railway** | $5/mo credit | None | Simple production deploys |
| Provider | Free Tier | Cold Start | Best For |
| ------------ | ---------------------- | ---------- | ----------------------------- |
| **Neon** | 0.5GB, auto-suspend | 1-3s | Development, testing |
| **Supabase** | 500MB, no auto-suspend | None | Projects needing auth/storage |
| **Railway** | $5/mo credit | None | Simple production deploys |
```bash
# Example: Neon
@@ -246,17 +248,17 @@ This section defines **who does what**. This is the contract between the VM and
The VM (the orchestrating agent running the .prose program) is responsible for:
| Responsibility | Description |
|----------------|-------------|
| **Schema initialization** | Create `openprose` schema and tables at run start |
| **Run registration** | Store the program source and metadata |
| **Execution tracking** | Update position, status, and timing as statements execute |
| **Subagent spawning** | Spawn sessions via Task tool with database instructions |
| **Parallel coordination** | Track branch status, implement join strategies |
| **Loop management** | Track iteration counts, evaluate conditions |
| **Error aggregation** | Record failures, manage retry state |
| **Context preservation** | Maintain sufficient narration in the main thread |
| **Completion detection** | Mark the run as complete when finished |
| Responsibility | Description |
| ------------------------- | --------------------------------------------------------- |
| **Schema initialization** | Create `openprose` schema and tables at run start |
| **Run registration** | Store the program source and metadata |
| **Execution tracking** | Update position, status, and timing as statements execute |
| **Subagent spawning** | Spawn sessions via Task tool with database instructions |
| **Parallel coordination** | Track branch status, implement join strategies |
| **Loop management** | Track iteration counts, evaluate conditions |
| **Error aggregation** | Record failures, manage retry state |
| **Context preservation** | Maintain sufficient narration in the main thread |
| **Completion detection** | Mark the run as complete when finished |
**Critical:** The VM must preserve enough context in its own conversation to understand execution state without re-reading the entire database. The database is for coordination and persistence, not a replacement for working memory.
@@ -264,13 +266,13 @@ The VM (the orchestrating agent running the .prose program) is responsible for:
Subagents (sessions spawned by the VM) are responsible for:
| Responsibility | Description |
|----------------|-------------|
| **Writing own outputs** | Insert/update their binding in the `bindings` table |
| **Memory management** | For persistent agents: read and update their memory record |
| **Segment recording** | For persistent agents: append segment history |
| Responsibility | Description |
| ----------------------- | ----------------------------------------------------------------- |
| **Writing own outputs** | Insert/update their binding in the `bindings` table |
| **Memory management** | For persistent agents: read and update their memory record |
| **Segment recording** | For persistent agents: append segment history |
| **Attachment handling** | Write large outputs to `attachments/` directory, store path in DB |
| **Atomic writes** | Use transactions when updating multiple related records |
| **Atomic writes** | Use transactions when updating multiple related records |
**Critical:** Subagents write ONLY to `bindings`, `agents`, and `agent_segments` tables. The VM owns the `execution` table entirely. Completion signaling happens through the substrate (Task tool return), not database updates.
@@ -279,6 +281,7 @@ Subagents (sessions spawned by the VM) are responsible for:
**What subagents return to the VM:** A confirmation message with the binding location—not the full content:
**Root scope:**
```
Binding written: research
Location: openprose.bindings WHERE name='research' AND run_id='20260116-143052-a7b3c9' AND execution_id IS NULL
@@ -286,6 +289,7 @@ Summary: AI safety research covering alignment, robustness, and interpretability
```
**Inside block invocation:**
```
Binding written: result
Location: openprose.bindings WHERE name='result' AND run_id='20260116-143052-a7b3c9' AND execution_id=43
@@ -297,12 +301,12 @@ The VM tracks locations, not values. This keeps the VM's context lean and enable
### Shared Concerns
| Concern | Who Handles |
|---------|-------------|
| Concern | Who Handles |
| ---------------- | ------------------------------------------------------------------ |
| Schema evolution | Either (use `CREATE TABLE IF NOT EXISTS`, `ALTER TABLE` as needed) |
| Custom tables | Either (prefix with `x_` for extensions) |
| Indexing | Either (add indexes for frequently-queried columns) |
| Cleanup | VM (at run end, optionally delete old data) |
| Custom tables | Either (prefix with `x_` for extensions) |
| Indexing | Either (add indexes for frequently-queried columns) |
| Cleanup | VM (at run end, optionally delete old data) |
---
@@ -601,12 +605,12 @@ Even with PostgreSQL state, the VM should narrate key events in its conversation
### Why Both?
| Purpose | Mechanism |
|---------|-----------|
| **Working memory** | Conversation narration (what the VM "remembers" without re-querying) |
| **Durable state** | PostgreSQL database (survives context limits, enables resumption) |
| **Subagent coordination** | PostgreSQL database (shared access point) |
| **Debugging/inspection** | PostgreSQL database (queryable history) |
| Purpose | Mechanism |
| ------------------------- | -------------------------------------------------------------------- |
| **Working memory** | Conversation narration (what the VM "remembers" without re-querying) |
| **Durable state** | PostgreSQL database (survives context limits, enables resumption) |
| **Subagent coordination** | PostgreSQL database (shared access point) |
| **Debugging/inspection** | PostgreSQL database (queryable history) |
The narration is the VM's "mental model" of execution. The database is the "source of truth" for resumption and inspection.
@@ -717,6 +721,7 @@ PRIMARY KEY (name, COALESCE(run_id, '__project__'))
```
This means:
- `name='advisor', run_id=NULL` has PK `('advisor', '__project__')`
- `name='advisor', run_id='20260116-143052-a7b3c9'` has PK `('advisor', '20260116-143052-a7b3c9')`
@@ -724,10 +729,10 @@ The same agent name can exist as both project-scoped and execution-scoped withou
### Query Patterns
| Scope | Query |
|-------|-------|
| Scope | Query |
| ---------------- | ------------------------------------------------ |
| Execution-scoped | `WHERE name = 'captain' AND run_id = '{RUN_ID}'` |
| Project-scoped | `WHERE name = 'advisor' AND run_id IS NULL` |
| Project-scoped | `WHERE name = 'advisor' AND run_id IS NULL` |
### Project-Scoped Memory Guidelines
@@ -841,20 +846,20 @@ The database is your workspace. Use it.
## Comparison with Other Modes
| Aspect | filesystem.md | in-context.md | sqlite.md | postgres.md |
|--------|---------------|---------------|-----------|-------------|
| **State location** | `.prose/runs/{id}/` files | Conversation history | `.prose/runs/{id}/state.db` | PostgreSQL database |
| **Queryable** | Via file reads | No | Yes (SQL) | Yes (SQL) |
| **Atomic updates** | No | N/A | Yes (transactions) | Yes (ACID) |
| **Concurrent writes** | Yes (different files) | N/A | **No (table locks)** | **Yes (row locks)** |
| **Network access** | No | No | No | **Yes** |
| **Team collaboration** | Via file sync | No | Via file sync | **Yes** |
| **Schema flexibility** | Rigid file structure | N/A | Flexible | Very flexible (JSONB) |
| **Resumption** | Read state.md | Re-read conversation | Query database | Query database |
| **Complexity ceiling** | High | Low (<30 statements) | High | **Very high** |
| **Dependency** | None | None | sqlite3 CLI | psql CLI + PostgreSQL |
| **Setup friction** | Zero | Zero | Low | Medium-High |
| **Status** | Stable | Stable | Experimental | **Experimental** |
| Aspect | filesystem.md | in-context.md | sqlite.md | postgres.md |
| ---------------------- | ------------------------- | -------------------- | --------------------------- | --------------------- |
| **State location** | `.prose/runs/{id}/` files | Conversation history | `.prose/runs/{id}/state.db` | PostgreSQL database |
| **Queryable** | Via file reads | No | Yes (SQL) | Yes (SQL) |
| **Atomic updates** | No | N/A | Yes (transactions) | Yes (ACID) |
| **Concurrent writes** | Yes (different files) | N/A | **No (table locks)** | **Yes (row locks)** |
| **Network access** | No | No | No | **Yes** |
| **Team collaboration** | Via file sync | No | Via file sync | **Yes** |
| **Schema flexibility** | Rigid file structure | N/A | Flexible | Very flexible (JSONB) |
| **Resumption** | Read state.md | Re-read conversation | Query database | Query database |
| **Complexity ceiling** | High | Low (<30 statements) | High | **Very high** |
| **Dependency** | None | None | sqlite3 CLI | psql CLI + PostgreSQL |
| **Setup friction** | Zero | Zero | Low | Medium-High |
| **Status** | Stable | Stable | Experimental | **Experimental** |
---
@@ -21,11 +21,11 @@ This document describes how the OpenProse VM tracks execution state using a **SQ
**Requires:** The `sqlite3` command-line tool must be available in your PATH.
| Platform | Installation |
|----------|--------------|
| macOS | Pre-installed |
| Linux | `apt install sqlite3` / `dnf install sqlite3` / etc. |
| Windows | `winget install SQLite.SQLite` or download from sqlite.org |
| Platform | Installation |
| -------- | ---------------------------------------------------------- |
| macOS | Pre-installed |
| Linux | `apt install sqlite3` / `dnf install sqlite3` / etc. |
| Windows | `winget install SQLite.SQLite` or download from sqlite.org |
If `sqlite3` is not available, the VM will fall back to filesystem state and warn the user.
@@ -93,17 +93,17 @@ This section defines **who does what**. This is the contract between the VM and
The VM (the orchestrating agent running the .prose program) is responsible for:
| Responsibility | Description |
|----------------|-------------|
| **Database creation** | Create `state.db` and initialize core tables at run start |
| **Program registration** | Store the program source and metadata |
| **Execution tracking** | Update position, status, and timing as statements execute |
| **Subagent spawning** | Spawn sessions via Task tool with database path and instructions |
| **Parallel coordination** | Track branch status, implement join strategies |
| **Loop management** | Track iteration counts, evaluate conditions |
| **Error aggregation** | Record failures, manage retry state |
| **Context preservation** | Maintain sufficient narration in the main conversation thread so execution can be understood and resumed |
| **Completion detection** | Mark the run as complete when finished |
| Responsibility | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------- |
| **Database creation** | Create `state.db` and initialize core tables at run start |
| **Program registration** | Store the program source and metadata |
| **Execution tracking** | Update position, status, and timing as statements execute |
| **Subagent spawning** | Spawn sessions via Task tool with database path and instructions |
| **Parallel coordination** | Track branch status, implement join strategies |
| **Loop management** | Track iteration counts, evaluate conditions |
| **Error aggregation** | Record failures, manage retry state |
| **Context preservation** | Maintain sufficient narration in the main conversation thread so execution can be understood and resumed |
| **Completion detection** | Mark the run as complete when finished |
**Critical:** The VM must preserve enough context in its own conversation to understand execution state without re-reading the entire database. The database is for coordination and persistence, not a replacement for working memory.
@@ -111,13 +111,13 @@ The VM (the orchestrating agent running the .prose program) is responsible for:
Subagents (sessions spawned by the VM) are responsible for:
| Responsibility | Description |
|----------------|-------------|
| **Writing own outputs** | Insert/update their binding in the `bindings` table |
| **Memory management** | For persistent agents: read and update their memory record |
| **Segment recording** | For persistent agents: append segment history |
| Responsibility | Description |
| ----------------------- | ----------------------------------------------------------------- |
| **Writing own outputs** | Insert/update their binding in the `bindings` table |
| **Memory management** | For persistent agents: read and update their memory record |
| **Segment recording** | For persistent agents: append segment history |
| **Attachment handling** | Write large outputs to `attachments/` directory, store path in DB |
| **Atomic writes** | Use transactions when updating multiple related records |
| **Atomic writes** | Use transactions when updating multiple related records |
**Critical:** Subagents write ONLY to `bindings`, `agents`, and `agent_segments` tables. The VM owns the `execution` table entirely. Completion signaling happens through the substrate (Task tool return), not database updates.
@@ -126,6 +126,7 @@ Subagents (sessions spawned by the VM) are responsible for:
**What subagents return to the VM:** A confirmation message with the binding location—not the full content:
**Root scope:**
```
Binding written: research
Location: .prose/runs/20260116-143052-a7b3c9/state.db (bindings table, name='research', execution_id=NULL)
@@ -133,6 +134,7 @@ Summary: AI safety research covering alignment, robustness, and interpretability
```
**Inside block invocation:**
```
Binding written: result
Location: .prose/runs/20260116-143052-a7b3c9/state.db (bindings table, name='result', execution_id=43)
@@ -144,12 +146,12 @@ The VM tracks locations, not values. This keeps the VM's context lean and enable
### Shared Concerns
| Concern | Who Handles |
|---------|-------------|
| Concern | Who Handles |
| ---------------- | ------------------------------------------------------------------ |
| Schema evolution | Either (use `CREATE TABLE IF NOT EXISTS`, `ALTER TABLE` as needed) |
| Custom tables | Either (prefix with `x_` for extensions) |
| Indexing | Either (add indexes for frequently-queried columns) |
| Cleanup | VM (at run end, optionally vacuum) |
| Custom tables | Either (prefix with `x_` for extensions) |
| Indexing | Either (add indexes for frequently-queried columns) |
| Cleanup | VM (at run end, optionally vacuum) |
---
@@ -390,12 +392,12 @@ Even with SQLite state, the VM should narrate key events in its conversation:
### Why Both?
| Purpose | Mechanism |
|---------|-----------|
| **Working memory** | Conversation narration (what the VM "remembers" without re-querying) |
| **Durable state** | SQLite database (survives context limits, enables resumption) |
| **Subagent coordination** | SQLite database (shared access point) |
| **Debugging/inspection** | SQLite database (queryable history) |
| Purpose | Mechanism |
| ------------------------- | -------------------------------------------------------------------- |
| **Working memory** | Conversation narration (what the VM "remembers" without re-querying) |
| **Durable state** | SQLite database (survives context limits, enables resumption) |
| **Subagent coordination** | SQLite database (shared access point) |
| **Debugging/inspection** | SQLite database (queryable history) |
The narration is the VM's "mental model" of execution. The database is the "source of truth" for resumption and inspection.
@@ -544,16 +546,16 @@ The database is your workspace. Use it.
## Comparison with Other Modes
| Aspect | filesystem.md | in-context.md | sqlite.md |
|--------|---------------|---------------|-----------|
| **State location** | `.prose/runs/{id}/` files | Conversation history | `.prose/runs/{id}/state.db` |
| **Queryable** | Via file reads | No | Yes (SQL) |
| **Atomic updates** | No | N/A | Yes (transactions) |
| **Schema flexibility** | Rigid file structure | N/A | Flexible (add tables/columns) |
| **Resumption** | Read state.md | Re-read conversation | Query database |
| **Complexity ceiling** | High | Low (<30 statements) | High |
| **Dependency** | None | None | sqlite3 CLI |
| **Status** | Stable | Stable | **Experimental** |
| Aspect | filesystem.md | in-context.md | sqlite.md |
| ---------------------- | ------------------------- | -------------------- | ----------------------------- |
| **State location** | `.prose/runs/{id}/` files | Conversation history | `.prose/runs/{id}/state.db` |
| **Queryable** | Via file reads | No | Yes (SQL) |
| **Atomic updates** | No | N/A | Yes (transactions) |
| **Schema flexibility** | Rigid file structure | N/A | Flexible (add tables/columns) |
| **Resumption** | Read state.md | Re-read conversation | Query database |
| **Complexity ceiling** | High | Low (<30 statements) | High |
| **Dependency** | None | None | sqlite3 CLI |
| **Status** | Stable | Stable | **Experimental** |
---