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 existingcriterion-changedreason. COLLECTION.md-as-gate is shipped (ADR 041): the selector derives(note, collection_md)pairs from note location under thecollection/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-alignmentpair, 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-pairtarget, has exactly two inputs,noteandcriterion(freshness architecture). The criterion role is path-generic, so any repo document can sit on the criterion side. - Adopted: cohort-scoped acknowledgement.
commonplace-ack-reviewconsumes 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'sCOLLECTION.md. Each factored pair reuses the entire freshness/ack/warn stack unchanged, exactly as type-conformance pairs do. Like the type spec,COLLECTION.mdis 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:
- link graph plus timestamps enables make-like staleness detection — rests-on: the build-product/prerequisite model; factored two-input pairs are its cheapest review-side realization
- 038-type-conformance reviews use the type spec as the gate — evidenced-by: the shipped first instance of the factoring pattern this proposal generalizes
- a derived copy of recomputable truth must be checked or absent — rests-on: why each dependency document must be the gate rather than be restated in one
- review system — part-of: the freshness, freshness baseline, and ack concepts every factored pair reuses unchanged
- 032-review freshness uses DB snapshots, not Git — see-also: the role-neutral snapshot substrate that lets any repo document sit on the criterion side