[refactor] hero_skills consumers (lib.nu + service_*.nu) should read secrets from hero_proc, not $env #222

Open
opened 2026-05-06 21:10:26 +00:00 by mik-tf · 0 comments
Owner

Context

Session 68 (2026-05-06, hero_office Bucket C item 4 of #212) surfaced an architectural mismatch in the install-side helpers.

hero_office is the only private non-archived repo in lhumina_code/, so its release assets 404 anonymously. To unblock service office install --download --reset on heroci, lhumina_code/hero_skills#225 (c28ba16) wired svc_forge_auth_args in nutools/modules/services/lib.nu to read $env.FORGEJO_TOKEN and forward it as Authorization: token … on the metadata + asset-download curl calls. It works mechanically — heroci smoke green — but the read happens at the wrong layer.

Why this is wrong

Per the hero_proc_secrets and hero_proc_meta skills:

  • hero_proc owns a built-in secret store with create/get/list/delete RPC, context-namespaced.
  • Every Hero process reads its config exclusively from hero_proc secrets, never from OS env or config files. That is the META rule.
  • Operators set/rotate/inspect secrets via hero_proc secret …, not via ~/.bashrc or one-shot SSH export FOO=….

The c28ba16 fix pushes the token requirement onto the operator's shell env, which is exactly what the secret store exists to eliminate. Next operator on a fresh deploy will hit failed to query latest release until someone tells them to export the token.

Same defect shape exists across service_*.nu env forwarders — e.g. service_office.nu reads ONLYOFFICE_JWT_SECRET, CONNECTOR_EXTERNAL_URL, DEFAULT_CONTEXT, OO_UPSTREAM_BASE, HERO_SOCKET_DIR from $env, then upserts them into the action env record passed to proc action set. That bridges OS env → hero_proc action env, but still treats OS env as the source of truth.

Scope

  1. lib.nu helperssvc_forge_auth_args (added c28ba16): replace the $env.FORGEJO_TOKEN read with proc secret get FORGEJO_TOKEN (using the existing clients/proc.nu SDK already imported in every service_*.nu). Keep $env.FORGEJO_TOKEN as a documented fallback during the transition, with a deprecation note in the error hint.
  2. All service_*.nu env-forwarder blocks — every place that does ($env | get -o FOO | default "") and then upserts into the action env record. Audit list (non-exhaustive, sample from one pass):
    • service_office.nu: ONLYOFFICE_JWT_SECRET, CONNECTOR_EXTERNAL_URL, DEFAULT_CONTEXT, OO_UPSTREAM_BASE, HERO_SOCKET_DIR
    • other services likely have similar blocks for service-specific tokens / external URLs / context names — full inventory done as the first task of this issue
  3. Deploy hosts (heroci, herodemo) — once the consumers read from hero_proc secrets, seed each secret once via hero_proc secret set on each host. Document the canonical secret list (FORGEJO_TOKEN, ONLYOFFICE_JWT_SECRET, …) somewhere stable — likely hero_demo/docs/ops/DEPLOYMENT.md and/or a hero_skills README.
  4. CLI ergonomicsproc secret set FORGEJO_TOKEN <value> should be the only operator step on a fresh host before any private-repo --download works. No more inline export … SSH dances.

Sequencing

After the home#212 binary rollout completes (currently 22/29 = 76% as of session 68 close). Explicitly: finish Bucket C (4 remaining repos: planner, logic, mail, after office) and Bucket D (compute, ledger, sync, tfspores). Then this becomes the next architectural arc.

Reason for the ordering: more private repos may surface in Bucket D, and the per-host export FORGEJO_TOKEN=… workaround is acceptable as a one-line operator step for a small number of repos. Once binary-rollout is done, this refactor consolidates the env-source convention org-wide rather than fixing it piecewise per repo.

Acceptance criteria

  • Every svc_* helper in lib.nu reads config-shaped values via proc secret get, not $env.
  • Every service_*.nu env-forwarder block reads from proc secret get, with $env removed (or kept as a documented transition fallback with a single-release deprecation window).
  • heroci + herodemo have all required secrets seeded via hero_proc secret set; documented in the deployment runbook.
  • service office install --download --reset works on a fresh host with only hero_proc secret set FORGEJO_TOKEN <value> as the operator-side prep — no ~/.bashrc edits, no inline SSH exports.
  • Memory entry project_hero_office_private_repo.md updated to reflect the secret-store-based contract.

References

## Context Session 68 (2026-05-06, hero_office Bucket C item 4 of https://forge.ourworld.tf/lhumina_code/home/issues/212) surfaced an architectural mismatch in the install-side helpers. `hero_office` is the only private non-archived repo in `lhumina_code/`, so its release assets 404 anonymously. To unblock `service office install --download --reset` on heroci, https://forge.ourworld.tf/lhumina_code/hero_skills/pulls/225 (`c28ba16`) wired `svc_forge_auth_args` in `nutools/modules/services/lib.nu` to read `$env.FORGEJO_TOKEN` and forward it as `Authorization: token …` on the metadata + asset-download curl calls. It works mechanically — heroci smoke green — but the read happens at the wrong layer. ## Why this is wrong Per the `hero_proc_secrets` and `hero_proc_meta` skills: - hero_proc owns a built-in secret store with create/get/list/delete RPC, context-namespaced. - **Every Hero process reads its config exclusively from hero_proc secrets, never from OS env or config files.** That is the META rule. - Operators set/rotate/inspect secrets via `hero_proc secret …`, not via `~/.bashrc` or one-shot SSH `export FOO=…`. The `c28ba16` fix pushes the token requirement onto the operator's shell env, which is exactly what the secret store exists to eliminate. Next operator on a fresh deploy will hit `failed to query latest release` until someone tells them to export the token. Same defect shape exists across `service_*.nu` env forwarders — e.g. `service_office.nu` reads `ONLYOFFICE_JWT_SECRET`, `CONNECTOR_EXTERNAL_URL`, `DEFAULT_CONTEXT`, `OO_UPSTREAM_BASE`, `HERO_SOCKET_DIR` from `$env`, then upserts them into the action env record passed to `proc action set`. That bridges OS env → hero_proc action env, but still treats OS env as the source of truth. ## Scope 1. **`lib.nu` helpers** — `svc_forge_auth_args` (added c28ba16): replace the `$env.FORGEJO_TOKEN` read with `proc secret get FORGEJO_TOKEN` (using the existing `clients/proc.nu` SDK already imported in every `service_*.nu`). Keep `$env.FORGEJO_TOKEN` as a documented fallback during the transition, with a deprecation note in the error hint. 2. **All `service_*.nu` env-forwarder blocks** — every place that does `($env | get -o FOO | default "")` and then upserts into the action env record. Audit list (non-exhaustive, sample from one pass): - `service_office.nu`: `ONLYOFFICE_JWT_SECRET`, `CONNECTOR_EXTERNAL_URL`, `DEFAULT_CONTEXT`, `OO_UPSTREAM_BASE`, `HERO_SOCKET_DIR` - other services likely have similar blocks for service-specific tokens / external URLs / context names — full inventory done as the first task of this issue 3. **Deploy hosts (heroci, herodemo)** — once the consumers read from hero_proc secrets, seed each secret once via `hero_proc secret set` on each host. Document the canonical secret list (`FORGEJO_TOKEN`, `ONLYOFFICE_JWT_SECRET`, …) somewhere stable — likely `hero_demo/docs/ops/DEPLOYMENT.md` and/or a `hero_skills` README. 4. **CLI ergonomics** — `proc secret set FORGEJO_TOKEN <value>` should be the only operator step on a fresh host before any private-repo `--download` works. No more inline `export …` SSH dances. ## Sequencing **After the home#212 binary rollout completes** (currently 22/29 = 76% as of session 68 close). Explicitly: finish Bucket C (4 remaining repos: planner, logic, mail, after office) and Bucket D (compute, ledger, sync, tfspores). Then this becomes the next architectural arc. Reason for the ordering: more private repos may surface in Bucket D, and the per-host `export FORGEJO_TOKEN=…` workaround is acceptable as a one-line operator step for a small number of repos. Once binary-rollout is done, this refactor consolidates the env-source convention org-wide rather than fixing it piecewise per repo. ## Acceptance criteria - [ ] Every `svc_*` helper in `lib.nu` reads config-shaped values via `proc secret get`, not `$env`. - [ ] Every `service_*.nu` env-forwarder block reads from `proc secret get`, with `$env` removed (or kept as a documented transition fallback with a single-release deprecation window). - [ ] heroci + herodemo have all required secrets seeded via `hero_proc secret set`; documented in the deployment runbook. - [ ] `service office install --download --reset` works on a fresh host with only `hero_proc secret set FORGEJO_TOKEN <value>` as the operator-side prep — no `~/.bashrc` edits, no inline SSH exports. - [ ] Memory entry `project_hero_office_private_repo.md` updated to reflect the secret-store-based contract. ## References - https://forge.ourworld.tf/lhumina_code/hero_skills/pulls/225 — the env-based fix that this issue replaces - https://forge.ourworld.tf/lhumina_code/hero_skills/commit/c28ba16 — squash-merged commit - `~/.claude/skills/hero_proc_secrets/SKILL.md` — secret store API - `~/.claude/skills/hero_proc_meta/SKILL.md` — canonical META env-from-secrets rule
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#222
No description provided.