refactor(hero_biz_admin): purge BASE_PATH env var (home#230 phase 2.1 ref impl) #49

Merged
mik-tf merged 2 commits from development_mik_basepath_purge into development 2026-05-08 15:22:29 +00:00
Owner

Summary

Reference implementation for home#230 phase 2 BASE_PATH purge. Per the hero_web_prefix skill (line 38): "There is no BASE_PATH environment variable. The proxy is the only source of truth for the prefix." The X-Forwarded-Prefix header from hero_router is captured per-request by prefix_middleware into the REQUEST_PREFIX task-local; direct access (no header) yields "" so links stay bare.

Changes (commit 1 — 7c41389)

  • Drop pub base_path: String, field from AppState.
  • Drop std::env::var("BASE_PATH") read at web/server.rs:122 and the corresponding field in the AppState literal.
  • Rewrite effective_base_path() to drop its &AppState parameter and the state.base_path.clone() fallback; default to "".
  • Update all 166 call sites in web/handlers/mod.rs from effective_base_path(&state) to effective_base_path(). One handler (login_page) loses its now-unused State<Arc<AppState>> extractor.

Pre-flight verification

hero_router/src/server/routes.rs:

  • Lines 669+677 set ("X-Forwarded-Prefix", "/{service}/{webname}") for /<svc>/<webname>/... paths
  • Lines 1274+1281 set ("X-Forwarded-Prefix", "/{service}/rpc") for /<svc>/rpc/... paths

So the env-var path was dead-letter — the header is correctly injected on every routed request.

Companion changes

  • hero_skills #x — drop BASE_PATH from service_biz.nu env block (supersedes c0186425)
  • hero_demo 809a7e8 — drop BASE_PATH from services/hero_biz.toml
  • hero_router PR-D: not needed — the launch-time env-tuple injection lives only on unmerged feature branches (development_mik_service_manager_v2); origin/development of hero_router has no Rust-side BASE_PATH env injection.

Commit 2 — clippy debt clearance (40eaa41)

Pre-existing rust-1.95 lint debt from upstream toolchain bump (53a52a1). Bundled here so the workspace pre-merge gate (feedback_workspace_build_before_merge.md) passes:

  • search/fuzzy.rs:240: sort_bysort_by_key(|r| Reverse(r.score)) per unnecessary_sort_by
  • web/templates/mod.rs 6 sites: if total == 0 { 0 } else { (done * 100 / total) as u8 }(done * 100).checked_div(total).unwrap_or(0) as u8 per manual_checked_ops

Test plan

  • cargo fmt --check green
  • cargo clippy --workspace --all-targets -- -D warnings green
  • cargo build --workspace --release green (exit 0)
  • On herodemo: service_biz install --download --version v0.5.0-rc1 --reset + browser smoke at https://herodemo.gent01.grid.tf/hero_biz/admin/ — links should render with /hero_biz/admin/ prefix; direct UDS access via curl --unix-socket .../admin.sock http://localhost/c/threefold should render bare-rooted links.

Refs

  • home#230 phase 2.1 — alignment audit META
  • home#225 — META rule umbrella; this is the first concrete instance shipping
  • ~/.claude/skills/hero_web_prefix/SKILL.md line 38

Signed-off-by: mik-tf

## Summary Reference implementation for [home#230](https://forge.ourworld.tf/lhumina_code/home/issues/230) phase 2 BASE_PATH purge. Per the [`hero_web_prefix`](https://forge.ourworld.tf/lhumina_code/home/issues/230) skill (line 38): *"There is no `BASE_PATH` environment variable. The proxy is the only source of truth for the prefix."* The `X-Forwarded-Prefix` header from hero_router is captured per-request by `prefix_middleware` into the `REQUEST_PREFIX` task-local; direct access (no header) yields `""` so links stay bare. ## Changes (commit 1 — `7c41389`) - Drop `pub base_path: String,` field from `AppState`. - Drop `std::env::var("BASE_PATH")` read at `web/server.rs:122` and the corresponding field in the `AppState` literal. - Rewrite `effective_base_path()` to drop its `&AppState` parameter and the `state.base_path.clone()` fallback; default to `""`. - Update all 166 call sites in `web/handlers/mod.rs` from `effective_base_path(&state)` to `effective_base_path()`. One handler (`login_page`) loses its now-unused `State<Arc<AppState>>` extractor. ## Pre-flight verification [hero_router/src/server/routes.rs](https://forge.ourworld.tf/lhumina_code/hero_router/src/branch/development/crates/hero_router/src/server/routes.rs): - Lines 669+677 set `("X-Forwarded-Prefix", "/{service}/{webname}")` for `/<svc>/<webname>/...` paths - Lines 1274+1281 set `("X-Forwarded-Prefix", "/{service}/rpc")` for `/<svc>/rpc/...` paths So the env-var path was dead-letter — the header is correctly injected on every routed request. ## Companion changes - [hero_skills #x](https://forge.ourworld.tf/lhumina_code/hero_skills/) — drop `BASE_PATH` from `service_biz.nu` env block (supersedes [c0186425](https://forge.ourworld.tf/lhumina_code/hero_skills/commit/c018642550ed4077bf499ca566618c72814e50b6)) - [hero_demo 809a7e8](https://forge.ourworld.tf/lhumina_code/hero_demo/commit/809a7e8) — drop `BASE_PATH` from `services/hero_biz.toml` - hero_router PR-D: not needed — the launch-time env-tuple injection lives only on unmerged feature branches (`development_mik_service_manager_v2`); origin/development of hero_router has no Rust-side BASE_PATH env injection. ## Commit 2 — clippy debt clearance (`40eaa41`) Pre-existing rust-1.95 lint debt from upstream toolchain bump (`53a52a1`). Bundled here so the workspace pre-merge gate (`feedback_workspace_build_before_merge.md`) passes: - `search/fuzzy.rs:240`: `sort_by` → `sort_by_key(|r| Reverse(r.score))` per `unnecessary_sort_by` - `web/templates/mod.rs` 6 sites: `if total == 0 { 0 } else { (done * 100 / total) as u8 }` → `(done * 100).checked_div(total).unwrap_or(0) as u8` per `manual_checked_ops` ## Test plan - [x] `cargo fmt --check` green - [x] `cargo clippy --workspace --all-targets -- -D warnings` green - [x] `cargo build --workspace --release` green (exit 0) - [ ] On herodemo: `service_biz install --download --version v0.5.0-rc1 --reset` + browser smoke at `https://herodemo.gent01.grid.tf/hero_biz/admin/` — links should render with `/hero_biz/admin/` prefix; direct UDS access via `curl --unix-socket .../admin.sock http://localhost/c/threefold` should render bare-rooted links. ## Refs - [home#230](https://forge.ourworld.tf/lhumina_code/home/issues/230) phase 2.1 — alignment audit META - [home#225](https://forge.ourworld.tf/lhumina_code/home/issues/225) — META rule umbrella; this is the first concrete instance shipping - `~/.claude/skills/hero_web_prefix/SKILL.md` line 38 Signed-off-by: mik-tf
Per the `hero_web_prefix` skill (line 38): "There is no `BASE_PATH`
environment variable. The proxy is the only source of truth for the
prefix." The header `X-Forwarded-Prefix` is injected by hero_router on
every routed request and captured per-request by `prefix_middleware`
into the `REQUEST_PREFIX` task-local; direct access (no header) yields
`""` so all links stay bare. There is no scenario where reading from
`std::env::var("BASE_PATH")` produces a correct value that the header
path doesn't already produce.

Changes:
- Drop `pub base_path: String,` field from `AppState`.
- Drop the `std::env::var("BASE_PATH")` read at `web/server.rs:122` and
  the corresponding `base_path,` field in the `AppState` literal.
- Rewrite `effective_base_path()` to drop its `&AppState` parameter
  and the `state.base_path.clone()` fallback; default to `""` when no
  `X-Forwarded-Prefix` is present.
- Update all 166 call sites in `web/handlers/mod.rs` from
  `effective_base_path(&state)` to `effective_base_path()` (mechanical
  sed-rewrite, plus one `login_page` handler signature simplification
  to drop the now-unused `State<Arc<AppState>>` extractor).

Verified via hero_router source audit (`hero_router/src/server/routes.rs`
lines 669+677 for `/<svc>/<webname>/...` paths and 1274+1281 for
`/<svc>/rpc/...` paths) that `X-Forwarded-Prefix` is set on every
forwarded request — the env-var path was dead-letter.

Reference implementation for home#230 phase 2; same shape will apply
to hero_foundry, hero_agent, hero_embedder, hero_code, hero_proc.
Companion changes ride in:
- hero_skills service_biz.nu (drop BASE_PATH env block — supersedes c0186425)
- hero_demo services/hero_biz.toml (drop BASE_PATH env line)
- hero_router service_manager/services/hero_biz.rs (drop ("BASE_PATH", ...) launch-time env tuple)

Refs:
- lhumina_code/home#230 — alignment audit META
- lhumina_code/home#225 — META rule umbrella
- ~/.claude/skills/hero_web_prefix/SKILL.md line 38

Signed-off-by: mik-tf
fix(hero_biz_admin): clear rust 1.95 manual_checked_div + sort_by_key clippy debt
All checks were successful
Build and Test / build (pull_request) Successful in 5m7s
40eaa41a60
Pre-existing clippy debt introduced by the rust 1.95 toolchain bump
(commit 53a52a1 on origin/development). The workspace pre-merge gate
(`feedback_workspace_build_before_merge.md`) requires
`cargo clippy --workspace --all-targets -- -D warnings` to pass before
squash-merge, so bundling the mechanical fix here.

Changes:
- search/fuzzy.rs:240: `sort_by(|a,b| b.score.cmp(&a.score))` →
  `sort_by_key(|r| std::cmp::Reverse(r.score))` per `unnecessary_sort_by`.
- web/templates/mod.rs (6 sites): `if total == 0 { 0 } else { (done * 100 / total) as u8 }`
  → `(done * 100).checked_div(total).unwrap_or(0) as u8` per
  `manual_checked_ops`. One f64 site rewritten to
  `(done * 100).checked_div(total).map(|v| v as f64).unwrap_or(0.0)`.

Refs:
- lhumina_code/home#230 — alignment audit phase 2.1
- https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#manual_checked_ops

Signed-off-by: mik-tf
mik-tf merged commit 9138516410 into development 2026-05-08 15:22:29 +00:00
mik-tf deleted branch development_mik_basepath_purge 2026-05-08 15:22:29 +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_biz!49
No description provided.