[bug] hero_osis bin codegen regressed #41 — silent X-Hero-Context fallback to root is back #42

Closed
opened 2026-04-30 19:34:20 +00:00 by mik-tf · 1 comment
Owner

Symptom

Hero OS shell's Contexts island shows the same context (named "Root") repeated for every registered context, instead of the actual distinct names (root, default, geomind, incubaid, threefold, …). All per-context API calls silently return data from the root context.

Live on herodemo as of 2026-04-30:

$ for ctx in default geomind threefold incubaid root; do
    curl --unix-socket .../hero_osis_base/rpc.sock \
      -H "X-Hero-Context: $ctx" \
      -d '{"jsonrpc":"2.0","method":"base.configuration.list","params":{}}'
  done
ctx=default    -> "result":"s001\n0002"
ctx=geomind    -> "result":"s001\n0002"  ← same
ctx=threefold  -> "result":"s001\n0002"  ← same
ctx=incubaid   -> "result":"s001\n0002"  ← same
ctx=root       -> "result":"s001\n0002"

All 5 distinct headers return the SAME root-context data. Every per-context query is silently falling back to root.

This is a regression of #41

Issue #41 ("fix(server): register MOCK_CONTEXTS by default to prevent silent X-Hero-Context fallback to root") was closed by commit 7807258 on crates/hero_osis_server/src/bin/hero_osis.rs. That commit expanded cli.contexts from the upstream default of "root" to the canonical demo list when no explicit --contexts / HERO_CONTEXTS was passed.

Since then, crates/hero_osis_server/src/bin/hero_osis.rs has been converted to an auto-generated file (the per-domain single-binary refactor). Its current header literally says:

//! Auto-generated single-binary orchestrator for `hero_osis`.
//! ...
//! DO NOT EDIT — regenerate via `cargo build` after schema or build.rs changes.

The codegen template that produces this file does not include the MOCK_CONTEXTS expansion. So #41's fix has been silently undone by regeneration.

Confirmation in the running binary

$ pgrep -af hero_osis
13093 /home/driver/hero/bin/hero_osis           ← no flags
$ cat /proc/13093/cmdline
/home/driver/hero/bin/hero_osis
$ cat /proc/13093/environ | grep CONTEXT
(no HERO_CONTEXTS set)

So cli.contexts falls back to its upstream ServerCli default of "root" and the dispatcher only registers a single context. Per the dispatcher's pre-#41 behaviour (also documented in #41's body), unknown X-Hero-Context: … values silently fall back to the lone registered root context.

Why launcher-side workaround isn't enough

We can mitigate operationally by:

hero_proc action env hero_osis --set HERO_CONTEXTS=root,default,geomind,incubaid,threefold
hero_proc service restart hero_osis

…but that only fixes this specific deploy. Tests, fresh installs, and other deployments still get the silent-fallback footgun. #41's original argument (running hero_osis --start should be sane out of the box) still applies. The right fix is in the codegen template so the canonical default ships with every regenerated bin.

Acceptance criteria

  • Codegen template (build.rs or wherever the generator emits hero_osis.rs) expanded so that when cli.contexts == "root" (the upstream ServerCli default), it auto-expands to the canonical context list — same logic as #41's 7807258.
  • Explicit --contexts <list> / HERO_CONTEXTS env var overrides untouched.
  • Regenerate the bin (cargo build), verify crates/hero_osis_server/src/bin/hero_osis.rs contains the expansion in its prelude.
  • On a fresh deploy following the runbook, browser shows distinct context names in the Contexts island (geomind / threefold / incubaid / default / root) — not 5× "Root".
  • Add a unit/integration test that asserts: with no --contexts passed, the running server has more than one context registered.

