Normative · version 1
The intent/1 specification
Canonical source: SPEC.md in the repository — this page mirrors it section for section and a test fails the build when a section goes missing. Anyone may write a competing implementation from the specification alone; if the reference library ever disagrees with it, one of them is wrong and we will say which.
Discovery
A publisher serves the public projection at
/.well-known/intent.json — never its own full record. Tiers below public are not
served without authentication; a partner-tier record behind no gate is a public record with a
misleading label. A consumer must fetch over https only, apply a timeout and a
size cap, follow redirects only within the same registrable domain, and must not
treat an unreachable publisher as one that published nothing — absent and
unreachable are different findings, and collapsing them makes a claim about somebody
else's organisation on the strength of your own network failure.
The document
{
"intent": "1",
"source": "repo/yourcompany",
"org": "org/yourcompany",
"generated": "2026-08-30T10:00:00Z",
"items": [ … ]
}
source is the repository that emitted it; org is the organisation it
speaks for. The pair is the authority claim: this document asserts intentions for that repository
and no other.
An item
| Field | ||
|---|---|---|
id | required | intent/<repo>/<slug> (or legacy backlog/…). Stable for the life of the intention; never reissued — an id is what somebody else may have quoted. |
rev | required | Integer from 1. A change is a new record with a higher rev, never an edit. |
kind | required | idea · task · bug · blocker · decision |
status | required | open · doing · blocked · done · dropped |
title | required | ≤ 140 characters |
owner | A node id — person/, agent/ or org/ | |
capabilitiesWanted | Normalised: trimmed, lowercased, de-duplicated, ≤ 20 | |
promoted | { at, by, note? } — by must be a person/ id | |
asserted / assertedBy | required | Date and node id. Usually an agent — the intended case. |
expires | required | Derived: asserted + the kind's window |
visibility | required | public · partner · private |
Decay windows: blocker 14 days, bug 30, decision 30, task 90, idea 180. An expired item is not false — it has stopped claiming to be current, which is the difference between a backlog and a graveyard. Re-asserting resets the window: somebody looked and said it again.
The legacy backlog key
This format was published as backlog/1 before IntentMesh existed. A conforming
reader MUST accept the backlog version key and treat it as identical;
ids beginning backlog/ stay valid permanently. Not a transitional measure with an end
date: thirty repositories emitted the old key first, and a protocol that breaks its first users to
tidy its branding teaches everyone else to wait for version three.
The rules a validator enforces
Schema-valid is well-formed; these cross-field rules are what makes a document permitted, and they are not expressible in JSON Schema:
1 · expires is exactly the derived value
Not "no longer than" — exactly. A writer who can shorten it can lengthen it by asserting a date that never happened.
2 · Any visibility above private requires promoted
And promoted.by must be a person/ id, dated on or after asserted.
3 · promoted + private is a contradiction
Promotion is one-way and recorded; a retraction is a new revision with status: dropped.
4–7 · Authority and normalisation
Every item's id names the fragment's own source; an org/ owner must be the fragment's own org; capabilitiesWanted arrives already normalised; one (id, rev) per fragment.
Merging
Highest rev per id wins. Two fragments carrying the same (id, rev) with different bodies is
reported, not resolved — a merge that silently picks a winner loses somebody's
plan without telling them. An item whose id names another repository is dropped with a
foreign-item problem.
Visibility
Filtering happens on the query: a consumer receives only the tiers it is entitled to and never holds a record it must remember to hide. An unrecognised tier is treated as public — failing closed is the only safe default for a rule whose failure mode is disclosure.
Relationship to the Directory
An intention is not yet a thing, so it does not enter the Directory's id space; when it becomes real, what enters the record is the settlement. Visibility vocabulary and canonicalisation are imported from published packages, never restated — a second spelling of one rule is how two implementations quietly disagree.