fix(server): register MOCK_CONTEXTS by default to prevent silent X-Hero-Context fallback to root #41

Merged
rawdaGastan merged 1 commit from development_default_context_register into development 2026-04-30 12:03:34 +00:00
Member

Summary

When hero_osis --start runs through hero_proc, the upstream ServerCli::contexts defaults to "root" and the binary registers only that one context. The hero_os UI shell sends X-Hero-Context: default (and other space names like geomind, incubaid, …); those names are not in the registered set, so the dispatcher in hero_rpc::server::unified_server silently falls back to "root" and every UI tab reads/writes the same store regardless of which space it's in.

This change overrides the contexts default in the hero_osis bin to the same MOCK_CONTEXTS list the workspace Makefile already uses for make mock, so production (hero_osis --start) and dev (make mock) cover the same set out of the box. An explicit --contexts flag or HERO_CONTEXTS env var continues to take precedence.

Closes #40

Changes

  • crates/hero_osis_server/src/bin/hero_osis.rs — when cli.contexts equals the upstream ServerCli default of "root", expand it to "root,default,geomind,incubaid,my_context,our_context,threefold,your_context,hero_osis". Explicit overrides untouched.

Test Results

  • cargo check --no-default-features --features all-domains — clean.
  • cargo test --lib --no-default-features --features all-domains — 113 passed, 0 failed.
  • End-to-end against running stack: stopped, reinstalled, restarted, ran conversation.list against ~/hero/var/sockets/hero_osis_communication/rpc.sock with each context in turn:
root            -> {"jsonrpc":"2.0","result":"0002","id":1}   (legacy data from prior silent-fallback)
default         -> {"jsonrpc":"2.0","result":"","id":1}
geomind         -> {"jsonrpc":"2.0","result":"","id":1}
incubaid        -> {"jsonrpc":"2.0","result":"","id":1}
my_context      -> {"jsonrpc":"2.0","result":"","id":1}
our_context     -> {"jsonrpc":"2.0","result":"","id":1}
threefold       -> {"jsonrpc":"2.0","result":"","id":1}
your_context    -> {"jsonrpc":"2.0","result":"","id":1}
hero_osis       -> {"jsonrpc":"2.0","result":"","id":1}
bob             -> {"jsonrpc":"2.0","result":"0002","id":1}   (unregistered name, still falls back — out of scope)

Every registered context returns isolated data. The bob case (unregistered name → fallback to root) is the deeper dispatcher-level silent fallback, tracked separately at hero_rpc#36.

Caveats

  • bin/hero_osis.rs is auto-generated by hero_rpc_osis::build. A future schema change or clean build that re-emits the bin will wipe this in-file patch. The proper upstream fix is to add a contexts_default(...) setter on OschemaBuildConfig so the generator emits this default itself — tracked at lhumina_code/hero_rpc#36. This PR is the temporary workaround until that lands.
  • Migration note for any local dev whose data accumulated under the silent-fallback bug: that data still lives in ~/hero/var/osisdb/root/. After this fix, the UI's default requests start hitting an empty ~/hero/var/osisdb/default/ store. Nothing is deleted; users who want the old data under default can copy it manually. Production isn't affected (no production deployments per the no-auth state of the project).

Out-of-scope follow-ups

  • hero_rpc#36 — OschemaBuildConfig::contexts_default(...) setter (proper upstream fix; supersedes this PR once landed).
  • Silent fallback to root for any unregistered context name in hero_rpc::server::unified_server::dispatch_rpc — should either return an error, auto-register, or at minimum log a warning. Worth filing separately against hero_rpc.
  • OServer::registry-backed context.list admin RPC currently still only enumerates root even though per-(context, domain) data stores are isolated — cosmetic, also belongs in hero_rpc.
