From 29ba3dedccbff44c8bdaf9017fb23be7f41fb53f Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 4 Oct 2026 12:46:01 +0200 Subject: [PATCH] Propose RMGR-WP-0020 bounded Forge-sourced freshness runner Activity Core definition draft (disabled) and activation/rollback plan for founder review; explicitly not the legacy --all --remote sweep (ADR-002). Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 671493@bnt-lap001 Assistant-Session: 60d7b11f-78f9-4731-9367-918511b2762d --- .../RMGR-WP-0020-bounded-freshness-runner.md | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 workplans/RMGR-WP-0020-bounded-freshness-runner.md diff --git a/workplans/RMGR-WP-0020-bounded-freshness-runner.md b/workplans/RMGR-WP-0020-bounded-freshness-runner.md new file mode 100644 index 0000000..331d630 --- /dev/null +++ b/workplans/RMGR-WP-0020-bounded-freshness-runner.md @@ -0,0 +1,153 @@ +--- +id: RMGR-WP-0020 +type: workplan +title: "Bounded Forge-sourced freshness runner via Activity Core" +domain: infotech +repo: repo-manager +status: proposed +owner: claude-repo-manager +created: "2026-10-04" +updated: "2026-10-04" +flavor: implementation +related: [STATE-WP-0094, STATE-WP-0086, RMGR-WP-0005, RMGR-WP-0017, RMGR-WP-0019] +depends_on: [] +--- + +## Goal + +Close the freshness half of STATE-WP-0094-T05 with a supported, bounded and +durable freshness runner. Activity Core schedules it. Repo Manager owns the +engine and selection. State Hub only receives immutable Forge-commit projections. + +Evidence of need: `docs/evidence/2026-10-04-freshness-coverage.md`. No C-rule +definition is active; the only one (`state-hub-consistency-sweep`) is paused. +Of 141 active repositories, 35 synced within 24 h, the median age is 109 h and +the maximum is 949 h. Receipts are not durable. + +Non-goals and constraints: + +- **Not** the legacy `--all --remote` sweep or `POST /consistency/sweep/remote-all`. + ADR-002 forbids central reads or writes of workstation checkouts. + `state-hub-consistency-sweep` stays paused and is retired, not repurposed. +- No full-fleet fan-out per fire, and no `for_each` task spawning (lesson from + daily-sbom-catchup / ACTIVITY-WP-0030). +- No graph-edge receiving. That remains STATE-WP-0094-T05 edge contract work. +- No change in this workplan is enabled, deployed or scheduled without founder authorization (T05). + +## Durable freshness receipt contract + +```task +id: RMGR-WP-0020-T01 +status: todo +priority: high +``` + +Define `repo-manager.freshness-receipt.v1`. It records the repository, the Forge +commit read via the Forge API or `ls-remote`, the expected/derived commit from the +State Hub `repository-projection-reconcile.v1` receipt, the outcome +(`applied|noop|queued|failed|refused|skipped`), the reason, the runner revision, +the definition id/version, the fire id and UTC timestamps. Choose one durable +read-only-queryable home: the Activity Core run artifact / ops-runs store, or the +Repo Manager evidence sink. Do not use the State Hub DB. This closes the +"last successful / failed receipt" gap. + +## Bounded Forge-sourced selector and runner + +```task +id: RMGR-WP-0020-T02 +status: todo +priority: high +``` + +Add `rmgr freshness run --limit N --max-seconds S [--dry-run]`: + +1. Rank active repositories by the last durable receipt, with never-received + repositories first. Before T01 data exists, fall back to `backing_synced_at`. +2. For each of at most N, resolve the Forge HEAD and skip with `noop` when the last + receipt already matches it. +3. Otherwise reconcile from the immutable Forge commit (STATE-WP-0086 path), never + from a checkout. Verify the receipt the way `projection_sync` does + (primary, instance label, expected == derived == Forge commit). +4. Persist one receipt per repository and stop at `max_seconds`. + +`--dry-run` emits the plan only. Tests must cover the ranking, the noop and the +refusals (RMGR-WP-0014/0019 holes stay `refused`, never forced). + +## Prepared ActivityDefinition (draft, disabled) + +```task +id: RMGR-WP-0020-T03 +status: todo +priority: medium +``` + +Hand the draft below to the activity-core owner as a proposal. Do not edit +activity-core from this repo. It needs a `repo-manager` context source (or the +existing HTTP sink pointed at a Repo Manager endpoint) that calls T02. + +```yaml +id: repo-manager-bounded-freshness +name: Repo Manager Bounded Freshness +type: activity-definition +version: "0.1" +enabled: false # founder flips after T05 proof; never in this workplan +owner: repo-manager +governance: custodian +status: proposed +trigger: + type: cron + cron_expression: "40 */2 * * *" # every 2 h, offset from other fleet jobs + timezone: UTC + misfire_policy: skip +context_sources: + - type: repo-manager + query: freshness_run + operation: repo_manager_freshness + required: true + params: + limit: 6 # 141 repos / 6 per fire x 12 fires/day ~= 2-day full rotation + max_seconds: 240 + apply: true # declared bounded side-effect; manual runs require confirmation + bind_to: context.freshness +``` + +Target SLA once enabled: every active, admissible repository has a receipt +younger than 48 h. Non-admissible repositories appear as explicit `refused` +holes. + +## Activation and rollback plan (founder review) + +```task +id: RMGR-WP-0020-T04 +status: wait +priority: high +``` + +Activation, each step gated: + +1. Founder approves T01–T03 design. Deploy the Repo Manager runner image (pinned + digest) and the context source; the definition ships with `enabled: false`. +2. Run two manual fires with `--dry-run`, then two manual fires with `apply`, `limit: 3`. + Verify receipts, zero task spawns and no checkout access. +3. Founder flips `enabled: true`. Re-run `python -m repo_manager.freshness` + after 48 h and accept when the 48 h coverage of admissible repositories is 100 %. + +Rollback: set `enabled: false` (or `status: paused`) in the definition ConfigMap +projection and restart nothing else. The runner holds no state beyond receipts, +and projections are idempotent per commit (RMGR-WP-0017), so no data rollback is +needed. To revert the runner itself, redeploy the previous image digest. +Kill criteria: any receipt with an unverified primary, any checkout read, or a +fire that exceeds `max_seconds` twice in a row. + +## Proof and handback to State Hub + +```task +id: RMGR-WP-0020-T05 +status: wait +priority: medium +``` + +After founder-authorized activation, record bounded freshness evidence: +runner revision, active definition, per-repository Forge commit, last success +and failed/queued receipts, and measured window. Return it to STATE-WP-0094-T05. +Historical registrar holes stay listed until each is resolved.