ops-warden/workplans/WARDEN-WP-0037-whynot-design-forgejo-npm-lane.md
tegwick 3aedd8f844
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
docs: record the answers received and the questions routed
Six inbound messages attended, three of them carrying real asks.

flex-auth FLEX-DEC-2026-004 answers WARDEN-WP-0034-T05's decision-lifetime
question: a decision lifetime shorter than the certificate TTL is meaningful,
but only as authority to ISSUE, never to USE an already-issued certificate.
The question had mistaken a decision lifetime for a credential lifetime. They
declined to move the §9.7.2 revocation residue to their side; that refusal is
right and the stance map is unchanged. T05 still waits on ops-mason and
railiance-infra.

WARDEN-WP-0039-T03 routed to flex-auth: is there an admitted contract for a
delegated credential read where caller and resource owner differ? Three
outcomes named as equally acceptable, including that there should be no such
contract and the interim proxy transport is itself the defect -- which would
shorten WP-0033 rather than block it. Two easy fixes ruled out in writing:
broadening the caller binding, and relabelling resource.system as ops-warden
so the binding matches. The second would make the audit trail assert we own
credentials we deliberately do not, by editing a field instead of making an
argument.

WARDEN-WP-0037: npm path routed to railiance-platform, catalog unchanged
pending their answer. secrets-engine refused to resolve it from a
coordination message and was right; asserting our own pointer is
authoritative because it is ours would route around that. The ask names a
location only, and flags that a `bao kv get` answer would be the 2026-07-16
disclosure vector on a risk: high lane.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EPuTc18FjU5WFqoSEKH3C

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1276224@bnt-lap001
Assistant-Session: 426ec497-e1c4-4dd3-b417-dfce1ca1dbc3
2026-09-09 16:40:46 +02:00

4.7 KiB

id type title domain repo status owner topic_slug created updated state_hub_workstream_id
WARDEN-WP-0037 workplan Repoint the whynot-design npm lane to Forgejo infotech ops-warden active codex whynot-design-forgejo-npm-lane 2026-09-04 2026-09-04 42a097db-1c24-558e-a724-030bb2b4443e

Verify the existing credential against Forgejo

id: WARDEN-WP-0037-T01
status: done
priority: high
state_hub_task_id: "afc4d325-1c6d-5c25-aaf7-2118aa8f86c6"

Use only the governed execution transport to test the existing publish identity against the canonical Forgejo npm endpoint. Do not print or persist the token.

2026-09-04: warden plan classified the exact verification as autonomous and selected this lane. A contained login using the documented whynot-design-workload-kv-read role proved read on the exact OpenBao data path, and the governed child proved the secret is present. A real 0.4.2 publish through that credential then failed. No value was printed or persisted and each contained session self-revoked. The lane therefore needs token rotation, not an OpenBao policy repair.

Repoint the catalog and playbook

id: WARDEN-WP-0037-T02
status: done
priority: high
state_hub_task_id: "7ceb2f74-496c-54e8-bf5a-3c49f994ff23"

Replace the retired Gitea endpoint and discovery language with Forgejo while preserving the established OpenBao path, field, and least-privilege boundary. This delivers the npm facet of routed intake 01a06e07-f2f9-7586-9745-b359eb0025b6; its inter-hub SSH facet remains separate.

Completed 2026-09-04. The catalog title, discovery keywords, rotation guidance, and worker playbook now name the canonical Forgejo registry at https://forgejo.coulomb.social/api/packages/coulomb/npm/. The OpenBao path, field, owner, native-exec pointer, and high-risk boundary are unchanged. A regression assertion prevents the retired Gitea discovery term and guidance from returning.

Prove routing and publication

id: WARDEN-WP-0037-T03
status: wait
priority: high
needs_human: true
intervention_note: "Rotate the dedicated Forgejo package token, then prove a fresh publish and exact npm view through this lane."
state_hub_task_id: "a8b1b855-ab34-5835-b9fd-5f48bc0b6817"

Pass catalog and routing tests, verify the checkout route, and record the exact Forgejo package release proven through the lane.

2026-09-04: repo-local verification is complete: the checkout route ranks whynot-design-npm-publish first for a Forgejo npm publish need, reports the canonical Forgejo title and verification command, all focused routing/access/proxy tests pass (145 passed).

The sibling repo's @whynot/design@0.4.2 release (105 files; IR designVersion 0.4.2; five visual tests pass) was published through the plan-authorized forgejo-admin-api-token one-time recovery lane. An authenticated exact-version lookup proved that Forgejo's remote integrity matches the local dry-run. T03 waits only on rotating the dedicated package token and proving the next fresh version through whynot-design-npm-publish; the package migration itself is complete.

2026-09-09 — field claim corrected, path routed. secrets-engine (msg 15f0c0ca) corrected two things and declined a third, all correctly.

The KV field is npm_token. NPM_AUTH_TOKEN is the environment variable their publication-scope policy injects, and ops-warden had copied the env var in as the field name — so the catalog's fetch_command named a field that does not exist and could only ever have failed. Corrected in registry/routing/catalog.yaml and wiki/playbooks/whynot-design-npm-publish.md from the owner's statement rather than re-derived here. This was ADR-0001's failure mode rather than a typo: a pointer layer restating an owner's procedure and getting a detail wrong.

The endpoint claim already agreed; delivery_config.npm.registry has been the Forgejo URL throughout.

The path is routed to railiance-platform and the catalog is unchanged pending their answer. Which location backs the lane for reads is custody state they own; secrets-engine has no lane read authority to confirm it and refused to rewrite a production lane pointer from a coordination message (SECRETS-WP-0006-T06). Their reasoning is right, and asserting our own pointer is authoritative because it is ours would route around it. The ask names a location only and flags that a bao kv get answer would be the 2026-07-16 disclosure vector on a risk: high lane.

ready: false is not being read as path evidence: a source checkout with no production authority reports not-ready regardless of which path the catalog names.

T03 still waits on the human rotation of the dedicated Forgejo package token; the path question does not block that, it determines whether the pointer is correct once it rotates.