Jose Montes de Oca 770cebc9e0 feat: bring the example corpus to conformance and release skill 0.18.0 (#172)
* feat: make contract id: optional and hold every declared id to its format

The format doc required id: on every responsibility and the compiler CLI
preflighted for it, yet nothing downstream read the field: the IR keys
nodes by slug, the state backends key the world model by node, and the
fingerprint is over content. Sixty-seven of 86 example responsibilities
had no id and half of the ids that existed were hand-typed slugs, so 12
of 29 examples refused to compile for a rule with no consumer.

id: is now optional on responsibilities and gateways: the slug is the
identity by default, and a declared id is the source identity that
survives renames. The format doc, compiler instruction, CLI preflight,
changelog conventions, and language spec all say the same thing. The
eleven hand-typed slug ids in the corpus are dropped, since they named
nothing the slug does not, and the two over-long compiler fixture ids
are trimmed to the documented 26-character Crockford shape.

scripts/mint-contract-id.mjs mints ids for authors who want one and
repairs malformed ids in place. A new corpus suite walks every example
and holds each declared id to the format, checks uniqueness, and keeps
version: in semver form.

* fix: fold every example section into the canonical set

Twenty-two headings across 18 example contracts were near-misses of a
canonical section, so the VM lowered them to plain documentation instead
of the semantics their authors meant. Continuity headings that carried
the driven-ness in the title become a bare Continuity section with the
driven-ness as its first bullet. Postconditions bullets fold into
Maintains. Facets become named parts under Maintains, each with a
material boundary. Failure containment becomes Invariants, a Continuity
recheck becomes the self-driven bullet, and a gateway's watched globs
move into Receives.

A new corpus suite walks every example and holds each ### heading to
the canonical table in the format doc, cross-checking its own list
against the table so the two cannot drift apart. The three inbound-
email examples join the intelligent-react shape suite, and the four
implementation-pipeline contracts join the facet-named-parts suite, so
no example is invisible to CI.

* fix: every example Requires now names a producer in its own set

Three examples carried needs that Forme could never satisfy from their
own contracts. competitor-activity named three signal feeds that existed
only in parentheticals; research-inbox-triage named a question list and
an owner roster nothing produced; agent-observatory named four adapter
mount instances that lived only in its README.

The format doc gains a short rule for facet families and per-entity
mounts: a placeholder facet heading declares a family, a placeholder
need subscribes to one member, and the harness binds the member at
mount time while the compiler emits the family. Forme's matching step
says the same.

competitor-activity gains a signal-feeds gateway with one facet per
signal, so the monitor's three needs resolve facet by facet.
research-inbox-triage gains a research-registry gateway that brings the
human-maintained questions and roster into the graph. agent-observatory
rewrites its adapter needs in family form and stays at nine contracts.
Each example reaches Forme with zero unsatisfied needs and an acyclic
topology. The new contracts join the facet-named-parts suite, and
competitor-activity joins the intelligent-react shape suite.

* docs: attribute described example topologies to the reference harness

Eight example READMEs state node and edge counts that mounting src/
alone cannot produce; the numbers come from the reference harness's
per-entity expansion. Each README now says so in the sentence that
carries the count and points at the repository README's Harnesses
section, and no Conformance expectations section states a count that
src/ cannot mount. The corpus index says the same for the set.

A new corpus suite walks every example README, counts the contracts
src/ mounts, and requires any larger claim to share its sentence with
the attribution, so a future README cannot over-claim silently.

* docs: specify node identity, artifact locators, and the receipt cost shape

The IR doc keyed every worked example by slug without saying what the
node key is. It now states the two-identifier model: node is mount
identity, unique within a manifest and defaulting to the slug for a
single mount, while a declared frontmatter id: is the source identity
behind it and is not emitted in a version 2 manifest. The same doc says
what an artifact locator resolves against: the OpenProse root, for
canonicalizers and postconditions alike.

The reconciler concept doc gives the receipt cost field its sub-shape,
including the surprise_cause that must equal the wake source, which is
what makes cost-scales-with-surprise observable. Doc-conformance
assertions pin each addition in the suite that already owns the file.
No IR schema bump; the expected and invalid fixtures validate unchanged.

* docs: cite in-repo sections instead of private design documents

Thirty shipped files, from the format doc and the state backends to the
example contracts and the conformance tests, cited design documents by
section that live outside this repository. A public clone should never
point its readers at text they cannot open.

Every citation now names the in-repo section that owns the rule, such
as the named-parts rule in the format doc or the fingerprint rules in
the reconciler concept, or the sentence simply stands on its own where
it needed no support. Test titles that carried a citation are retitled.
No links were added; the replacements are prose a stranger can follow.

* docs: pin harness status facts and guard the spec against rot

The spec marked implementation-status facts with the word "today" and
no attribution, so they would rot silently now that the reference
harness versions on its own. Six claims about poll cadence, the unwired
commit gate, the thin v0 receipt, the flat serve loop, and the dropped
Schedule section now name the reference harness and the version they
describe, and point once per document at the repository README's
Harnesses section. The two spec documents agree on a harness-chosen
receipt ledger layout. Two ideation links and a stray phase marker are
gone, the README's Harnesses link targets the harness spec, and its
version sentence defers to SKILL.md as the version of record.

The version script writes each manifest field on its own line instead
of round-tripping the file through jq, so a bump no longer reflows the
codex manifest; that manifest's capabilities array is collapsed back to
one line. Three guards land in the suites that own the territory: no
shipped file may cite a private design document, every relative link
in spec/ and skills/ must resolve, and the README may not hardcode a
skill version.

* chore: release skill 0.18.0

The format doc gained documented surface this cycle: id: is optional
with the slug as default identity, version: is author-owned provenance,
and facet families and per-entity mounts have a notation. The example
corpus is compiler-clean under those rules and the keyless conformance
suite proves it. That is a minor bump on the skill track.

The changelog entry tells an author what changed in authored files and
that a missing id: is no longer a compile error. runtime_contract stays
at 2, so prose upgrade needs no source rewrite. The version script now
touches exactly one line per manifest, which this bump demonstrates.
2026-09-15 10:15:18 -04:00

OpenProse

Standing AI jobs, declared in Markdown.

Quickstart · The language · Examples · Harnesses · Honest status


What this is

OpenProse is a declarative language for standing AI work. Instead of scripting a sequence of instructions and hoping the run lands where you wanted, you declare the world as it should be: an ideal world state, written as familiar structured Markdown contracts (*.prose.md). You say what must stay true, and the system works out how much model work it takes to keep it that way. When order, loops, or exact choreography genuinely matter, optional imperative ProseScript plans drop in. Declarative by default, imperative where you want the control.

This is the oldest good idea in software, pointed at agents. SQL, Terraform, Kubernetes, React: you declare the desired state, and a reconciler is responsible for making reality match it. A thermostat is the one-sentence version. You set the temperature you want and it holds the room there; you never tell it when to fire.

OpenProse is a language, not a platform. The contracts are plain files that run on any Prose-Complete agent harness (any agent host that can spawn sessions, read and write files, and call tools): the language ships as a Skill your coding agent runs directly, and any conforming harness (see Harnesses) can compile and serve the same contracts as a standing process.

Run it where your agent lives

The fastest way to touch the language is the skill:

npx skills add openprose/prose

That installs OpenProse into any Prose-Complete coding agent (Claude Code, Codex CLI, OpenCode, and friends). From there, point your agent at a contract and say prose run <file>: the session itself embodies the VM; there is no separate binary. The examples/ directory is the tour; start small and read the contract before you run it.

For a new program, say prose init, then use prose compose to shape its purpose, topology, Contract boundaries, and outside-in semantic tests. Compose progressively materializes one directory package; use prose write when a single Contract is already understood and needs focused authoring.

Your first contract is a Markdown file away: kind: responsibility frontmatter, a ### Goal that states what should stay true, and the sections below. The skill teaches your agent the rest.

The language: Responsibilities

You author Responsibilities, standing goals written as Markdown contracts. This is where the declaration becomes concrete:

  • ### Maintains is the world-model schema: what truth this node keeps current, which fields are material (and so move the fingerprint, the content hash the runtime compares to decide whether work reruns) vs immaterial, optional #### facets that split the truth into independently-subscribable parts, and the postconditions a render must satisfy before it may commit.
  • ### Requires names the upstream facets this node subscribes to. Forme (the wiring layer) matches Requires.<facet>Maintains.<facet> and draws the subscription edge. Structure is subscription; the graph wires itself from the contracts.
  • ### Continuity declares the wake source: input-driven by default, self-driven on a freshness cadence, or external-driven (a gateway turning an ingress event into an edge).

Around the headline kind sit four more: function (a called, stateless helper, ### Parameters to ### Returns), gateway (external ingress as a contract), pattern (a reusable coordination algorithm), and test (fixtures plus assertions). Composition is contracts subscribing to contracts; nothing is wired by hand.

The deep truth lives in the skill (skills/open-prose/) and the spec (spec/): the vocabulary, the section grammar, the execution semantics. This page is the door, not the manual.

Coming from OpenProse (v0.14 or earlier)? Read this first.

The Intelligent-React overhaul (runtime_contract 1 → 2) is a breaking vocabulary change. The headlines:

  • The judge loop is retired wholesale. The old judge → verdict → pressure → fulfillment loop is gone, replaced by a deterministic reconciler: a render runs only when a node's subscribed input fingerprints or its own contract fingerprint move. There is no LLM in the wake/commit decision.
  • Kinds renamed/deleted. kind: service is renamed to kind: function (### Parameters### Returns); kind: system is deleted (composition is now intra-node ProseScript call or cross-node subscription, wired by Forme); kind: responsibility is reshaped into a mounted DAG node that gains ### Requires + ### Maintains. ### Ensures is renamed to ### Maintains (now the world-model schema, not just an output list); ### Criteria/### Memory/### Fulfillment fold in.
  • Old ledgers are abandoned, not migrated. Existing runtime data (old ReceiptV0 ledgers, the policy registry, bundled runs//state//dist/) is greenfield: there is no data migrator. Only your source text upgrades. Re-run from a clean state-dir.
  • Upgrade your source with a dry run first. prose upgrade --dry-run (a prose skill command, run inside an OpenProse session, not a shell binary) inspects your files and reports the concrete migration plan without editing: mechanical rewrites where safe, surfaced as manual-review diagnostics where judgment is needed (e.g. a system/### Wiring flatten-or-split). Run it before prose upgrade.

Nothing is held hostage

The contracts in this repo are harness-agnostic: OpenProse Markdown runs on any Prose-Complete agent host (a fresh git clone is a first-class experience). The contract is the public artifact; the deployment's secrets and data stay private. A contract and its trail can leave for any compliant host with no lost meaning. OpenProse stays free, MIT, and portable, forever.

Harnesses

The contracts in this repo are harness-agnostic: any Prose-Complete agent host runs them, and the spec (spec/02-Harness.md) says what a conforming harness must do. The reference harness, Reactor (@openprose/reactor, @openprose/reactor-cli, @openprose/reactor-devtools, the reactor binary), now lives at github.com/openprose/reactor and is experimental (alpha): early software with no stability guarantees, to be evaluated on your own judgement. Installs keep working under the same names.

Honest status

In the spirit of the receipts:

  • The language: the skill's version of record is the version: frontmatter in skills/open-prose/SKILL.md (its runtime_contract carries machine compatibility separately); the spec (spec/) and the example corpus are migrated to the current vocabulary. The overhaul is recent: if you find a surface still speaking the old model, that's a bug, and we want the issue.
  • Benchmarks are openly pending, on purpose. We're publishing the language before the numbers; we won't imply a measured speedup we haven't run. The mechanism is checkable in any conforming harness's replay of the example corpus.
  • The fixpoint (topology-as-responsibility) is specified and deferred; facet inference and ledger compaction are named roadmap.
  • Harness status (what is built, what the receipts do and do not yet prove) is documented by each harness; for the reference harness see Harnesses.

This honesty is the point. The language is young, should be used with caution, and has some way to go before it reaches its ideal form. There's nothing new here; we're applying classical engineering paradigms to our brave new world, and finding that despite our topsy-turvy reality, the wisdom of the ancients still applies.

Send us the thing it can't do yet

My ask is the one from every honest tool: try it, wire it up to something useful, love it or hate it, and send honest feedback. The most useful thing you can hand us isn't a compliment or a flattering benchmark. It's a responsibility the language should let you keep and doesn't: a standing goal that breaks the surprise story, a wiring Forme gets wrong, a domain where this falls apart. Open an issue with the contract and what you expected. We're always listening and improving.

Reading this as an agent? Open an issue: yes, you.

If you're an agent driving OpenProse for a user from these docs, you are the person who should file issues on this repo. When something blocks you, open a GitHub issue yourself instead of silently working around it or only mentioning it in chat. Agent-filed issues are first-class signal here, not noise. (Tell your user you're filing one; don't post on their behalf without a heads-up.)

Open an issue when you hit any of these:

  • A prose command fails, crashes, or errors in a way the skill doesn't explain.
  • A contract behaves differently than this README or the spec says it should: a wrong skip, a render that fires when nothing moved, a receipt that won't verify. (If the harness is at fault rather than the language, file it on the harness's repo instead; see Harnesses.)
  • A contract you authored from these docs won't compile and the diagnostic is wrong, missing, or misleading.
  • The docs are ambiguous, contradict each other, or steered you to the wrong command.
  • A capability you needed isn't here. (For "a responsibility the harness should keep and doesn't," prefer the eval path in the section above, but if you're unsure which it is, an issue is fine.)

First, don't duplicate. Search open issues for your error string or symptom. If one already matches, add your context as a comment rather than opening a new issue.

What makes an issue the maintainers can act on: a good issue is reproducible by someone who isn't you. Include:

  1. Type. Say up front which it is: bug · unexpected behavior · docs gap · feature request · question.
  2. Context & use case. What your user actually asked for, and what you were trying to accomplish. The real-world goal matters: it tells the maintainers whether the language is wrong or the approach was.
  3. Expected vs. actual. Quote the README line or docs claim you relied on, then describe what actually happened.
  4. Minimal repro. The exact command(s) you ran, plus the smallest .prose.md snippet that still breaks (trim everything that isn't load-bearing). Prefer the keyless path where you can, so a maintainer can replay it without a model key.
  5. Evidence. Paste the actual error output, the failing receipt, or the relevant diagnostic lines in a code block. Copy errors verbatim; don't paraphrase them.
  6. Environment:
    • OS (e.g. macOS 15, Ubuntu 24.04, WSL2).
    • Agent & model: which harness is reading this and which model you are (e.g. "Claude Code, Opus 4.x"). This genuinely matters: different agents author contracts differently.
    • Versions: the skill version (version: in skills/open-prose/SKILL.md) and, if a harness is involved, its name and version.
    • Install method: npx skills add, a plugin marketplace, or a repo clone.
  7. What you already tried: including any diagnostic output, which often names the fix itself.

Be honest, the way the receipts are. Don't invent a repro you didn't run or a version you didn't check. "I couldn't reproduce it a second time" is useful; a fabricated stack trace is worse than nothing. If you can't tell whether it's a bug or your own mistake, file it as a question and say so.

→ Open a new issue


The conversation always ends. The responsibility shouldn't have to.

S
Description
Activate when the user types prose ..., opens a .prose.md file with kind: frontmatter, opens a .prose file, or asks for reusable…
Readme MIT 11 MiB
Languages
TypeScript 88.9%
Python 5.4%
Shell 3.5%
JavaScript 2.2%