Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 692292@bnt-lap001 Assistant-Session: 89c7d8e8-e1b3-47eb-9411-a0ab227fca2f
8.4 KiB
| id | type | title | domain | repo | status | owner | created | updated | flavor | related | depends_on | state_hub_workstream_id | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RMGR-WP-0020 | workplan | Bounded Forge-sourced freshness runner via Activity Core | infotech | repo-manager | blocked | claude-repo-manager | 2026-10-04 | 2026-10-04 | implementation |
|
cda2296b-9fe0-5e9e-b630-7e143a3c2796 |
Status note
2026-10-04: the founder approved the T01–T03 design, so the status is now active.
Approval covers source implementation only. Deployment, schedules and any
non-dry-run fire stay gated behind T04/T05.
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 --remotesweep orPOST /consistency/sweep/remote-all. ADR-002 forbids central reads or writes of workstation checkouts.state-hub-consistency-sweepstays paused and is retired, not repurposed. - No full-fleet fan-out per fire, and no
for_eachtask 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
id: RMGR-WP-0020-T01
status: done
priority: high
state_hub_task_id: "065ef2ad-82ff-5d02-80e1-717e4d1819af"
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.
Implementation note (2026-10-04): src/repo_manager/freshness_receipts.py.
The store is an append-only JSON Lines file in the Repo Manager evidence sink,
~/.repo-manager/freshness-receipts.jsonl (override with
RM_FRESHNESS_RECEIPTS_PATH or the freshness_receipts_path key in the
dual-run config). It is the same persistence pattern as the mutation meter and
the idempotency store, so it needs no new service. Appends are flock-serialised
and fsynced. The store is queryable with rmgr freshness receipts [--repo] [--latest]. A receipt cannot be constructed without a verified primary hub. A
deployed runner must mount this path on a persistent volume (T04).
Bounded Forge-sourced selector and runner
id: RMGR-WP-0020-T02
status: done
priority: high
state_hub_task_id: "8333b4a7-9d12-57a1-ba9d-d447a0ba26b5"
Add rmgr freshness run --limit N --max-seconds S [--dry-run]:
- Rank active repositories by the last durable receipt, with never-received
repositories first. Before T01 data exists, fall back to
backing_synced_at. - For each of at most N, resolve the Forge HEAD and skip with
noopwhen the last receipt already matches it. - Otherwise reconcile from the immutable Forge commit (STATE-WP-0086 path), never
from a checkout. Verify the receipt the way
projection_syncdoes (primary, instance label, expected == derived == Forge commit). - 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).
Implementation note (2026-10-04): src/repo_manager/freshness_runner.py, CLI
rmgr freshness run --limit N --max-seconds S [--dry-run]. Optional flags:
--api-base, --expected-instance-label, --forge-base, --forge-owner,
--receipts-path, --definition-id, --definition-version, --fire-id.
The Forge HEAD is read over the Forgejo HTTP API (forgejo.coulomb.social/coulomb/<slug>,
the same source the hub derives from). It does not use the workstation SSH alias
in remote_url. Repositories that already have receipts rank by their latest
receipt of any outcome, so refused holes cannot starve the rotation. The
backing_synced_at fallback is capped at 25 % of the budget (at most 60 s). Snapshots that do not answer in time fall back to the /repos/ row's last_state_synced_at.
Exit codes: 0 ok, 1 failed or aborted attempts, 2 bad arguments, 3 hub not
verified primary (no receipts written), 4 hub unreachable.
Tests: tests/test_freshness_runner.py.
Prepared ActivityDefinition (draft, disabled)
id: RMGR-WP-0020-T03
status: done
priority: medium
state_hub_task_id: "76925a63-ff7b-5487-bcb4-b7ed64a3add5"
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.
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)
id: RMGR-WP-0020-T04
status: wait
blocking_reason: "Runner deployed in the Activity Core worker (Argo a86a143); apply trials need the read-only Forgejo token (draft CCR-2026-0034)"
priority: high
state_hub_task_id: "8941af6b-f2c1-5ad1-bb13-a757b3f71c12"
Activation, each step gated:
- Founder approves T01–T03 design. Deploy the Repo Manager runner image (pinned
digest) and the context source; the definition ships with
enabled: false. - Run two manual fires with
--dry-run, then two manual fires withapply,limit: 3. Verify receipts, zero task spawns and no checkout access. - Founder flips
enabled: true. Re-runpython -m repo_manager.freshnessafter 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
id: RMGR-WP-0020-T05
status: wait
blocking_reason: "Proof follows the T04 trials and the memo 4 schedule"
priority: medium
state_hub_task_id: "f01fb241-8f35-52ba-9119-86c9cc359528"
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.
2026-10-04 session close: workplan set to blocked. T03 done: the disabled
definition repo-manager-bounded-freshness landed in activity-core (ACTIVITY-WP-0044,
b2c6c56). The founder accepted memos 3 and 4 (approvals 4ae04c8e, b75752d1). rmgr
e77f8b4 ships in the Activity Core worker image git-34d1dc5 (Argo a86a143), with
receipts on PVC actcore-ops-artefacts. No fire has run. Apply trials need a
read-only Forgejo token; the draft lane is in railiance-platform.