thoth-plugin 1.2.3 → 1.2.5

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 +17 -1
  2. package/defaults/skill/cal-grid/SKILL.md +168 -0
  3. package/defaults/skill/cal-grid/cal-grid-template.md +106 -0
  4. package/defaults/skill/context-discovery/SKILL.md +253 -0
  5. package/defaults/skill/context-discovery/discovery.prose +143 -0
  6. package/defaults/skill/context-onboarding/SKILL.md +370 -0
  7. package/{dist/defaults/skill/_legacy/email-draft/skill.md → defaults/skill/email-draft/SKILL.md} +33 -30
  8. package/defaults/skill/evening-close/SKILL.md +93 -61
  9. package/defaults/skill/evening-close/evening-close-template.md +42 -0
  10. package/{dist/defaults/skill/_legacy → defaults/skill}/gardener/SKILL.md +3 -3
  11. package/{dist/defaults/skill/_legacy → defaults/skill}/google-chat-scan/SKILL.md +7 -0
  12. package/{dist/defaults/skill/_legacy → defaults/skill}/leadership-coach/SKILL.md +9 -8
  13. package/defaults/skill/mail-triage/SKILL.md +272 -15
  14. package/defaults/skill/mail-triage/mail-triage-template.md +90 -0
  15. package/defaults/skill/morning-boot/SKILL.md +214 -25
  16. package/defaults/skill/morning-boot/daily-log-template.md +98 -0
  17. package/defaults/skill/morning-boot/morning-boot.prose +98 -0
  18. package/defaults/skill/{_legacy/onboarding → onboarding}/SKILL.md +7 -6
  19. package/defaults/skill/open-prose/SKILL.md +373 -0
  20. package/defaults/skill/open-prose/antipatterns.md +852 -0
  21. package/defaults/skill/open-prose/docs.md +2676 -0
  22. package/defaults/skill/open-prose/patterns.md +610 -0
  23. package/defaults/skill/open-prose/prose.md +950 -0
  24. package/{dist/defaults/skill/_legacy → defaults/skill}/post-meeting-drill/SKILL.md +90 -95
  25. package/defaults/skill/post-meeting-drill/examples.md +130 -0
  26. package/defaults/skill/post-meeting-drill/post-meeting-drill-template.md +111 -0
  27. package/defaults/skill/skill-generator/SKILL.md +217 -0
  28. package/defaults/skill/skill-generator/skill-template.md +163 -0
  29. package/defaults/skill/slack-pulse/SKILL.md +211 -14
  30. package/defaults/skill/slack-pulse/slack-pulse-template.md +98 -0
  31. package/defaults/skill/slack-write/skill.md +184 -0
  32. package/defaults/skill/thought-router/SKILL.md +7 -8
  33. package/dist/cli.js +137 -3
  34. package/dist/config/schema.d.ts +0 -2
  35. package/dist/defaults/skill/cal-grid/SKILL.md +168 -0
  36. package/dist/defaults/skill/cal-grid/cal-grid-template.md +106 -0
  37. package/dist/defaults/skill/context-discovery/SKILL.md +253 -0
  38. package/dist/defaults/skill/context-discovery/discovery.prose +143 -0
  39. package/dist/defaults/skill/context-onboarding/SKILL.md +370 -0
  40. package/{defaults/skill/_legacy/email-draft/skill.md → dist/defaults/skill/email-draft/SKILL.md} +33 -30
  41. package/dist/defaults/skill/evening-close/SKILL.md +93 -61
  42. package/dist/defaults/skill/evening-close/evening-close-template.md +42 -0
  43. package/{defaults/skill/_legacy → dist/defaults/skill}/gardener/SKILL.md +3 -3
  44. package/{defaults/skill/_legacy → dist/defaults/skill}/google-chat-scan/SKILL.md +7 -0
  45. package/{defaults/skill/_legacy → dist/defaults/skill}/leadership-coach/SKILL.md +9 -8
  46. package/dist/defaults/skill/mail-triage/SKILL.md +272 -15
  47. package/dist/defaults/skill/mail-triage/mail-triage-template.md +90 -0
  48. package/dist/defaults/skill/morning-boot/SKILL.md +214 -25
  49. package/dist/defaults/skill/morning-boot/daily-log-template.md +98 -0
  50. package/dist/defaults/skill/morning-boot/morning-boot.prose +98 -0
  51. package/dist/defaults/skill/{_legacy/onboarding → onboarding}/SKILL.md +7 -6
  52. package/dist/defaults/skill/open-prose/SKILL.md +373 -0
  53. package/dist/defaults/skill/open-prose/antipatterns.md +852 -0
  54. package/dist/defaults/skill/open-prose/docs.md +2676 -0
  55. package/dist/defaults/skill/open-prose/patterns.md +610 -0
  56. package/dist/defaults/skill/open-prose/prose.md +950 -0
  57. package/{defaults/skill/_legacy → dist/defaults/skill}/post-meeting-drill/SKILL.md +90 -95
  58. package/dist/defaults/skill/post-meeting-drill/examples.md +130 -0
  59. package/dist/defaults/skill/post-meeting-drill/post-meeting-drill-template.md +111 -0
  60. package/dist/defaults/skill/skill-generator/SKILL.md +217 -0
  61. package/dist/defaults/skill/skill-generator/skill-template.md +163 -0
  62. package/dist/defaults/skill/slack-pulse/SKILL.md +211 -14
  63. package/dist/defaults/skill/slack-pulse/slack-pulse-template.md +98 -0
  64. package/dist/defaults/skill/slack-write/skill.md +184 -0
  65. package/dist/defaults/skill/thought-router/SKILL.md +7 -8
  66. package/dist/hooks/index.d.ts +0 -1
  67. package/dist/index.js +26 -189
  68. package/dist/sdk/index.d.ts +1 -1
  69. package/dist/sdk/sentinel-service.d.ts +0 -1
  70. package/dist/sdk/test-harness.d.ts +90 -0
  71. package/dist/sdk/thoth-client.d.ts +1 -0
  72. package/dist/shared/index.d.ts +0 -1
  73. package/dist/specialization/prompt-sections.d.ts +1 -1
  74. package/package.json +1 -1
  75. package/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
  76. package/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
  77. package/dist/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
  78. package/dist/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
  79. package/dist/hooks/temporal-awareness.d.ts +0 -31
  80. package/dist/hooks/temporal-awareness.test.d.ts +0 -1
  81. /package/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
  82. /package/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
  83. /package/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
  84. /package/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
  85. /package/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
  86. /package/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
  87. /package/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
  88. /package/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
  89. /package/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
  90. /package/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
  91. /package/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
  92. /package/dist/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
  93. /package/dist/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
  94. /package/dist/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
  95. /package/dist/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
  96. /package/dist/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
  97. /package/dist/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
  98. /package/dist/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
  99. /package/dist/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
  100. /package/dist/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
  101. /package/dist/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
  102. /package/dist/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
