---
schema_version: 1
id: RAC-KV3GREQKTMVB
type: roadmap
---
# RAC v0.14.1 — Status Consistency

## Status

Planned

## Context

ADR-049 makes deterministic cross-artifact validation RAC's core, and
`rac-cross-artifact-enforcement` REQ-003 scopes status-consistency: a live
artifact must not point at a decision the team has retired. v0.14.0 surfaced
illegal edges; this milestone adds the second enforcement rule — the one behind
the positioning line "nothing points at a superseded artifact."

Lifecycle status exists only on decisions today (`Proposed`/`Accepted`/
`Superseded`/`Deprecated`), so the rule is decision-targeted: a resolved
relationship whose target is a decision with status `Superseded` or `Deprecated`
is a validation issue — except the `supersedes` edge by which a replacing
decision legitimately points at the one it replaces. A source that is itself a
retired decision is exempt: the rule is about *live* knowledge referencing dead
knowledge, not historical chains between retired decisions.

The check needs the resolved target's type and status at validation time.
`_validate` already materialises the corpus items, so it can index them by path
and read the target's status in a single self-contained pass — no change to the
shared `_resolve_references` (which feeds `rac portfolio`) and no second walk.

## Outcomes

- A relationship resolving to a `Superseded`/`Deprecated` decision is reported as
  `relationship-target-superseded` and fails `rac relationships --validate`,
  except the `supersedes` edge.
- A retired decision's own outbound references do not trigger the rule (not live).
- Referential integrity, edge-legality, and all existing issue codes are
  unchanged; the corpus stays green (no decision is currently retired).

## Initiatives

### Initiative 1 — Status-consistency rule

In `_validate`, index items by path and, for each resolved (uniquely-matched,
non-self) reference from a live source, emit `relationship-target-superseded` when
the target is a decision whose status is `Superseded`/`Deprecated` and the edge is
not `supersedes`. Determine retired status inline (first non-empty line of the
decision's `## Status`), without importing `inspect` (it imports this module).

### Initiative 2 — Output, wiring, coverage

Render the finding in human output (a reference-style "✗ <target> superseded"
line) and JSON (`{source_path, relationship, target, code}`). Confirm it flows
through the existing `validate → exit code → watchkeeper` chain. Tests: a live
artifact referencing a superseded decision fails; the `supersedes` edge to that
decision does not; a deprecated target also fails; a retired-source reference is
exempt; CLI exit code and JSON shape.

## Constraints

- Deterministic (ADR-002): same corpus state, identical findings and ordering.
- Additive (ADR-007): existing relationship issue codes are unchanged; the new
  code is added. `supersedes` semantics are untouched.
- Decision-only: the rule applies where lifecycle status exists; generalising
  status to other types is out of scope (a later, separately scoped decision).
- No change to `_resolve_references` or `summarize_relationships` — portfolio's
  resolution accounting stays exactly as it is.

## Non-Goals

- Generalising lifecycle status to requirements, roadmaps, prompts, or designs.
- Flagging references *from* a retired decision (historical chains are exempt).
- Treating `Proposed` as retired — only `Superseded`/`Deprecated` are retired.
- A `rac review`/portfolio "broken" reclassification — status-consistency is a
  `--validate` finding, like edge-legality.

## Implementation Contract

The following decisions are pinned for v0.14.1.

### Behaviour

- A uniquely-resolved, non-self relationship from a live source whose target is a
  decision with status `Superseded` or `Deprecated` raises one
  `relationship-target-superseded` issue (source path, snake section name, raw
  reference), unless the edge is `supersedes`.
- "Live source" excludes a decision whose own status is `Superseded`/`Deprecated`.
- Edge-legality and referential-integrity issue codes and output are unchanged.

### Interface

- `rac relationships <dir> --validate` reports the new issue and exits `1` when it
  occurs. Human and JSON outputs both carry it.

## Success Measures

- `rac relationships rac/ --validate` stays `0` on the corpus and returns `1` on a
  fixture where a live artifact references a superseded decision.
- The `supersedes` edge from the replacing decision to the superseded one does not
  raise the issue.
- A `Deprecated` decision target is treated identically to `Superseded`.

## Risks

- Over-strict: flagging legitimate historical references. Mitigated by the
  `supersedes` exception and the retired-source exemption.
- Reading status inline could drift from the canonical spelling. Mitigated by
  matching only the retired values case-insensitively on the first status line,
  the same first-line rule `inspect` uses.

## Assumptions

- Lifecycle status remains decision-only (`spec.metadata["status"]`).
- `_validate` remains the single place that assembles relationship-validation
  issues from the materialised corpus items.

## Related Decisions

- adr-049
- adr-016
- adr-007

## Related Requirements

- rac-cross-artifact-enforcement

## Related Roadmaps

- v0.14.0-enforcement-foundation