## Summary When `hero_osis --start` runs through `hero_proc`, the upstream `ServerCli::contexts` defaults to `"root"` and the binary registers only that one context. The hero_os UI shell sends `X-Hero-Context: default` (and other space names like `geomind`, `incubaid`, …); those names are not in the registered set, so the dispatcher in `hero_rpc::server::unified_server` silently falls back to `"root"` and every UI tab reads/writes the same store regardless of which space it's in. This change overrides the contexts default in the hero_osis bin to the same `MOCK_CONTEXTS` list the workspace `Makefile` already uses for `make mock`, so production (`hero_osis --start`) and dev (`make mock`) cover the same set out of the box. An explicit `--contexts` flag or `HERO_CONTEXTS` env var continues to take precedence. ## Related Issue Closes https://forge.ourworld.tf/lhumina_code/hero_osis/issues/40 ## Changes - `crates/hero_osis_server/src/bin/hero_osis.rs` — when `cli.contexts` equals the upstream `ServerCli` default of `"root"`, expand it to `"root,default,geomind,incubaid,my_context,our_context,threefold,your_context,hero_osis"`. Explicit overrides untouched. ## Test Results - `cargo check --no-default-features --features all-domains` — clean. - `cargo test --lib --no-default-features --features all-domains` — 113 passed, 0 failed. - End-to-end against running stack: stopped, reinstalled, restarted, ran `conversation.list` against `~/hero/var/sockets/hero_osis_communication/rpc.sock` with each context in turn: ``` root -> {"jsonrpc":"2.0","result":"0002","id":1} (legacy data from prior silent-fallback) default -> {"jsonrpc":"2.0","result":"","id":1} geomind -> {"jsonrpc":"2.0","result":"","id":1} incubaid -> {"jsonrpc":"2.0","result":"","id":1} my_context -> {"jsonrpc":"2.0","result":"","id":1} our_context -> {"jsonrpc":"2.0","result":"","id":1} threefold -> {"jsonrpc":"2.0","result":"","id":1} your_context -> {"jsonrpc":"2.0","result":"","id":1} hero_osis -> {"jsonrpc":"2.0","result":"","id":1} bob -> {"jsonrpc":"2.0","result":"0002","id":1} (unregistered name, still falls back — out of scope) ``` Every registered context returns isolated data. The `bob` case (unregistered name → fallback to root) is the deeper dispatcher-level silent fallback, tracked separately at hero_rpc#36. ## Caveats - **`bin/hero_osis.rs` is auto-generated** by `hero_rpc_osis::build`. A future schema change or clean build that re-emits the bin will wipe this in-file patch. The proper upstream fix is to add a `contexts_default(...)` setter on `OschemaBuildConfig` so the generator emits this default itself — tracked at https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/36. This PR is the temporary workaround until that lands. - **Migration note** for any local dev whose data accumulated under the silent-fallback bug: that data still lives in `~/hero/var/osisdb/root/`. After this fix, the UI's `default` requests start hitting an empty `~/hero/var/osisdb/default/` store. Nothing is deleted; users who want the old data under `default` can copy it manually. Production isn't affected (no production deployments per the no-auth state of the project). ## Out-of-scope follow-ups - hero_rpc#36 — `OschemaBuildConfig::contexts_default(...)` setter (proper upstream fix; supersedes this PR once landed). - Silent fallback to `root` for any unregistered context name in `hero_rpc::server::unified_server::dispatch_rpc` — should either return an error, auto-register, or at minimum log a warning. Worth filing separately against hero_rpc. - `OServer::registry`-backed `context.list` admin RPC currently still only enumerates `root` even though per-`(context, domain)` data stores are isolated — cosmetic, also belongs in hero_rpc.
fix(server): register MOCK_CONTEXTS by default to prevent silent X-Hero-Context fallback to root
All checks were successful
Build Linux / build-linux (linux-amd64-musl, false, x86_64-unknown-linux-musl) (push) Successful in 3m0s
Build and Test / build (push) Successful in 4m58s
Build Linux / build-linux (linux-amd64-musl, false, x86_64-unknown-linux-musl) (pull_request) Successful in 5m14s
Build and Test / build (pull_request) Successful in 7m2s
7807258480
The hero_os UI shell sends X-Hero-Context names like `default`,
`geomind`, `incubaid` etc. that are not registered when hero_osis is
launched via `hero_osis --start` (which uses the upstream ServerCli
`root`-only default). The dispatcher in
hero_rpc::server::unified_server silently falls back to `root`,
collapsing every space into the same store.

When the user has not set --contexts or HERO_CONTEXTS explicitly,
expand the default to the same MOCK_CONTEXTS list the workspace
Makefile already uses for `make mock`. Explicit overrides remain
authoritative.

Note: bin/hero_osis.rs is auto-generated by hero_rpc_osis::build, so
this in-file patch is the workaround until hero_rpc#36 lands a
contexts_default(...) setter on OschemaBuildConfig.

#40
rawdaGastan merged commit 41892cccab into development 2026-04-30 12:03:34 +00:00
rawdaGastan deleted branch development_default_context_register 2026-04-30 12:03:40 +00:00
Sign in to join this conversation.
No reviewers
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!41
No description provided.