Factored dependency pairs for review freshness

Type: reference/types/design-proposal.md · Tags: kb-maintenance, observability, review-system

An accepted review is a build product and its inputs are prerequisites — make-like staleness detection. Review freshness realizes this for exactly two inputs per pair: note text and criterion text. Type-conformance pairs (ADR 038) showed the cheap way to admit a new dependency: do not widen one pair's input set to N — factor each dependency into its own two-input pair where the dependency document is the gate side. This proposal holds the not-yet-adopted remainder of that direction: whether a review target may ever take more than two inputs.

Current state (as of 2026-09-22)

  • Type-conformance pairs are shipped (ADR 038): the selector derives (note, type_spec) pairs from note frontmatter, the type spec is the gate snapshot, and a type edit stales its cohort via the existing criterion-changed reason.
  • COLLECTION.md-as-gate is shipped (ADR 041): the selector derives (note, collection_md) pairs from note location under the collection/collection/{path} lens, again with no storage change.
  • Source-as-gate was shipped and then removed by the ADR 073 revision. It factored each direct ingest link into a separate pair, but its criterion was an interpreted Claims ledger. Direct source alignment now belongs to the standard semantic/grounding-alignment pair, which reads retained quotes or a declared snapshot through the note's links. The factoring pattern remains proven for type and collection dependencies.
  • The general freshness store (ADR 052) records each target's inputs as role-labelled rows, so storage already admits any number of inputs per target. The one registered specialization, the review-pair target, has exactly two inputs, note and criterion (freshness architecture). The criterion role is path-generic, so any repo document can sit on the criterion side.
  • Adopted: cohort-scoped acknowledgement. commonplace-ack-review consumes inspected selector JSON and advances the exact observed hashes of every retained target and role in one invocation (review system). This was this proposal's preferred cohort-ack input; it shipped under ADR 052, so it is recorded here rather than proposed below.
  • No judgment has been identified that irreducibly reads three or more texts in one prompt; no review target registers a third input.
  • A fuller design for a general lineage model — lineage targets, append-only events, per-event input versions, typed resolvers — is in flight in the workshop layer at kb/work/lineage-mechanisms/general-lineage-refresh-state-design.md (cited by path, not linked, per the no-workshop-links convention); factoring-into-pairs narrows how much of it review freshness will ever need.

The design: one pair per dependency edge

Each new review dependency becomes its own (note_path, dependency_path) pair with the dependency document as the gate:

  • COLLECTION.md-as-gate — adopted by ADR 041: a note's conformance to its collection's text contract. One pair per note, criterion side the collection's COLLECTION.md. Each factored pair reuses the entire freshness/ack/warn stack unchanged, exactly as type-conformance pairs do. Like the type spec, COLLECTION.md is not written as a Failure mode / Test procedure, so it needs a mechanical wrapper (or an authored review section in the dependency document, which the hash then sees).

A review target with three or more inputs remains the fallback for a judgment that irreducibly reads three or more texts in one prompt. The store could hold such a target's inputs; what is unbuilt is a review target kind that registers them, and the selector, job, and ack behavior that would read them. No such judgment is identified yet, which is exactly why that target stays unbuilt.

Forces that keep the remainder at planning

  • Review cost. Every factored dependency adds a pair per note; the corpus-times-dependencies product is real. The retired source case showed how a multi-link artifact can multiply pairs even when one standard semantic gate already owns the judgment.

Free choices

  • Wrapper prompt vs authored review section. Same trade as for type specs, and the freshness boundary weighs the same way: criteria in the dependency document are hashed, wrapper text is not.

Adoption criteria

  • Adopt a review target with more than two inputs only if a judgment appears that genuinely needs a third text in one prompt; the default answer to a new dependency is a new factored pair, not a wider input set.

Relevant Notes: