Contracts
Write requirements in Contract Markdown. Learn the five contract kinds and the sections that define inputs, maintained state, required steps, and limits.
Contracts
A contract states requirements and the context needed to interpret and apply them. Authors specify what the agent must accomplish, the conditions it must satisfy, and the choices it may make. Humans and agents can both author and reuse contracts.
This page describes the public skill's Contract Markdown format:
*.prose.md files with YAML frontmatter and recognized ### sections. The
five kinds support standing work, one-time calls, external inputs, tests, and
reusable coordination. Contract authoring explains how to
use these building blocks to express requirements together.
The sections declare requirements and interfaces. The selected host supplies tools and runtime behavior; see Harness-agnostic for that boundary and implementation limits.
Frontmatter and identity
A contract opens with YAML frontmatter. Two fields carry weight:
kind:names which of the five contract kinds this is (below). This is the one field that changes how the file is executed.name:is the human-facing slug.
An optional id: gives a responsibility or gateway a source identity that
survives name: and filename renames. Without it, the slug is the identity.
The language repository's scripts/mint-contract-id.mjs tool mints the
26-character base32 value. The compiled node key identifies a particular mount;
it is distinct from the optional source id:.
The five kinds
kind: selects one of five authored kinds. Each has a different run model.
| Kind | Run model | Purpose |
|---|---|---|
responsibility | Served (continuously reconciled) | A mounted DAG node with requirements for state maintained over time. |
function | Called (one-shot) | A stateless, ephemeral helper. Bind ### Parameters, run one render, return ### Returns. No Forme phase, no world-model. |
gateway | Mounted as external-driven | Sugar for an external-driven responsibility. Compiles into a trigger registration for the serving host; refuses a direct run. |
test | Via the test path | Fixtures plus natural-language assertions against a subject responsibility or function. |
pattern | Instantiated at compile time | A reusable coordination algorithm, expanded into nodes at compile time. Never directly run. |
There is no kind: service (it was renamed to function) and no
kind: system (deleted). Cross-node composition is a Forme-wired
subscription between responsibilities; intra-node composition is an imperative
call inside one render. There is never an internally-autowired graph kind.
The rest of this page focuses on responsibility: its declared inputs,
maintained state, and conditions for carrying out the work. Functions use the
separate call interface described below.
The recognized sections
### Description is a summary for readers. ### Goal states the intended
result. Use the recognized semantic sections for the requirements that guide
execution.
The following sections describe a responsibility's subscriptions, maintained
state, and wake source: ### Requires, ### Maintains, and ### Continuity.
### Invariants states limits that must hold during the work; ### Execution
can specify required steps. Use the sections applicable to the contract.
### Maintains: the world-model schema (four jobs at once)
### Maintains is the schema for the state this node maintains. It does
four jobs in one section:
- It types the maintained truth, the shape of the world-model the node owns.
- It carries the canonicalization spec: which fields are material and how they normalize. This compiles into the node's fingerprint, the cheap content identity the run phase compares.
- It declares facets (below), the named parts of the truth.
- It states postconditions that a render must satisfy before it may commit.
There is no separate judge and no ### Criteria section in this format.
### Maintains states postconditions: deterministic validators can check some,
while semantic conditions rely on render self-attestation. The language
requires a render that cannot satisfy its postconditions to leave prior state
unchanged and report failure. Actual enforcement and receipt detail depend on
the host; see implementation limits.
Facets make subscription structural
A #### sub-heading inside ### Maintains declares a facet, a named
part of the truth. The facet's name is, at once, three things:
- its fingerprint unit (the canonicalizer emits one token per facet, plus an always-on atomic token over the whole truth);
- its subscription symbol (a consumer names it in
### Requires, and the reconciler wakes that consumer only when that facet's token moves:Requires.<facet>↔Maintains.<facet>); - and its region of the world-model.
With no named parts, the whole state is one atomic facet. Named facets reuse
the heading hierarchy and the Requires↔Maintains connection. The parts you
define in ### Maintains determine what downstream nodes can subscribe to.
### Requires: what the node subscribes to
### Requires names the upstream facets this node consumes. Forme matches each
entry to a producer's ### Maintains facet and draws the subscription edge.
### Requires is the input side of the memo key: the run phase fingerprints
the node's contract together with its subscribed inputs, and re-renders only
when one of them moves.
### Continuity: the wake source
### Continuity declares when, beyond a subscribed input changing, a node
should re-render. It is not a schedule. A node is input-driven by default
(it wakes when a subscribed facet moves). ### Continuity adds one of:
- a self-driven cadence, for truth that goes stale on its own. A
valid_untilfreshness state lives in the world-model as data;### Continuitycarries only the policy that reads it on a forecast cadence. When avalid_untillapses, the harness mechanically moves the facet's fingerprint and wakes the node. No model call decides that time has passed. - external-driven, which marks a
kind: gatewayso an ingress event wakes it.
The author states the requirements in these sections. A serving host provides fingerprinting, cadence, receipts, and subscription processing. Its supported wake sources determine when it attempts the work.
Functions: the call interface
A kind: function does not maintain a world-model and is not part of the DAG.
It declares a plain call interface instead of the four-jobs schema:
### Parameters: the inputs bound at call time.### Returns: the return value of its single render.
A lone function has no Forme phase: bind parameters, spawn one render, return
### Returns. It is the stateless, ephemeral helper.
A contract in full
The following retained source snapshots illustrate how a responsibility and
its gateway connect. They predate the current section cleanup and are shown
verbatim; ### Continuity recheck in the gateway is an older heading. For
current runnable source, use the skill 0.18.0 basic-unit-suite.
Read the responsibility top to bottom: the >
description states intent for a human, ### Requires names the single facet it
subscribes to, ### Maintains types the CountSummary truth and declares one
#### structured facet with an explicit postcondition, and ### Continuity
declares it input-driven, so it wakes only when its counts input moves.
---
name: count-summary
kind: responsibility
---
# Count Summary
> The single responsibility that turns the gateway's `counts` facet into a
> threshold-aware summary (U02). It reads its prior world-model by reference,
> writes a new `CountSummary`, and signs a receipt naming the upstream receipt it
> consumed. It skips when `counts` has not moved (U03).
### Requires
- `counts`: the numeric tallies. *(Maintained by `counter-events.counts`.)*
This is the only subscribed input. `count-summary` is **input-driven**: it wakes
iff the `counts` facet fingerprint moves. A metadata-only event moves only
`raw_events`, so this node stays dark while `Raw Event Auditor` wakes (U05).
### Maintains
The `CountSummary` world-model — the structured summary the alerting chain reads.
- `total` — the material event count.
- `by_kind` — the per-kind tallies.
- `threshold_crossed` — whether `total` reached the alert threshold.
- `explanation` — a short rationale string.
#### structured
The whole summary is material: any change to `total`, `by_kind`, or
`threshold_crossed` moves this node's truth and propagates to `Alert State`.
**Postcondition:** `total` equals the count of accepted material events;
`threshold_crossed` is true iff `total ≥ threshold`. Self-policed before signing —
no separate judge beat.
### Execution
Read the `counts` facet and the prior summary by reference, fold the per-kind
totals, set `threshold_crossed`, and commit the structured summary.
### Continuity
input-driven
And here is the gateway that feeds it. A gateway has no ### Requires (its
input arrives from outside the graph). Notice how ### Maintains splits the
ledger into two #### facets, counts and raw_events, so a
metadata-only event moves raw_events (waking the auditor) without moving
counts (the summary above stays dark). That split is the subscription wiring.
---
name: counter-events
kind: gateway
---
# Counter Events
> The gateway — the system's ingress. It has no `### Requires` (its input arrives
> from outside the graph), it `### Maintains` the canonical `CounterEventLedger`,
> and its `### Continuity` is **external-driven**, which is how Forme registers it
> as the single DAG entry point (U11).
### Continuity
external-driven
A webhook, a poll, or a manual kick becomes one external wake at the system's
edge. The gateway folds each accepted counter event into the canonical ledger and
projects two **independent facets** so a downstream subscriber wakes only on the
slice it actually depends on (U05). Replaying the same event id is a no-op — the
ledger dedups by id, so a re-delivery produces a byte-identical world-model and
the gateway memo-skips (U01/U03).
### Receives
- A counter event: `{ id, kind, value, material? }`. An event with
`material: false` is **accepted into the audit trail but excluded from the
tallies** — it is the metadata-only event that moves `raw_events` without moving
`counts`.
### Maintains
The `CounterEventLedger` — the standing truth every downstream responsibility
subscribes to. Its canonicalization splits the truth into the two facets below, so
a change to one slice never spuriously wakes a subscriber of the other.
- `high_water_mark` — the running material event total.
- `counts_by_kind` — the per-kind material tallies.
- `accepted_event_ids` — the full accepted id set (material and metadata-only).
- `last_seen_at` — an immaterial monotone marker (it never appears in a facet, so
it cannot wake a subscriber on its own).
#### counts
The numeric tallies (`high_water_mark`, `counts_by_kind`) over **material events
only**. Moves when a material event is accepted; does NOT move on a metadata-only
event. `Count Summary` and `Count Trend` subscribe here.
#### raw_events
The accepted-event id set plus duplicate / malformed flags. Moves whenever the
accepted set changes — including a metadata-only event. `Raw Event Auditor`
subscribes here.
### Emits
- count-summary
- raw-event-auditor
- count-trend
Forme keys the wake on the producing node; the subscribers above resolve their
edges to this gateway's `counts` / `raw_events` facets.
### Continuity recheck
A weekday 09:00 self-kick may re-scan even when no webhook fires; a byte-identical
re-scan memo-skips, so the self-kick costs nothing when nothing changed.
These examples combine a gateway's published inputs with a responsibility's requirements for a summary. The declared interfaces make the composition inspectable. Evidence and checks still determine whether a particular result satisfies those requirements.
Where to go next
ProseScript
The optional imperative layer inside ### Execution, for when declarative defaults are not enough.
Harness-agnostic
How a host serves a ### Maintains schema. Fingerprints, memoization, and receipts are one host's runtime, not language features.
Contract authoring
State requirements, reuse contracts, and leave appropriate choices to the agent.
Set up a project
Install the skill, author a first contract, and run it where your agent lives.
For the full language semantics, the authoritative source is the OpenProse
spec (01-Language.md)
and the loaded open-prose SKILL. If the docs and the skill ever disagree,
trust the skill.