state-hub/workplans/STATE-WP-0084-forge-read-for-private-repositories.md
repo-manager 8b38f815e5
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
chore(registrar): assign State Hub identifiers
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
2026-08-26 21:30:30 +02:00

4.8 KiB

id type title domain repo status owner topic_slug created updated related state_hub_workstream_id
STATE-WP-0084 workplan Derive private repositories, and report unreadable as unreadable infotech state-hub proposed codex infotech 2026-08-26 2026-08-26
CUST-ADR-012
STATE-WP-0083
MASON-WP-0003
9c4b8c79-edba-5d2d-ad37-a45707e89304

Derive private repositories, and report unreadable as unreadable

Goal

Consume the forge read credential that ops-mason/MASON-WP-0003 builds, so derivation covers private repositories — and make a repository central cannot read report as unreadable rather than as an error or, worse, as a repository whose records no longer derive.

Why this exists

STATE-WP-0083-T04 reset 121 repositories on 2026-08-26. Nine failed identically:

fatal: could not read Username for 'https://forgejo.coulomb.social'

rapp-core-hub, rapp-issue-core, rapp-openbao, rapp-policy-nexus and five others are invisible to derivation entirely. ADR-012's premise — the forge is the projection source — holds only for repositories central can read, and nothing in the current design says so.

Split from MASON-WP-0003

The credential lane itself (OpenBao policy, AppRole, KV path, and the warden route find catalog entry) is ops-mason's to build: that repository exists to build "AppRoles, policies, and KV secret paths so ops-warden always has something real to route to". Deployment plumbing and derivation code are this repository's.

T01 does not depend on the credential and should land first. T02 and T03 wait on MASON-WP-0003-T02.

Distinguish "cannot read" from "does not exist"

id: STATE-WP-0084-T01
status: todo
priority: high
state_hub_task_id: "e955067d-2152-59f7-b672-12755ceb26b0"

A repository the hub is not permitted to read must be reported as unreadable — a named condition — not as a generic clone error and never as an empty derivation.

Today the reset treats a failed clone as an error, which is correct only by accident: if a clone ever returned empty instead of failing, every record in that repository would be proposed for retirement. That is the failure that nearly retired vergabe-teilnahme, and it must be impossible here by construction rather than by luck.

An empty clone result and an unreadable repository must both be incapable of producing retirement work. Retirement proposals require a successful read that positively lacks the record.

This also carries the decision in MASON-WP-0003-T01: a per-repository grant is only safe to choose if a missing grant surfaces as a named condition. Until this lands, the narrow option fails silently.

Acceptance: an unreadable repository is reported as unreadable; a clone that succeeds but returns nothing produces no retirement proposals; both cases are covered by tests that fail if the retirement path is reachable from either.

Deliver the credential to the pod

id: STATE-WP-0084-T02
status: wait
priority: medium
state_hub_task_id: "d8d41a89-1ebc-5118-bb73-cf8d8c114e16"

Blocked on MASON-WP-0003-T02.

Make the credential available to the state-hub deployment as a Kubernetes Secret, mounted or injected, referenced by the chart the same way state-hub-env already is.

It must not be baked into the image and must not be committed to the chart. Rotation must not require a chart change or a redeploy.

Acceptance: the pod can read the credential; nothing in the repository contains it; rotating the token does not require a redeploy.

Teach the derivation to use it

id: STATE-WP-0084-T03
status: wait
priority: medium
state_hub_task_id: "b22b24d9-7ed3-533c-bda7-3130693cf4d2"

Blocked on T02.

derive_from_forge() clones anonymously. It should use the credential when present and continue working without it — a hub with no token must still derive public repositories rather than failing wholesale.

Credentials must never reach the clone URL in a way that lands in logs or process listings: use a credential helper or an HTTP header, not an embedded userinfo URL.

Acceptance: private repositories derive; a hub without the credential still derives public ones; no credential appears in logs, process listings, or recorded clone URLs.

Confirm the nine

id: STATE-WP-0084-T04
status: wait
priority: medium
state_hub_task_id: "33c09a78-5974-57c6-bb7f-ad73082046bb"

Blocked on T03.

Re-run the fleet reset and confirm the nine repositories derive rather than error. Expect a real diff for each — quite possibly a large one, since none has ever been reconciled against its files.

Treat the first diff for each as review material, not as work to apply. Every repository examined this way for the first time has produced findings.

Acceptance: fleet errors fall from nine to zero; each newly readable repository has its first diff reviewed before anything is applied.