Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306
4.3 KiB
whynot-design real publish closeout
This runbook is the SECRETS-WP-0003 closeout path for turning the
whynot-design-npm-publish pilot from a dry-run/demo lane into a real production
@whynot/design publish through secrets-engine exec.
No raw npm token, OpenBao token, token accessor, NPM_AUTH_TOKEN, package-token
value, or private credential material may be written to Git, State Hub, chat,
prompts, workplans, or normal logs.
Current non-secret pointers
| Pointer | Value |
|---|---|
| Catalog id | whynot-design-npm-publish |
| Canonical decision | e6381a56-6b04-4fd5-b2de-f3ef59cde888 |
| Org/repo | coulomb/whynot-design |
| npm package | @whynot/design |
| npm registry | https://forgejo.coulomb.social/api/packages/coulomb/npm/ |
| Catalog mount/path | secret/coulomb/whynot-design/npm/publish |
| Catalog field | npm_token |
| Injected env var | NPM_AUTH_TOKEN |
The decision UUID above is resolved from State Hub in normal operation. A UUID-named local fixture exists only as an offline fallback for throwaway demos.
Source-side preflight
From this repo, with State Hub reachable:
scripts/whynot-real-publish-preflight.sh
Expected source-side result:
decision inspect e6381a56-6b04-4fd5-b2de-f3ef59cde888showssource: hubandAPPROVED;policy publication whynot-design-npm-publishresolves to the repo-clampedNPM_AUTH_TOKENpath while netkingdom remainsmaturity-build;route whynot-design-npm-publish --jsonreturns a pointer only. If OpenBao is not reachable or the value is not provisioned,ready=falseis acceptable and must be handled by the operator steps below.
Operator live gates
- Create or confirm a dedicated Gitea bot account such as
se-whynot-design. Record only non-secret evidence: username, owning org/repo, package scope, creation timestamp, and who confirmed it. - Confirm the bot can publish
@whynot/designto the coulomb registry and cannot publish outside the intended org/scope. Record only pass/fail and package names. - Mint the Gitea npm/package token for that bot and place it in a mode-0600 file outside any Git worktree. Do not print the value.
- Apply/provision through secrets-engine using approved OpenBao authority:
BAO_ADDR=https://bao.coulomb.social \
secrets-engine apply whynot-design-npm-publish --stage prod \
--bootstrap-token-file ~/.secrets-engine/bootstrap/prod-whynot-design.token
BAO_ADDR=https://bao.coulomb.social \
secrets-engine provision whynot-design-npm-publish --stage prod \
--field npm_token \
--from-file ~/.secrets-engine/handoff/whynot-design-npm.token \
--bootstrap-token-file ~/.secrets-engine/bootstrap/prod-whynot-design.token
- Verify without disclosing the value:
BAO_ADDR=https://bao.coulomb.social \
secrets-engine verify whynot-design-npm-publish \
--field npm_token --positive --negative \
--negative-token-file /secure/path/reviewed-unrelated.token \
--bootstrap-token-file ~/.secrets-engine/bootstrap/prod-whynot-design.token
The unrelated token must represent a reviewed identity outside the lane policy; it is not the bootstrap token and must be held in a separate mode-0600 file outside Git.
- In the
whynot-designrepo, coordinate a real version bump. Run the publish through child-only injection:
BAO_ADDR=https://bao.coulomb.social \
secrets-engine exec --catalog whynot-design-npm-publish -- npm publish
- Confirm the published version appears in the coulomb Gitea npm registry. Record package name, version, registry URL, timestamp, and result only.
ops-warden handoff
ops-warden should route npm publish credential requests here and return a pointer, not a value:
secrets-engine route whynot-design-npm-publish --json
Safe pointer payload:
{
"catalog_id": "whynot-design-npm-publish",
"kind": "kv",
"decision_ref": "e6381a56-6b04-4fd5-b2de-f3ef59cde888",
"owner": "coulomb/whynot-design",
"stage": "prod",
"next_command": "secrets-engine exec --catalog whynot-design-npm-publish -- npm publish"
}
Revocation and cleanup
Track the OpenBao bootstrap token and the Gitea bot package token in
hardening-backlog.md. After publish verification, remove
any handoff/source token files with shred -u and revoke or rotate the Gitea bot
token according to the recorded lifecycle task.