[arch] hero_osis: contexts as data, strict resolution, drop auto-generated single-bin #43
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_osis#43
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Premise
Two recurring bugs and one sister issue (#41, #42, lhumina_code/home#203) all trace back to the same architectural choice: the canonical context list lives as a hardcoded CLI default in a binary that is itself auto-generated.
This issue is the architecture review — the durable fix that would make all three sister issues moot.
What's wrong with the current shape
Contexts are data, but live as config
The list
root,default,geomind,incubaid,threefold,…describes the actual state of the demo. It is data — populated by the seed step, persisted in OSIS storage, queried by the UI. But the dispatcher learns about the same names from thecli.contextsCLI string default, baked into the binary at compile time. So:--contextsflag silently registers the wrong set.X-Hero-Contextheaders fall back to root instead of returning a clear error.The dispatcher silently falls back to root
Even if
cli.contextswere correct, the per-context routing layer accepts unknown headers and quietly serves them from root. This is the actual bug behind #41 — MOCK_CONTEXTS expansion only papers over it. The real fix is: unknown context → 400 Bad Request, with a clear message listing valid contexts. Silent fallback is the security-and-correctness footgun, not the missing default list.The per-domain bin is string-pasted Rust code
crates/hero_osis_server/src/bin/hero_osis.rsis auto-generated bybuild.rsfrom per-domain crates. The header literally says "DO NOT EDIT — regenerate via cargo build." Every fix to that file is a time bomb against the next regen (lhumina_code/home#203). String-pasted code generation is also harder to debug, harder to grep, and bypasses the type checker for the seam.Proposal
Three changes, separable but related:
1. Contexts as data
Boot path:
~/hero/var/hero_osis/contexts.toml, or viaosis.contexts.listRPC against thebasedomain).osis.contexts.create) or seed step, not by editing CLI defaults.cli.contextsflag is removed or repurposed as a development override only.2. Strict context resolution
X-Hero-Context: <unknown>→ 400 Bad Request (or 404 if we want to be HTTP-purist about it). Body lists valid contexts.3. Real workspace composition, not codegen
register_handlers(server: &mut OServer)function.register_handlers. Standard Rust, no codegen, type-checked, greppable.build.rsmay still emit data (e.g., a generated registry list, OpenRPC spec) — but never code that is the entry point.Each of the three is independently shippable:
Why this is "long-term," not coping
Once shipped:
Acceptance
X-Hero-Contextreturns 400 (or 404) with explicit error body. Tested.crates/hero_osis_server/src/bin/hero_osis.rsbecomes a hand-written file imported from per-domain crates. The "DO NOT EDIT" header is gone. Diff is reviewable in PR.Cross-references
Signed-off-by: mik-tf
contexts_default(...)setter so single-bin codegen can override theServerCliroot-only default #36Source location confirmed (session 52)
The line behind the silent context fallback is in
crates/hero_osis_server/src/server/unified_server.rs:591-608:Unknown context names degrade silently to
"root"rather than returning HTTP 400.For the strict-resolution implementation, replace
unwrap_or_elsewith an explicit registry lookup against the configuredHERO_CONTEXTSlist (per D-01) that returns400 Bad Request(or 404) on unknown context name and propagates the error up. This also closes the silent-fallback variant of hero_osis#42.Spotted during the docs_hero Phase 1 source-grounded read; reconciliation memo
memory/investigation_roadmap_reconciliation.md(session 52).sourcedirectives — env.sh exports silently lost across all service deploys #191