DR-127: The review surface is one faceted queue over the three real axes
DR-127 — The review surface is one faceted queue over the three real axes, and the quality score retires
Section titled “DR-127 — The review surface is one faceted queue over the three real axes, and the quality score retires”Context
Section titled “Context”S528 declined to rule on the review surface, calling for a UX spike first. S529’s lane B ran
it and found that the built /review vs /api/governance/review split matches neither
axis record_lifecycle declares — because a third axis exists that the facet never
modelled:
| Axis | Home | Owner kinds |
|---|---|---|
| A — Review/Governance | record_lifecycle | both {source_document, q_a_pair} |
| B — Freshness/cadence | record_lifecycle | source_document only (record_lifecycle_freshness_axis_chk) |
| C — Publication | source_documents and q_a_pairs, not record_lifecycle | both |
/review serves axis C. Three violations were measured: the platform can act on a Q&A
governance review it cannot list (the write path is polymorphic, all five governance read
queries pin source_document); all three crons write the governance column while two derive
their trigger entirely from freshness, dissolving at runtime the separation the DDL enforces;
and approving a governance review advances next_review_date, an axis-B column.
The quality score was measured directly: best attainable 65/100 with 35 points structurally unreachable, freshness 46% of the reachable range, every expired document below the threshold of 40 even at perfect quality, and no persistence home in any schema. Its originating requirement was a client “fix completeness scoring or remove it” ask that took neither branch.
Decision
Section titled “Decision”/review becomes one faceted queue with facets publication | governance | freshness,
each owner-kind-polymorphic exactly where its axis is. It absorbs /api/governance/review
and the /promotion-gate awaiting_review bucket, which is a governance sign-off on a
proposed diff.
The quality-score cron and lib/quality/quality-score.ts retire, and the level-triggered
governance backstop moves to the freshness axis as a freshness sweep.
Version and changelog are covered by DR-108’s append-only register-history — no new
record_lifecycle columns.
Alternatives considered
Section titled “Alternatives considered”- Option 2 — fix the axis violations, keep three surfaces. Faster, no DR-041 exposure.
Rejected: does not deliver reviewing promoted Q&As in the review surface, and leaves
/reviewserving an axis the facet does not model, so the next task still opens with archaeology — the precise cost id-417 exists to end. - Option 3 — document-lifecycle-first. Delivers the one requirement carrying an explicit pre-launch owner decision, but version and changelog have no schema home, and it hard-splits document review from Q&A review. Removed from consideration by the DR-108 ruling above.
- Retire the quality score outright with no replacement. Rejected: it is the only
level-triggered backstop —
freshness-transitionsflags only on a transition, so anything that expired before that flag existed is never re-flagged.
Consequences
Section titled “Consequences”- Needs a DR-041 nav ruling for the Governance zone entry set, since
/promotion-gateloses its own nav entry. The owner accepted this when ruling. DR-041 is a navigation ruling only and makes no claim about concern boundaries. - Composes with id-71 {71.9}, which is shipped. The facet enum is the seam: widen
content_quality|governance|all→publication|governance|freshness|all. {71.9}‘s test strategy asserts “/review + /api/governance/review routes unchanged”, so this lands as an amendment to that enum plus its fixture, never a silent break. Verify againstlib/mcp/tools/review.tsbefore costing it — lane B derived the seam from {71.9}‘s task record and TECH text, not from reading the tool file, and declared that gap. - The retirement frees
governance_config.quality_score_threshold/auto_flag_on_quality_drop, thequality_flagnotification type, id-71 {71.29}‘s deadqualityExposureLayerKeymember, and/api/review/queue’s hardcodedquality_score: nullwith its documented no-op sort. - The backstop replacement is not yet built. The module was deleted in S529; until the freshness sweep lands, the level-triggered gap is live. Tracked as an AC on id-420.
- The cadence-penalty schedule’s only cited source,
p0-document-control-lifecycle-spec.md, was recovered atknowledge-hub-archive/specs/— read as provenance, not authority (its §3.1 is built on the droppedcontent_itemsand its §3.5 governs the retired scorer).