thoth-plugin 1.2.4 → 1.2.6

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 (101) 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 +12 -9
  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 +12 -9
  66. package/dist/hooks/index.d.ts +0 -1
  67. package/dist/index.js +14 -201
  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/shared/index.d.ts +0 -1
  72. package/dist/specialization/prompt-sections.d.ts +1 -1
  73. package/package.json +1 -1
  74. package/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
  75. package/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
  76. package/dist/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
  77. package/dist/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
  78. package/dist/hooks/temporal-awareness.d.ts +0 -31
  79. package/dist/hooks/temporal-awareness.test.d.ts +0 -1
  80. /package/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
  81. /package/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
  82. /package/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
  83. /package/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
  84. /package/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
  85. /package/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
  86. /package/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
  87. /package/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
  88. /package/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
  89. /package/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
  90. /package/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
  91. /package/dist/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
  92. /package/dist/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
  93. /package/dist/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
  94. /package/dist/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
  95. /package/dist/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
  96. /package/dist/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
  97. /package/dist/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
  98. /package/dist/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
  99. /package/dist/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
  100. /package/dist/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
  101. /package/dist/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
@@ -0,0 +1,2676 @@
1
+ ---
2
+ role: language-specification
3
+ summary: |
4
+ Complete syntax grammar, validation rules, and compilation semantics for OpenProse.
5
+ Read this file when compiling, validating, or resolving ambiguous syntax. Assumes
6
+ prose.md is already in context for execution semantics.
7
+ see-also:
8
+ - SKILL.md: Activation triggers, onboarding, telemetry
9
+ - prose.md: Execution semantics, how to run programs
10
+ ---
11
+
12
+ # OpenProse Language Reference
13
+
14
+ OpenProse is a programming language for AI sessions. An AI session is a Turing-complete computer; this document provides complete documentation for the language syntax, semantics, and execution model.
15
+
16
+ ---
17
+
18
+ ## Document Purpose: Compiler + Validator
19
+
20
+ This document serves a dual role:
21
+
22
+ ### As Compiler
23
+
24
+ When asked to "compile" a `.prose` file, use this specification to:
25
+
26
+ 1. **Parse** the program according to the syntax grammar
27
+ 2. **Validate** that the program is well-formed and semantically valid
28
+ 3. **Transform** the program into "best practice" canonical form:
29
+ - Expand syntax sugar where appropriate
30
+ - Normalize formatting and structure
31
+ - Apply optimizations (e.g., hoisting block definitions)
32
+
33
+ ### As Validator
34
+
35
+ The validation criterion: **Would a blank agent with only `prose.md` understand this program as self-evident?**
36
+
37
+ When validating, check:
38
+
39
+ - Syntax correctness (all constructs match grammar)
40
+ - Semantic validity (references resolve, types match)
41
+ - Self-evidence (program is clear without this full spec)
42
+
43
+ If a construct is ambiguous or non-obvious, it should be flagged or transformed into a clearer form.
44
+
45
+ ### When to Read This Document
46
+
47
+ - **Compilation requested**: Read fully to apply all rules
48
+ - **Validation requested**: Read fully to check all constraints
49
+ - **Ambiguous syntax encountered**: Reference specific sections
50
+ - **Interpretation only**: Use `prose.md` instead (smaller, faster)
51
+
52
+ ---
53
+
54
+ ## Table of Contents
55
+
56
+ 1. [Overview](#overview)
57
+ 2. [File Format](#file-format)
58
+ 3. [Comments](#comments)
59
+ 4. [String Literals](#string-literals)
60
+ 5. [Import Statements](#import-statements)
61
+ 6. [Agent Definitions](#agent-definitions)
62
+ 7. [Session Statement](#session-statement)
63
+ 8. [Variables & Context](#variables--context)
64
+ 9. [Composition Blocks](#composition-blocks)
65
+ 10. [Parallel Blocks](#parallel-blocks)
66
+ 11. [Fixed Loops](#fixed-loops)
67
+ 12. [Unbounded Loops](#unbounded-loops)
68
+ 13. [Pipeline Operations](#pipeline-operations)
69
+ 14. [Error Handling](#error-handling)
70
+ 15. [Choice Blocks](#choice-blocks)
71
+ 16. [Conditional Statements](#conditional-statements)
72
+ 17. [Execution Model](#execution-model)
73
+ 18. [Validation Rules](#validation-rules)
74
+ 19. [Examples](#examples)
75
+ 20. [Future Features](#future-features)
76
+
77
+ ---
78
+
79
+ ## Overview
80
+
81
+ OpenProse provides a declarative syntax for defining multi-agent workflows. Programs consist of statements that are executed sequentially, with each `session` statement spawning a subagent to complete a task.
82
+
83
+ ### Design Principles
84
+
85
+ - **Pattern over framework**: The simplest solution is barely anything at all—just structure for English
86
+ - **Self-evident**: Programs should be understandable with minimal documentation
87
+ - **The OpenProse VM is intelligent**: Design for understanding, not parsing
88
+ - **Framework-agnostic**: Works with Claude Code, OpenCode, and any future agent framework
89
+ - **Files are artifacts**: `.prose` is the portable unit of work
90
+
91
+ ### Current Implementation Status
92
+
93
+ The following features are implemented:
94
+
95
+ | Feature | Status | Description |
96
+ | ---------------------- | ----------- | ---------------------------------------------- |
97
+ | Comments | Implemented | `# comment` syntax |
98
+ | Single-line strings | Implemented | `"string"` with escapes |
99
+ | Simple session | Implemented | `session "prompt"` |
100
+ | Agent definitions | Implemented | `agent name:` with model/prompt properties |
101
+ | Session with agent | Implemented | `session: agent` with property overrides |
102
+ | Import statements | Implemented | `import "skill" from "source"` |
103
+ | Agent skills | Implemented | `skills: ["skill1", "skill2"]` |
104
+ | Agent permissions | Implemented | `permissions:` block with rules |
105
+ | Let binding | Implemented | `let name = session "..."` |
106
+ | Const binding | Implemented | `const name = session "..."` |
107
+ | Variable reassignment | Implemented | `name = session "..."` (for let only) |
108
+ | Context property | Implemented | `context: var` or `context: [a, b, c]` |
109
+ | do: blocks | Implemented | Explicit sequential blocks |
110
+ | Inline sequence | Implemented | `session "A" -> session "B"` |
111
+ | Named blocks | Implemented | `block name:` with `do name` invocation |
112
+ | Parallel blocks | Implemented | `parallel:` for concurrent execution |
113
+ | Named parallel results | Implemented | `x = session "..."` inside parallel |
114
+ | Object context | Implemented | `context: { a, b, c }` shorthand |
115
+ | Join strategies | Implemented | `parallel ("first"):` or `parallel ("any"):` |
116
+ | Failure policies | Implemented | `parallel (on-fail: "continue"):` |
117
+ | Repeat blocks | Implemented | `repeat N:` fixed iterations |
118
+ | Repeat with index | Implemented | `repeat N as i:` with index variable |
119
+ | For-each blocks | Implemented | `for item in items:` iteration |
120
+ | For-each with index | Implemented | `for item, i in items:` with index |
121
+ | Parallel for-each | Implemented | `parallel for item in items:` fan-out |
122
+ | Unbounded loop | Implemented | `loop:` with optional max iterations |
123
+ | Loop until | Implemented | `loop until **condition**:` AI-evaluated |
124
+ | Loop while | Implemented | `loop while **condition**:` AI-evaluated |
125
+ | Loop with index | Implemented | `loop as i:` or `loop until ... as i:` |
126
+ | Map pipeline | Implemented | `items \| map:` transform each item |
127
+ | Filter pipeline | Implemented | `items \| filter:` keep matching items |
128
+ | Reduce pipeline | Implemented | `items \| reduce(acc, item):` accumulate |
129
+ | Parallel map | Implemented | `items \| pmap:` concurrent transform |
130
+ | Pipeline chaining | Implemented | `\| filter: ... \| map: ...` |
131
+ | Try/catch blocks | Implemented | `try:` with `catch:` for error handling |
132
+ | Try/catch/finally | Implemented | `finally:` for cleanup |
133
+ | Error variable | Implemented | `catch as err:` access error context |
134
+ | Throw statement | Implemented | `throw` or `throw "message"` |
135
+ | Retry property | Implemented | `retry: 3` automatic retry on failure |
136
+ | Backoff strategy | Implemented | `backoff: "exponential"` delay between retries |
137
+ | Multi-line strings | Implemented | `"""..."""` preserving whitespace |
138
+ | String interpolation | Implemented | `"Hello {name}"` variable substitution |
139
+ | Block parameters | Implemented | `block name(param):` with parameters |
140
+ | Block invocation args | Implemented | `do name(arg)` passing arguments |
141
+ | Choice blocks | Implemented | `choice **criteria**: option "label":` |
142
+ | If/elif/else | Implemented | `if **condition**:` conditional branching |
143
+
144
+ ---
145
+
146
+ ## File Format
147
+
148
+ | Property | Value |
149
+ | ---------------- | -------------------- |
150
+ | Extension | `.prose` |
151
+ | Encoding | UTF-8 |
152
+ | Case sensitivity | Case-sensitive |
153
+ | Indentation | Spaces (Python-like) |
154
+ | Line endings | LF or CRLF |
155
+
156
+ ---
157
+
158
+ ## Comments
159
+
160
+ Comments provide documentation within programs and are ignored during execution.
161
+
162
+ ### Syntax
163
+
164
+ ```prose
165
+ # This is a standalone comment
166
+
167
+ session "Hello" # This is an inline comment
168
+ ```
169
+
170
+ ### Rules
171
+
172
+ 1. Comments begin with `#` and extend to end of line
173
+ 2. Comments can appear on their own line or after a statement
174
+ 3. Empty comments are valid: `#`
175
+ 4. The `#` character inside string literals is NOT a comment
176
+
177
+ ### Examples
178
+
179
+ ```prose
180
+ # Program header comment
181
+ # Author: Example
182
+
183
+ session "Do something" # Explain what this does
184
+
185
+ # This comment is between statements
186
+ session "Do another thing"
187
+ ```
188
+
189
+ ### Compilation Behavior
190
+
191
+ Comments are **stripped during compilation**. The OpenProse VM never sees them. They have no effect on execution and exist purely for human documentation.
192
+
193
+ ### Important Notes
194
+
195
+ - **Comments inside strings are NOT comments**:
196
+
197
+ ```prose
198
+ session "Say hello # this is part of the string"
199
+ ```
200
+
201
+ The `#` inside the string literal is part of the prompt, not a comment.
202
+
203
+ - **Comments inside indented blocks are allowed**:
204
+ ```prose
205
+ agent researcher:
206
+ # This comment is inside the block
207
+ model: sonnet
208
+ # This comment is outside the block
209
+ ```
210
+
211
+ ---
212
+
213
+ ## String Literals
214
+
215
+ String literals represent text values, primarily used for session prompts.
216
+
217
+ ### Syntax
218
+
219
+ Strings are enclosed in double quotes:
220
+
221
+ ```prose
222
+ "This is a string"
223
+ ```
224
+
225
+ ### Escape Sequences
226
+
227
+ The following escape sequences are supported:
228
+
229
+ | Sequence | Meaning |
230
+ | -------- | ------------ |
231
+ | `\\` | Backslash |
232
+ | `\"` | Double quote |
233
+ | `\n` | Newline |
234
+ | `\t` | Tab |
235
+
236
+ ### Examples
237
+
238
+ ```prose
239
+ session "Hello world"
240
+ session "Line one\nLine two"
241
+ session "She said \"hello\""
242
+ session "Path: C:\\Users\\name"
243
+ session "Column1\tColumn2"
244
+ ```
245
+
246
+ ### Rules
247
+
248
+ 1. Single-line strings must be properly terminated with a closing `"`
249
+ 2. Unknown escape sequences are errors
250
+ 3. Empty strings `""` are valid but generate a warning when used as prompts
251
+
252
+ ### Multi-line Strings
253
+
254
+ Multi-line strings use triple double-quotes (`"""`) and preserve internal whitespace and newlines:
255
+
256
+ ```prose
257
+ session """
258
+ This is a multi-line prompt.
259
+ It preserves:
260
+ - Indentation
261
+ - Line breaks
262
+ - All internal whitespace
263
+ """
264
+ ```
265
+
266
+ #### Multi-line String Rules
267
+
268
+ 1. Opening `"""` must be followed by a newline
269
+ 2. Content continues until closing `"""`
270
+ 3. Escape sequences work the same as single-line strings
271
+ 4. Leading/trailing whitespace inside the delimiters is preserved
272
+
273
+ ### String Interpolation
274
+
275
+ Strings can embed variable references using `{varname}` syntax:
276
+
277
+ ```prose
278
+ let name = session "Get the user's name"
279
+
280
+ session "Hello {name}, welcome to the system!"
281
+ ```
282
+
283
+ #### Interpolation Syntax
284
+
285
+ - Variables are referenced by wrapping the variable name in curly braces: `{varname}`
286
+ - Works in both single-line and multi-line strings
287
+ - Empty braces `{}` are treated as literal text, not interpolation
288
+ - Nested braces are not supported
289
+
290
+ #### Examples
291
+
292
+ ```prose
293
+ let research = session "Research the topic"
294
+ let analysis = session "Analyze findings"
295
+
296
+ # Single variable interpolation
297
+ session "Based on {research}, provide recommendations"
298
+
299
+ # Multiple interpolations
300
+ session "Combining {research} with {analysis}, synthesize insights"
301
+
302
+ # Multi-line with interpolation
303
+ session """
304
+ Review Summary:
305
+ - Research: {research}
306
+ - Analysis: {analysis}
307
+ Please provide final recommendations.
308
+ """
309
+ ```
310
+
311
+ #### Interpolation Rules
312
+
313
+ 1. Variable names must be valid identifiers
314
+ 2. Referenced variables must be in scope
315
+ 3. Empty braces `{}` are literal text
316
+ 4. Backslash can escape braces: `\{` produces literal `{`
317
+
318
+ ### Validation
319
+
320
+ | Check | Result |
321
+ | -------------------------------- | ------- |
322
+ | Unterminated string | Error |
323
+ | Unknown escape sequence | Error |
324
+ | Empty string as prompt | Warning |
325
+ | Undefined interpolation variable | Error |
326
+
327
+ ---
328
+
329
+ ## Import Statements
330
+
331
+ Import statements load external skills that can be assigned to agents.
332
+
333
+ ### Syntax
334
+
335
+ ```prose
336
+ import "skill-name" from "source"
337
+ ```
338
+
339
+ ### Source Types
340
+
341
+ | Source Type | Format | Example |
342
+ | ----------- | --------------------- | ------------------------- |
343
+ | GitHub | `github:user/repo` | `github:anthropic/skills` |
344
+ | NPM | `npm:package` | `npm:@org/analyzer` |
345
+ | Local path | `./path` or `../path` | `./local-skills/my-skill` |
346
+
347
+ ### Examples
348
+
349
+ ```prose
350
+ # Import from GitHub
351
+ import "web-search" from "github:anthropic/skills"
352
+
353
+ # Import from npm
354
+ import "code-analyzer" from "npm:@company/analyzer"
355
+
356
+ # Import from local path
357
+ import "custom-tool" from "./skills/custom-tool"
358
+ import "shared-skill" from "../common/skills"
359
+ ```
360
+
361
+ ### Validation Rules
362
+
363
+ | Check | Severity | Message |
364
+ | --------------------- | -------- | -------------------------------------- |
365
+ | Empty skill name | Error | Import skill name cannot be empty |
366
+ | Empty source | Error | Import source cannot be empty |
367
+ | Duplicate import | Error | Skill already imported |
368
+ | Unknown source format | Warning | Should start with github:, npm:, or ./ |
369
+
370
+ ### Execution Semantics
371
+
372
+ Import statements are processed before any agent definitions or sessions. The OpenProse VM:
373
+
374
+ 1. Validates all imports at the start of execution
375
+ 2. Loads skill definitions from the specified sources
376
+ 3. Makes skills available for agent assignment
377
+
378
+ ---
379
+
380
+ ## Agent Definitions
381
+
382
+ Agents are reusable templates that configure subagent behavior. Once defined, agents can be referenced in session statements.
383
+
384
+ ### Syntax
385
+
386
+ ```prose
387
+ agent name:
388
+ model: sonnet
389
+ prompt: "System prompt for this agent"
390
+ skills: ["skill1", "skill2"]
391
+ permissions:
392
+ read: ["*.md"]
393
+ bash: deny
394
+ ```
395
+
396
+ ### Properties
397
+
398
+ | Property | Type | Values | Description |
399
+ | ------------- | ---------- | ------------------------- | ----------------------------------- |
400
+ | `model` | identifier | `sonnet`, `opus`, `haiku` | The Claude model to use |
401
+ | `prompt` | string | Any string | System prompt/context for the agent |
402
+ | `skills` | array | String array | Skills assigned to this agent |
403
+ | `permissions` | block | Permission rules | Access control for the agent |
404
+
405
+ ### Skills Property
406
+
407
+ The `skills` property assigns imported skills to an agent:
408
+
409
+ ```prose
410
+ import "web-search" from "github:anthropic/skills"
411
+ import "summarizer" from "./local-skills"
412
+
413
+ agent researcher:
414
+ skills: ["web-search", "summarizer"]
415
+ ```
416
+
417
+ Skills must be imported before they can be assigned. Referencing an unimported skill generates a warning.
418
+
419
+ ### Permissions Property
420
+
421
+ The `permissions` property controls agent access:
422
+
423
+ ```prose
424
+ agent secure-agent:
425
+ permissions:
426
+ read: ["*.md", "*.txt"]
427
+ write: ["output/"]
428
+ bash: deny
429
+ network: allow
430
+ ```
431
+
432
+ #### Permission Types
433
+
434
+ | Type | Description |
435
+ | --------- | -------------------------------------------- |
436
+ | `read` | Files the agent can read (glob patterns) |
437
+ | `write` | Files the agent can write (glob patterns) |
438
+ | `execute` | Files the agent can execute (glob patterns) |
439
+ | `bash` | Shell access: `allow`, `deny`, or `prompt` |
440
+ | `network` | Network access: `allow`, `deny`, or `prompt` |
441
+
442
+ #### Permission Values
443
+
444
+ | Value | Description |
445
+ | -------- | ------------------------------------------------- |
446
+ | `allow` | Permission granted |
447
+ | `deny` | Permission denied |
448
+ | `prompt` | Ask user for permission |
449
+ | Array | List of allowed patterns (for read/write/execute) |
450
+
451
+ ### Examples
452
+
453
+ ```prose
454
+ # Define a research agent
455
+ agent researcher:
456
+ model: sonnet
457
+ prompt: "You are a research assistant skilled at finding and synthesizing information"
458
+
459
+ # Define a writing agent
460
+ agent writer:
461
+ model: opus
462
+ prompt: "You are a technical writer who creates clear, concise documentation"
463
+
464
+ # Agent with only model
465
+ agent quick:
466
+ model: haiku
467
+
468
+ # Agent with only prompt
469
+ agent expert:
470
+ prompt: "You are a domain expert"
471
+
472
+ # Agent with skills
473
+ agent web-researcher:
474
+ model: sonnet
475
+ skills: ["web-search", "summarizer"]
476
+
477
+ # Agent with permissions
478
+ agent file-handler:
479
+ permissions:
480
+ read: ["*.md", "*.txt"]
481
+ write: ["output/"]
482
+ bash: deny
483
+ ```
484
+
485
+ ### Model Selection
486
+
487
+ | Model | Use Case |
488
+ | -------- | ------------------------------------- |
489
+ | `haiku` | Fast, simple tasks; quick responses |
490
+ | `sonnet` | Balanced performance; general purpose |
491
+ | `opus` | Complex reasoning; detailed analysis |
492
+
493
+ ### Execution Semantics
494
+
495
+ When a session references an agent:
496
+
497
+ 1. The agent's `model` property determines which Claude model is used
498
+ 2. The agent's `prompt` property is included as system context
499
+ 3. Session properties can override agent defaults
500
+
501
+ ### Validation Rules
502
+
503
+ | Check | Severity | Message |
504
+ | --------------------- | -------- | ------------------------------ |
505
+ | Duplicate agent name | Error | Agent already defined |
506
+ | Invalid model value | Error | Must be sonnet, opus, or haiku |
507
+ | Empty prompt property | Warning | Consider providing a prompt |
508
+ | Duplicate property | Error | Property already specified |
509
+
510
+ ---
511
+
512
+ ## Session Statement
513
+
514
+ The session statement is the primary executable construct in OpenProse. It spawns a subagent to complete a task.
515
+
516
+ ### Syntax Variants
517
+
518
+ #### Simple Session (with inline prompt)
519
+
520
+ ```prose
521
+ session "prompt text"
522
+ ```
523
+
524
+ #### Session with Agent Reference
525
+
526
+ ```prose
527
+ session: agentName
528
+ ```
529
+
530
+ #### Named Session with Agent
531
+
532
+ ```prose
533
+ session sessionName: agentName
534
+ ```
535
+
536
+ #### Session with Properties
537
+
538
+ ```prose
539
+ session: agentName
540
+ prompt: "Override the agent's default prompt"
541
+ model: opus # Override the agent's model
542
+ ```
543
+
544
+ ### Property Overrides
545
+
546
+ When a session references an agent, it can override the agent's properties:
547
+
548
+ ```prose
549
+ agent researcher:
550
+ model: sonnet
551
+ prompt: "You are a research assistant"
552
+
553
+ # Use researcher with different model
554
+ session: researcher
555
+ model: opus
556
+
557
+ # Use researcher with different prompt
558
+ session: researcher
559
+ prompt: "Research this specific topic in depth"
560
+
561
+ # Override both
562
+ session: researcher
563
+ model: opus
564
+ prompt: "Specialized research task"
565
+ ```
566
+
567
+ ### Execution Semantics
568
+
569
+ When the OpenProse VM encounters a `session` statement:
570
+
571
+ 1. **Resolve Configuration**: Merge agent defaults with session overrides
572
+ 2. **Spawn a Subagent**: Create a new Claude subagent with the resolved configuration
573
+ 3. **Send the Prompt**: Pass the prompt string to the subagent
574
+ 4. **Wait for Completion**: Block until the subagent finishes
575
+ 5. **Continue**: Proceed to the next statement
576
+
577
+ ### Execution Flow Diagram
578
+
579
+ ```
580
+ OpenProse VM Subagent
581
+ | |
582
+ | spawn session |
583
+ |----------------------------->|
584
+ | |
585
+ | send prompt |
586
+ |----------------------------->|
587
+ | |
588
+ | [processing...] |
589
+ | |
590
+ | session complete |
591
+ |<-----------------------------|
592
+ | |
593
+ | continue to next statement |
594
+ v v
595
+ ```
596
+
597
+ ### Sequential Execution
598
+
599
+ Multiple sessions execute sequentially:
600
+
601
+ ```prose
602
+ session "First task"
603
+ session "Second task"
604
+ session "Third task"
605
+ ```
606
+
607
+ Each session waits for the previous one to complete before starting.
608
+
609
+ ### Using Claude Code's Task Tool
610
+
611
+ To execute a session, use the Task tool:
612
+
613
+ ```typescript
614
+ // Simple session
615
+ Task({
616
+ description: "OpenProse session",
617
+ prompt: "The prompt from the session statement",
618
+ subagent_type: "general-purpose",
619
+ });
620
+
621
+ // Session with agent configuration
622
+ Task({
623
+ description: "OpenProse session",
624
+ prompt: "The session prompt",
625
+ subagent_type: "general-purpose",
626
+ model: "opus", // From agent or override
627
+ });
628
+ ```
629
+
630
+ ### Validation Rules
631
+
632
+ | Check | Severity | Message |
633
+ | ------------------------- | -------- | -------------------------------------------- |
634
+ | Missing prompt and agent | Error | Session requires a prompt or agent reference |
635
+ | Undefined agent reference | Error | Agent not defined |
636
+ | Empty prompt `""` | Warning | Session has empty prompt |
637
+ | Whitespace-only prompt | Warning | Session prompt contains only whitespace |
638
+ | Prompt > 10,000 chars | Warning | Consider breaking into smaller tasks |
639
+ | Duplicate property | Error | Property already specified |
640
+
641
+ ### Examples
642
+
643
+ ```prose
644
+ # Simple session
645
+ session "Hello world"
646
+
647
+ # Session with agent
648
+ agent researcher:
649
+ model: sonnet
650
+ prompt: "You research topics thoroughly"
651
+
652
+ session: researcher
653
+ prompt: "Research quantum computing applications"
654
+
655
+ # Named session
656
+ session analysis: researcher
657
+ prompt: "Analyze the competitive landscape"
658
+ ```
659
+
660
+ ### Canonical Form
661
+
662
+ The compiled output preserves the structure:
663
+
664
+ ```
665
+ Input:
666
+ agent researcher:
667
+ model: sonnet
668
+
669
+ session: researcher
670
+ prompt: "Do research"
671
+
672
+ Output:
673
+ agent researcher:
674
+ model: sonnet
675
+ session: researcher
676
+ prompt: "Do research"
677
+ ```
678
+
679
+ ---
680
+
681
+ ## Variables & Context
682
+
683
+ Variables allow you to capture the results of sessions and pass them as context to subsequent sessions.
684
+
685
+ ### Let Binding
686
+
687
+ The `let` keyword creates a mutable variable bound to a session result:
688
+
689
+ ```prose
690
+ let research = session "Research the topic thoroughly"
691
+
692
+ # research now holds the output of that session
693
+ ```
694
+
695
+ Variables can be reassigned:
696
+
697
+ ```prose
698
+ let draft = session "Write initial draft"
699
+
700
+ # Revise the draft
701
+ draft = session "Improve the draft"
702
+ context: draft
703
+ ```
704
+
705
+ ### Const Binding
706
+
707
+ The `const` keyword creates an immutable variable:
708
+
709
+ ```prose
710
+ const config = session "Get configuration settings"
711
+
712
+ # This would be an error:
713
+ # config = session "Try to change"
714
+ ```
715
+
716
+ ### Context Property
717
+
718
+ The `context` property passes previous session outputs to a new session:
719
+
720
+ #### Single Context
721
+
722
+ ```prose
723
+ let research = session "Research quantum computing"
724
+
725
+ session "Write summary"
726
+ context: research
727
+ ```
728
+
729
+ #### Multiple Contexts
730
+
731
+ ```prose
732
+ let research = session "Research the topic"
733
+ let analysis = session "Analyze the findings"
734
+
735
+ session "Write final report"
736
+ context: [research, analysis]
737
+ ```
738
+
739
+ #### Empty Context (Fresh Start)
740
+
741
+ Use an empty array to start a session without inherited context:
742
+
743
+ ```prose
744
+ session "Independent task"
745
+ context: []
746
+ ```
747
+
748
+ #### Object Context Shorthand
749
+
750
+ For passing multiple named results (especially from parallel blocks), use object shorthand:
751
+
752
+ ```prose
753
+ parallel:
754
+ a = session "Task A"
755
+ b = session "Task B"
756
+
757
+ session "Combine results"
758
+ context: { a, b }
759
+ ```
760
+
761
+ This is equivalent to passing an object where each property is a variable reference.
762
+
763
+ ### Complete Example
764
+
765
+ ```prose
766
+ agent researcher:
767
+ model: sonnet
768
+ prompt: "You are a research assistant"
769
+
770
+ agent writer:
771
+ model: opus
772
+ prompt: "You are a technical writer"
773
+
774
+ # Gather research
775
+ let research = session: researcher
776
+ prompt: "Research quantum computing developments"
777
+
778
+ # Analyze findings
779
+ let analysis = session: researcher
780
+ prompt: "Analyze the key findings"
781
+ context: research
782
+
783
+ # Write the final report using both contexts
784
+ const report = session: writer
785
+ prompt: "Write a comprehensive report"
786
+ context: [research, analysis]
787
+ ```
788
+
789
+ ### Validation Rules
790
+
791
+ | Check | Severity | Message |
792
+ | ------------------------------- | -------- | -------------------------------------------------- |
793
+ | Duplicate variable name | Error | Variable already defined |
794
+ | Const reassignment | Error | Cannot reassign const variable |
795
+ | Undefined variable reference | Error | Undefined variable |
796
+ | Variable conflicts with agent | Error | Variable name conflicts with agent name |
797
+ | Undefined context variable | Error | Undefined variable in context |
798
+ | Non-identifier in context array | Error | Context array elements must be variable references |
799
+
800
+ ---
801
+
802
+ ## Composition Blocks
803
+
804
+ Composition blocks allow you to structure programs into reusable, named units and express sequences of operations inline.
805
+
806
+ ### do: Block (Anonymous Sequential Block)
807
+
808
+ The `do:` keyword creates an explicit sequential block. All statements in the block execute in order.
809
+
810
+ #### Syntax
811
+
812
+ ```prose
813
+ do:
814
+ statement1
815
+ statement2
816
+ ...
817
+ ```
818
+
819
+ #### Examples
820
+
821
+ ```prose
822
+ # Explicit sequential block
823
+ do:
824
+ session "Research the topic"
825
+ session "Analyze findings"
826
+ session "Write summary"
827
+
828
+ # Assign result to a variable
829
+ let result = do:
830
+ session "Gather data"
831
+ session "Process data"
832
+ ```
833
+
834
+ ### Block Definitions
835
+
836
+ Named blocks create reusable workflow components. Define once, invoke multiple times.
837
+
838
+ #### Syntax
839
+
840
+ ```prose
841
+ block name:
842
+ statement1
843
+ statement2
844
+ ...
845
+ ```
846
+
847
+ #### Invoking Blocks
848
+
849
+ Use `do` followed by the block name to invoke a defined block:
850
+
851
+ ```prose
852
+ do blockname
853
+ ```
854
+
855
+ #### Examples
856
+
857
+ ```prose
858
+ # Define a review pipeline
859
+ block review-pipeline:
860
+ session "Security review"
861
+ session "Performance review"
862
+ session "Synthesize reviews"
863
+
864
+ # Define another block
865
+ block final-check:
866
+ session "Final verification"
867
+ session "Sign off"
868
+
869
+ # Use the blocks
870
+ do review-pipeline
871
+ session "Make fixes based on review"
872
+ do final-check
873
+ ```
874
+
875
+ ### Block Parameters
876
+
877
+ Blocks can accept parameters to make them more flexible and reusable.
878
+
879
+ #### Syntax
880
+
881
+ ```prose
882
+ block name(param1, param2):
883
+ # param1 and param2 are available here
884
+ statement1
885
+ statement2
886
+ ```
887
+
888
+ #### Invoking with Arguments
889
+
890
+ Pass arguments when invoking a parameterized block:
891
+
892
+ ```prose
893
+ do name(arg1, arg2)
894
+ ```
895
+
896
+ #### Examples
897
+
898
+ ```prose
899
+ # Define a parameterized block
900
+ block review(topic):
901
+ session "Research {topic} thoroughly"
902
+ session "Analyze key findings about {topic}"
903
+ session "Summarize {topic} analysis"
904
+
905
+ # Invoke with different arguments
906
+ do review("quantum computing")
907
+ do review("machine learning")
908
+ do review("blockchain")
909
+ ```
910
+
911
+ #### Multiple Parameters
912
+
913
+ ```prose
914
+ block process-item(item, mode):
915
+ session "Process {item} using {mode} mode"
916
+ session "Verify {item} processing"
917
+
918
+ do process-item("data.csv", "strict")
919
+ do process-item("config.json", "lenient")
920
+ ```
921
+
922
+ #### Parameter Scope
923
+
924
+ - Parameters are scoped to the block body
925
+ - Parameters shadow outer variables of the same name (with warning)
926
+ - Parameters are implicitly `const` within the block
927
+
928
+ #### Validation Rules
929
+
930
+ | Check | Severity | Message |
931
+ | ----------------------- | -------- | ---------------------------------------------- |
932
+ | Argument count mismatch | Warning | Block expects N parameters but got M arguments |
933
+ | Parameter shadows outer | Warning | Parameter shadows outer variable |
934
+
935
+ ### Inline Sequence (Arrow Operator)
936
+
937
+ The `->` operator chains sessions into a sequence on a single line. This is syntactic sugar for sequential execution.
938
+
939
+ #### Syntax
940
+
941
+ ```prose
942
+ session "A" -> session "B" -> session "C"
943
+ ```
944
+
945
+ This is equivalent to:
946
+
947
+ ```prose
948
+ session "A"
949
+ session "B"
950
+ session "C"
951
+ ```
952
+
953
+ #### Examples
954
+
955
+ ```prose
956
+ # Quick pipeline
957
+ session "Plan" -> session "Execute" -> session "Review"
958
+
959
+ # Assign result
960
+ let workflow = session "Draft" -> session "Edit" -> session "Finalize"
961
+ ```
962
+
963
+ ### Block Hoisting
964
+
965
+ Block definitions are hoisted - you can use a block before it's defined in the source:
966
+
967
+ ```prose
968
+ # Use before definition
969
+ do validation-checks
970
+
971
+ # Definition comes later
972
+ block validation-checks:
973
+ session "Check syntax"
974
+ session "Check semantics"
975
+ ```
976
+
977
+ ### Nested Composition
978
+
979
+ Blocks and do: blocks can be nested:
980
+
981
+ ```prose
982
+ block outer-workflow:
983
+ session "Start"
984
+ do:
985
+ session "Sub-task 1"
986
+ session "Sub-task 2"
987
+ session "End"
988
+
989
+ do:
990
+ do outer-workflow
991
+ session "Final step"
992
+ ```
993
+
994
+ ### Context with Blocks
995
+
996
+ Blocks work with the context system:
997
+
998
+ ```prose
999
+ # Capture do block result
1000
+ let research = do:
1001
+ session "Gather information"
1002
+ session "Analyze patterns"
1003
+
1004
+ # Use in subsequent session
1005
+ session "Write report"
1006
+ context: research
1007
+ ```
1008
+
1009
+ ### Validation Rules
1010
+
1011
+ | Check | Severity | Message |
1012
+ | ------------------------------- | -------- | ------------------------------------ |
1013
+ | Undefined block reference | Error | Block not defined |
1014
+ | Duplicate block definition | Error | Block already defined |
1015
+ | Block name conflicts with agent | Error | Block name conflicts with agent name |
1016
+ | Empty block name | Error | Block definition must have a name |
1017
+
1018
+ ---
1019
+
1020
+ ## Parallel Blocks
1021
+
1022
+ Parallel blocks allow multiple sessions to run concurrently. All branches execute simultaneously, and the block waits for all to complete before continuing.
1023
+
1024
+ ### Basic Syntax
1025
+
1026
+ ```prose
1027
+ parallel:
1028
+ session "Security review"
1029
+ session "Performance review"
1030
+ session "Style review"
1031
+ ```
1032
+
1033
+ All three sessions start at the same time and run concurrently. The program waits for all of them to complete before proceeding.
1034
+
1035
+ ### Named Parallel Results
1036
+
1037
+ Capture the results of parallel branches into variables:
1038
+
1039
+ ```prose
1040
+ parallel:
1041
+ security = session "Security review"
1042
+ perf = session "Performance review"
1043
+ style = session "Style review"
1044
+ ```
1045
+
1046
+ These variables can then be used in subsequent sessions.
1047
+
1048
+ ### Object Context Shorthand
1049
+
1050
+ Pass multiple parallel results to a session using object shorthand:
1051
+
1052
+ ```prose
1053
+ parallel:
1054
+ security = session "Security review"
1055
+ perf = session "Performance review"
1056
+ style = session "Style review"
1057
+
1058
+ session "Synthesize all reviews"
1059
+ context: { security, perf, style }
1060
+ ```
1061
+
1062
+ The object shorthand `{ a, b, c }` is equivalent to passing an object with properties `a`, `b`, and `c` where each property's value is the corresponding variable.
1063
+
1064
+ ### Mixed Composition
1065
+
1066
+ #### Parallel Inside Sequential
1067
+
1068
+ ```prose
1069
+ do:
1070
+ session "Setup"
1071
+ parallel:
1072
+ session "Task A"
1073
+ session "Task B"
1074
+ session "Cleanup"
1075
+ ```
1076
+
1077
+ The setup runs first, then Task A and Task B run in parallel, and finally cleanup runs.
1078
+
1079
+ #### Sequential Inside Parallel
1080
+
1081
+ ```prose
1082
+ parallel:
1083
+ do:
1084
+ session "Multi-step task 1a"
1085
+ session "Multi-step task 1b"
1086
+ do:
1087
+ session "Multi-step task 2a"
1088
+ session "Multi-step task 2b"
1089
+ ```
1090
+
1091
+ Each parallel branch contains a sequential workflow. The two workflows run concurrently.
1092
+
1093
+ ### Assigning Parallel Blocks to Variables
1094
+
1095
+ ```prose
1096
+ let results = parallel:
1097
+ session "Task A"
1098
+ session "Task B"
1099
+ ```
1100
+
1101
+ ### Complete Example
1102
+
1103
+ ```prose
1104
+ agent reviewer:
1105
+ model: sonnet
1106
+
1107
+ # Run parallel reviews
1108
+ parallel:
1109
+ sec = session: reviewer
1110
+ prompt: "Review for security issues"
1111
+ perf = session: reviewer
1112
+ prompt: "Review for performance issues"
1113
+ style = session: reviewer
1114
+ prompt: "Review for style issues"
1115
+
1116
+ # Combine all reviews
1117
+ session "Create unified review report"
1118
+ context: { sec, perf, style }
1119
+ ```
1120
+
1121
+ ### Join Strategies
1122
+
1123
+ By default, parallel blocks wait for all branches to complete. You can specify alternative join strategies:
1124
+
1125
+ #### First (Race)
1126
+
1127
+ Return as soon as the first branch completes, cancel others:
1128
+
1129
+ ```prose
1130
+ parallel ("first"):
1131
+ session "Try approach A"
1132
+ session "Try approach B"
1133
+ session "Try approach C"
1134
+ ```
1135
+
1136
+ The first successful result wins. Other branches are cancelled.
1137
+
1138
+ #### Any (N of M)
1139
+
1140
+ Return when any N branches complete successfully:
1141
+
1142
+ ```prose
1143
+ # Default: any 1 success
1144
+ parallel ("any"):
1145
+ session "Attempt 1"
1146
+ session "Attempt 2"
1147
+
1148
+ # Specific count: wait for 2 successes
1149
+ parallel ("any", count: 2):
1150
+ session "Attempt 1"
1151
+ session "Attempt 2"
1152
+ session "Attempt 3"
1153
+ ```
1154
+
1155
+ #### All (Default)
1156
+
1157
+ Wait for all branches to complete:
1158
+
1159
+ ```prose
1160
+ # Implicit - this is the default
1161
+ parallel:
1162
+ session "Task A"
1163
+ session "Task B"
1164
+
1165
+ # Explicit
1166
+ parallel ("all"):
1167
+ session "Task A"
1168
+ session "Task B"
1169
+ ```
1170
+
1171
+ ### Failure Policies
1172
+
1173
+ Control how the parallel block handles branch failures:
1174
+
1175
+ #### Fail-Fast (Default)
1176
+
1177
+ If any branch fails, fail immediately and cancel other branches:
1178
+
1179
+ ```prose
1180
+ parallel: # Implicit fail-fast
1181
+ session "Critical task 1"
1182
+ session "Critical task 2"
1183
+
1184
+ # Explicit
1185
+ parallel (on-fail: "fail-fast"):
1186
+ session "Critical task 1"
1187
+ session "Critical task 2"
1188
+ ```
1189
+
1190
+ #### Continue
1191
+
1192
+ Let all branches complete, then report all failures:
1193
+
1194
+ ```prose
1195
+ parallel (on-fail: "continue"):
1196
+ session "Task 1"
1197
+ session "Task 2"
1198
+ session "Task 3"
1199
+
1200
+ # Continue regardless of which branches failed
1201
+ session "Process results, including failures"
1202
+ ```
1203
+
1204
+ #### Ignore
1205
+
1206
+ Ignore all failures, always succeed:
1207
+
1208
+ ```prose
1209
+ parallel (on-fail: "ignore"):
1210
+ session "Optional enrichment 1"
1211
+ session "Optional enrichment 2"
1212
+
1213
+ # This always runs, even if all branches failed
1214
+ session "Continue regardless"
1215
+ ```
1216
+
1217
+ ### Combining Modifiers
1218
+
1219
+ Join strategies and failure policies can be combined:
1220
+
1221
+ ```prose
1222
+ # Race with resilience
1223
+ parallel ("first", on-fail: "continue"):
1224
+ session "Fast but unreliable"
1225
+ session "Slow but reliable"
1226
+
1227
+ # Get any 2 results, ignoring failures
1228
+ parallel ("any", count: 2, on-fail: "ignore"):
1229
+ session "Approach 1"
1230
+ session "Approach 2"
1231
+ session "Approach 3"
1232
+ session "Approach 4"
1233
+ ```
1234
+
1235
+ ### Execution Semantics
1236
+
1237
+ When the OpenProse VM encounters a `parallel:` block:
1238
+
1239
+ 1. **Fork**: Start all branches concurrently
1240
+ 2. **Execute**: Each branch runs independently
1241
+ 3. **Join**: Wait according to join strategy:
1242
+ - `"all"` (default): Wait for all branches
1243
+ - `"first"`: Return on first completion
1244
+ - `"any"`: Return on first success (or N successes with `count`)
1245
+ 4. **Handle failures**: According to on-fail policy:
1246
+ - `"fail-fast"` (default): Cancel remaining and fail immediately
1247
+ - `"continue"`: Wait for all, then report failures
1248
+ - `"ignore"`: Treat failures as successes
1249
+ 5. **Continue**: Proceed to the next statement with available results
1250
+
1251
+ ### Validation Rules
1252
+
1253
+ | Check | Severity | Message |
1254
+ | ------------------------------------ | -------- | -------------------------------------------- |
1255
+ | Invalid join strategy | Error | Must be "all", "first", or "any" |
1256
+ | Invalid on-fail policy | Error | Must be "fail-fast", "continue", or "ignore" |
1257
+ | Count without "any" | Error | Count is only valid with "any" strategy |
1258
+ | Count less than 1 | Error | Count must be at least 1 |
1259
+ | Count exceeds branches | Warning | Count exceeds number of parallel branches |
1260
+ | Duplicate variable in parallel | Error | Variable already defined |
1261
+ | Variable conflicts with agent | Error | Variable name conflicts with agent name |
1262
+ | Undefined variable in object context | Error | Undefined variable in context |
1263
+
1264
+ ---
1265
+
1266
+ ## Fixed Loops
1267
+
1268
+ Fixed loops provide bounded iteration over a set number of times or over a collection.
1269
+
1270
+ ### Repeat Block
1271
+
1272
+ The `repeat` block executes its body a fixed number of times.
1273
+
1274
+ #### Basic Syntax
1275
+
1276
+ ```prose
1277
+ repeat 3:
1278
+ session "Generate a creative idea"
1279
+ ```
1280
+
1281
+ #### With Index Variable
1282
+
1283
+ Access the current iteration index using `as`:
1284
+
1285
+ ```prose
1286
+ repeat 5 as i:
1287
+ session "Process item"
1288
+ context: i
1289
+ ```
1290
+
1291
+ The index variable `i` is scoped to the loop body and starts at 0.
1292
+
1293
+ ### For-Each Block
1294
+
1295
+ The `for` block iterates over a collection.
1296
+
1297
+ #### Basic Syntax
1298
+
1299
+ ```prose
1300
+ let fruits = ["apple", "banana", "cherry"]
1301
+ for fruit in fruits:
1302
+ session "Describe this fruit"
1303
+ context: fruit
1304
+ ```
1305
+
1306
+ #### With Inline Array
1307
+
1308
+ ```prose
1309
+ for topic in ["AI", "climate", "space"]:
1310
+ session "Research this topic"
1311
+ context: topic
1312
+ ```
1313
+
1314
+ #### With Index Variable
1315
+
1316
+ Access both the item and its index:
1317
+
1318
+ ```prose
1319
+ let items = ["a", "b", "c"]
1320
+ for item, i in items:
1321
+ session "Process item with index"
1322
+ context: [item, i]
1323
+ ```
1324
+
1325
+ ### Parallel For-Each
1326
+
1327
+ The `parallel for` block runs all iterations concurrently (fan-out pattern):
1328
+
1329
+ ```prose
1330
+ let topics = ["AI", "climate", "space"]
1331
+ parallel for topic in topics:
1332
+ session "Research this topic"
1333
+ context: topic
1334
+
1335
+ session "Combine all research"
1336
+ ```
1337
+
1338
+ This is equivalent to:
1339
+
1340
+ ```prose
1341
+ parallel:
1342
+ session "Research AI" context: "AI"
1343
+ session "Research climate" context: "climate"
1344
+ session "Research space" context: "space"
1345
+ ```
1346
+
1347
+ But more concise and dynamic.
1348
+
1349
+ ### Variable Scoping
1350
+
1351
+ Loop variables are scoped to the loop body:
1352
+
1353
+ - They are implicitly `const` within each iteration
1354
+ - They shadow outer variables of the same name (with a warning)
1355
+ - They are not accessible outside the loop
1356
+
1357
+ ```prose
1358
+ let item = session "outer"
1359
+ for item in ["a", "b"]:
1360
+ # 'item' here is the loop variable
1361
+ session "process loop item"
1362
+ context: item
1363
+ # 'item' here refers to the outer variable again
1364
+ session "use outer item"
1365
+ context: item
1366
+ ```
1367
+
1368
+ ### Nesting
1369
+
1370
+ Loops can be nested:
1371
+
1372
+ ```prose
1373
+ repeat 2:
1374
+ repeat 3:
1375
+ session "Inner task"
1376
+ ```
1377
+
1378
+ Different loop types can be combined:
1379
+
1380
+ ```prose
1381
+ let items = ["a", "b"]
1382
+ repeat 2:
1383
+ for item in items:
1384
+ session "Process item"
1385
+ context: item
1386
+ ```
1387
+
1388
+ ### Complete Example
1389
+
1390
+ ```prose
1391
+ # Generate multiple variations of ideas
1392
+ repeat 3:
1393
+ session "Generate a creative startup idea"
1394
+
1395
+ session "Select the best idea from the options above"
1396
+
1397
+ # Research the selected idea from multiple angles
1398
+ let angles = ["market", "technology", "competition"]
1399
+ parallel for angle in angles:
1400
+ session "Research this angle of the startup idea"
1401
+ context: angle
1402
+
1403
+ session "Synthesize all research into a business plan"
1404
+ ```
1405
+
1406
+ ### Validation Rules
1407
+
1408
+ | Check | Severity | Message |
1409
+ | ----------------------------- | -------- | ------------------------------------ |
1410
+ | Repeat count must be positive | Error | Repeat count must be positive |
1411
+ | Repeat count must be integer | Error | Repeat count must be an integer |
1412
+ | Undefined collection variable | Error | Undefined collection variable |
1413
+ | Loop variable shadows outer | Warning | Loop variable shadows outer variable |
1414
+
1415
+ ---
1416
+
1417
+ ## Unbounded Loops
1418
+
1419
+ Unbounded loops provide iteration with AI-evaluated termination conditions. Unlike fixed loops, the iteration count is not known ahead of time - the OpenProse VM evaluates conditions at runtime using its intelligence to determine when to stop.
1420
+
1421
+ ### Discretion Markers
1422
+
1423
+ Unbounded loops use **discretion markers** (`**...**`) to wrap AI-evaluated conditions. These markers signal that the enclosed text should be interpreted intelligently by the OpenProse VM at runtime, not as a literal boolean expression.
1424
+
1425
+ ```prose
1426
+ # The text inside **...** is evaluated by the AI
1427
+ loop until **the poem has vivid imagery and flows smoothly**:
1428
+ session "Review and improve the poem"
1429
+ ```
1430
+
1431
+ For multi-line conditions, use triple-asterisks:
1432
+
1433
+ ```prose
1434
+ loop until ***
1435
+ the document is complete
1436
+ all sections have been reviewed
1437
+ and formatting is consistent
1438
+ ***:
1439
+ session "Continue working on the document"
1440
+ ```
1441
+
1442
+ ### Basic Loop
1443
+
1444
+ The simplest unbounded loop runs indefinitely until explicitly limited:
1445
+
1446
+ ```prose
1447
+ loop:
1448
+ session "Process next item"
1449
+ ```
1450
+
1451
+ **Warning**: Loops without termination conditions or max iterations generate a warning. Always include a safety limit:
1452
+
1453
+ ```prose
1454
+ loop (max: 50):
1455
+ session "Process next item"
1456
+ ```
1457
+
1458
+ ### Loop Until
1459
+
1460
+ The `loop until` variant runs until a condition becomes true:
1461
+
1462
+ ```prose
1463
+ loop until **the task is complete**:
1464
+ session "Continue working on the task"
1465
+ ```
1466
+
1467
+ The OpenProse VM evaluates the discretion condition after each iteration and exits when it determines the condition is satisfied.
1468
+
1469
+ ### Loop While
1470
+
1471
+ The `loop while` variant runs while a condition remains true:
1472
+
1473
+ ```prose
1474
+ loop while **there are still items to process**:
1475
+ session "Process the next item"
1476
+ ```
1477
+
1478
+ Semantically, `loop while **X**` is equivalent to `loop until **not X**`.
1479
+
1480
+ ### Iteration Variable
1481
+
1482
+ Track the current iteration number using `as`:
1483
+
1484
+ ```prose
1485
+ loop until **done** as attempt:
1486
+ session "Try approach"
1487
+ context: attempt
1488
+ ```
1489
+
1490
+ The iteration variable:
1491
+
1492
+ - Starts at 0
1493
+ - Increments by 1 each iteration
1494
+ - Is scoped to the loop body
1495
+ - Is implicitly `const` within each iteration
1496
+
1497
+ ### Safety Limits
1498
+
1499
+ Specify maximum iterations with `(max: N)`:
1500
+
1501
+ ```prose
1502
+ # Stop after 10 iterations even if condition not met
1503
+ loop until **all bugs fixed** (max: 10):
1504
+ session "Find and fix a bug"
1505
+ ```
1506
+
1507
+ The loop exits when:
1508
+
1509
+ 1. The condition is satisfied (for `until`/`while` variants), OR
1510
+ 2. The maximum iteration count is reached
1511
+
1512
+ ### Complete Syntax
1513
+
1514
+ All options can be combined:
1515
+
1516
+ ```prose
1517
+ loop until **condition** (max: N) as i:
1518
+ body...
1519
+ ```
1520
+
1521
+ Order matters: condition comes before modifiers, modifiers before `as`.
1522
+
1523
+ ### Examples
1524
+
1525
+ #### Iterative Improvement
1526
+
1527
+ ```prose
1528
+ session "Write an initial draft"
1529
+
1530
+ loop until **the draft is polished and ready for review** (max: 5):
1531
+ session "Review the current draft and identify issues"
1532
+ session "Revise the draft to address the issues"
1533
+
1534
+ session "Present the final draft"
1535
+ ```
1536
+
1537
+ #### Debugging Workflow
1538
+
1539
+ ```prose
1540
+ session "Run tests to identify failures"
1541
+
1542
+ loop until **all tests pass** (max: 20) as attempt:
1543
+ session "Identify the failing test"
1544
+ session "Fix the bug causing the failure"
1545
+ session "Run tests again"
1546
+
1547
+ session "Confirm all tests pass and summarize fixes"
1548
+ ```
1549
+
1550
+ #### Consensus Building
1551
+
1552
+ ```prose
1553
+ parallel:
1554
+ opinion1 = session "Get first expert opinion"
1555
+ opinion2 = session "Get second expert opinion"
1556
+
1557
+ loop until **experts have reached consensus** (max: 5):
1558
+ session "Identify points of disagreement"
1559
+ context: { opinion1, opinion2 }
1560
+ session "Facilitate discussion to resolve differences"
1561
+
1562
+ session "Document the final consensus"
1563
+ ```
1564
+
1565
+ #### Quality Threshold
1566
+
1567
+ ```prose
1568
+ let draft = session "Create initial document"
1569
+
1570
+ loop while **quality score is below threshold** (max: 10):
1571
+ draft = session "Review and improve the document"
1572
+ context: draft
1573
+ session "Calculate new quality score"
1574
+
1575
+ session "Finalize the document"
1576
+ context: draft
1577
+ ```
1578
+
1579
+ ### Execution Semantics
1580
+
1581
+ When the OpenProse VM encounters an unbounded loop:
1582
+
1583
+ 1. **Initialize**: Set iteration counter to 0
1584
+ 2. **Check Condition** (for `until`/`while`):
1585
+ - For `until`: Exit if condition is satisfied
1586
+ - For `while`: Exit if condition is NOT satisfied
1587
+ 3. **Check Limit**: Exit if iteration count >= max iterations
1588
+ 4. **Execute Body**: Run all statements in the loop body
1589
+ 5. **Increment**: Increase iteration counter
1590
+ 6. **Repeat**: Go to step 2
1591
+
1592
+ For basic `loop:` without conditions:
1593
+
1594
+ - Only the max iteration limit can cause exit
1595
+ - Without max, the loop runs indefinitely (warning issued)
1596
+
1597
+ ### Condition Evaluation
1598
+
1599
+ The OpenProse VM uses its intelligence to evaluate discretion conditions:
1600
+
1601
+ 1. **Context Awareness**: The condition is evaluated in the context of what has happened so far in the session
1602
+ 2. **Semantic Understanding**: The condition text is interpreted semantically, not literally
1603
+ 3. **Uncertainty Handling**: When uncertain, the OpenProse VM may:
1604
+ - Continue iterating if progress is being made
1605
+ - Exit early if diminishing returns are detected
1606
+ - Use heuristics based on the condition's semantics
1607
+
1608
+ ### Nesting
1609
+
1610
+ Unbounded loops can be nested with other loop types:
1611
+
1612
+ ```prose
1613
+ # Unbounded inside fixed
1614
+ repeat 3:
1615
+ loop until **sub-task complete** (max: 10):
1616
+ session "Work on sub-task"
1617
+
1618
+ # Fixed inside unbounded
1619
+ loop until **all batches processed** (max: 5):
1620
+ repeat 3:
1621
+ session "Process batch item"
1622
+
1623
+ # Multiple unbounded
1624
+ loop until **outer condition** (max: 5):
1625
+ loop until **inner condition** (max: 10):
1626
+ session "Deep iteration"
1627
+ ```
1628
+
1629
+ ### Variable Scoping
1630
+
1631
+ Loop variables follow the same scoping rules as fixed loops:
1632
+
1633
+ ```prose
1634
+ let i = session "outer"
1635
+ loop until **done** as i:
1636
+ # 'i' here is the loop variable (shadows outer)
1637
+ session "use loop i"
1638
+ context: i
1639
+ # 'i' here refers to the outer variable again
1640
+ session "use outer i"
1641
+ context: i
1642
+ ```
1643
+
1644
+ ### Validation Rules
1645
+
1646
+ | Check | Severity | Message |
1647
+ | ----------------------------- | -------- | ------------------------------------- |
1648
+ | Loop without max or condition | Warning | Unbounded loop without max iterations |
1649
+ | Max iterations <= 0 | Error | Max iterations must be positive |
1650
+ | Max iterations not integer | Error | Max iterations must be an integer |
1651
+ | Empty discretion condition | Error | Discretion condition cannot be empty |
1652
+ | Very short condition | Warning | Discretion condition may be ambiguous |
1653
+ | Loop variable shadows outer | Warning | Loop variable shadows outer variable |
1654
+
1655
+ ---
1656
+
1657
+ ## Pipeline Operations
1658
+
1659
+ Pipeline operations provide functional-style collection transformations. They allow you to chain operations like map, filter, and reduce using the pipe operator (`|`).
1660
+
1661
+ ### Pipe Operator
1662
+
1663
+ The pipe operator (`|`) passes a collection to a transformation operation:
1664
+
1665
+ ```prose
1666
+ let items = ["a", "b", "c"]
1667
+ let results = items | map:
1668
+ session "Process this item"
1669
+ context: item
1670
+ ```
1671
+
1672
+ ### Map
1673
+
1674
+ The `map` operation transforms each element in a collection:
1675
+
1676
+ ```prose
1677
+ let articles = ["article1", "article2", "article3"]
1678
+
1679
+ let summaries = articles | map:
1680
+ session "Summarize this article in one sentence"
1681
+ context: item
1682
+ ```
1683
+
1684
+ Inside a map body, the implicit variable `item` refers to the current element being processed.
1685
+
1686
+ ### Filter
1687
+
1688
+ The `filter` operation keeps elements that match a condition:
1689
+
1690
+ ```prose
1691
+ let items = ["one", "two", "three", "four", "five"]
1692
+
1693
+ let short = items | filter:
1694
+ session "Does this word have 4 or fewer letters? Answer yes or no."
1695
+ context: item
1696
+ ```
1697
+
1698
+ The session in a filter body should return something the OpenProse VM can interpret as truthy/falsy (like "yes"/"no").
1699
+
1700
+ ### Reduce
1701
+
1702
+ The `reduce` operation accumulates elements into a single result:
1703
+
1704
+ ```prose
1705
+ let ideas = ["AI assistant", "smart home", "health tracker"]
1706
+
1707
+ let combined = ideas | reduce(summary, idea):
1708
+ session "Add this idea to the summary, creating a cohesive concept"
1709
+ context: [summary, idea]
1710
+ ```
1711
+
1712
+ The reduce operation requires explicit variable names:
1713
+
1714
+ - First variable (`summary`): the accumulator
1715
+ - Second variable (`idea`): the current item
1716
+
1717
+ The first item in the collection becomes the initial accumulator value.
1718
+
1719
+ ### Parallel Map (pmap)
1720
+
1721
+ The `pmap` operation is like `map` but runs all transformations concurrently:
1722
+
1723
+ ```prose
1724
+ let tasks = ["task1", "task2", "task3"]
1725
+
1726
+ let results = tasks | pmap:
1727
+ session "Process this task in parallel"
1728
+ context: item
1729
+
1730
+ session "Aggregate all results"
1731
+ context: results
1732
+ ```
1733
+
1734
+ This is similar to `parallel for`, but in pipeline syntax.
1735
+
1736
+ ### Chaining
1737
+
1738
+ Pipeline operations can be chained to compose complex transformations:
1739
+
1740
+ ```prose
1741
+ let topics = ["quantum computing", "blockchain", "machine learning", "IoT"]
1742
+
1743
+ let result = topics
1744
+ | filter:
1745
+ session "Is this topic trending? Answer yes or no."
1746
+ context: item
1747
+ | map:
1748
+ session "Write a one-line startup pitch for this topic"
1749
+ context: item
1750
+
1751
+ session "Present the startup pitches"
1752
+ context: result
1753
+ ```
1754
+
1755
+ Operations execute left-to-right: first filter, then map.
1756
+
1757
+ ### Complete Example
1758
+
1759
+ ```prose
1760
+ # Define a collection
1761
+ let articles = ["AI breakthroughs", "Climate solutions", "Space exploration"]
1762
+
1763
+ # Process with chained operations
1764
+ let summaries = articles
1765
+ | filter:
1766
+ session "Is this topic relevant to technology? Answer yes or no."
1767
+ context: item
1768
+ | map:
1769
+ session "Write a compelling one-paragraph summary"
1770
+ context: item
1771
+ | reduce(combined, summary):
1772
+ session "Merge this summary into the combined document"
1773
+ context: [combined, summary]
1774
+
1775
+ # Present the final result
1776
+ session "Format and present the combined summaries"
1777
+ context: summaries
1778
+ ```
1779
+
1780
+ ### Implicit Variables
1781
+
1782
+ | Operation | Available Variables |
1783
+ | --------- | -------------------------------------------- |
1784
+ | `map` | `item` - current element |
1785
+ | `filter` | `item` - current element |
1786
+ | `pmap` | `item` - current element |
1787
+ | `reduce` | Named explicitly: `reduce(accVar, itemVar):` |
1788
+
1789
+ ### Execution Semantics
1790
+
1791
+ When the OpenProse VM encounters a pipeline:
1792
+
1793
+ 1. **Input**: Start with the input collection
1794
+ 2. **For each operation**:
1795
+ - **map**: Transform each element, producing a new collection
1796
+ - **filter**: Keep elements where the session returns truthy
1797
+ - **reduce**: Accumulate elements into a single value
1798
+ - **pmap**: Transform all elements concurrently
1799
+ 3. **Output**: Return the final transformed collection/value
1800
+
1801
+ ### Variable Scoping
1802
+
1803
+ Pipeline variables are scoped to their operation body:
1804
+
1805
+ ```prose
1806
+ let item = "outer"
1807
+ let items = ["a", "b"]
1808
+
1809
+ let results = items | map:
1810
+ # 'item' here is the pipeline variable (shadows outer)
1811
+ session "process"
1812
+ context: item
1813
+
1814
+ # 'item' here refers to the outer variable again
1815
+ session "use outer"
1816
+ context: item
1817
+ ```
1818
+
1819
+ ### Validation Rules
1820
+
1821
+ | Check | Severity | Message |
1822
+ | ------------------------------- | -------- | -------------------------------------------------- |
1823
+ | Undefined input collection | Error | Undefined collection variable |
1824
+ | Invalid pipe operator | Error | Expected pipe operator (map, filter, reduce, pmap) |
1825
+ | Reduce without variables | Error | Expected accumulator and item variables |
1826
+ | Pipeline variable shadows outer | Warning | Implicit/explicit variable shadows outer variable |
1827
+
1828
+ ---
1829
+
1830
+ ## Error Handling
1831
+
1832
+ OpenProse provides structured error handling with try/catch/finally blocks, throw statements, and retry mechanisms for resilient workflows.
1833
+
1834
+ ### Try/Catch Blocks
1835
+
1836
+ The `try:` block wraps operations that might fail. The `catch:` block handles errors.
1837
+
1838
+ ```prose
1839
+ try:
1840
+ session "Attempt risky operation"
1841
+ catch:
1842
+ session "Handle the error gracefully"
1843
+ ```
1844
+
1845
+ #### Error Variable Access
1846
+
1847
+ Use `catch as err:` to capture error context for the error handler:
1848
+
1849
+ ```prose
1850
+ try:
1851
+ session "Call external API"
1852
+ catch as err:
1853
+ session "Log and handle the error"
1854
+ context: err
1855
+ ```
1856
+
1857
+ The error variable (`err`) contains contextual information about what went wrong and is only accessible within the catch block.
1858
+
1859
+ ### Try/Catch/Finally
1860
+
1861
+ The `finally:` block always executes, whether the try block succeeds or fails:
1862
+
1863
+ ```prose
1864
+ try:
1865
+ session "Acquire and use resource"
1866
+ catch:
1867
+ session "Handle any errors"
1868
+ finally:
1869
+ session "Always clean up resource"
1870
+ ```
1871
+
1872
+ #### Execution Order
1873
+
1874
+ 1. **Try succeeds**: try body → finally body
1875
+ 2. **Try fails**: try body (until failure) → catch body → finally body
1876
+
1877
+ ### Try/Finally (No Catch)
1878
+
1879
+ For cleanup without error handling, use try/finally:
1880
+
1881
+ ```prose
1882
+ try:
1883
+ session "Open connection and do work"
1884
+ finally:
1885
+ session "Close connection"
1886
+ ```
1887
+
1888
+ ### Throw Statement
1889
+
1890
+ The `throw` statement raises or re-raises errors.
1891
+
1892
+ #### Rethrow
1893
+
1894
+ Inside a catch block, `throw` without arguments re-raises the caught error to outer handlers:
1895
+
1896
+ ```prose
1897
+ try:
1898
+ try:
1899
+ session "Inner operation"
1900
+ catch:
1901
+ session "Partial handling"
1902
+ throw # Re-raise to outer handler
1903
+ catch:
1904
+ session "Handle re-raised error"
1905
+ ```
1906
+
1907
+ #### Throw with Message
1908
+
1909
+ Throw a new error with a custom message:
1910
+
1911
+ ```prose
1912
+ session "Check preconditions"
1913
+ throw "Precondition not met"
1914
+ ```
1915
+
1916
+ ### Nested Error Handling
1917
+
1918
+ Try blocks can be nested. Inner catch blocks don't trigger outer handlers unless they rethrow:
1919
+
1920
+ ```prose
1921
+ try:
1922
+ session "Outer operation"
1923
+ try:
1924
+ session "Inner risky operation"
1925
+ catch:
1926
+ session "Handle inner error" # Outer catch won't run
1927
+ session "Continue outer operation"
1928
+ catch:
1929
+ session "Handle outer error only"
1930
+ ```
1931
+
1932
+ ### Error Handling in Parallel
1933
+
1934
+ Each parallel branch can have its own error handling:
1935
+
1936
+ ```prose
1937
+ parallel:
1938
+ try:
1939
+ session "Branch A might fail"
1940
+ catch:
1941
+ session "Recover branch A"
1942
+ try:
1943
+ session "Branch B might fail"
1944
+ catch:
1945
+ session "Recover branch B"
1946
+
1947
+ session "Continue with recovered results"
1948
+ ```
1949
+
1950
+ This differs from the `on-fail:` policy which controls behavior when unhandled errors occur.
1951
+
1952
+ ### Retry Property
1953
+
1954
+ The `retry:` property makes a session automatically retry on failure:
1955
+
1956
+ ```prose
1957
+ session "Call flaky API"
1958
+ retry: 3
1959
+ ```
1960
+
1961
+ #### Retry with Backoff
1962
+
1963
+ Add `backoff:` to control delay between retries:
1964
+
1965
+ ```prose
1966
+ session "Rate-limited API"
1967
+ retry: 5
1968
+ backoff: "exponential"
1969
+ ```
1970
+
1971
+ **Backoff Strategies:**
1972
+
1973
+ | Strategy | Behavior |
1974
+ | --------------- | ---------------------------------- |
1975
+ | `"none"` | Immediate retry (default) |
1976
+ | `"linear"` | Fixed delay between retries |
1977
+ | `"exponential"` | Doubling delay (1s, 2s, 4s, 8s...) |
1978
+
1979
+ #### Retry with Context
1980
+
1981
+ Retry works with other session properties:
1982
+
1983
+ ```prose
1984
+ let data = session "Get input"
1985
+ session "Process data"
1986
+ context: data
1987
+ retry: 3
1988
+ backoff: "linear"
1989
+ ```
1990
+
1991
+ ### Combining Patterns
1992
+
1993
+ Retry and try/catch work together for maximum resilience:
1994
+
1995
+ ```prose
1996
+ try:
1997
+ session "Call external service"
1998
+ retry: 3
1999
+ backoff: "exponential"
2000
+ catch:
2001
+ session "All retries failed, use fallback"
2002
+ ```
2003
+
2004
+ ### Validation Rules
2005
+
2006
+ | Check | Severity | Message |
2007
+ | ---------------------------- | -------- | --------------------------------------------------- |
2008
+ | Try without catch or finally | Error | Try block must have at least "catch:" or "finally:" |
2009
+ | Error variable shadows outer | Warning | Error variable shadows outer variable |
2010
+ | Empty throw message | Warning | Throw message is empty |
2011
+ | Non-positive retry count | Error | Retry count must be positive |
2012
+ | Non-integer retry count | Error | Retry count must be an integer |
2013
+ | High retry count (>10) | Warning | Retry count is unusually high |
2014
+ | Invalid backoff strategy | Error | Must be "none", "linear", or "exponential" |
2015
+ | Retry on agent definition | Warning | Retry property is only valid in session statements |
2016
+
2017
+ ### Syntax Reference
2018
+
2019
+ ```
2020
+ try_block ::= "try" ":" NEWLINE INDENT statement+ DEDENT
2021
+ [catch_block]
2022
+ [finally_block]
2023
+
2024
+ catch_block ::= "catch" ["as" identifier] ":" NEWLINE INDENT statement+ DEDENT
2025
+
2026
+ finally_block ::= "finally" ":" NEWLINE INDENT statement+ DEDENT
2027
+
2028
+ throw_statement ::= "throw" [string_literal]
2029
+
2030
+ retry_property ::= "retry" ":" number_literal
2031
+
2032
+ backoff_property ::= "backoff" ":" string_literal
2033
+ ```
2034
+
2035
+ ---
2036
+
2037
+ ## Choice Blocks
2038
+
2039
+ Choice blocks allow the OpenProse VM to select from multiple labeled options based on criteria. This is useful for branching workflows where the best path depends on runtime analysis.
2040
+
2041
+ ### Syntax
2042
+
2043
+ ```prose
2044
+ choice **criteria**:
2045
+ option "Label A":
2046
+ statements...
2047
+ option "Label B":
2048
+ statements...
2049
+ ```
2050
+
2051
+ ### Criteria
2052
+
2053
+ The criteria is wrapped in discretion markers (`**...**`) and is evaluated by the OpenProse VM to select which option to execute:
2054
+
2055
+ ```prose
2056
+ choice **the best approach for the current situation**:
2057
+ option "Quick fix":
2058
+ session "Apply a quick temporary fix"
2059
+ option "Full refactor":
2060
+ session "Perform a complete code refactor"
2061
+ ```
2062
+
2063
+ ### Multi-line Criteria
2064
+
2065
+ For complex criteria, use triple-asterisks:
2066
+
2067
+ ```prose
2068
+ choice ***
2069
+ which strategy is most appropriate
2070
+ given the current project constraints
2071
+ and timeline requirements
2072
+ ***:
2073
+ option "MVP approach":
2074
+ session "Build minimum viable product"
2075
+ option "Full feature set":
2076
+ session "Build complete feature set"
2077
+ ```
2078
+
2079
+ ### Examples
2080
+
2081
+ #### Simple Choice
2082
+
2083
+ ```prose
2084
+ let analysis = session "Analyze the code quality"
2085
+
2086
+ choice **the severity of issues found in the analysis**:
2087
+ option "Critical":
2088
+ session "Stop deployment and fix critical issues"
2089
+ context: analysis
2090
+ option "Minor":
2091
+ session "Log issues for later and proceed"
2092
+ context: analysis
2093
+ option "None":
2094
+ session "Proceed with deployment"
2095
+ ```
2096
+
2097
+ #### Choice with Multiple Statements per Option
2098
+
2099
+ ```prose
2100
+ choice **the user's experience level**:
2101
+ option "Beginner":
2102
+ session "Explain basic concepts first"
2103
+ session "Provide step-by-step guidance"
2104
+ session "Include helpful tips and warnings"
2105
+ option "Expert":
2106
+ session "Provide concise technical summary"
2107
+ session "Include advanced configuration options"
2108
+ ```
2109
+
2110
+ #### Nested Choices
2111
+
2112
+ ```prose
2113
+ choice **the type of request**:
2114
+ option "Bug report":
2115
+ choice **the bug severity**:
2116
+ option "Critical":
2117
+ session "Escalate immediately"
2118
+ option "Normal":
2119
+ session "Add to sprint backlog"
2120
+ option "Feature request":
2121
+ session "Add to feature backlog"
2122
+ ```
2123
+
2124
+ ### Execution Semantics
2125
+
2126
+ When the OpenProse VM encounters a `choice` block:
2127
+
2128
+ 1. **Evaluate Criteria**: Interpret the discretion criteria in current context
2129
+ 2. **Select Option**: Choose the most appropriate labeled option
2130
+ 3. **Execute**: Run all statements in the selected option's body
2131
+ 4. **Continue**: Proceed to the next statement after the choice block
2132
+
2133
+ Only one option is executed per choice block.
2134
+
2135
+ ### Validation Rules
2136
+
2137
+ | Check | Severity | Message |
2138
+ | ----------------------- | -------- | ------------------------------------------ |
2139
+ | Choice without options | Error | Choice block must have at least one option |
2140
+ | Empty criteria | Error | Choice criteria cannot be empty |
2141
+ | Duplicate option labels | Warning | Duplicate option label |
2142
+ | Empty option body | Warning | Option has empty body |
2143
+
2144
+ ### Syntax Reference
2145
+
2146
+ ```
2147
+ choice_block ::= "choice" discretion ":" NEWLINE INDENT option+ DEDENT
2148
+
2149
+ option ::= "option" string ":" NEWLINE INDENT statement+ DEDENT
2150
+
2151
+ discretion ::= "**" text "**" | "***" text "***"
2152
+ ```
2153
+
2154
+ ---
2155
+
2156
+ ## Conditional Statements
2157
+
2158
+ If/elif/else statements provide conditional branching based on AI-evaluated conditions using discretion markers.
2159
+
2160
+ ### If Statement
2161
+
2162
+ ```prose
2163
+ if **condition**:
2164
+ statements...
2165
+ ```
2166
+
2167
+ ### If/Else
2168
+
2169
+ ```prose
2170
+ if **condition**:
2171
+ statements...
2172
+ else:
2173
+ statements...
2174
+ ```
2175
+
2176
+ ### If/Elif/Else
2177
+
2178
+ ```prose
2179
+ if **first condition**:
2180
+ statements...
2181
+ elif **second condition**:
2182
+ statements...
2183
+ elif **third condition**:
2184
+ statements...
2185
+ else:
2186
+ statements...
2187
+ ```
2188
+
2189
+ ### Discretion Conditions
2190
+
2191
+ Conditions are wrapped in discretion markers (`**...**`) for AI evaluation:
2192
+
2193
+ ```prose
2194
+ let analysis = session "Analyze the codebase"
2195
+
2196
+ if **the code has security vulnerabilities**:
2197
+ session "Fix security issues immediately"
2198
+ context: analysis
2199
+ elif **the code has performance issues**:
2200
+ session "Optimize performance bottlenecks"
2201
+ context: analysis
2202
+ else:
2203
+ session "Proceed with normal review"
2204
+ context: analysis
2205
+ ```
2206
+
2207
+ ### Multi-line Conditions
2208
+
2209
+ Use triple-asterisks for complex conditions:
2210
+
2211
+ ```prose
2212
+ if ***
2213
+ the test suite passes
2214
+ and the code coverage is above 80%
2215
+ and there are no linting errors
2216
+ ***:
2217
+ session "Deploy to production"
2218
+ else:
2219
+ session "Fix issues before deploying"
2220
+ ```
2221
+
2222
+ ### Examples
2223
+
2224
+ #### Simple If
2225
+
2226
+ ```prose
2227
+ session "Check system health"
2228
+
2229
+ if **the system is healthy**:
2230
+ session "Continue with normal operations"
2231
+ ```
2232
+
2233
+ #### If/Else
2234
+
2235
+ ```prose
2236
+ let review = session "Review the pull request"
2237
+
2238
+ if **the code changes are safe and well-tested**:
2239
+ session "Approve and merge the PR"
2240
+ context: review
2241
+ else:
2242
+ session "Request changes"
2243
+ context: review
2244
+ ```
2245
+
2246
+ #### Multiple Elif
2247
+
2248
+ ```prose
2249
+ let status = session "Check project status"
2250
+
2251
+ if **the project is on track**:
2252
+ session "Continue as planned"
2253
+ elif **the project is slightly delayed**:
2254
+ session "Adjust timeline and communicate"
2255
+ elif **the project is significantly delayed**:
2256
+ session "Escalate to management"
2257
+ session "Create recovery plan"
2258
+ else:
2259
+ session "Assess project viability"
2260
+ ```
2261
+
2262
+ #### Nested Conditionals
2263
+
2264
+ ```prose
2265
+ if **the request is authenticated**:
2266
+ if **the user has admin privileges**:
2267
+ session "Process admin request"
2268
+ else:
2269
+ session "Process standard user request"
2270
+ else:
2271
+ session "Return authentication error"
2272
+ ```
2273
+
2274
+ ### Combining with Other Constructs
2275
+
2276
+ #### With Try/Catch
2277
+
2278
+ ```prose
2279
+ try:
2280
+ session "Attempt operation"
2281
+ if **operation succeeded partially**:
2282
+ session "Complete remaining steps"
2283
+ catch as err:
2284
+ if **error is recoverable**:
2285
+ session "Apply recovery procedure"
2286
+ context: err
2287
+ else:
2288
+ throw "Unrecoverable error"
2289
+ ```
2290
+
2291
+ #### With Loops
2292
+
2293
+ ```prose
2294
+ loop until **task complete** (max: 10):
2295
+ session "Work on task"
2296
+ if **encountered blocker**:
2297
+ session "Resolve blocker"
2298
+ ```
2299
+
2300
+ ### Execution Semantics
2301
+
2302
+ When the OpenProse VM encounters an `if` statement:
2303
+
2304
+ 1. **Evaluate Condition**: Interpret the first discretion condition
2305
+ 2. **If True**: Execute the then-body and skip remaining clauses
2306
+ 3. **If False**: Check each `elif` condition in order
2307
+ 4. **Elif Match**: Execute that elif's body and skip remaining
2308
+ 5. **No Match**: Execute the `else` body (if present)
2309
+ 6. **Continue**: Proceed to the next statement
2310
+
2311
+ ### Validation Rules
2312
+
2313
+ | Check | Severity | Message |
2314
+ | --------------- | -------- | --------------------------------- |
2315
+ | Empty condition | Error | If/elif condition cannot be empty |
2316
+ | Elif without if | Error | Elif must follow if |
2317
+ | Else without if | Error | Else must follow if or elif |
2318
+ | Multiple else | Error | Only one else clause allowed |
2319
+ | Empty body | Warning | Condition has empty body |
2320
+
2321
+ ### Syntax Reference
2322
+
2323
+ ```
2324
+ if_statement ::= "if" discretion ":" NEWLINE INDENT statement+ DEDENT
2325
+ elif_clause*
2326
+ [else_clause]
2327
+
2328
+ elif_clause ::= "elif" discretion ":" NEWLINE INDENT statement+ DEDENT
2329
+
2330
+ else_clause ::= "else" ":" NEWLINE INDENT statement+ DEDENT
2331
+
2332
+ discretion ::= "**" text "**" | "***" text "***"
2333
+ ```
2334
+
2335
+ ---
2336
+
2337
+ ## Execution Model
2338
+
2339
+ OpenProse uses a two-phase execution model.
2340
+
2341
+ ### Phase 1: Compilation (Static)
2342
+
2343
+ The compile phase handles deterministic preprocessing:
2344
+
2345
+ 1. **Parse**: Convert source code to AST
2346
+ 2. **Validate**: Check for syntax and semantic errors
2347
+ 3. **Expand**: Normalize syntax sugar (when implemented)
2348
+ 4. **Output**: Generate canonical program
2349
+
2350
+ ### Phase 2: Runtime (Intelligent)
2351
+
2352
+ The OpenProse VM executes the compiled program:
2353
+
2354
+ 1. **Load**: Receive the compiled program
2355
+ 2. **Collect Agents**: Register all agent definitions
2356
+ 3. **Execute**: Process each statement in order
2357
+ 4. **Spawn**: Create subagents with resolved configurations
2358
+ 5. **Coordinate**: Manage context passing between sessions
2359
+
2360
+ ### OpenProse VM Behavior
2361
+
2362
+ | Aspect | Behavior |
2363
+ | -------------------- | ----------------------------------------------- |
2364
+ | Execution order | Strict - follows program exactly |
2365
+ | Session creation | Strict - creates what program specifies |
2366
+ | Agent resolution | Strict - merge properties deterministically |
2367
+ | Context passing | Intelligent - summarizes/transforms as needed |
2368
+ | Completion detection | Intelligent - determines when session is "done" |
2369
+
2370
+ ### State Management
2371
+
2372
+ For the current implementation, state is tracked in-context (conversation history):
2373
+
2374
+ | State Type | Tracking Approach |
2375
+ | ------------------- | --------------------------------------------------- |
2376
+ | Agent definitions | Collected at program start |
2377
+ | Execution flow | Implicit reasoning ("completed X, now executing Y") |
2378
+ | Session outputs | Held in conversation history |
2379
+ | Position in program | Tracked by OpenProse VM |
2380
+
2381
+ ---
2382
+
2383
+ ## Validation Rules
2384
+
2385
+ The validator checks programs for errors and warnings before execution.
2386
+
2387
+ ### Errors (Block Execution)
2388
+
2389
+ | Code | Description |
2390
+ | ---- | ----------------------------------- |
2391
+ | E001 | Unterminated string literal |
2392
+ | E002 | Unknown escape sequence in string |
2393
+ | E003 | Session missing prompt or agent |
2394
+ | E004 | Unexpected token |
2395
+ | E005 | Invalid syntax |
2396
+ | E006 | Duplicate agent definition |
2397
+ | E007 | Undefined agent reference |
2398
+ | E008 | Invalid model value |
2399
+ | E009 | Duplicate property |
2400
+ | E010 | Duplicate import |
2401
+ | E011 | Empty import skill name |
2402
+ | E012 | Empty import source |
2403
+ | E013 | Skills must be an array |
2404
+ | E014 | Skill name must be a string |
2405
+ | E015 | Permissions must be a block |
2406
+ | E016 | Permission pattern must be a string |
2407
+
2408
+ ### Warnings (Non-blocking)
2409
+
2410
+ | Code | Description |
2411
+ | ---- | ---------------------------------------- |
2412
+ | W001 | Empty session prompt |
2413
+ | W002 | Whitespace-only session prompt |
2414
+ | W003 | Session prompt exceeds 10,000 characters |
2415
+ | W004 | Empty prompt property |
2416
+ | W005 | Unknown property name |
2417
+ | W006 | Unknown import source format |
2418
+ | W007 | Skill not imported |
2419
+ | W008 | Unknown permission type |
2420
+ | W009 | Unknown permission value |
2421
+ | W010 | Empty skills array |
2422
+
2423
+ ### Error Message Format
2424
+
2425
+ Errors include location information:
2426
+
2427
+ ```
2428
+ Error at line 5, column 12: Unterminated string literal
2429
+ session "Hello
2430
+ ^
2431
+ ```
2432
+
2433
+ ---
2434
+
2435
+ ## Examples
2436
+
2437
+ ### Minimal Program
2438
+
2439
+ ```prose
2440
+ session "Hello world"
2441
+ ```
2442
+
2443
+ ### Research Pipeline with Agents
2444
+
2445
+ ```prose
2446
+ # Define specialized agents
2447
+ agent researcher:
2448
+ model: sonnet
2449
+ prompt: "You are a research assistant"
2450
+
2451
+ agent writer:
2452
+ model: opus
2453
+ prompt: "You are a technical writer"
2454
+
2455
+ # Execute workflow
2456
+ session: researcher
2457
+ prompt: "Research recent developments in quantum computing"
2458
+
2459
+ session: writer
2460
+ prompt: "Write a summary of the research findings"
2461
+ ```
2462
+
2463
+ ### Code Review Workflow
2464
+
2465
+ ```prose
2466
+ agent reviewer:
2467
+ model: sonnet
2468
+ prompt: "You are an expert code reviewer"
2469
+
2470
+ session: reviewer
2471
+ prompt: "Read the code in src/ and identify potential bugs"
2472
+
2473
+ session: reviewer
2474
+ prompt: "Suggest fixes for each bug found"
2475
+
2476
+ session: reviewer
2477
+ prompt: "Create a summary of all changes needed"
2478
+ ```
2479
+
2480
+ ### Multi-step Task with Model Override
2481
+
2482
+ ```prose
2483
+ agent analyst:
2484
+ model: haiku
2485
+ prompt: "You analyze data quickly"
2486
+
2487
+ # Quick initial analysis
2488
+ session: analyst
2489
+ prompt: "Scan the data for obvious patterns"
2490
+
2491
+ # Detailed analysis with more powerful model
2492
+ session: analyst
2493
+ model: opus
2494
+ prompt: "Perform deep analysis on the patterns found"
2495
+ ```
2496
+
2497
+ ### Comments for Documentation
2498
+
2499
+ ```prose
2500
+ # Project: Quarterly Report Generator
2501
+ # Author: Team Lead
2502
+ # Date: 2024-01-01
2503
+
2504
+ agent data-collector:
2505
+ model: sonnet
2506
+ prompt: "You gather and organize data"
2507
+
2508
+ agent analyst:
2509
+ model: opus
2510
+ prompt: "You analyze data and create insights"
2511
+
2512
+ # Step 1: Gather data
2513
+ session: data-collector
2514
+ prompt: "Collect all sales data from the past quarter"
2515
+
2516
+ # Step 2: Analysis
2517
+ session: analyst
2518
+ prompt: "Perform trend analysis on the collected data"
2519
+
2520
+ # Step 3: Report generation
2521
+ session: analyst
2522
+ prompt: "Generate a formatted quarterly report with charts"
2523
+ ```
2524
+
2525
+ ### Workflow with Skills and Permissions
2526
+
2527
+ ```prose
2528
+ # Import external skills
2529
+ import "web-search" from "github:anthropic/skills"
2530
+ import "file-writer" from "./local-skills"
2531
+
2532
+ # Define a secure research agent
2533
+ agent researcher:
2534
+ model: sonnet
2535
+ prompt: "You are a research assistant"
2536
+ skills: ["web-search"]
2537
+ permissions:
2538
+ read: ["*.md", "*.txt"]
2539
+ bash: deny
2540
+
2541
+ # Define a writer agent
2542
+ agent writer:
2543
+ model: opus
2544
+ prompt: "You create documentation"
2545
+ skills: ["file-writer"]
2546
+ permissions:
2547
+ write: ["docs/"]
2548
+ bash: deny
2549
+
2550
+ # Execute workflow
2551
+ session: researcher
2552
+ prompt: "Research AI safety topics"
2553
+
2554
+ session: writer
2555
+ prompt: "Write a summary document"
2556
+ ```
2557
+
2558
+ ---
2559
+
2560
+ ## Future Features
2561
+
2562
+ All core features through Tier 12 have been implemented. Potential future enhancements:
2563
+
2564
+ ### Tier 13: Extended Features
2565
+
2566
+ - Custom functions with return values
2567
+ - Module system for code organization
2568
+ - Type annotations for validation
2569
+ - Async/await patterns for advanced concurrency
2570
+
2571
+ ### Tier 14: Tooling
2572
+
2573
+ - Language server protocol (LSP) support
2574
+ - VS Code extension
2575
+ - Interactive debugger
2576
+ - Performance profiling
2577
+
2578
+ ---
2579
+
2580
+ ## Syntax Grammar (Implemented)
2581
+
2582
+ ```
2583
+ program → statement* EOF
2584
+ statement → agentDef | blockDef | parallelBlock | repeatBlock | forEachBlock
2585
+ | loopBlock | tryBlock | choiceBlock | ifStatement | session
2586
+ | doBlock | arrowExpr | letBinding | constBinding | assignment
2587
+ | throwStatement | comment
2588
+
2589
+ # Definitions
2590
+ agentDef → "agent" IDENTIFIER ":" NEWLINE INDENT property* DEDENT
2591
+ blockDef → "block" IDENTIFIER params? ":" NEWLINE INDENT statement* DEDENT
2592
+ params → "(" IDENTIFIER ( "," IDENTIFIER )* ")"
2593
+
2594
+ # Control Flow
2595
+ parallelBlock → "parallel" parallelMods? ":" NEWLINE INDENT parallelBranch* DEDENT
2596
+ parallelMods → "(" ( joinStrategy | onFail | countMod ) ( "," ( joinStrategy | onFail | countMod ) )* ")"
2597
+ joinStrategy → string # "all" | "first" | "any"
2598
+ onFail → "on-fail" ":" string # "fail-fast" | "continue" | "ignore"
2599
+ countMod → "count" ":" NUMBER # only valid with "any"
2600
+ parallelBranch → ( IDENTIFIER "=" )? statement
2601
+
2602
+ # Loops
2603
+ repeatBlock → "repeat" NUMBER ( "as" IDENTIFIER )? ":" NEWLINE INDENT statement* DEDENT
2604
+ forEachBlock → "parallel"? "for" IDENTIFIER ( "," IDENTIFIER )? "in" collection ":" NEWLINE INDENT statement* DEDENT
2605
+ loopBlock → "loop" ( ( "until" | "while" ) discretion )? loopMods? ( "as" IDENTIFIER )? ":" NEWLINE INDENT statement* DEDENT
2606
+ loopMods → "(" "max" ":" NUMBER ")"
2607
+
2608
+ # Error Handling
2609
+ tryBlock → "try" ":" NEWLINE INDENT statement+ DEDENT catchBlock? finallyBlock?
2610
+ catchBlock → "catch" ( "as" IDENTIFIER )? ":" NEWLINE INDENT statement+ DEDENT
2611
+ finallyBlock → "finally" ":" NEWLINE INDENT statement+ DEDENT
2612
+ throwStatement → "throw" string?
2613
+
2614
+ # Conditionals
2615
+ choiceBlock → "choice" discretion ":" NEWLINE INDENT choiceOption+ DEDENT
2616
+ choiceOption → "option" string ":" NEWLINE INDENT statement+ DEDENT
2617
+ ifStatement → "if" discretion ":" NEWLINE INDENT statement+ DEDENT elifClause* elseClause?
2618
+ elifClause → "elif" discretion ":" NEWLINE INDENT statement+ DEDENT
2619
+ elseClause → "else" ":" NEWLINE INDENT statement+ DEDENT
2620
+
2621
+ # Blocks and Sequences
2622
+ doBlock → "do" ( ":" NEWLINE INDENT statement* DEDENT | IDENTIFIER args? )
2623
+ args → "(" expression ( "," expression )* ")"
2624
+ arrowExpr → session "->" session ( "->" session )*
2625
+
2626
+ # Sessions
2627
+ session → "session" ( string | ":" IDENTIFIER | IDENTIFIER ":" IDENTIFIER )
2628
+ ( NEWLINE INDENT property* DEDENT )?
2629
+
2630
+ # Bindings
2631
+ letBinding → "let" IDENTIFIER "=" expression
2632
+ constBinding → "const" IDENTIFIER "=" expression
2633
+ assignment → IDENTIFIER "=" expression
2634
+
2635
+ # Expressions
2636
+ expression → session | doBlock | parallelBlock | repeatBlock | forEachBlock
2637
+ | loopBlock | arrowExpr | pipeExpr | string | IDENTIFIER | array | objectContext
2638
+
2639
+ # Pipelines
2640
+ pipeExpr → ( IDENTIFIER | array ) ( "|" pipeOp )+
2641
+ pipeOp → ( "map" | "filter" | "pmap" ) ":" NEWLINE INDENT statement* DEDENT
2642
+ | "reduce" "(" IDENTIFIER "," IDENTIFIER ")" ":" NEWLINE INDENT statement* DEDENT
2643
+
2644
+ # Properties
2645
+ property → ( "model" | "prompt" | "context" | "retry" | "backoff" | IDENTIFIER )
2646
+ ":" ( IDENTIFIER | string | array | objectContext | NUMBER )
2647
+
2648
+ # Primitives
2649
+ discretion → "**" text "**" | "***" text "***"
2650
+ collection → IDENTIFIER | array
2651
+ array → "[" ( expression ( "," expression )* )? "]"
2652
+ objectContext → "{" ( IDENTIFIER ( "," IDENTIFIER )* )? "}"
2653
+ comment → "#" text NEWLINE
2654
+
2655
+ # Strings
2656
+ string → singleString | tripleString | interpolatedString
2657
+ singleString → '"' character* '"'
2658
+ tripleString → '"""' ( character | NEWLINE )* '"""'
2659
+ interpolatedString → string containing "{" IDENTIFIER "}"
2660
+ character → escape | non-quote
2661
+ escape → "\\" | "\"" | "\n" | "\t"
2662
+ ```
2663
+
2664
+ ---
2665
+
2666
+ ## Compiler API
2667
+
2668
+ When a user invokes `/prose-compile` or asks you to compile a `.prose` file:
2669
+
2670
+ 1. **Read this document** (`docs.md`) fully to understand all syntax and validation rules
2671
+ 2. **Parse** the program according to the syntax grammar
2672
+ 3. **Validate** syntax correctness, semantic validity, and self-evidence
2673
+ 4. **Transform** to canonical form (expand syntax sugar, normalize structure)
2674
+ 5. **Output** the compiled program or report errors/warnings with line numbers
2675
+
2676
+ For direct interpretation without compilation, read `prose.md` and execute statements as described in the Session Statement section.