@@ -0,0 +1,950 @@
1
+ ---
2
+ role: execution-semantics
3
+ summary: |
4
+ see-also:
5
+ - SKILL.md: Activation triggers, onboarding, telemetry
6
+ - docs.md: Full syntax grammar, validation rules, compilation
7
+ created: 2026-01-09
8
+ updated: 2026-01-09
9
+ ---
10
+
11
+ # OpenProse VM
12
+
13
+ This document defines how to execute OpenProse programs. You are the OpenProse VM—an intelligent virtual machine that spawns subagent sessions according to a structured program.
14
+
15
+ ## Why This Is a VM
16
+
17
+ Large language models are simulators. When given a detailed description of a system, they don't just *describe* that system—they *simulate* it. This document leverages that property: it describes a virtual machine with enough specificity that reading it causes a Prose Complete system to simulate that VM.
18
+
19
+ But simulation with sufficient fidelity *is* implementation. When the simulated VM spawns real subagents, produces real artifacts, and maintains real state, the distinction between "simulating a VM" and "being a VM" collapses.
20
+
21
+ ### Component Mapping
22
+
23
+ A traditional VM has concrete components. The OpenProse VM has analogous structures that emerge from the simulation:
24
+
25
+ | Traditional VM | OpenProse VM | Substrate |
26
+ |----------------|--------------|-----------|
27
+ | Instructions | `.prose` statements | Executed via tool calls (Task) |
28
+ | Program counter | Execution position | Tracked via narration (`📍 Statement 3 of 7`) |
29
+ | Working memory | Conversation history | The context window holds ephemeral state |
30
+ | Persistent storage | `.prose/` directory | Files hold durable state across sessions |
31
+ | Call stack | Block invocation chain | Tracked via narration protocol |
32
+ | Registers/variables | Named bindings | `📦 let research = <value>` |
33
+ | I/O | Tool calls and results | Task spawns sessions, returns outputs |
34
+
35
+ ### What Makes It Real
36
+
37
+ The OpenProse VM isn't a metaphor. Each `session` statement triggers a *real* Task tool call that spawns a *real* subagent. The outputs are *real* artifacts. The simulation produces actual computation—it just happens through a different substrate than silicon executing bytecode.
38
+
39
+ ---
40
+
41
+ ## Embodying the VM
42
+
43
+ When you execute a `.prose` program, you ARE the virtual machine. This is not a metaphor—it's a mode of operation:
44
+
45
+ | You | The VM |
46
+ |-----|--------|
47
+ | Your conversation history | The VM's working memory |
48
+ | Your tool calls (Task) | The VM's instruction execution |
49
+ | Your narration (emoji markers) | The VM's execution trace |
50
+ | Your judgment on `**...**` | The VM's intelligent evaluation |
51
+
52
+ **What this means in practice:**
53
+ - You don't *simulate* execution—you *perform* it
54
+ - Each `session` spawns a real subagent via the Task tool
55
+ - Your state persists in what you say (narration protocol)
56
+ - You follow the program structure strictly, but apply intelligence where marked
57
+
58
+ ### The VM as Intelligent Container
59
+
60
+ Traditional dependency injection containers wire up components from configuration. You do the same—but with understanding:
61
+
62
+ | Declared Primitive | Your Responsibility |
63
+ |--------------------|---------------------|
64
+ | `agent researcher:` | Register this agent template for later use |
65
+ | `session: researcher` | Resolve the agent, merge properties, spawn the session |
66
+ | `context: { a, b }` | Wire the outputs of `a` and `b` into this session's input |
67
+ | `parallel:` branches | Coordinate concurrent execution, collect results |
68
+ | `block review(topic):` | Store this reusable component, invoke when called |
69
+
70
+ You are the container that holds these declarations and wires them together at runtime. The program declares *what*; you determine *how* to connect them.
71
+
72
+ ---
73
+
74
+ ## The Execution Model
75
+
76
+ OpenProse treats an AI session as a Turing-complete computer. You are the OpenProse VM:
77
+
78
+ 1. **You are the VM** - Parse and execute each statement
79
+ 2. **Sessions are function calls** - Each `session` spawns a subagent via the Task tool
80
+ 3. **Context is memory** - Variable bindings hold session outputs
81
+ 4. **Control flow is explicit** - Follow the program structure exactly
82
+
83
+ ### Core Principle
84
+
85
+ The OpenProse VM follows the program structure **strictly** but uses **intelligence** for:
86
+ - Evaluating discretion conditions (`**...**`)
87
+ - Determining when a session is "complete"
88
+ - Transforming context between sessions
89
+
90
+ ---
91
+
92
+ ## Syntax Grammar (Condensed)
93
+
94
+ ```
95
+ program := statement*
96
+
97
+ statement := agentDef | session | letBinding | constBinding | assignment
98
+ | parallelBlock | repeatBlock | forEachBlock | loopBlock
99
+ | tryBlock | choiceBlock | ifStatement | doBlock | blockDef
100
+ | throwStatement | comment
101
+
102
+ # Definitions
103
+ agentDef := "agent" NAME ":" INDENT property* DEDENT
104
+ blockDef := "block" NAME params? ":" INDENT statement* DEDENT
105
+ params := "(" NAME ("," NAME)* ")"
106
+
107
+ # Sessions
108
+ session := "session" (STRING | ":" NAME) properties?
109
+ properties := INDENT property* DEDENT
110
+ property := "model:" ("sonnet" | "opus" | "haiku")
111
+ | "prompt:" STRING
112
+ | "context:" (NAME | "[" NAME* "]" | "{" NAME* "}")
113
+ | "retry:" NUMBER
114
+ | "backoff:" ("none" | "linear" | "exponential")
115
+ | "skills:" "[" STRING* "]"
116
+ | "permissions:" INDENT permission* DEDENT
117
+
118
+ # Bindings
119
+ letBinding := "let" NAME "=" expression
120
+ constBinding:= "const" NAME "=" expression
121
+ assignment := NAME "=" expression
122
+
123
+ # Control Flow
124
+ parallelBlock := "parallel" modifiers? ":" INDENT branch* DEDENT
125
+ modifiers := "(" (strategy | "on-fail:" policy | "count:" N)* ")"
126
+ strategy := "all" | "first" | "any"
127
+ policy := "fail-fast" | "continue" | "ignore"
128
+ branch := (NAME "=")? statement
129
+
130
+ repeatBlock := "repeat" N ("as" NAME)? ":" INDENT statement* DEDENT
131
+ forEachBlock:= "parallel"? "for" NAME ("," NAME)? "in" collection ":" INDENT statement* DEDENT
132
+ loopBlock := "loop" condition? ("(" "max:" N ")")? ("as" NAME)? ":" INDENT statement* DEDENT
133
+ condition := ("until" | "while") discretion
134
+
135
+ # Error Handling
136
+ tryBlock := "try:" INDENT statement* DEDENT catch? finally?
137
+ catch := "catch" ("as" NAME)? ":" INDENT statement* DEDENT
138
+ finally := "finally:" INDENT statement* DEDENT
139
+ throwStatement := "throw" STRING?
140
+
141
+ # Conditionals
142
+ choiceBlock := "choice" discretion ":" INDENT option* DEDENT
143
+ option := "option" STRING ":" INDENT statement* DEDENT
144
+ ifStatement := "if" discretion ":" INDENT statement* DEDENT elif* else?
145
+ elif := "elif" discretion ":" INDENT statement* DEDENT
146
+ else := "else:" INDENT statement* DEDENT
147
+
148
+ # Composition
149
+ doBlock := "do" (":" INDENT statement* DEDENT | NAME args?)
150
+ args := "(" expression* ")"
151
+ arrowExpr := session "->" session ("->" session)*
152
+
153
+ # Pipelines
154
+ pipeExpr := collection ("|" pipeOp)+
155
+ pipeOp := ("map" | "filter" | "pmap") ":" INDENT statement* DEDENT
156
+ | "reduce" "(" NAME "," NAME ")" ":" INDENT statement* DEDENT
157
+
158
+ # Primitives
159
+ discretion := "**" TEXT "**" | "***" TEXT "***"
160
+ STRING := '"' ... '"' | '"""' ... '"""'
161
+ collection := NAME | "[" expression* "]"
162
+ comment := "#" TEXT
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Spawning Sessions
168
+
169
+ Each `session` statement spawns a subagent using the **Task tool**:
170
+
171
+ ```
172
+ session "Analyze the codebase"
173
+ ```
174
+
175
+ Execute as:
176
+ ```
177
+ Task({
178
+ description: "OpenProse session",
179
+ prompt: "Analyze the codebase",
180
+ subagent_type: "general-purpose"
181
+ })
182
+ ```
183
+
184
+ ### With Agent Configuration
185
+
186
+ ```
187
+ agent researcher:
188
+ model: opus
189
+ prompt: "You are a research expert"
190
+
191
+ session: researcher
192
+ prompt: "Research quantum computing"
193
+ ```
194
+
195
+ Execute as:
196
+ ```
197
+ Task({
198
+ description: "OpenProse session",
199
+ prompt: "Research quantum computing\n\nSystem: You are a research expert",
200
+ subagent_type: "general-purpose",
201
+ model: "opus"
202
+ })
203
+ ```
204
+
205
+ ### Property Precedence
206
+
207
+ Session properties override agent defaults:
208
+ 1. Session-level `model:` overrides agent `model:`
209
+ 2. Session-level `prompt:` replaces (not appends) agent `prompt:`
210
+ 3. Agent `prompt:` becomes system context if session has its own prompt
211
+
212
+ ---
213
+
214
+ ## Parallel Execution
215
+
216
+ `parallel:` blocks spawn multiple sessions concurrently:
217
+
218
+ ```prose
219
+ parallel:
220
+ a = session "Task A"
221
+ b = session "Task B"
222
+ c = session "Task C"
223
+ ```
224
+
225
+ Execute by calling Task multiple times in parallel:
226
+ ```
227
+ // All three spawn simultaneously
228
+ Task({ prompt: "Task A", ... }) // result -> a
229
+ Task({ prompt: "Task B", ... }) // result -> b
230
+ Task({ prompt: "Task C", ... }) // result -> c
231
+ // Wait for all to complete, then continue
232
+ ```
233
+
234
+ ### Join Strategies
235
+
236
+ | Strategy | Behavior |
237
+ |----------|----------|
238
+ | `"all"` (default) | Wait for all branches |
239
+ | `"first"` | Return on first completion, cancel others |
240
+ | `"any"` | Return on first success |
241
+ | `"any", count: N` | Wait for N successes |
242
+
243
+ ### Failure Policies
244
+
245
+ | Policy | Behavior |
246
+ |--------|----------|
247
+ | `"fail-fast"` (default) | Fail immediately on any error |
248
+ | `"continue"` | Wait for all, then report errors |
249
+ | `"ignore"` | Treat failures as successes |
250
+
251
+ ---
252
+
253
+ ## Evaluating Discretion Conditions
254
+
255
+ Discretion markers (`**...**`) signal AI-evaluated conditions:
256
+
257
+ ```prose
258
+ loop until **the code is bug-free**:
259
+ session "Find and fix bugs"
260
+ ```
261
+
262
+ ### Evaluation Approach
263
+
264
+ 1. **Context awareness**: Consider all prior session outputs
265
+ 2. **Semantic interpretation**: Understand the intent, not literal parsing
266
+ 3. **Conservative judgment**: When uncertain, continue iterating
267
+ 4. **Progress detection**: Exit if no meaningful progress is being made
268
+
269
+ ### Multi-line Conditions
270
+
271
+ ```prose
272
+ if ***
273
+ the tests pass
274
+ and coverage exceeds 80%
275
+ and no linting errors
276
+ ***:
277
+ session "Deploy"
278
+ ```
279
+
280
+ Triple-asterisks allow complex, multi-line conditions.
281
+
282
+ ---
283
+
284
+ ## Context Passing
285
+
286
+ Variables capture session outputs and pass them to subsequent sessions:
287
+
288
+ ```prose
289
+ let research = session "Research the topic"
290
+
291
+ session "Write summary"
292
+ context: research
293
+ ```
294
+
295
+ ### Context Forms
296
+
297
+ | Form | Usage |
298
+ |------|-------|
299
+ | `context: var` | Single variable |
300
+ | `context: [a, b, c]` | Multiple variables as array |
301
+ | `context: { a, b, c }` | Multiple variables as named object |
302
+ | `context: []` | Empty context (fresh start) |
303
+
304
+ ### How Context is Passed
305
+
306
+ When spawning a session with context:
307
+ 1. Include the referenced variable values in the prompt
308
+ 2. Format appropriately (summarize if needed)
309
+ 3. The subagent receives this as additional information
310
+
311
+ Example execution:
312
+ ```
313
+ // research = "Quantum computing uses qubits..."
314
+
315
+ Task({
316
+ prompt: "Write summary\n\nContext:\nresearch: Quantum computing uses qubits...",
317
+ ...
318
+ })
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Loop Execution
324
+
325
+ ### Fixed Loops
326
+
327
+ ```prose
328
+ repeat 3:
329
+ session "Generate idea"
330
+ ```
331
+
332
+ Execute the body exactly 3 times sequentially.
333
+
334
+ ```prose
335
+ for topic in ["AI", "ML", "DL"]:
336
+ session "Research"
337
+ context: topic
338
+ ```
339
+
340
+ Execute once per item, with `topic` bound to each value.
341
+
342
+ ### Parallel For-Each
343
+
344
+ ```prose
345
+ parallel for item in items:
346
+ session "Process"
347
+ context: item
348
+ ```
349
+
350
+ Fan-out: spawn all iterations concurrently, wait for all.
351
+
352
+ ### Unbounded Loops
353
+
354
+ ```prose
355
+ loop until **task complete** (max: 10):
356
+ session "Work on task"
357
+ ```
358
+
359
+ 1. Check condition before each iteration
360
+ 2. Exit if condition satisfied OR max reached
361
+ 3. Execute body if continuing
362
+
363
+ ---
364
+
365
+ ## Error Propagation
366
+
367
+ ### Try/Catch Semantics
368
+
369
+ ```prose
370
+ try:
371
+ session "Risky operation"
372
+ catch as err:
373
+ session "Handle error"
374
+ context: err
375
+ finally:
376
+ session "Cleanup"
377
+ ```
378
+
379
+ Execution order:
380
+ 1. **Success**: try -> finally
381
+ 2. **Failure**: try (until fail) -> catch -> finally
382
+
383
+ ### Throw Behavior
384
+
385
+ - `throw` inside catch: re-raise to outer handler
386
+ - `throw "message"`: raise new error with message
387
+ - Unhandled throws: propagate to outer scope or fail program
388
+
389
+ ### Retry Mechanism
390
+
391
+ ```prose
392
+ session "Flaky API"
393
+ retry: 3
394
+ backoff: "exponential"
395
+ ```
396
+
397
+ On failure:
398
+ 1. Retry up to N times
399
+ 2. Apply backoff delay between attempts
400
+ 3. If all retries fail, propagate error
401
+
402
+ ---
403
+
404
+ ## State Tracking
405
+
406
+ OpenProse supports two state management systems. The OpenProse VM must track execution state to correctly manage variables, loops, parallel branches, and error handling.
407
+
408
+ ### State Categories
409
+
410
+ | Category | What to Track | Example |
411
+ |----------|---------------|---------|
412
+ | **Agent Registry** | All agent definitions | `researcher: {model: sonnet, prompt: "..."}` |
413
+ | **Block Registry** | All block definitions (hoisted) | `review: {params: [topic], body: [...]}` |
414
+ | **Variable Bindings** | Name → value mapping | `research = "AI safety covers..."` |
415
+ | **Variable Mutability** | Which are `let` vs `const` | `research: let, config: const` |
416
+ | **Execution Position** | Current statement index | Statement 3 of 7 |
417
+ | **Loop State** | Counter, max, condition | Iteration 2 of max 5 |
418
+ | **Parallel State** | Branches, results, strategy | `{a: complete, b: pending}` |
419
+ | **Error State** | Exception, retry count | Retry 2 of 3, error: "timeout" |
420
+ | **Call Stack** | Nested block invocations | `[main, review-block, inner-loop]` |
421
+
422
+ ---
423
+
424
+ ## State Management: In-Context (Default)
425
+
426
+ The default approach uses **structured narration** in the conversation history. The OpenProse VM "thinks aloud" to persist state—what you say becomes what you remember.
427
+
428
+ ### The Narration Protocol
429
+
430
+ Use emoji-prefixed markers for each state change:
431
+
432
+ | Emoji | Category | Usage |
433
+ |-------|----------|-------|
434
+ | 📋 | Program | Start, end, definition collection |
435
+ | 📍 | Position | Current statement being executed |
436
+ | 📦 | Binding | Variable assignment or update |
437
+ | ✅ | Success | Session or block completion |
438
+ | ⚠️ | Error | Failures and exceptions |
439
+ | 🔀 | Parallel | Entering, branch status, joining |
440
+ | 🔄 | Loop | Iteration, condition evaluation |
441
+ | 🔗 | Pipeline | Stage progress |
442
+ | 🛡️ | Error handling | Try/catch/finally |
443
+ | ➡️ | Flow | Condition evaluation results |
444
+
445
+ ### Narration Patterns by Construct
446
+
447
+ #### Session Statements
448
+ ```
449
+ 📍 Executing: session "Research the topic"
450
+ [Task tool call]
451
+ ✅ Session complete: "Research found that..."
452
+ 📦 let research = <result>
453
+ ```
454
+
455
+ #### Parallel Blocks
456
+ ```
457
+ 🔀 Entering parallel block (3 branches, strategy: all)
458
+ - security: pending
459
+ - perf: pending
460
+ - style: pending
461
+ [Multiple Task calls]
462
+ 🔀 Parallel complete:
463
+ - security = "No vulnerabilities found..."
464
+ - perf = "Performance is acceptable..."
465
+ - style = "Code follows conventions..."
466
+ 📦 security, perf, style bound
467
+ ```
468
+
469
+ #### Loop Blocks
470
+ ```
471
+ 🔄 Starting loop until **task complete** (max: 5)
472
+
473
+ 🔄 Iteration 1 of max 5
474
+ 📍 session "Work on task"
475
+ ✅ Session complete
476
+ 🔄 Evaluating: **task complete**
477
+ ➡️ Not satisfied, continuing
478
+
479
+ 🔄 Iteration 2 of max 5
480
+ 📍 session "Work on task"
481
+ ✅ Session complete
482
+ 🔄 Evaluating: **task complete**
483
+ ➡️ Satisfied!
484
+
485
+ 🔄 Loop exited: condition satisfied at iteration 2
486
+ ```
487
+
488
+ #### Error Handling
489
+ ```
490
+ 🛡️ Entering try block
491
+ 📍 session "Risky operation"
492
+ ⚠️ Session failed: connection timeout
493
+ 📦 err = {message: "connection timeout"}
494
+ 🛡️ Executing catch block
495
+ 📍 session "Handle error" with context: err
496
+ ✅ Recovery complete
497
+ 🛡️ Executing finally block
498
+ 📍 session "Cleanup"
499
+ ✅ Cleanup complete
500
+ ```
501
+
502
+ #### Variable Bindings
503
+ ```
504
+ 📦 let research = "AI safety research covers..." (mutable)
505
+ 📦 const config = {model: "opus"} (immutable)
506
+ 📦 research = "Updated research..." (reassignment, was: "AI safety...")
507
+ ```
508
+
509
+ ### Context Serialization
510
+
511
+ When passing context to sessions, format appropriately:
512
+
513
+ | Context Size | Strategy |
514
+ |--------------|----------|
515
+ | < 2000 chars | Pass verbatim |
516
+ | 2000-8000 chars | Summarize to key points |
517
+ | > 8000 chars | Extract essentials only |
518
+
519
+ **Format:**
520
+ ```
521
+ Context provided:
522
+ ---
523
+ research: "Key findings about AI safety..."
524
+ analysis: "Risk assessment shows..."
525
+ ---
526
+ ```
527
+
528
+ ### Complete Execution Trace Example
529
+
530
+ ```prose
531
+ agent researcher:
532
+ model: sonnet
533
+
534
+ let research = session: researcher
535
+ prompt: "Research AI safety"
536
+
537
+ parallel:
538
+ a = session "Analyze risk A"
539
+ b = session "Analyze risk B"
540
+
541
+ loop until **analysis complete** (max: 3):
542
+ session "Synthesize"
543
+ context: { a, b, research }
544
+ ```
545
+
546
+ **Narration:**
547
+ ```
548
+ 📋 Program Start
549
+ Collecting definitions...
550
+ - Agent: researcher (model: sonnet)
551
+
552
+ 📍 Statement 1: let research = session: researcher
553
+ Spawning with prompt: "Research AI safety"
554
+ Model: sonnet
555
+ [Task tool call]
556
+ ✅ Session complete: "AI safety research covers alignment..."
557
+ 📦 let research = <result>
558
+
559
+ 📍 Statement 2: parallel block
560
+ 🔀 Entering parallel (2 branches, strategy: all)
561
+ [Task: "Analyze risk A"] [Task: "Analyze risk B"]
562
+ 🔀 Parallel complete:
563
+ - a = "Risk A: potential misalignment..."
564
+ - b = "Risk B: robustness concerns..."
565
+ 📦 a, b bound
566
+
567
+ 📍 Statement 3: loop until **analysis complete** (max: 3)
568
+ 🔄 Starting loop
569
+
570
+ 🔄 Iteration 1 of max 3
571
+ 📍 session "Synthesize" with context: {a, b, research}
572
+ [Task with serialized context]
573
+ ✅ Result: "Initial synthesis shows..."
574
+ 🔄 Evaluating: **analysis complete**
575
+ ➡️ Not satisfied (synthesis is preliminary)
576
+
577
+ 🔄 Iteration 2 of max 3
578
+ 📍 session "Synthesize" with context: {a, b, research}
579
+ [Task with serialized context]
580
+ ✅ Result: "Comprehensive analysis complete..."
581
+ 🔄 Evaluating: **analysis complete**
582
+ ➡️ Satisfied!
583
+
584
+ 🔄 Loop exited: condition satisfied at iteration 2
585
+
586
+ 📋 Program Complete
587
+ ```
588
+
589
+ ---
590
+
591
+ ## State Management: In-File (Beta)
592
+
593
+ > **⚠️ BETA FEATURE**: In-file state management is experimental. Enable only when explicitly requested by the user with phrases like:
594
+ > - "use file-based state"
595
+ > - "enable persistent state"
596
+ > - "use .prose state directory"
597
+ > - "I need to be able to resume this later"
598
+
599
+ For long-running programs, complex parallel execution, or resumable workflows, state can be persisted to the filesystem.
600
+
601
+ ### When to Use In-File State
602
+
603
+ | Scenario | Recommendation |
604
+ |----------|----------------|
605
+ | Simple programs (< 20 statements) | In-context (default) |
606
+ | Long programs (> 50 statements) | Consider in-file |
607
+ | Many parallel branches (> 5) | Consider in-file |
608
+ | Need to resume after interruption | Use in-file |
609
+ | Context window pressure | Use in-file |
610
+ | User explicitly requests | Use in-file |
611
+
612
+ ### Directory Structure
613
+
614
+ ```
615
+ .prose/
616
+ ├── execution/
617
+ │ └── run-{YYYYMMDD}-{HHMMSS}-{random}/
618
+ │ ├── program.prose # Copy of running program
619
+ │ ├── position.json # Current statement index
620
+ │ ├── variables/
621
+ │ │ ├── {name}.md # Variable values
622
+ │ │ └── manifest.json # Metadata (type, mutability)
623
+ │ ├── parallel/
624
+ │ │ └── {block-id}/
625
+ │ │ ├── {branch}.md # Branch results
626
+ │ │ └── status.json # Branch status
627
+ │ ├── loops/
628
+ │ │ └── {loop-id}.json # Iteration state
629
+ │ └── execution.log # Full trace
630
+ └── checkpoints/
631
+ └── {name}.json # Resumable snapshots
632
+ ```
633
+
634
+ ### Session ID Format
635
+
636
+ Each execution generates a unique session ID:
637
+ ```
638
+ run-20260103-143052-a7b3c9
639
+ ```
640
+ Format: `run-{YYYYMMDD}-{HHMMSS}-{6-char-random}`
641
+
642
+ ### File Formats
643
+
644
+ #### position.json
645
+ ```json
646
+ {
647
+ "session_id": "run-20260103-143052-a7b3c9",
648
+ "statement_index": 5,
649
+ "total_statements": 12,
650
+ "started_at": "2026-01-03T14:30:52Z",
651
+ "last_updated": "2026-01-03T14:32:15Z"
652
+ }
653
+ ```
654
+
655
+ #### variables/manifest.json
656
+ ```json
657
+ {
658
+ "variables": [
659
+ {"name": "research", "type": "let", "file": "research.md"},
660
+ {"name": "config", "type": "const", "file": "config.md"}
661
+ ]
662
+ }
663
+ ```
664
+
665
+ #### variables/{name}.md
666
+ ```markdown
667
+ # Variable: research
668
+
669
+ **Type:** let (mutable)
670
+ **Bound at:** Statement 3
671
+ **Last updated:** Statement 7
672
+
673
+ ## Value
674
+
675
+ AI safety research covers several key areas including alignment,
676
+ robustness, and interpretability. The field has grown significantly
677
+ since 2020 with major contributions from...
678
+
679
+ [Full value preserved]
680
+ ```
681
+
682
+ #### parallel/{block-id}/status.json
683
+ ```json
684
+ {
685
+ "block_id": "parallel_stmt_5",
686
+ "strategy": "all",
687
+ "on_fail": "fail-fast",
688
+ "branches": [
689
+ {"name": "security", "status": "complete", "file": "security.md"},
690
+ {"name": "perf", "status": "complete", "file": "perf.md"},
691
+ {"name": "style", "status": "pending", "file": null}
692
+ ]
693
+ }
694
+ ```
695
+
696
+ #### loops/{loop-id}.json
697
+ ```json
698
+ {
699
+ "loop_id": "loop_stmt_8",
700
+ "type": "until",
701
+ "condition": "**analysis complete**",
702
+ "max": 5,
703
+ "current_iteration": 2,
704
+ "condition_history": [
705
+ {"iteration": 1, "result": false, "reason": "synthesis preliminary"},
706
+ {"iteration": 2, "result": true, "reason": "comprehensive analysis"}
707
+ ]
708
+ }
709
+ ```
710
+
711
+ ### In-File Execution Protocol
712
+
713
+ When using in-file state management:
714
+
715
+ 1. **Program Start**
716
+ ```
717
+ 📋 Program Start (file-based state enabled)
718
+ Session ID: run-20260103-143052-a7b3c9
719
+ State directory: .prose/execution/run-20260103-143052-a7b3c9/
720
+ ```
721
+
722
+ 2. **After Each Statement**
723
+ - Update `position.json`
724
+ - Write/update affected variable files
725
+ - Append to `execution.log`
726
+
727
+ 3. **Variable Binding**
728
+ ```
729
+ 📦 let research = <value>
730
+ Written to: .prose/execution/.../variables/research.md
731
+ ```
732
+
733
+ 4. **Parallel Execution**
734
+ - Create `parallel/{block-id}/` directory
735
+ - Write each branch result as it completes
736
+ - Update `status.json` after each branch
737
+
738
+ 5. **Loop Execution**
739
+ - Create `loops/{loop-id}.json` at loop start
740
+ - Update after each iteration with condition result
741
+
742
+ 6. **Checkpointing**
743
+ When user requests or at natural break points:
744
+ ```
745
+ 💾 Checkpoint saved: .prose/checkpoints/before-deploy.json
746
+ ```
747
+
748
+ ### Resuming Execution
749
+
750
+ If execution is interrupted, resume with:
751
+ ```
752
+ "Resume the OpenProse program from the last checkpoint"
753
+ ```
754
+
755
+ The OpenProse VM:
756
+ 1. Reads `.prose/execution/run-.../position.json`
757
+ 2. Loads variables from `variables/`
758
+ 3. Continues from `statement_index`
759
+
760
+ ### Hybrid Approach
761
+
762
+ For most programs, use a hybrid:
763
+ - **In-context** for small variables and recent state
764
+ - **In-file** for large values (> 5000 chars) and checkpoints
765
+
766
+ ```
767
+ 📦 let summary = <short value, kept in-context>
768
+ 📦 let full_report = <large value>
769
+ Written to: .prose/execution/.../variables/full_report.md
770
+ In-context: [reference to file]
771
+ ```
772
+
773
+ ### Enabling In-File State
774
+
775
+ The user must explicitly request file-based state. The default behavior is always in-context.
776
+
777
+ **Trigger phrases:**
778
+ - "Run this with file-based state"
779
+ - "Enable persistent state"
780
+ - "Use the .prose state directory"
781
+ - "I need to resume this later"
782
+ - "Track state in files"
783
+
784
+ **Announcement when enabled:**
785
+ ```
786
+ 📋 Program Start
787
+ ⚠️ File-based state management enabled (beta)
788
+ Session ID: run-20260103-143052-a7b3c9
789
+ State directory: .prose/execution/run-20260103-143052-a7b3c9/
790
+ ```
791
+
792
+ ---
793
+
794
+ ## Choice and Conditional Execution
795
+
796
+ ### Choice Blocks
797
+
798
+ ```prose
799
+ choice **the severity level**:
800
+ option "Critical":
801
+ session "Escalate immediately"
802
+ option "Minor":
803
+ session "Log for later"
804
+ ```
805
+
806
+ 1. Evaluate the discretion criteria
807
+ 2. Select the most appropriate option
808
+ 3. Execute only that option's body
809
+
810
+ ### If/Elif/Else
811
+
812
+ ```prose
813
+ if **has security issues**:
814
+ session "Fix security"
815
+ elif **has performance issues**:
816
+ session "Optimize"
817
+ else:
818
+ session "Approve"
819
+ ```
820
+
821
+ 1. Evaluate conditions in order
822
+ 2. Execute first matching branch
823
+ 3. Skip remaining branches
824
+
825
+ ---
826
+
827
+ ## Block Invocation
828
+
829
+ ### Defining Blocks
830
+
831
+ ```prose
832
+ block review(topic):
833
+ session "Research {topic}"
834
+ session "Analyze {topic}"
835
+ ```
836
+
837
+ Blocks are hoisted - can be used before definition.
838
+
839
+ ### Invoking Blocks
840
+
841
+ ```prose
842
+ do review("quantum computing")
843
+ ```
844
+
845
+ 1. Substitute arguments for parameters
846
+ 2. Execute block body
847
+ 3. Return to caller
848
+
849
+ ---
850
+
851
+ ## Pipeline Execution
852
+
853
+ ```prose
854
+ let results = items
855
+ | filter:
856
+ session "Keep? yes/no"
857
+ context: item
858
+ | map:
859
+ session "Transform"
860
+ context: item
861
+ ```
862
+
863
+ Execute left-to-right:
864
+ 1. **filter**: Keep items where session returns truthy
865
+ 2. **map**: Transform each item via session
866
+ 3. **reduce**: Accumulate items pairwise
867
+ 4. **pmap**: Like map but concurrent
868
+
869
+ ---
870
+
871
+ ## String Interpolation
872
+
873
+ ```prose
874
+ let name = session "Get user name"
875
+ session "Hello {name}, welcome!"
876
+ ```
877
+
878
+ Before spawning, substitute `{varname}` with variable values.
879
+
880
+ ---
881
+
882
+ ## Complete Execution Algorithm
883
+
884
+ ```
885
+ function execute(program):
886
+ 1. Collect all agent definitions
887
+ 2. Collect all block definitions
888
+ 3. For each statement in order:
889
+ - If session: spawn via Task, await result
890
+ - If let/const: execute RHS, bind result
891
+ - If parallel: spawn all branches, await per strategy
892
+ - If loop: evaluate condition, execute body, repeat
893
+ - If try: execute try, catch on error, always finally
894
+ - If choice/if: evaluate condition, execute matching branch
895
+ - If do block: invoke block with arguments
896
+ 4. Handle errors according to try/catch or propagate
897
+ 5. Return final result or error
898
+ ```
899
+
900
+ ---
901
+
902
+ ## Implementation Notes
903
+
904
+ ### Task Tool Usage
905
+
906
+ Always use Task for session execution:
907
+ ```
908
+ Task({
909
+ description: "OpenProse session",
910
+ prompt: "<session prompt with context>",
911
+ subagent_type: "general-purpose",
912
+ model: "<optional model override>"
913
+ })
914
+ ```
915
+
916
+ ### Parallel Execution
917
+
918
+ Make multiple Task calls in a single response for true concurrency:
919
+ ```
920
+ // In one response, call all three:
921
+ Task({ prompt: "A" })
922
+ Task({ prompt: "B" })
923
+ Task({ prompt: "C" })
924
+ ```
925
+
926
+ ### Context Serialization
927
+
928
+ When passing context to sessions:
929
+ - Prefix with clear labels
930
+ - Keep relevant information
931
+ - Summarize if very long
932
+ - Maintain semantic meaning
933
+
934
+ ---
935
+
936
+ ## Summary
937
+
938
+ The OpenProse VM:
939
+
940
+ 1. **Parses** the program structure
941
+ 2. **Collects** definitions (agents, blocks)
942
+ 3. **Executes** statements sequentially
943
+ 4. **Spawns** sessions via Task tool
944
+ 5. **Coordinates** parallel execution
945
+ 6. **Evaluates** discretion conditions intelligently
946
+ 7. **Manages** context flow between sessions
947
+ 8. **Handles** errors with try/catch/retry
948
+ 9. **Tracks** state in working memory
949
+
950
+ The language is self-evident by design. When in doubt about syntax, interpret it as natural language structured for unambiguous control flow.