manni lifecycle vocabulary
Built-in id: manni:lifecycle:1.0.0
Published at https://hawkeyexl.github.io/manni/schemas/lifecycle/1.0.0.json.
A $schema that names this URL resolves to the bundled copy, with no network
call.
The question it answers: where is this page in its life? It carries one rule. A deprecated page must say what comes next, meaning a successor, a removal date, or both. Adopt it when pages retire on a schedule and readers need to be sent somewhere else.
Use it
Section titled “Use it”Lifecycle is in the
default set, so a
run checks it on every page with no config line. A config’s own schemas add
to the default set. An override replaces the set, so an entry that should keep
lifecycle sets defaults: true:
meta: overrides: - collection: guides defaults: true schemas: - ./schemas/guide.jsonFields
Section titled “Fields”| Field | Type | Required | Location | Notes |
|---|---|---|---|---|
lifecycle | enum | no | page | One of draft, published, deprecated, or archived |
replaced-by | string, non-empty | when deprecated | page | The page, id, or URL that supersedes this one |
supersedes | string or list | no | external | Pages this one replaced. The record survives after the old page is deleted |
remove-by | W3CDTF date | when deprecated | external | The date the page should be removed by |
The conditional. lifecycle: deprecated requires replaced-by or
remove-by, or both. A page can reach end of life without a successor, and
requiring a replacement in every case forces a false value into it. A
deprecated page with no horizon and no successor is a permanent state, and that
is what the rule forbids.
The Location column is the x-manni-location mark each field carries. page
means the value belongs in the document’s own metadata and reaches delivered
output. external means it belongs in the collection’s external-metadata
manifest. A field is page when an agent fetching the page acts on it. An
agent must see lifecycle: deprecated and follow replaced-by. supersedes
and remove-by are the maintainers’ side of the same record. See
field location for how the marks are
used.
Additional properties
Section titled “Additional properties”Allowed. The root is open, so a generator’s keys and the other vocabularies’ keys pass beside lifecycle’s. Lifecycle checks only the four keys it claims.
Example
Section titled “Example”---title: Configure the legacy exporterdescription: The exporter settings for operator releases before 1.4.lifecycle: deprecatedreplaced-by: configure-the-collectorremove-by: 2027-01-01---The valid no-successor form:
lifecycle: deprecatedremove-by: 2027-01-01 # ends without a replacement; legalA common mistake
Section titled “A common mistake”A page marked deprecated with nothing after it fails the conditional.
---title: Configure the legacy exporterdescription: The exporter settings for operator releases before 1.4.lifecycle: deprecated---$ manni meta validate page.md --no-config -s manni:core:1.0.0 -s manni:lifecycle:1.0.0✗ page.md (root) must have required property 'replaced-by' (line 1) [manni:lifecycle:1.0.0] (root) must have required property 'remove-by' (line 1) [manni:lifecycle:1.0.0] (root) must match a schema in anyOf (line 1) [manni:lifecycle:1.0.0] (root) must match "then" schema (line 1) [manni:lifecycle:1.0.0]
1 file checked, 0 passed, 1 failed, 4 errorsThe exit code is 1. The four lines are one rule, reported from each branch it
tried. Adding either key clears all four. A typo such as lifecycle: depreciated
fails too, with must be equal to one of the allowed values.
Design decisions
Section titled “Design decisions”- The enum is closed, and the cost is recorded. The family’s default is
never to invent an enum. This ladder catches typos such as
depreciatedand makes the deprecation rule enforceable. The cost is that an org with its own stages, such asexperimentalorretired, must override the key. Likevisibility, it is a key downstream tooling branches on. remove-byis a date. A removal date gives a build something to act on. A boolean flag only says the page goes away someday, and pages flagged that way tend to stay forever. Ansible’s deprecation practice, which records a removal date, is the model.- The inverse edges live on two files, and the schema says so.
replaced-bypoints from the old page to the new, andsupersedespoints back. JSON Schema validates one file at a time, so the pair is not cross-checked here. A knowledge graph is where the two edges reconcile. The graph vocabulary’srevision-ofemits the sameprov:wasRevisionOfpredicate. This vocabulary records the fact and states the limit of what it can check. lifecycleis editorial state, andvisibilityis access. Who may see the page isvisibility. The two axes are independent. An unfinished page that is visible inside the org islifecycle: draftwithvisibility: internal, which is legal and common.
Strict overlay
Section titled “Strict overlay”Strict overlay id: manni:lifecycle-strict:1.0.0
Published at https://hawkeyexl.github.io/manni/schemas/lifecycle-strict/1.0.0.json.
The overlay holds only what strict adds. It narrows the form of a value that is
present and requires no key, so a page with no lifecycle fields still passes
it.
| Field | Strict adds |
|---|---|
replaced-by | One id, path or URL on one line with no leading or trailing whitespace. A path may contain spaces |
supersedes | Each value is one id, path or URL on one line with no surrounding space, in the string form and the list form alike |
remove-by | An RFC 3339 full date, YYYY-MM-DD. A year or month alone fails, and so does a timestamp |
lifecycle is the same in both, because its ladder is already closed. The
deprecation rule is also unchanged.
strict: true stacks it right after the vocabulary, with every other
default’s overlay beside its own base:
meta: strict: trueTo adopt this overlay alone, list its id. The default set already carries the vocabulary:
meta: schemas: - manni:lifecycle-strict:1.0.0Each schema is checked on its own, and a finding names the one that produced it. A strict-only failure reads as one, beside the location warning a run without a manifest prints.
---title: Configure the legacy exporterdescription: The exporter settings for operator releases before 1.4.lifecycle: deprecatedreplaced-by: configure-the-collectorremove-by: 2027-01---$ manni meta validate page.md --no-config -s manni:lifecycle:1.0.0 -s manni:lifecycle-strict:1.0.0✗ page.md /remove-by must match pattern "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$" (line 6) [manni:lifecycle-strict:1.0.0] /remove-by warning "remove-by" is stored in the page; manni:lifecycle:1.0.0 prefers external metadata, and --no-config leaves it no manifest. (line 6) [location:external]
1 file checked, 0 passed, 1 failed, 1 error, 1 warningThe open vocabulary accepts a month alone, so the overlay alone fails the page.