<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Facts and their status markers</title>
  <status stage="doc" state="work" audience="author"/>
  <p p="1">A spec is a list of promises, and each promise has a state: proposed, being built, done, abandoned. vibe reads that state from a small marker written next to the promise, in Markdown or in the XML form, and one command tells you when a marker is malformed or in the wrong place. This page is the grammar of those markers.</p>
  <example id="facts-check" fixture="package-spec" p="2">
    <run>vibe facts check</run>
    <expect>progress check: clean (2 files, 0 warning(s))</expect>
  </example>
  <section id="the-marker" title="The marker">
    <p p="3">A marker is one XML-shaped element, `&lt;status stage="…" state="…"/&gt;`, embedded in Markdown or native in the dialect. A point marker is self-closing; an unclosed one is not well-formed and is an error. The shorthand `@status:spec/done` means the same as the element, and `@status:impl` alone means `impl/work`, with one exception: `@status:unknown` means `unknown/hold`. The older spellings without `status:` are still read. Every vocabulary is closed: a value outside the tables is an error, with the nearest legal value as a hint.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#STATUS-ELEMENT" p="4"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#POINT-SELF-CLOSING" p="5"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#SHORTHAND-FORMS" p="6"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#SHORTHAND-BARE" p="7"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#VOCAB-CLOSED" p="8"/>
  </section>
  <section id="anchors" title="Anchors">
    <p p="9">A marked unit must have an address. In Markdown the [anchor](../glossary/index.xml#anchor) is `@fact:ID` as the first token of a paragraph or a list item. The id starts with a letter and continues with letters, digits, underscore and hyphen, and it shares one address space with the heading anchors, so a duplicate across the two forms is an error. A marker on a unit without an anchor is an error. The scanner ignores fenced code, inline code and addresses, so a marker quoted inside them is text, not a marker.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#FACT-ANCHOR-SYNTAX" p="10"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#FACT-ID-GRAMMAR" p="11"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#ANCHORED-WHEN-MARKED" p="12"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#FENCE-AWARE" p="13"/>
  </section>
  <section id="placement" title="Where a marker goes">
    <p p="14">There are four places. A document marker stands in the preamble, or right after the first heading when the document opens with one. A section marker stands alone on the line after its heading; that is the only legal standalone position in a body. A paragraph marker sits inside the paragraph's own text, as its first or its last token. Every list item is a unit of its own, at every nesting level, and its marker sits inside the item's text. A marker standing alone between two paragraphs is an error; there is no nearest-paragraph guess. A unit carries at most one status marker and any number of action markers.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#PLACE-DOCUMENT" p="15"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#PLACE-SECTION" p="16"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#PLACE-PARAGRAPH" p="17"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#PLACE-LIST-ITEM" p="18"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#NO-ORPHAN-MARKER" p="19"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#MULTI-MARKERS" p="20"/>
  </section>
  <section id="rollup" title="How a status rolls up and down">
    <p p="21">A node's marker covers the descendants that carry none. An unmarked node's computed status is the worst of its children, and `unknown` wins the bottom.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#ROLLUP-DOWNWARD" p="22"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#ROLLUP-UPWARD" p="23"/>
  </section>
  <section id="actions" title="Actions, stages and audiences">
    <p p="24">Beside the status a marker may carry an action, what should happen next, and `actionstage` narrows it: `action="remove" actionstage="doc"` means the documentation of this is to be removed while `stage` still describes the unit itself. A `doc` action with an `audience` is an obligation of the documentation: a page written for that audience must cite the [fact](../glossary/index.xml#fact), and `vibe doc check --coverage` checks that one does.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#ACTIONSTAGE-NARROWS" p="25"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#AUDIENCE-DOC-USE" p="26"/>
  </section>
  <section id="requires" title="What closes a fact">
    <p p="27">A fact may say what closes it: `@requires:implementation,verification` right before its final status in Markdown, or a `requires` attribute in the XML form. The kinds are a closed list, `specification`, `implementation`, `verification`, `documentation`, `decision`, `research`, `plan`, `disposition` and `external`. They name closure artifacts, not genres: a research note may require an implementation.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#REQUIRES-GRAMMAR" p="28"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#REQUIRED-ARTIFACT-KINDS" p="29"/>
  </section>
  <section id="the-tool" title="The tool">
    <p p="30">`vibe facts check` is the lint, and `--exhaustive` demands a marker on every paragraph; `vibe progress check` is a transitional alias that prints the new spelling. The observed files are named by include globs in `facts.toml` at the package root: globs that say what is observed, never a list of exclusions.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#BOUNDARY-CLI" p="31"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#CONFIG-FILE" p="32"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-facts/PROP-043#INCLUDE-STYLE" p="33"/>
  </section>
  <section id="edge-cases" title="Edge cases and rules">
    <p p="34">A document written before the qualified spelling keeps parsing: the legacy `@spec/done` and `##ID` forms mean what the new ones mean. Converting a file between Markdown and XML keeps every marker, because the marker is part of the model, not of the syntax.</p>
  </section>
</spec>
