prose-dev Atlas OpenProse docs bound to the contracts they describe
144 documents
skills/open-prose/contract-markdown.md

The canonical format spec for .prose.md source: tiny YAML frontmatter (name, kind, optional id and version) plus Markdown sections, where every file is one render and kind is sugar over that render atom. It defines five kinds (responsibility as a mounted DAG node, function as a called Parameters-to-Returns helper replacing service, gateway as external-driven responsibility sugar, pattern, test), the header hierarchy (# title, ## inline node, ### section, #### facet semantics inside Maintains and Requires), and the full section table from Description and Goal through Requires, Maintains, Continuity, Errors, Invariants, Strategies, Runtime, Shape, Skills, Tools, Execution, Fixtures, Expects, Slots, Config, Delegation, Schedule, Receives, Emits, and Payload. It details the Maintains four jobs (type, canonicalization spec, facets, postconditions), the named-parts facet rule with Requires-to-Maintains matching and facet families with placeholder members, Continuity modes (input-driven, self-driven, external-driven), Skills and Tools fail-closed resolution, run/run[] typed inputs, and the folded legacy sections (Ensures, Criteria, Memory, Services/Wiring). Authors and reviewers read this when writing, linting, or parsing any .prose.md responsibility, function, gateway, pattern, or test.

Contract lifecycle: author to receipt

Author intentstartForme wires the DAGstepCompile emits IRstepRun and receiptoutput

Click any node to read its source — a doc section or the code itself.


role: contract-markdown-format summary: | Canonical Markdown format for OpenProse responsibilities, functions, gateways, patterns, and tests. Defines the header hierarchy, contract sections, and how interpreters extract *.prose.md source for the mounted-node DAG. see-also:

  • forme.md: Wiring semantics (the responsibility DAG)
  • prose.md: Execution semantics (the render harness)
  • responsibility-runtime.md: Compile/run reconciler semantics
  • prosescript.md: Imperative scripting layer for ### Execution
  • guidance/tenets.md: Design reasoning
  • guidance/authoring.md: Authoring guidance

Contract Markdown

A contract states requirements and the context needed to interpret and apply them. Contract authoring explains how reusable contracts express those requirements together.

Contract Markdown is the human-facing *.prose.md format for OpenProse responsibilities, functions, gateways, patterns, and tests. It uses tiny YAML frontmatter for file identity, then Markdown sections for the human-facing language: contracts, the world-model schema, runtime hints, and the render body.

Every authored file is one render — a declaration plus the bounded session that runs it. The kind field is sugar over that single render atom: each kind is the same render with different or missing sections (the render atom in concepts/reconciler.md).

The format optimizes for two readers:

  1. Humans scanning a workflow.
  2. Agents extracting contracts and wiring the responsibility DAG with Forme.

Authored Kinds

prose run and the reconciler recognize five kinds. Two are data-flow kinds (sugar over the render atom); three are tooling kinds.

  • Responsibility — a mounted node: the headline kind. A responsibility declares its inputs as subscription contracts (### Requires) and the shape of the standing truth it keeps current (### Maintains), and is woken over time. Mounting (a harness act) gives it identity, a persisted world-model, and resolved subscriptions. A responsibility is a node because it is mounted as a subscribable producer — not because it holds state.

  • Function — a called render: the library tier, and the replacement for the retired service. A function is stateless and ephemeral. Its interface is ### Parameters → ### Returns — a plain call interface, not a subscription contract — so it carries no world-model and no ### Continuity. You call functions constantly and author them rarely; most ship pre-built in std/.

  • Gateway — sugar for an external-driven responsibility. A gateway is how time or the outside world enters the graph: schedules, local HTTP routes, webhooks, or provider events. It has no ### Requires (its input arrives from outside the graph) and declares ### Continuity: external-driven. It maintains the latest incoming truth. Forme finds the entry-point set precisely by finding the responsibilities whose ### Continuity is external-driven.

  • Pattern — a reusable agent design pattern: slots, config, invariants, and delegation rules. Patterns are not run directly; they are instantiated at compile time and expanded into nodes.

  • Test — a harness executed by prose test: it supplies fixtures, runs a subject responsibility or function, and evaluates assertions over the subject's world-model / returned value.

There is no system kind. Composition is imperative call inside a render (ProseScript ### Execution) or a cross-node subscription across responsibilities (wired by Forme) — never a third "internally-autowired graph" kind in the middle.

A run starts from the file the caller invokes, which is a responsibility, function, or gateway.

Gateway shape

Gateway sections are intentionally small. A gateway always declares ### Continuity: external-driven:

---
name: github-stars
kind: gateway
---

### Continuity

- external-driven

### Receives

- POST /webhooks/github/stars
- Provider: GitHub
- Event: star

### Maintains

- `stargazers`: the latest incoming star events as structured truth

### Emits

- high-intent-stargazer-outreach

Core Shape

A function declares a plain call interface:

---
name: research-report
kind: function
---

### Parameters

- `topic`: the question to investigate

### Returns

- `report`: concise answer with sources

### Strategies

- when sources are thin: broaden search terms

### Execution

```prose
let findings = call researcher
  topic: topic

return findings
```

A responsibility declares subscription contracts and the world-model schema it maintains:

---
name: competitor-activity-monitor
kind: responsibility
id: 067NC4KG01RG50R40M30E20918
---

### Goal

A current, corroborated view of each tracked competitor's material activity.

### Requires

- `funding`: a current view of competitor funding events
- `hiring`: a current view of competitor hiring activity

### Maintains

A current, corroborated view of each tracked competitor. Each competitor carries a
stable `name` and a `last_corroborated` field; `fetched_at` and source request-ids
are immaterial everywhere. Postcondition: every competitor cites a corroborating
source.

#### funding
Funding events per competitor — round, amount, date. Material: the event set
(unordered) and each event's round/amount/date.

#### hiring
Open-role activity — the department set and the open-role count (exact).

#### product-launches
Announced or shipped products — the launch set; a ship-date slipping past today
flips `shipped`, which is material.

### Continuity

- self-driven: re-check every 6h

The three #### parts under ### Maintains are facets: a subscriber that ### Requires funding wakes only when #### funding's fingerprint moves. The ### Requires bullets name the producer facet they subscribe to — Requires.<facet> ↔ Maintains.<facet>.

Header Hierarchy

Level Meaning
# Optional human title. Ignored by Forme unless no frontmatter name exists.
## Inline responsibility/function boundary in multi-node files.
### Section inside the current responsibility, function, or gateway.
#### inside ### Maintains Semantic: a facet. A named, independently-subscribable part of the maintained truth (the named-parts rule, §Facets). Its name is the fingerprint unit, subscription symbol, and world-model subtree.
#### inside ### Requires Semantic: a facet-need. A named subscription to a producer's facet; Forme matches Requires.<facet> ↔ Maintains.<facet>.
####+ elsewhere Free-form nested documentation inside a section.

## is reserved for inline node names so a file can contain several responsibilities or functions without ambiguous parsing. Contract sections use ### so they work uniformly in standalone files and inside inline nodes.

Inside ### Maintains and ### Requires, a #### sub-heading is not free-form documentation — it is a facet (a named part of the truth) or a facet-need (a named subscription to one). Everywhere else #### is plain nested prose (the named-parts rule under ## Maintains below).

Canonical Sections

Forme and the Prose VM recognize these ### sections case-insensitively:

Section Applies To Purpose
### Description all Human summary. Preserved for readers; not used as a contract
### Goal responsibility, gateway The render's one-sentence standing intent
### Requires responsibility, pattern slots Subscription contracts naming facet-level needs; a #### sub-heading is a facet-need. Forme's match target (Requires.<facet> ↔ Maintains.<facet>)
### Maintains responsibility, gateway The world-model schema — type, canonicalization spec, facets (a #### sub-heading is a facet, the named-parts rule), and postconditions (see Maintains)
### Parameters function Inputs the caller passes at call time
### Returns function The value the function returns
### Continuity responsibility, gateway The intrinsic wake-source declaration: input-driven, self-driven, or external-driven (see Continuity)
### Errors responsibility, function Declared failures the node may signal
### Invariants responsibility, function, pattern Properties that must hold regardless of outcome
### Strategies responsibility, function, test Guidance for judgment calls and edge cases
### Environment responsibility, function Runtime variables supplied by host infrastructure
### Runtime responsibility, function Execution hints such as model
### Skills responsibility, function Agent harness skills the component requires the host harness to provide. See Skills
### Tools responsibility, function Host tools the component requires the host environment to provide. See Tools
### Shape responsibility, function Capability boundaries: self, delegates, and prohibited work
### Execution responsibility, function ProseScript render body that pins choreography
### Fixtures test Test inputs supplied without prompting
### Expects test Positive natural-language assertions
### Expects Not test Negative natural-language assertions
### Slots pattern Responsibilities or functions a pattern requires from its caller
### Config pattern Pattern-level parameters and defaults
### Delegation pattern ProseScript or pseudocode describing slot interaction
### Schedule gateway Optional cron-like ingress cadence
### Receives gateway Optional HTTP/event ingress description
### Emits gateway Responsibility name the gateway should wake
### Payload gateway Notes about the event payload shape

Unknown ### sections are preserved as documentation. They are not contract sections unless a future spec names them.

Folded and deleted sections

The judge-era responsibility vocabulary folds into the world-model model:

Legacy section Folds into
### Ensures ### Maintains (data-flow) / ### Returns (function) — re-purpose, not just rename
### Criteria ### Maintains postconditions
### Fulfillment the render itself, or a delegated function
### Constraints ### Invariants / ### Shape
### Memory the single persisted world-model (responsibility); dropped (function)
### Services / ### Wiring deleted with system; composition is call or subscription

### Memory is gone: one persisted world-model per node subsumes the old reads/writes ledger. A function is stateless and has no world-model, so it simply has no memory; a former service-with-memory that was genuinely stateful is really a responsibility, and its persisted state is its world-model.

File Extraction

Interpreters parse a file in this order:

  1. Read YAML frontmatter for identity metadata (name, kind; kind: test files also declare subject; kind: responsibility files declare id).
  2. Create the file-level responsibility, function, gateway, pattern, or test from the frontmatter.
  3. Attach all ### sections before the first ## to the file-level entry.
  4. For every ## {name} heading, create an inline node named {name}.
  5. Attach subsequent ### sections to that inline node until the next ##.

Example — a file with one responsibility and two helper functions it calls:

---
name: content-pipeline
kind: responsibility
---

### Requires

- `draft`: text to improve

### Maintains

- `final`: the current polished text

### Execution

```prose
let notes = call review
  draft: draft

let polished = call polish
  draft: draft
  feedback: notes

return polished
```

## review

### Parameters

- `draft`: text to review

### Returns

- `feedback`: editorial notes

## polish

### Parameters

- `draft`: original text
- `feedback`: editorial notes

### Returns

- `final`: polished text

The file-level responsibility requires draft and maintains final. It also contains inline functions review and polish that its render calls.

Responsibilities

A kind: responsibility is a mounted DAG node: a standing truth kept current over time. It declares both halves of its interface — ### Requires (what it subscribes to) and ### Maintains (the shape of the truth it keeps) — and its wake-source in ### Continuity.

---
name: qualified-stargazer-outreach
kind: responsibility
id: 067NC4KG01RG50R40M30E20918
---

### Goal

High-intent GitHub stargazers are identified, enriched, and thoughtfully
followed up with.

### Requires

- `stargazers`: a current view of new high-intent stargazers

### Maintains

Per-stargazer outreach truth. Each entry carries GitHub activity, company context,
plausible pain, and the outreach already sent; scan timestamps are immaterial.
Postcondition: outreach is specific (a concrete program idea or sample result),
never generic. Postcondition: a stargazer is never contacted twice without new
evidence.

#### qualification
The qualification verdict per stargazer. Material: the verdict and its supporting
signals.

#### enrichment
Company and profile context. Material: the resolved company, role, and plausible
pain.

#### contact-history
What outreach has been sent. Material: each sent contact and its evidence basis.

### Continuity

- input-driven

### Tools

(none)

Forme matches each ### Requires facet-contract to the ### Maintains facet that satisfies it semantically, across all mounted responsibilities, and draws the subscription edge (the wiring algorithm in forme.md). ### Requires is the need (intent stays with the human); the resolved producer is Forme's choice (mechanism).

Load responsibility-runtime.md and concepts/responsibility.md for the compile/run reconciler semantics.

Maintains

### Maintains declares the shape of the world-model — the schema, not the instance. It is not just a renamed ### Ensures: a maintained truth is a standing, typed, subscribable artifact, so its declaration does four jobs:

  1. A type — the fields and their shapes, including any freshness fields (valid_until, last_corroborated, confidence; see Continuity).
  2. A canonicalization spec — what equality means for the fingerprint: which fields are material, which are volatile-but-immaterial and excluded (timestamps, request ids, cosmetic ordering), and how sets / numbers / text normalize. This is the single highest-leverage memoization control: without it, a feed re-polled every few minutes always looks changed and "cost scales with surprise" degrades into "cost scales with the clock."
  3. Facets (optional) — named, independently-subscribable parts of the truth, declared by the named-parts rule: a #### {name} sub-heading inside ### Maintains is a facet. A downstream that subscribes to facet X does not wake when facet Y moves. A single-truth (leaf) node declares no #### parts; its atomic world-model is the one implicit facet, so a ### Requires match still resolves. See Facets — the named-parts rule.
  4. Postconditions — the folded-in ### Criteria: validators the render must leave the truth satisfying before it signs. Not a separate judge beat; just conditions on the output. Deterministically-expressible postconditions are verified by the harness on commit; irreducibly-semantic ones are self-attested by the render.

All four jobs live inside ### Maintains — none gets its own block. The canonicalization spec and facet declarations may be written as semantically rich natural language, as long as they are unambiguous, because the spec is compiled into a deterministic canonicalizer ahead of run time (the canonicalizers section of compiler/ir-v0.md). The compiled canonicalizer travels with the contract, so a standalone render computes its own fingerprints and signs a fingerprinted receipt with no harness present.

The structured-backing rule. Anything subscribed must have a structured, canonicalizable backing. Free-form rendered prose is a derived projection excluded from the fingerprint — otherwise an LLM re-rendering the same paragraph hashes differently every time and falsely re-triggers downstreams. Rule: fingerprint the structured truth; render prose from it. The compiler lints subscribed fields that lack a structured backing.

The world-model itself — the materialized truth the render writes and commits — is a content-addressable artifact, a directory by default. ### Maintains describes its shape; state/filesystem.md describes its on-disk canonical form.

Facets — the named-parts rule

A facet is a named part of a maintained truth, and authors declare facets simply by naming the parts: a #### {name} sub-heading inside ### Maintains is a facet, and its body describes that part's fields and which are material — in prose. Name no parts and the node has one truth: the atomic facet, the free default that costs nothing. Atomic-only — no #### parts — is the v1 default and the leaf-node case; the ####-part lowering in compiler/ir-v0.md says the same thing from the compiler's side.

The name an author writes is the same name in three places at once (the named-parts rule):

  1. Fingerprint unit — the compiled canonicalizer emits one token per #### part, plus the always-on atomic token over the whole truth. A part moves only its token; fields that sit outside any part move only the atomic token.
  2. Subscription symbol — a consumer names the part in ### Requires, and the reconciler wakes that consumer only when that part's token moves. The join is Requires.<facet> ↔ Maintains.<facet> (in the compiled topology of compiler/ir-v0.md, an edge is subscriber.Requires.<facet-contract> → producer.Maintains.<facet>).
  3. World-model subtree — the part is a named region of the content-addressed artifact, published/<facet>/…, so "the directory structure is the state" shows the facets literally (state/filesystem.md).

Faceting therefore adds no new grammar: it reuses the heading hierarchy the format already has (#### = structure inside a ### section), the Requires↔Maintains join already specified, and the directory store. Structure is subscription. Material/immaterial and normalization stay prose inside each part, lowered at compile time into that part's facet name + material field-paths; a part subscribed without a structured backing is a lint (the structured-backing rule, above).

Worked example — the competitor-activity monitor maintains three subscribable parts:

### Maintains

A current, corroborated view of each tracked competitor. Each competitor carries
a stable `name` and a `last_corroborated` field; `fetched_at` and source
request-ids are immaterial everywhere. Postcondition: every competitor cites a
corroborating source.

#### funding
Funding events per competitor — round, amount, date. Material: the event set
(unordered) and each event's round/amount/date.

#### hiring
Open-role activity — the department set and the open-role count (exact).

#### product-launches
Announced or shipped products — the launch set; a ship-date slipping past today
flips `shipped`, which is material.

A downstream that ### Requires funding wakes only when #### funding's fingerprint moves — not when hiring or launches move. The shared name / last_corroborated sit outside any part, so they move only the atomic token. This is React's selector boundary made authorable.

The symmetry is total: a producer's #### funding part under ### Maintains is exactly the symbol a subscriber names in its ### Requires (Requires.funding ↔ Maintains.funding). The memo key is unchanged — (contract_fingerprint, input_fingerprints); facet granularity lives in which input-fingerprints a subscriber consumes (one per subscribed facet), not in the key shape.

Facet families and per-entity mounts

Some truths have one part per entity — one facet per starring user, per inbound email, per agent session — and the entities are not known until run time. The format has no grammar for enumerating them, and it does not need one: the contract declares the family, and a harness instantiates the members.

  • A placeholder heading declares a family. #### user:<login> inside ### Maintains declares one facet per entity: every member shares the heading's shape and material boundary, and the entity is named at run time. The angle-bracket token is the placeholder; the prefix (user:) keeps the family distinct from any literal #### part beside it. A fixed, known set of entities may instead be enumerated as literal parts (#### claude, #### codex, …); the two forms differ only in whether the author or the harness names the members.
  • A placeholder in a facet-need subscribes to one member. session:<id> in a ### Requires entry names a member of the family, not the whole family; the harness binds the member when it mounts the subscriber, so the summary for claudeA never wakes on a codexA edit. A need that asks for every member is the diamond rule's deliberate fan-in — one slot per member — and should say so.
  • A bracketed title marks a per-entity mount. # Title [instance] — as in # Runtime Adapter [runtime] — says that a harness mounts this contract once per entity, one adapter per runtime. Forme ignores the title as always; the bracket is a cue to the reader and to the harness, and the per-mount node name is the harness's to assign.

The division of labor is the same as for any node: the contract declares the family; a harness instantiates facets and mounts. The compiler emits the family, never an enumeration — src/ lists no instances, and a topology produced by mounting src/ alone carries one node per contract. Forme matches a placeholder need against the family it names (forme.md, Step 2); the per-entity fan-out an example's README describes is a harness's expansion of that family, not a second copy of the contract.

Continuity

### Continuity is the node's wake-source declaration — what can wake this node — and is intrinsic to the responsibility: it travels with the contract, not the mount (the wake model in concepts/reconciler.md). It has three modes:

  • input-driven (the default) — woken by an upstream node's receipt whose subscribed facet-fingerprint moved. Falls out of ### Requires, so it needs no explicit declaration.
  • self-driven — a declared cadence (e.g. "re-check every 6h", "re-validate when stale"). The node's own continuity clock emits a synthetic self-receipt (a tick); the node re-renders and either writes a moved fingerprint (surprise propagates) or an unmoved one (the tick stops there, costing nothing downstream).
  • external-driven — a declared outside trigger (webhook / cron / manual kick). This is the gateway case; its input arrives from outside the graph.

Every wake is a receipt; the only variable is who emitted it. ### Continuity declares which sources may wake a node — it never makes the wake decision intelligent; the reconciler stays dumb.

Freshness — state vs. policy. Freshness state (valid_until, last_corroborated, confidence) lives in the world-model as data declared by ### Maintains. Freshness policy — the recheck cadence — lives in ### Continuity. The bridge: a valid_until lapsing flips a fact's status, which moves that facet's fingerprint, so "time becoming material" is just another change that propagates as surprise. ### Continuity may read the world-model's soonest valid_until to drive a data-driven recheck cadence, but the cadence rule stays in ### Continuity and the expiry data stays in the world-model.

Functions

A kind: function is a called helper — stateless, ephemeral, and the replacement for the retired service. Its interface is ### Parameters → ### Returns, a plain call interface: arguments in, a value out. A function carries no world-model, no ### Maintains, and no ### Continuity.

---
name: summarizer
kind: function
---

### Parameters

- `text`: the document to compress

### Returns

- `summary`: a five-bullet précis preserving key claims

Functions are invoked from a render body with ProseScript call:

let s = call summarizer
  text: document

You author functions rarely and call them constantly; most ship pre-built in std/. They are the standard-library tier — the place the "unmounted" render actually lives.

Patterns

A pattern is a reusable agent design pattern: slots, config, invariants, and delegation rules for how filled nodes interact. Patterns are not run directly; they are instantiated at compile time and expanded into nodes.

---
name: worker-critic
kind: pattern
---

### Slots

- `worker`: produces the draft
- `critic`: reviews and returns notes

### Config

- `max_rounds`: 3

### Delegation

```prose
loop up to config.max_rounds:
  let draft = call worker ...
  let notes = call critic draft: draft
  if notes.accepted: break
```

A pattern is instantiated with a fenced yaml declaration. Use with: for slot bindings and config: for pattern parameters:

- name: reviewed-draft
  pattern: std/patterns/worker-critic
  with:
    worker: writer
    critic: reviewer
  config:
    max_rounds: 3

pattern: names a kind: pattern file. with: binds slots to responsibilities, functions, or nested pattern instances. After expansion, the named instance behaves like a node. Nested pattern declarations are allowed only as slot values inside another pattern instance's with: block.

Structured Blocks

Use Markdown structure directly for Markdown: section headers, bullets, and tables are the language surface and should not be wrapped in code fences.

Use fenced yaml only for structured YAML declarations such as pattern instances. Use fenced prose only for ProseScript in ### Execution and pattern ### Delegation. Do not use markdown or text fences as structured data formats.

Runtime and Shape

Runtime hints and behavioral boundaries are sections:

### Runtime

- `model`: sonnet

### Shape

- `self`: evaluate sources, score confidence
- `delegates`:
  - `summarizer`: compression
- `prohibited`: direct web scraping

### Shape describes the capability boundary of this render. delegates names the helper functions the render calls inside the node (intra-node, ephemeral) — it is not a DAG edge and not a subscription. Cross-node dependency is expressed only through ### Requires / ### Maintains.

Skills

A responsibility or function that depends on the host agent's harness skills declares them in a ### Skills section. The compiler resolves the named skills against the host's installed skills before emitting the component's IR, and prose compile fails closed with a skill_unresolved diagnostic if any are missing.

### Skills

- document-skills:pdf
- document-skills:xlsx

Skill names use the namespace:name colon form that matches the plugin marketplace convention shown in /skill invocations.

Rules:

  • A responsibility's skill declarations apply to every function its render calls. Node-level declarations are additive, not exclusive.
  • The compiler resolves each declared skill by looking, in order, in:
    1. The project's ./skills/ directory.
    2. ~/.claude/skills/.
    3. ~/.codex/skills/.
    4. ~/.agents/skills/.
  • If a declared skill cannot be resolved in any of those paths, prose compile fails closed with a skill_unresolved diagnostic naming the skill and the paths that were searched.

The compiler program implements this resolution rule; see skills/open-prose/compiler/index.prose.md (skills_resolver) for the program-level contract.

BYO harness invariant

OpenProse never installs, modifies, or removes the user's harness skills. Installing skills is the user's responsibility; the compiler only verifies they are present and stops the compile when they are not.

Tools

A responsibility or function that depends on host capabilities declares them in a ### Tools section. Tool declarations are host capability requirements: they do not satisfy ### Requires, do not create Forme dependency-graph edges, and do not grant or restrict tool use. Use ### Shape for capability boundaries and prohibited actions.

### Tools

- `cli:gh`: GitHub CLI available on PATH for PR inspection
- `cli:jq`: JSON CLI available on PATH for JSON validation
- `mcp:gmail`: MCP server registered with the host

The supported deterministic tool declaration shapes are cli:<executable-name> and mcp:<server-name>. A CLI executable name is the command name the host should find by PATH lookup. An MCP server name is the registered server name the host advertises. Names must be non-empty and must not contain path separators. Tool declarations belong only in the ### Tools section; there is no frontmatter form.

Rules:

  • A responsibility's tool declarations apply to every function its render calls. Node-level declarations are additive, not exclusive.
  • cli:<name> checks only executable presence on PATH. Version ranges, auth checks, and installer behavior are outside the declaration.
  • mcp:<name> checks only server presence in the host MCP registry. The compiler does not install, contact, or introspect the server during this check.
  • For kind: responsibility, declared tools are the host capabilities the render may use to observe and act on the maintained truth. The compiler does not pre-split read vs write; capability scope is enforced by the connector adapter at runtime.
  • Namespaces other than cli and mcp are reserved. The current compiler reports tool_unsupported_kind for reserved but unsupported namespaces such as http:example.
  • A malformed declaration, such as gh, cli:, or mcp:, reports tool_invalid.
  • A supported cli:<name> declaration that cannot be found on PATH reports tool_unresolved.
  • A supported mcp:<name> declaration that cannot be found in the host MCP registry reports tool_unresolved.
  • prose compile fails closed when any tool_invalid, tool_unsupported_kind, or tool_unresolved diagnostic is emitted.

The compiler program implements this resolution rule; see skills/open-prose/compiler/index.prose.md (tools_resolver) for the program-level contract.

BYO host tools invariant

OpenProse never installs, modifies, upgrades, or removes host tools. Installing and authenticating host tools is the user's responsibility; the compiler only verifies declared tools are present and stops the compile when they are not.

Frontmatter

Every responsibility, function, gateway, pattern, or test declares identity with name and kind:

---
name: entry-name
kind: responsibility | function | gateway | pattern | test
---

Frontmatter should stay structural. If a field would be useful to read, review, or discuss, it should usually be a ### section.

A kind: test file also declares subject: to name the responsibility or function it runs.

A kind: responsibility or kind: gateway file may declare id: frontmatter to give the contract an identity that survives filename and name: renames. Without one, the slug is the identity. An id is a UUIDv7-compatible 16-byte value rendered as 26 characters of uppercase Crockford base32 (0-9A-HJKMNP-TV-Z), minted once by scripts/mint-contract-id.mjs in the language repository and never hand-typed.

version: is optional, author-owned provenance in semver form. The compiler ignores it; it is not the skill version.

Contract Item Style

Use backticked names followed by a colon:

- `topic`: a research question
- `report`: executive-ready summary with sources

This is visually clear and easy for agents to extract.

each postconditions are contract items:

- `articles`: collected articles from the feed
- each article has: a summary, relevance score, and key claims

Typed Caller Inputs

Most ### Parameters and ### Requires entries are free-form values provided at run time. Two keywords are reserved for passing completed runs as inputs — the typical shape for inspectors, regression checkers, and meta-systems:

### Parameters

- `subject`: run — a completed run to inspect
- `cohort`: run[] — a set of completed runs to compare

When an entry's type is run or run[], the caller supplies a run ID (or a list of them). The Prose VM resolves each ID to its run directory and writes a structured binding at bindings/caller/{name}.md containing the run ID, path, root source name, and status. The render reads that binding and then reaches into the run's own bindings/, vm.log.md, and compiled artifacts directly.

See prose.md (Run-Typed Inputs) for binding format, resolution order (bare ID, ~/{id} for user scope, absolute path), and staleness validation.

Execution Sections

### Execution contains the render body in ProseScript. Use a fenced block:

### Execution

```prose
let research = call researcher
  topic: topic

return research
```

### Execution is the intra-node render body: call (invoke a function), session / agent / resume (spawn ephemeral sub-agents), plus control flow. All of it is internal to producing this node's world-model, and none of it is a node. Cross-node connection is only ever a subscription. When ### Execution is present, Forme validates contracts and extracts the call graph, but the Prose VM follows the written order.

Tests

Test files use the same section grammar. A kind: test names a subject responsibility or function, supplies fixtures as caller inputs, then evaluates semantic assertions against the subject's world-model or returned value:

---
name: test-summarizer
kind: test
subject: summarizer
---

### Fixtures

- `text`: recent developments in quantum error correction

### Expects

- `summary`: contains at least five bullet points
- `summary`: is under 500 words

### Expects Not

- `summary`: contains fabricated citations

Rules:

  • subject: must name a responsibility or function. Tests do not execute patterns directly.
  • Path-like subjects use normal resolution. Bare subjects may resolve by matching frontmatter name: in the test file's directory and nearest OpenProse source/package root.
  • ### Fixtures must provide every caller input needed by the subject; tests do not prompt the user.
  • ### Expects and ### Expects Not assert observable behavior, not exact phrasing.
  • Test reports should list each assertion with pass/fail status and concise evidence for failures.

Design Guidance

Use Contract Markdown when the author cares about the promise more than the choreography — declare a ### Requires need and let Forme choose the graph when the end-state matters. Use ProseScript ### Execution when the author needs exact order, control flow, or human-readable procedural steps inside a render.

For canonical responsibility, function, gateway, pattern, test, world-model, and security guidance, load guidance/authoring.md.