feat(cache): add rebuild and provenance safeguards

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
tegwick 2026-08-21 23:23:03 +02:00
parent bf3f416b82
commit 5dc2f3cdf6
11 changed files with 2809 additions and 4 deletions

62
docs/cache-rebuild_v1.md Normal file
View file

@ -0,0 +1,62 @@
---
id: RMGR-RUNBOOK-CACHE-0001
type: runbook
title: "Repository projection cache rebuild"
version: "1"
status: active
created: "2026-08-21"
updated: "2026-08-21"
workplan_task: RMGR-WP-0005-T07
---
# Repository projection cache rebuild v1
Repo Manager's local index is advisory. Repository files and Git history are
authoritative; deleting `.repo-manager/index.json` cannot delete work.
## Inspect and rebuild
```bash
rmgr cache status --path /path/to/repository
rmgr cache rebuild --path /path/to/repository --slug repository-slug
```
Status always reports `advisory`, `observed_at`, `age_seconds`, the indexed and
current source fingerprints, and explicit staleness reasons. Legacy indexes
without a fingerprint are stale. A source file changing after observation is
stale. Rebuild parses the files afresh and atomically replaces only the local
JSON projection.
The fingerprint covers workplans, intake/decision record locations, registers,
classification, and the repository intent/goal file. It hashes relative paths
and bytes so uncommitted authoritative changes are visible even when Git HEAD
has not moved.
## State Hub cache replacement gate
Before replacing a legacy State Hub database, export the closed unbound
workplan provenance:
```bash
rmgr cache export-closed \
--api-base http://127.0.0.1:8000 \
--output closed-workplan-provenance.json
```
The export is minimized to identity, repository, title, lifecycle, owner, and
creation/update timestamps. It includes a canonical UTC generation timestamp
and SHA-256 over canonical row JSON. The command refuses to overwrite an
existing export unless `--force` is supplied.
A database replacement is not authorized by this command. Before replacement:
1. verify the export count and `rows_sha256`;
2. prove that no live unbound file-derived records remain;
3. prove that hub-native records have reached their one authoritative central
owner, or retain the old database;
4. rebuild file-derived records into an isolated database and compare counts,
identifiers, statuses, and source provenance;
5. switch the local cache only after the comparison passes.
The old database remains a recoverable source until those gates pass. Repo
Manager does not merge database-local file-derived state back into repositories.

File diff suppressed because it is too large Load diff

View file

@ -48,6 +48,11 @@ used for the repair because it aborts while refreshing the brief for stale
registered path `/home/worsch/inter-hub`; the targeted binding route avoided
coupling this data repair to that unrelated registry defect.
The 217 closed rows were subsequently exported to
`docs/evidence/RMGR-WP-0005-closed-provenance-2026-08-21.json`. The minimized
export is 90,458 bytes and seals the canonical row payload with SHA-256
`40f227ecb138880d41cebf30a1f0559e709ab2d753be892409ea8e00f96d37d7`.
## Reproduction
The counts came from `GET /workplans/`, selecting rows whose

View file

@ -62,3 +62,8 @@ records require both repository and domain context and resolve to
types resolve to their one declared hub owner. Unknown types and writes whose
claimed owner disagrees with the contract are rejected instead of falling back
to whichever hub received the request.
Local repository projections implement the cache side through `rmgr cache
status|rebuild`; every read carries observation age and fingerprint-based
staleness. The guarded legacy-cache procedure and closed provenance export are
defined in `docs/cache-rebuild_v1.md`.