Every knowledge fact has a lifecycle state that decides whether it may reach
agents:
| State | Meaning | Reaches agents by default |
|---|---|---|
approved |
Current, curated knowledge | yes |
draft |
Proposed, not yet reviewed | no |
deprecated |
No longer valid | no |
superseded |
Replaced by another fact (superseded_by) |
no |
Vault and git-source facts carry the state in their YAML frontmatter:
---
title: Old deploy flow
state: superseded
superseded_by: new-deploy-flow
---The replacement fact records the reverse link as supersedes: <slug>.
Facts written before lifecycle states existed have no state: key and load as
approved, so existing vaults keep working unchanged. A fact with a
superseded_by: link, or a legacy status: deprecated / status: superseded
(for example a connector tombstone), loads as superseded / deprecated.
Remote wiki layers only carry a status, which is mapped the same way.
- Kick primers include approved facts only. Set
knowledge.PrimerConfig.IncludeStates(include_states) to admit other states. GET /api/knowledge/searchreturns approved facts only unless the operator passesinclude_states, e.g.include_states=deprecated,supersededorinclude_states=all.- Public knowledge MCP (
/mcp/knowledge) only ever publishes approved facts. GET /api/knowledge/tocandGET /api/knowledge/entry/{id}apply the same default andinclude_statesopt-in; see Scoped knowledge table of contents.GET /api/knowledge(the dashboard inventory) still lists every fact, and vault facts report theirstate, so operators can review and restore them.
PUT /api/knowledge/{layer}/{slug} accepts two lifecycle fields. When
{layer} names a local channel (vault), they rewrite the fact's frontmatter:
{"state": "deprecated"}(ordraft/approved) sets the state.{"superseded_by": "new-slug"}marks the factsuperseded, recordssuperseded_by: new-slugon it andsupersedes: <slug>on the replacement. Both facts must be in the same channel.
On a remote wiki layer state is forwarded as the page status; supersession
links are only supported in local channels.
Operators change an entry's state by id with an audited, owner-only call. The channel does not need to be named:
PUT /api/knowledge/entry/old-deploy-flow/state
{"state": "superseded", "superseded_by": "new-deploy-flow", "reason": "deploy flow rewritten"}hivectl knowledge state old-deploy-flow deprecated --reason "deploy flow removed"statemust bedraft,approved,deprecatedorsuperseded.supersededrequiressuperseded_by, andsuperseded_byis only accepted withsuperseded. The replacement must be in the same local channel as the entry. Invalid input returns 400.- The entry must be in a local channel (vault). Entries from remote wiki layers, git sources and the reserved automation channel return 404.
- Every change writes an audit entry:
knowledge_set_state, orknowledge_supersedefor supersession. The entry records the actor, the entry id and channel, the previous and new state,superseded_by, and thereason(whitespace collapsed, capped at 500 characters). - The response returns the
channel,previous_state, the newstate,superseded_byand the updatedfact.
Restoring a fact to approved clears its superseded_by link. It then
reaches primers and the table of contents again.