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 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 671493@bnt-lap001 Assistant-Session: 60d7b11f-78f9-4731-9367-918511b2762d
This commit is contained in:
parent
e3940cdc26
commit
29ba3dedcc
1 changed files with 153 additions and 0 deletions
153
workplans/RMGR-WP-0020-bounded-freshness-runner.md
Normal file
153
workplans/RMGR-WP-0020-bounded-freshness-runner.md
Normal file
|
|
@ -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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue