007-Reports collection separates output retention policies

Type: ../types/adr.md · Status: accepted

Status: accepted Date: 2026-03-24 Amended: 2026-08-29 — collection boundary and retention-policy areas

Context

The original decision created kb/reports/ for generated, regenerable analytical snapshots. That solved a real routing problem: promotion candidates, orphan listings, coverage views, and similar outputs are neither durable claims nor workshop state. Their value is replaced by a fresh computation.

The directory name then became a stronger routing cue than the decision's regenerability test. Long-lived experiments and exact evaluation records were placed beside replaceable snapshots because they were called reports. At the same time, ignored review evidence and full-pass packets acquired load-bearing judgments or dispositions that could not safely be regenerated. One directory therefore mixed three incompatible deletion policies while its broad "generated reports" identity biased new output toward the wrong one.

The directory also carried kb/reports/types/ without a COLLECTION.md. Commonplace permits local types only under their owning collection, so reports used collection-local structure without the collection boundary and text contract that make that ownership valid.

Decision

kb/reports/ is a top-level collection for analytical outputs, evaluation records, and local operational evidence consumed as reports. Its COLLECTION.md is the text contract for the entire subtree, and kb/reports/types/ owns report-specific type contracts.

Every report payload lives under one retention-policy area:

Area Policy
kb/reports/cache/ Replaceable output. Its authoritative inputs and producer exist elsewhere; deleting it loses no unique evidence, decision, or unresolved state. Payloads are ignored.
kb/reports/state/ Machine-local operational evidence or state. Payloads are ignored, but the producing workflow owns cleanup because an artifact may be non-reproducible or authoritative for a live disposition.
kb/reports/retained/ Durable report records kept with the project. These outputs are tracked and remain usable from a clean checkout.
kb/reports/types/ Collection-local structural contracts; not report payloads.

Report payloads do not live directly at the collection root. A policy change is represented by moving the artifact. In particular, making one cache report durable means moving it to retained/, not adding an exception to an ignore rule.

The word report does not select this collection. A generated synthesis that contributes a transferable claim still belongs in kb/notes/; a shipped-system premise or decision belongs in kb/reference/; a procedure belongs in kb/instructions/; and draft reasoning or run traces consumed by unfinished work belong in kb/work/. Reports holds outputs whose exact result is the consumed artifact after those routing tests.

The collection remains outside the published site and generated directory indexes. Package-owned validation markers exclude cache/ and state/ from a collection sweep because their payloads use producer-owned validation and may be absent in a clean checkout. The markers do not hide those files from general discovery, and explicit validation of a typed report still applies its type.

Operativity runs through three paths. Report producers write to their declared policy paths; kb/reports/COLLECTION.md binds authors and reviewers choosing a home or changing retention; and the project scaffold creates the collection, policy directories, ignore rules, validation markers, landing, and local types. Directory placement carries the retention contract even when Git is absent; Git implements ignored versus project-kept storage in checkouts that use it.

Considered alternatives

Create a top-level kb/cache/. This gives replaceable output a strong name, but report producers share local types and neighboring operational policies. It would either make cache another collection solely to own those types or move the contracts away from the artifacts they shape. Keeping policy areas under one reports collection preserves one type and text-contract boundary.

Keep reports as an uncontracted support directory and move its types to kb/types/. The types are report-specific rather than framework-global, and the directory still needs a binding rule for distinguishing replaceable output from retained evidence and state. Globalizing the types would remove the visible inconsistency without fixing the routing error that exposed it.

Treat every ignored or generated report as cache. Rejected because generation says how an artifact was produced, not whether its evidence or state can be reconstructed. Review judgment bodies and full-pass dispositions are the counterexamples: they can be ignored and generated while still being load-bearing.

Put only replaceable snapshots under reports and move durable records to a new library collection. Rejected because exact experiment and evaluation records are not automatically claims, system descriptions, or decisions. A new collection would duplicate the same report-local types and require another boundary for ignored operational state. Retention policy is the changing axis; first-level areas expose it directly.

Leave durable reports at the collection root. Rejected because an unqualified root preserves the original ambiguity. A writer would still infer policy from the artifact name or neighboring files instead of selecting it explicitly.

Consequences

Replaceable snapshots now have a deletion-safe home without making every generated output disposable. Ignored operational state advertises that it is local yet load-bearing, and durable reports such as the planning-delegation corpus are visibly project-kept. Local report types now have a valid owner and compose with one complete collection contract.

The extra path segment changes producer defaults, stored report paths, links, tests, and operator commands. A path alone cannot prove that a cache entry is actually reconstructable or that state cleanup is safe; producer instructions must keep those claims true. General discovery still sees visible Markdown under cache/ and state/ because validation markers are not visibility controls under ADR 039.

This decision stops at outputs consumed as reports. It does not classify local source snapshots, build caches, workshop-generated fixtures, or execution traces whose owning subsystem already supplies a stronger lifecycle. It also does not make retained/ a second library: durable conclusions are still extracted to the collection whose consumer and force require them.


Relevant Notes:

  • Storage — implemented-by: distinguishes reconstructable views, retained judgment evidence, stateful packets, and canonical database state
  • Content routing — rests-on: routes by regeneration source and consumer rather than output name
  • ADR 039 — rests-on: validation markers do not make ignored report payloads invisible
  • ADR 051 — example: generated local packets whose actionable state prevents cache treatment