Cross-references

  • Closes [#41 regression] — i.e. re-applies the spirit of #41 at the durable layer
  • Discovered live on herodemo 2026-04-30 during seed-data investigation
  • Operational immediate fix tracked in hero_demo#46 (op restore)
  • Architectural lesson worth filing as a separate convention: any manual edit to a // DO NOT EDIT — auto-generated file MUST instead be applied at the generator layer, otherwise next regen drops it.

Signed-off-by: mik-tf

## Symptom Hero OS shell's Contexts island shows the same context (named "Root") repeated for every registered context, instead of the actual distinct names (root, default, geomind, incubaid, threefold, …). All per-context API calls silently return data from the root context. Live on herodemo as of 2026-04-30: ``` $ for ctx in default geomind threefold incubaid root; do curl --unix-socket .../hero_osis_base/rpc.sock \ -H "X-Hero-Context: $ctx" \ -d '{"jsonrpc":"2.0","method":"base.configuration.list","params":{}}' done ctx=default -> "result":"s001\n0002" ctx=geomind -> "result":"s001\n0002" ← same ctx=threefold -> "result":"s001\n0002" ← same ctx=incubaid -> "result":"s001\n0002" ← same ctx=root -> "result":"s001\n0002" ``` All 5 distinct headers return the SAME root-context data. Every per-context query is silently falling back to root. ## This is a regression of #41 Issue [#41](https://forge.ourworld.tf/lhumina_code/hero_osis/issues/41) ("fix(server): register MOCK_CONTEXTS by default to prevent silent X-Hero-Context fallback to root") was closed by commit [`7807258`](https://forge.ourworld.tf/lhumina_code/hero_osis/commit/7807258) on `crates/hero_osis_server/src/bin/hero_osis.rs`. That commit expanded `cli.contexts` from the upstream default of `"root"` to the canonical demo list when no explicit `--contexts` / `HERO_CONTEXTS` was passed. Since then, `crates/hero_osis_server/src/bin/hero_osis.rs` has been **converted to an auto-generated file** (the per-domain single-binary refactor). Its current header literally says: ```rust //! Auto-generated single-binary orchestrator for `hero_osis`. //! ... //! DO NOT EDIT — regenerate via `cargo build` after schema or build.rs changes. ``` The codegen template that produces this file does **not** include the MOCK_CONTEXTS expansion. So #41's fix has been silently undone by regeneration. ## Confirmation in the running binary ```bash $ pgrep -af hero_osis 13093 /home/driver/hero/bin/hero_osis ← no flags $ cat /proc/13093/cmdline /home/driver/hero/bin/hero_osis $ cat /proc/13093/environ | grep CONTEXT (no HERO_CONTEXTS set) ``` So `cli.contexts` falls back to its upstream `ServerCli` default of `"root"` and the dispatcher only registers a single context. Per the dispatcher's pre-#41 behaviour (also documented in #41's body), unknown `X-Hero-Context: …` values silently fall back to the lone registered `root` context. ## Why launcher-side workaround isn't enough We can mitigate operationally by: ```bash hero_proc action env hero_osis --set HERO_CONTEXTS=root,default,geomind,incubaid,threefold hero_proc service restart hero_osis ``` …but that only fixes this specific deploy. Tests, fresh installs, and other deployments still get the silent-fallback footgun. #41's original argument (running `hero_osis --start` should be sane out of the box) still applies. The **right** fix is in the codegen template so the canonical default ships with every regenerated bin. ## Acceptance criteria - [ ] Codegen template (`build.rs` or wherever the generator emits `hero_osis.rs`) expanded so that when `cli.contexts == "root"` (the upstream `ServerCli` default), it auto-expands to the canonical context list — same logic as #41's `7807258`. - [ ] Explicit `--contexts <list>` / `HERO_CONTEXTS` env var overrides untouched. - [ ] Regenerate the bin (`cargo build`), verify `crates/hero_osis_server/src/bin/hero_osis.rs` contains the expansion in its prelude. - [ ] On a fresh deploy following the runbook, browser shows distinct context names in the Contexts island (geomind / threefold / incubaid / default / root) — not 5× "Root". - [ ] Add a unit/integration test that asserts: with no `--contexts` passed, the running server has more than one context registered. ## Cross-references - Closes [#41 regression] — i.e. re-applies the spirit of #41 at the durable layer - Discovered live on herodemo 2026-04-30 during seed-data investigation - Operational immediate fix tracked in hero_demo#46 (op restore) - Architectural lesson worth filing as a separate convention: any manual edit to a `// DO NOT EDIT — auto-generated` file MUST instead be applied at the generator layer, otherwise next regen drops it. Signed-off-by: mik-tf
Author
Owner

After discussion, taking a different approach than the codegen template fix proposed in the issue body.

What we considered: lift the MOCK_CONTEXTS expansion into the codegen template (or via a new OschemaBuildConfig::contexts_default(...) builder method, hero_rpc#36) so every regenerated hero_osis.rs ships with the canonical demo list as its --contexts default.

Why we backed off: that approach hardcodes deployment-specific data (geomind, incubaid, threefold, ...) into shared infrastructure source code. Every other hero_osis consumer would inherit the demo's identity. Adding a new context still requires a rebuild + redeploy. It's a more durable place for the workaround, but it's not architecture — it's contamination.

What we're doing instead:

  1. HERO_CONTEXTS env var is the official deploy knob, required, documented in hero_demo/docs/ops/DEPLOYMENT.md §0.x and §4.4. Each deployment carries its own list in its env overlay; hero_osis source stays clean of any deploy-specific names.
  2. The wiring already works — hero_skills/tools/modules/services/service_osis.nu forwards HERO_CONTEXTS from the operator's env into the hero_proc action env.
  3. A verification step in §8 that catches regression: per-context queries must return distinct responses for distinct headers; same response 5× means hero_osis registered only root (the structural bug).

Closing this issue. The structural fix — contexts as data in OSIS storage, loaded at boot from a registry instead of from CLI default, with strict (no-silent-fallback) dispatcher resolution — is tracked in #43. That's where this should land properly.

hero_rpc#36 (the codegen API gap) is also being dropped — adding API surface that we just argued shouldn't be used is noise.

Signed-off-by: mik-tf

After discussion, taking a different approach than the codegen template fix proposed in the issue body. **What we considered**: lift the MOCK_CONTEXTS expansion into the codegen template (or via a new `OschemaBuildConfig::contexts_default(...)` builder method, hero_rpc#36) so every regenerated `hero_osis.rs` ships with the canonical demo list as its `--contexts` default. **Why we backed off**: that approach hardcodes deployment-specific data (`geomind`, `incubaid`, `threefold`, ...) into shared infrastructure source code. Every other hero_osis consumer would inherit the demo's identity. Adding a new context still requires a rebuild + redeploy. It's a more durable place for the workaround, but it's not architecture — it's contamination. **What we're doing instead**: 1. `HERO_CONTEXTS` env var is the official deploy knob, **required**, documented in `hero_demo/docs/ops/DEPLOYMENT.md` §0.x and §4.4. Each deployment carries its own list in its env overlay; `hero_osis` source stays clean of any deploy-specific names. 2. The wiring already works — `hero_skills/tools/modules/services/service_osis.nu` forwards `HERO_CONTEXTS` from the operator's env into the hero_proc action env. 3. A verification step in §8 that catches regression: per-context queries must return *distinct* responses for distinct headers; same response 5× means hero_osis registered only `root` (the structural bug). **Closing this issue.** The structural fix — contexts as data in OSIS storage, loaded at boot from a registry instead of from CLI default, with strict (no-silent-fallback) dispatcher resolution — is tracked in https://forge.ourworld.tf/lhumina_code/hero_osis/issues/43. That's where this should land properly. hero_rpc#36 (the codegen API gap) is also being dropped — adding API surface that we just argued shouldn't be used is noise. Signed-off-by: mik-tf
Sign in to join this conversation.
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/hero_osis#42
No description provided.