[META] Standardize Hero service architecture — template, hero_rpc alignment, framework hoist, skills #262

Open
opened 2026-05-18 14:40:33 +00:00 by timur · 5 comments
Owner

TL;DR

The Hero ecosystem has too much divergence across service repos: different layouts, different lifecycle paths, hand-written SDKs, duplicated admin UIs, inconsistent socket conventions. This umbrella tracks the work to fix that — landing a canonical service template, aligning hero_rpc to current standards (incl. vendoring hero_rpc2 for transport+Rust client), hoisting reusable admin components into hero_website_framework, and writing the skills that let AI agents reproduce the pattern reliably.

Agents picking up any child issue: read this issue first, including the child's full comment thread. Decisions iterate in comments, not in issue bodies. The locked-decisions list below is canonical. Pull development on every relevant repo before reading code — many are mid-refactor.

Why this work

From team meeting (2026-05-13):

We cannot keep solving everything by engineering more. First we need a clean template, clean skills, and disciplined use of agents. Once that works, the agents can multiply the team's productivity — but only if the standards are clear and everyone follows them.

  • One human + AI agents can move 50× faster — but only when the standards are codified. Otherwise agents amplify drift.
  • Services today hand-roll socket setup, hand-write SDKs, hand-template admin UIs. Every new service starts from a different baseline.
  • Hero needs a single "clone-me" starting point, generated by tooling that bakes in the conventions.
  • Skills are the durable AI context that makes agents respect those conventions automatically.

Already in development (don't redo)

Avoid reinventing — these have landed and are referenced by child issues:

  • <hero-api-docs> OpenRPC explorer web component (commit 630f702) — lives in hero_website_framework/crates/hero_admin_lib/static/js/api-docs.js. The meeting's #1 hoist target is already there.
  • WorkspaceScaffolder in hero_rpc/crates/generator/src/build/scaffold.rs (1208 lines). Today's output naming is wrong (_ui, _client) and incomplete (no _admin crate, no service.toml, ships a Makefile that shouldn't exist). #54 is now "fix and extend" this, not "build from scratch."
  • Legacy unix_server surface partly cleanedhero_rpc/crates/osis/src/rpc/server.rs was reduced by 755 lines. Some legacy file (unix_server.rs) still exists; verify its role before final cleanup.
  • hero_admin_lib already provides standard admin routes (/health, /.well-known/heroservice.json), socket helpers, middleware, embedded assets — at hero_website_framework/crates/hero_admin_lib/src/{routes,socket,middleware,assets}.rs. Build new admin features on this, not from scratch.
  • Skills reorganized into hero_skills/skills/hero/{service,proc,ui,config,networkprotocol}/. Service skills at skills/hero/service/ (file paths unchanged).

The plan

Four workstreams, 9 issues (one closed):

  1. hero_rpc — extend the existing WorkspaceScaffolder to align with current standards. Update codegen to read service.toml (single source of truth), vendor hero_rpc2 for transport + Rust-client codegen, add Python SDK target, rename crates/service/ to crates/hero_lifecycle/ to free the hero_service name, modularize the 2653-line generator, upgrade example/recipe_server as the end-to-end demo.
  2. hero_website_framework — hoist remaining reusable admin components from existing service UIs into hero_admin_lib. (Alias-drop issue #5 was closed as wrong premise — see below.)
  3. hero_web_template — centralize shared stylesheets.
  4. hero_skills — add AI context skills for scaffold/check/refactor; refresh existing service skills; bootstrap canonical hero_service template repo.

Architectural decisions — locked

Settled in child-issue comment threads. Do not violate without flagging back here.

Source of truth

  • service.toml is the single source of truth for a service's identity (name, binaries, sockets, deps, env). Written at scaffold time, read by codegen (OschemaBuildConfig::from_service_toml()). Codegen NEVER overwrites it.
  • Schema source is OSchema (.oschema files). OSchema is the input to codegen for types, OSIS storage, OpenRPC spec, and all SDK targets.

Runtime + RPC

  • Hybrid hero_rpc + hero_rpc2 (Path C from #55):
    • OSchema codegen produces Rust traits annotated with hero_rpc2's #[rpc(server, client)] macros.
    • hero_rpc2 owns wire protocol, UDS transports, and the auto-generated Rust client.
    • hero_rpc2 is vendored in place as hero_rpc/crates/hero_rpc2/ (copy-over, no fork relationship, no upstream PR).
    • OSchema codegen still produces: OSIS storage layer (OsisObject, DBTyped<T>, SmartID), OpenRPC spec, JS/TS + Rhai + Python SDK targets. Python is new.
  • One socket per service. Context via the X-Hero-Context HTTP header. No per-context socket dirs anywhere — legacy mentions must be removed.
  • Context routing in hero_rpc2: add a header-lift extension that materialises configured headers (X-Hero-Context, X-Hero-Claims) into a typed HeroRequestContext. Trait methods take ctx: Option<HeroRequestContext> as the first arg so they work over both line and HTTP transports.

Lifecycle + service identity

  • Canonical lifecycle path: herolib_core::base + service_base!() macro + lab tool. The lab crate (in hero_skills/crates/lab/) is the single tool for install/start/stop/status across all services.
  • Rename hero_rpc/crates/service/hero_rpc/crates/hero_lifecycle/ (package name hero_servicehero_lifecycle). Recent commits show this crate is actively developed, so rename rather than delete. Frees the hero_service name for the template repo. (Earlier "delete" decision flipped — see #55 latest comment.)
  • --info flag is NOT deprecated — it prints the embedded service.toml (TOML or JSON). Mandatory on every binary, served by herolib_core::base::handle_info_flag. lab infocheck validates it.
  • No Makefile, no scripts/*.sh, no service_<name>.nulab handles all lifecycle (ADR-0001). The current scaffolder generates a Makefile; that has to go.

Naming (no exceptions, per hero_service_check_fix.md)

  • Server: hero_<name>_server
  • Admin UI: hero_<name>_admin (never _ui; current scaffolder emits _ui and must be fixed)
  • SDK: hero_<name>_sdk (lib crate; current scaffolder emits _client and must be fixed)
  • CLI: hero_<name> — only if non-trivial; bare selfstart CLIs must be removed
  • End-user web (Askama): hero_<name>_web
  • End-user app (Dioxus): hero_<name>_app
  • Examples: hero_<name>_examples (currently not generated; must be added)

Templating

  • Askama by default (compile-time, type-checked).
  • Tera only when templates must be loaded/edited at runtime (user-editable blog posts, document templates).
  • hero_website_lib uses Tera (full website framework). hero_admin_lib is Axum + rust-embed, Askama-friendly. New admin components go into hero_admin_lib with Askama.

Framework structure (corrected)

  • Two crates, intentionally separate in hero_website_framework:
    • hero_admin_lib — admin-dashboard shared assets, middleware, routes, socket helpers. Axum + rust-embed, no Tera, no SQLite. Consumed by every service's _admin crate (hero_proc_admin, hero_osis_admin, …).
    • hero_website_lib — full public-facing website framework with Tera, SQLite, auth, blog, docs. Only used by the framework's own demo_website example today.
    • (Earlier umbrella claimed there was one crate with an alias. Wrong. hero_website_framework#5 closed as wrong premise.)
  • Shared CSS / theme tokens live in hero_web_template, referenced by both framework crates.

Reference services

  • hero_proc — canonical wiring reference. hero_proc_server/src/main.rs uses service_base!(), validate_service_toml, handle_info_flag exactly as required. Its hero_proc_admin is the model admin binary.
  • hero_compute — workspace layout + hero_rpc OSchema dep set. (Its _server main.rs uses an older subcommand pattern — do NOT mimic that.)
  • hero_inspector is out-of-date and explicitly NOT a reference.

Open decisions — waiting on Timur

  • lab service new <subcommand> — exposing hero_rpc scaffold as a lab subcommand. Out of scope for this batch; should be its own follow-up issue.
  • Framework Tera → Askama migration — does hero_website_lib migrate its existing Tera templates to Askama, or stay hybrid? Separate follow-up issue if migration is desired.
  • SDK output crate layout — where does each language target land? hero_<name>_sdk is the Rust crate. JS/TS, Rhai, Python: separate crates? subdirs of sdk/? Single mono-SDK with feature flags? Needs a design comment on hero_rpc#55.
  • hero_rpc2 vendor logistics — who copies what, when. Confirm with @delandtj if any heads-up needed.

Child issues

hero_rpc (4)

  • #54Extend WorkspaceScaffolder to current standards (naming fixes, service.toml, admin crate, Python SDK, drop Makefile, examples crate).
  • #55Codegen alignment + hero_rpc2 vendor + Python SDK + rename crates/service/ to hero_lifecycle.
  • #56Modularize 2653-line generator/src/build/build.rs (refactor; public API stable).
  • #57Upgrade example/recipe_server to the new end-to-end pattern.

hero_website_framework (1 active + 1 closed)

  • #4Hoist remaining reusable admin components into hero_admin_lib (connection-status, live logs, jobs viewer, markdown viewer). OpenRPC explorer already landed.
  • #5CLOSED as wrong premise (two crates are intentionally separate, no alias).

hero_web_template (1)

  • #4Centralize shared stylesheets.

hero_skills (2)

  • #260Scaffold/check/refactor context skills + refresh existing service skills (no Tera/Askama inversion — Askama stays the default).
  • #261Bootstrap hero_service template repo (decision B locked).

Suggested execution order

Tier Issues Why parallel-safe
1 (start now) #56, #4 (hoist remaining components), web_template#4, #260 (cleanup pass only — Askama-default audit, drop hero_inspector references) No open decisions block; pure refactor / hoist / cleanup.
2 (after tier-1 lands) #55 (rename, then codegen alignment + hero_rpc2 vendor) Decisions locked; just need the action.
3 (consumes tier 2) #54 (extend scaffolder), #260 (write new skills) Needs codegen alignment + framework cleanup done.
4 (consumes tier 3) #57 (recipe_server upgrade), #261 (template repo bootstrap) Pure end-to-end consumers.

Reference materials

When working on a child issue, start here:

For agents picking up a child issue

  1. Run git fetch && git pull --rebase origin development on every repo you'll touch. Don't trust prior-session memory of file sizes / structure / crate inventories.
  2. Read this issue + the child issue and all its comments. Decisions iterate in comments — the issue body may be stale until the consolidation pass.
  3. Authority order: child-issue comments > this umbrella > skills in hero_skills/skills/hero/service/ > reference services (hero_proc, hero_compute) > anything else.
  4. If a locked decision no longer makes sense, comment here before deviating. Never silently choose differently.
  5. Update progress as comments on the child issue, not the body.

Status board

  • hero_rpc#54 — extend scaffolder
  • hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename crates/service/
  • hero_rpc#56 — modularize generator build.rs
  • hero_rpc#57 — upgrade recipe_server
  • hero_website_framework#4 — hoist remaining components
  • hero_website_framework#5 — drop alias (closed, wrong premise)
  • hero_web_template#4 — shared CSS
  • hero_skills#260 — scaffold/check/refactor skills
  • hero_skills#261 — bootstrap hero_service template repo (decision B locked)
## TL;DR The Hero ecosystem has too much divergence across service repos: different layouts, different lifecycle paths, hand-written SDKs, duplicated admin UIs, inconsistent socket conventions. This umbrella tracks the work to fix that — landing a **canonical service template**, aligning **hero_rpc** to current standards (incl. vendoring **hero_rpc2** for transport+Rust client), hoisting reusable admin components into **hero_website_framework**, and writing the **skills** that let AI agents reproduce the pattern reliably. **Agents picking up any child issue: read this issue first, including the child's full comment thread.** Decisions iterate in comments, not in issue bodies. The locked-decisions list below is canonical. Pull `development` on every relevant repo before reading code — many are mid-refactor. ## Why this work From team meeting (2026-05-13): > *We cannot keep solving everything by engineering more. First we need a clean template, clean skills, and disciplined use of agents. Once that works, the agents can multiply the team's productivity — but only if the standards are clear and everyone follows them.* - One human + AI agents can move 50× faster — but only when the standards are codified. Otherwise agents amplify drift. - Services today hand-roll socket setup, hand-write SDKs, hand-template admin UIs. Every new service starts from a different baseline. - Hero needs a single "clone-me" starting point, generated by tooling that bakes in the conventions. - Skills are the durable AI context that makes agents respect those conventions automatically. ## Already in `development` (don't redo) Avoid reinventing — these have landed and are referenced by child issues: - **`<hero-api-docs>` OpenRPC explorer web component** ([commit 630f702](https://forge.ourworld.tf/lhumina_code/hero_website_framework/commit/630f702)) — lives in `hero_website_framework/crates/hero_admin_lib/static/js/api-docs.js`. The meeting's #1 hoist target is already there. - **`WorkspaceScaffolder`** in `hero_rpc/crates/generator/src/build/scaffold.rs` (1208 lines). Today's output naming is wrong (`_ui`, `_client`) and incomplete (no `_admin` crate, no `service.toml`, ships a `Makefile` that shouldn't exist). [#54](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/54) is now "fix and extend" this, not "build from scratch." - **Legacy `unix_server` surface partly cleaned** — `hero_rpc/crates/osis/src/rpc/server.rs` was reduced by 755 lines. Some legacy file (`unix_server.rs`) still exists; verify its role before final cleanup. - **`hero_admin_lib` already provides standard admin routes** (`/health`, `/.well-known/heroservice.json`), socket helpers, middleware, embedded assets — at `hero_website_framework/crates/hero_admin_lib/src/{routes,socket,middleware,assets}.rs`. Build new admin features on this, not from scratch. - **Skills reorganized** into `hero_skills/skills/hero/{service,proc,ui,config,networkprotocol}/`. Service skills at `skills/hero/service/` (file paths unchanged). ## The plan Four workstreams, 9 issues (one closed): 1. **hero_rpc** — extend the existing `WorkspaceScaffolder` to align with current standards. Update codegen to read `service.toml` (single source of truth), vendor `hero_rpc2` for transport + Rust-client codegen, add Python SDK target, rename `crates/service/` to `crates/hero_lifecycle/` to free the `hero_service` name, modularize the 2653-line generator, upgrade `example/recipe_server` as the end-to-end demo. 2. **hero_website_framework** — hoist remaining reusable admin components from existing service UIs into `hero_admin_lib`. (Alias-drop issue #5 was closed as wrong premise — see below.) 3. **hero_web_template** — centralize shared stylesheets. 4. **hero_skills** — add AI context skills for scaffold/check/refactor; refresh existing service skills; bootstrap canonical `hero_service` template repo. ## Architectural decisions — locked Settled in child-issue comment threads. **Do not violate without flagging back here.** ### Source of truth - **`service.toml`** is the single source of truth for a service's identity (name, binaries, sockets, deps, env). Written at **scaffold time**, **read** by codegen (`OschemaBuildConfig::from_service_toml()`). Codegen NEVER overwrites it. - Schema source is **OSchema** (`.oschema` files). OSchema is the input to codegen for types, OSIS storage, OpenRPC spec, and all SDK targets. ### Runtime + RPC - **Hybrid hero_rpc + hero_rpc2** ([Path C from #55](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/55#issuecomment-33680)): - OSchema codegen produces Rust traits annotated with hero_rpc2's `#[rpc(server, client)]` macros. - **hero_rpc2** owns wire protocol, UDS transports, and the auto-generated Rust client. - hero_rpc2 is **vendored in place** as `hero_rpc/crates/hero_rpc2/` (copy-over, no fork relationship, no upstream PR). - OSchema codegen still produces: OSIS storage layer (`OsisObject`, `DBTyped<T>`, SmartID), OpenRPC spec, **JS/TS + Rhai + Python** SDK targets. Python is new. - **One socket per service.** Context via the `X-Hero-Context` HTTP header. **No per-context socket dirs anywhere** — legacy mentions must be removed. - **Context routing in hero_rpc2:** add a header-lift extension that materialises configured headers (`X-Hero-Context`, `X-Hero-Claims`) into a typed `HeroRequestContext`. Trait methods take `ctx: Option<HeroRequestContext>` as the first arg so they work over both line and HTTP transports. ### Lifecycle + service identity - Canonical lifecycle path: **`herolib_core::base` + `service_base!()` macro + `lab` tool**. The `lab` crate (in `hero_skills/crates/lab/`) is the single tool for install/start/stop/status across all services. - **Rename `hero_rpc/crates/service/` → `hero_rpc/crates/hero_lifecycle/`** (package name `hero_service` → `hero_lifecycle`). Recent commits show this crate is actively developed, so rename rather than delete. Frees the `hero_service` name for the template repo. (Earlier "delete" decision flipped — see [#55](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/55#issuecomment-33720) latest comment.) - **`--info` flag is NOT deprecated** — it prints the embedded `service.toml` (TOML or JSON). Mandatory on every binary, served by `herolib_core::base::handle_info_flag`. `lab infocheck` validates it. - No `Makefile`, no `scripts/*.sh`, no `service_<name>.nu` — `lab` handles all lifecycle (ADR-0001). The current scaffolder generates a `Makefile`; that has to go. ### Naming (no exceptions, per [`hero_service_check_fix.md`](https://forge.ourworld.tf/lhumina_code/hero_skills/src/branch/development/skills/hero/service/hero_service_check_fix.md)) - Server: `hero_<name>_server` - Admin UI: `hero_<name>_admin` (never `_ui`; current scaffolder emits `_ui` and must be fixed) - SDK: `hero_<name>_sdk` (lib crate; current scaffolder emits `_client` and must be fixed) - CLI: `hero_<name>` — only if non-trivial; bare `selfstart` CLIs must be removed - End-user web (Askama): `hero_<name>_web` - End-user app (Dioxus): `hero_<name>_app` - Examples: `hero_<name>_examples` (currently not generated; must be added) ### Templating - **Askama by default** (compile-time, type-checked). - **Tera** only when templates must be loaded/edited at runtime (user-editable blog posts, document templates). - `hero_website_lib` uses Tera (full website framework). `hero_admin_lib` is Axum + rust-embed, Askama-friendly. New admin components go into `hero_admin_lib` with Askama. ### Framework structure (corrected) - **Two crates, intentionally separate** in `hero_website_framework`: - **[`hero_admin_lib`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/src/branch/development/crates/hero_admin_lib)** — admin-dashboard shared assets, middleware, routes, socket helpers. Axum + rust-embed, no Tera, no SQLite. **Consumed by every service's `_admin` crate** (`hero_proc_admin`, `hero_osis_admin`, …). - **[`hero_website_lib`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/src/branch/development/crates/hero_website_lib)** — full public-facing website framework with Tera, SQLite, auth, blog, docs. Only used by the framework's own `demo_website` example today. - (Earlier umbrella claimed there was one crate with an alias. Wrong. [hero_website_framework#5](https://forge.ourworld.tf/lhumina_code/hero_website_framework/issues/5) closed as wrong premise.) - Shared CSS / theme tokens live in **`hero_web_template`**, referenced by both framework crates. ### Reference services - **[`hero_proc`](https://forge.ourworld.tf/lhumina_code/hero_proc)** — canonical wiring reference. `hero_proc_server/src/main.rs` uses `service_base!()`, `validate_service_toml`, `handle_info_flag` exactly as required. Its `hero_proc_admin` is the model admin binary. - **[`hero_compute`](https://forge.ourworld.tf/lhumina_code/hero_compute)** — workspace layout + hero_rpc OSchema dep set. (Its `_server` main.rs uses an older subcommand pattern — do NOT mimic that.) - **`hero_inspector`** is out-of-date and explicitly NOT a reference. ## Open decisions — waiting on Timur - **`lab service new <subcommand>`** — exposing `hero_rpc scaffold` as a `lab` subcommand. Out of scope for this batch; should be its own follow-up issue. - **Framework Tera → Askama migration** — does `hero_website_lib` migrate its existing Tera templates to Askama, or stay hybrid? Separate follow-up issue if migration is desired. - **SDK output crate layout** — where does each language target land? `hero_<name>_sdk` is the Rust crate. JS/TS, Rhai, Python: separate crates? subdirs of `sdk/`? Single mono-SDK with feature flags? Needs a design comment on [hero_rpc#55](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/55). - **hero_rpc2 vendor logistics** — who copies what, when. Confirm with @delandtj if any heads-up needed. ## Child issues ### hero_rpc (4) - [#54](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/54) — **Extend `WorkspaceScaffolder`** to current standards (naming fixes, service.toml, admin crate, Python SDK, drop Makefile, examples crate). - [#55](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/55) — **Codegen alignment** + hero_rpc2 vendor + Python SDK + **rename** `crates/service/` to `hero_lifecycle`. - [#56](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/56) — **Modularize 2653-line `generator/src/build/build.rs`** (refactor; public API stable). - [#57](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/57) — **Upgrade `example/recipe_server`** to the new end-to-end pattern. ### hero_website_framework (1 active + 1 closed) - [#4](https://forge.ourworld.tf/lhumina_code/hero_website_framework/issues/4) — **Hoist remaining reusable admin components** into `hero_admin_lib` (connection-status, live logs, jobs viewer, markdown viewer). OpenRPC explorer already landed. - ~~[#5](https://forge.ourworld.tf/lhumina_code/hero_website_framework/issues/5)~~ — **CLOSED** as wrong premise (two crates are intentionally separate, no alias). ### hero_web_template (1) - [#4](https://forge.ourworld.tf/lhumina_code/hero_web_template/issues/4) — **Centralize shared stylesheets**. ### hero_skills (2) - [#260](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/260) — **Scaffold/check/refactor context skills** + refresh existing service skills (no Tera/Askama inversion — Askama stays the default). - [#261](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/261) — **Bootstrap `hero_service` template repo** (decision B locked). ### Suggested execution order | Tier | Issues | Why parallel-safe | |---|---|---| | **1 (start now)** | #56, #4 (hoist remaining components), web_template#4, #260 (cleanup pass only — Askama-default audit, drop hero_inspector references) | No open decisions block; pure refactor / hoist / cleanup. | | **2 (after tier-1 lands)** | #55 (rename, then codegen alignment + hero_rpc2 vendor) | Decisions locked; just need the action. | | **3 (consumes tier 2)** | #54 (extend scaffolder), #260 (write new skills) | Needs codegen alignment + framework cleanup done. | | **4 (consumes tier 3)** | #57 (recipe_server upgrade), #261 (template repo bootstrap) | Pure end-to-end consumers. | ## Reference materials When working on a child issue, start here: - **Skills bundle** — [`hero_skills/skills/hero/service/`](https://forge.ourworld.tf/lhumina_code/hero_skills/src/branch/development/skills/hero/service): - [`hero_service.md`](https://forge.ourworld.tf/lhumina_code/hero_skills/src/branch/development/skills/hero/service/hero_service.md) — startup banner, `--info`, `--help`. - [`hero_service_toml_info.md`](https://forge.ourworld.tf/lhumina_code/hero_skills/src/branch/development/skills/hero/service/hero_service_toml_info.md) — service.toml schema, `service_base!()` macro. - [`hero_service_check_fix.md`](https://forge.ourworld.tf/lhumina_code/hero_skills/src/branch/development/skills/hero/service/hero_service_check_fix.md) — `lab infocheck` contract, naming, socket rules. - `herolib_base` skill — `print_startup_banner`, `prepare_sockets` API. - `hero_sockets` skill — `HERO_SOCKET_DIR` layout and router homepage card naming rule. - **Reference services**: [`hero_proc`](https://forge.ourworld.tf/lhumina_code/hero_proc) (wiring + `hero_proc_admin` admin model), [`hero_compute`](https://forge.ourworld.tf/lhumina_code/hero_compute) (workspace layout). - **Framework crates**: [`hero_admin_lib`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/src/branch/development/crates/hero_admin_lib) (admin shared), [`hero_website_lib`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/src/branch/development/crates/hero_website_lib) (full website). - **Existing scaffolder** to extend: [`hero_rpc/crates/generator/src/build/scaffold.rs`](https://forge.ourworld.tf/lhumina_code/hero_rpc/src/branch/development/crates/generator/src/build/scaffold.rs). - **Lab tool**: `hero_skills/crates/lab/`. - **hero_rpc2**: [`delandtj/hero_rpc2`](https://forge.ourworld.tf/delandtj/hero_rpc2) — to be vendored. ## For agents picking up a child issue 1. Run `git fetch && git pull --rebase origin development` on every repo you'll touch. Don't trust prior-session memory of file sizes / structure / crate inventories. 2. Read this issue + the child issue **and all its comments**. Decisions iterate in comments — the issue body may be stale until the consolidation pass. 3. Authority order: **child-issue comments > this umbrella > skills in `hero_skills/skills/hero/service/` > reference services (`hero_proc`, `hero_compute`) > anything else**. 4. If a locked decision no longer makes sense, **comment here** before deviating. Never silently choose differently. 5. Update progress as comments on the child issue, not the body. ## Status board - [ ] hero_rpc#54 — extend scaffolder - [ ] hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename `crates/service/` - [ ] hero_rpc#56 — modularize generator build.rs - [ ] hero_rpc#57 — upgrade recipe_server - [ ] hero_website_framework#4 — hoist remaining components - [x] ~~hero_website_framework#5 — drop alias~~ (closed, wrong premise) - [ ] hero_web_template#4 — shared CSS - [ ] hero_skills#260 — scaffold/check/refactor skills - [ ] hero_skills#261 — bootstrap hero_service template repo (decision B locked)
Author
Owner

Tier-1 progress (2026-05-19)

Done & pushed

Issue Commit Notes
hero_rpc#56 — modularize generator/src/build/build.rs 8a8d66d 2653 LOC split into 12 sub-500 files. recipe_server builds unchanged. Tests + clippy green.
hero_website_framework#4 — hoist admin components f6af8ab, 9d80616, 8df3330 3 components added (<hero-logs-viewer>, <hero-jobs-viewer>, <hero-markdown-viewer>). Total 5 components in hero_admin_lib. Skill docs in progress (separate agent, hero_skills commit pending).

Done locally, not yet pushed

Issue Commit Status
hero_skills#260 — cleanup pass on existing service skills 2a05555 (local) Awaiting push authorization. New scaffold/check/refactor skills held back pending hero_rpc#54/#55.

Not started

Issue Status
hero_web_template#4 — centralize shared stylesheets No agent assigned yet. Last tier-1 work outstanding.

Deviations & follow-ups flagged by agents

  1. hero_rpc#56 scope clarification (comment 33741). The original META said "extract per-target emitters (rust_types, rust_rpc, openrpc, js, rhai, python) into build/emit/." In reality those emitters live in crate::generate::Generator, not build.rs. Agent split what build.rs actually owns (bins, server-crate mods, SDK scaffolding, docs index). Per-target emission refactor needs a separate, larger follow-up issue against Generator — out of scope for #56's "no behaviour change" rule. To file.
  2. hero_website_framework#4 cross-repo follow-up (comment 33847). hero_proc_admin still hand-rolls its API tab; should migrate to the now-canonical <hero-api-docs> component. Belongs in a hero_proc issue. To file.
  3. UI component skill location (in flight). hero_website_framework#4 acceptance asks for skills at hero_skills/skills/web/. The existing precedent (hero_ui_connection_status.md) lives at skills/hero/ui/. Going with the existing on-disk convention — 4 new skills (hero_ui_api_docs, hero_ui_logs_viewer, hero_ui_jobs_viewer, hero_ui_markdown_viewer) being added there. Acceptance reading: aspirational path, real convention wins.

Tier-1 status board

  • hero_rpc#56 — modularize generator build.rs (pushed)
  • hero_website_framework#4 — hoist components (components pushed; skill docs in flight)
  • hero_skills#260 — cleanup pass on existing service skills (local, pending push)
  • hero_web_template#4 — shared CSS (not started)

Next steps

  • Authorize push of hero_skills 2a05555.
  • File the two follow-up issues (Generator refactor in hero_rpc; API-tab migration in hero_proc). I'll do this once you confirm.
  • Assign hero_web_template#4 to an agent.
  • Unblock tier 2 by kicking off hero_rpc#55 — all decisions locked (rename crates/service/hero_lifecycle/, vendor hero_rpc2, Python SDK, OschemaBuildConfig reads service.toml).
## Tier-1 progress (2026-05-19) ### Done & pushed | Issue | Commit | Notes | |---|---|---| | [hero_rpc#56](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/56) — modularize `generator/src/build/build.rs` | [`8a8d66d`](https://forge.ourworld.tf/lhumina_code/hero_rpc/commit/8a8d66d) | 2653 LOC split into 12 sub-500 files. recipe_server builds unchanged. Tests + clippy green. | | [hero_website_framework#4](https://forge.ourworld.tf/lhumina_code/hero_website_framework/issues/4) — hoist admin components | [`f6af8ab`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/commit/f6af8ab), [`9d80616`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/commit/9d80616), [`8df3330`](https://forge.ourworld.tf/lhumina_code/hero_website_framework/commit/8df3330) | 3 components added (`<hero-logs-viewer>`, `<hero-jobs-viewer>`, `<hero-markdown-viewer>`). Total 5 components in `hero_admin_lib`. Skill docs in progress (separate agent, hero_skills commit pending). | ### Done locally, not yet pushed | Issue | Commit | Status | |---|---|---| | [hero_skills#260](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/260) — cleanup pass on existing service skills | `2a05555` (local) | Awaiting push authorization. New scaffold/check/refactor skills held back pending hero_rpc#54/#55. | ### Not started | Issue | Status | |---|---| | [hero_web_template#4](https://forge.ourworld.tf/lhumina_code/hero_web_template/issues/4) — centralize shared stylesheets | No agent assigned yet. Last tier-1 work outstanding. | ### Deviations & follow-ups flagged by agents 1. **hero_rpc#56 scope clarification** ([comment 33741](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/56#issuecomment-33741)). The original META said "extract per-target emitters (`rust_types`, `rust_rpc`, `openrpc`, `js`, `rhai`, `python`) into `build/emit/`." In reality those emitters live in `crate::generate::Generator`, not `build.rs`. Agent split what `build.rs` actually owns (bins, server-crate mods, SDK scaffolding, docs index). Per-target emission refactor needs a **separate, larger follow-up issue against `Generator`** — out of scope for #56's "no behaviour change" rule. To file. 2. **hero_website_framework#4 cross-repo follow-up** ([comment 33847](https://forge.ourworld.tf/lhumina_code/hero_website_framework/issues/4#issuecomment-33847)). `hero_proc_admin` still hand-rolls its API tab; should migrate to the now-canonical `<hero-api-docs>` component. **Belongs in a `hero_proc` issue.** To file. 3. **UI component skill location** (in flight). `hero_website_framework#4` acceptance asks for skills at `hero_skills/skills/web/`. The existing precedent (`hero_ui_connection_status.md`) lives at `skills/hero/ui/`. Going with the existing on-disk convention — 4 new skills (`hero_ui_api_docs`, `hero_ui_logs_viewer`, `hero_ui_jobs_viewer`, `hero_ui_markdown_viewer`) being added there. Acceptance reading: aspirational path, real convention wins. ### Tier-1 status board - [x] hero_rpc#56 — modularize generator build.rs (pushed) - [x] hero_website_framework#4 — hoist components (components pushed; skill docs in flight) - [ ] hero_skills#260 — cleanup pass on existing service skills (local, pending push) - [ ] hero_web_template#4 — shared CSS (not started) ### Next steps - **Authorize push** of `hero_skills` `2a05555`. - **File the two follow-up issues** (Generator refactor in hero_rpc; API-tab migration in hero_proc). I'll do this once you confirm. - **Assign hero_web_template#4** to an agent. - **Unblock tier 2** by kicking off [hero_rpc#55](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/55) — all decisions locked (rename `crates/service/` → `hero_lifecycle/`, vendor hero_rpc2, Python SDK, OschemaBuildConfig reads service.toml).
Author
Owner

Follow-up issues filed

  • hero_rpc#59 — Refactor crate::generate::Generator per-target emission into modules (continuation of #56; behaviour-preserving).
  • hero_proc#108 — Migrate hero_proc_admin's hand-rolled API tab to the new <hero-api-docs> component.

Both are agent-ready, no decision risk, no dependency on tier-2.

Status board update

  • hero_rpc#56 — modularize generator build.rs (pushed)
  • hero_website_framework#4 — hoist components (component code pushed; 4 UI skill docs in progress in hero_skills)
  • hero_skills#260 — cleanup pass (local; awaiting push) + new scaffold/check/refactor skills (blocked on tier-2)
  • hero_web_template#4 — shared CSS (in flight; agent assigned)
  • hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename crates/service/ (tier-2 in flight)
  • hero_rpc#59 — Generator per-target refactor (new, ready to assign)
  • hero_proc#108 — <hero-api-docs> migration (new, ready to assign)
  • hero_rpc#54 — extend WorkspaceScaffolder (tier-3; blocked on #55)
  • hero_rpc#57 — upgrade recipe_server (tier-4; blocked on #54+#55+#56)
  • hero_skills#261 — bootstrap hero_service template repo (tier-4; blocked on #54)
## Follow-up issues filed - [hero_rpc#59](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/59) — Refactor `crate::generate::Generator` per-target emission into modules (continuation of #56; behaviour-preserving). - [hero_proc#108](https://forge.ourworld.tf/lhumina_code/hero_proc/issues/108) — Migrate `hero_proc_admin`'s hand-rolled API tab to the new `<hero-api-docs>` component. Both are agent-ready, no decision risk, no dependency on tier-2. ## Status board update - [x] hero_rpc#56 — modularize generator build.rs (pushed) - [x] hero_website_framework#4 — hoist components (component code pushed; 4 UI skill docs in progress in hero_skills) - [ ] hero_skills#260 — cleanup pass (local; awaiting push) + new scaffold/check/refactor skills (blocked on tier-2) - [ ] hero_web_template#4 — shared CSS (in flight; agent assigned) - [ ] hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename `crates/service/` (tier-2 in flight) - [ ] hero_rpc#59 — Generator per-target refactor (new, ready to assign) - [ ] hero_proc#108 — `<hero-api-docs>` migration (new, ready to assign) - [ ] hero_rpc#54 — extend WorkspaceScaffolder (tier-3; blocked on #55) - [ ] hero_rpc#57 — upgrade recipe_server (tier-4; blocked on #54+#55+#56) - [ ] hero_skills#261 — bootstrap `hero_service` template repo (tier-4; blocked on #54)
Author
Owner

#55 landed on issue-55-codegen-alignment (review-ready)

All 6 sections covered, 141 tests green, workspace clean.

§ Status Highlight
§1 from_service_toml recipe_server/build.rs 41 → 5 lines
§2 hero_rpc2 hybrid SDK rails (vendor + HeroRequestContext); 2 method-translators scoped out → [new issue filed below]
§3 _admin scaffold uses hero_admin_lib Drops HeroUiServer
§4 rename hero_servicehero_lifecycle + coordinated branches on 7 downstream repos
§5 generated main.rs boilerplate Matches hero_proc_server pattern
§6 naming suffixes _admin / _sdk everywhere

Cross-repo branches awaiting hero_rpc PR merge

Branches issue-55-hero-lifecycle-rename pushed on: hero_proxy, hero_osis, hero_index_ui_old, hero_compute, hero_os, hero_router, hero_voice. After the hero_rpc PR merges, a one-line sweep per repo flips the pin from branch = "issue-55-codegen-alignment" back to branch = "development".

development_wip side-branches archived dirty state on hero_os, hero_voice, hero_foundry.

Follow-up filed

hero_rpc#60 — OSchema → Rust trait methods + Python dataclass methods translators (clean rails-on, no architectural decisions left).

Updated status board

  • hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename (review-ready on branch)
  • hero_rpc#54 — extend scaffolder (now unblocked — gating tier-3/4)
  • hero_rpc#59 — Generator per-target refactor (now unblocked; defer until #60 lands to avoid conflict)
  • hero_rpc#60 — §2 method translators (new, ready to assign)
  • hero_skills#260 — new scaffold/check/refactor skills (now unblocked — scaffolder shape is known)
  • hero_rpc#57 — upgrade recipe_server (blocked on #54)
  • hero_skills#261 — bootstrap hero_service template repo (blocked on #54)

Open Timur actions

  • Review + merge the hero_rpc#55 PR (and the matching downstream branches).
  • Push the still-local hero_skills cleanup commit 2a05555 (from #260 tier-1).
## #55 landed on `issue-55-codegen-alignment` (review-ready) All 6 sections covered, 141 tests green, workspace clean. | § | Status | Highlight | |---|---|---| | §1 `from_service_toml` | ✅ | `recipe_server/build.rs` 41 → 5 lines | | §2 hero_rpc2 hybrid SDK | ✅ rails (vendor + HeroRequestContext); 2 method-translators scoped out → [new issue filed below] | | §3 `_admin` scaffold uses `hero_admin_lib` | ✅ | Drops `HeroUiServer` | | §4 rename `hero_service` → `hero_lifecycle` | ✅ | + coordinated branches on 7 downstream repos | | §5 generated `main.rs` boilerplate | ✅ | Matches `hero_proc_server` pattern | | §6 naming suffixes | ✅ | `_admin` / `_sdk` everywhere | ### Cross-repo branches awaiting hero_rpc PR merge Branches `issue-55-hero-lifecycle-rename` pushed on: `hero_proxy`, `hero_osis`, `hero_index_ui_old`, `hero_compute`, `hero_os`, `hero_router`, `hero_voice`. After the hero_rpc PR merges, a one-line sweep per repo flips the pin from `branch = "issue-55-codegen-alignment"` back to `branch = "development"`. `development_wip` side-branches archived dirty state on `hero_os`, `hero_voice`, `hero_foundry`. ### Follow-up filed [hero_rpc#60](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/60) — OSchema → Rust trait methods + Python dataclass methods translators (clean rails-on, no architectural decisions left). ### Updated status board - [x] hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename (review-ready on branch) - [ ] **hero_rpc#54 — extend scaffolder** (now unblocked — gating tier-3/4) - [ ] hero_rpc#59 — Generator per-target refactor (now unblocked; defer until #60 lands to avoid conflict) - [ ] hero_rpc#60 — §2 method translators (new, ready to assign) - [ ] hero_skills#260 — new scaffold/check/refactor skills (now unblocked — scaffolder shape is known) - [ ] hero_rpc#57 — upgrade recipe_server (blocked on #54) - [ ] hero_skills#261 — bootstrap hero_service template repo (blocked on #54) ### Open Timur actions - Review + merge the hero_rpc#55 PR (and the matching downstream branches). - Push the still-local `hero_skills` cleanup commit `2a05555` (from #260 tier-1).
Author
Owner

Timur actions — done

hero_skills cleanup pushed

Commit 2a05555 was sitting local since the #260 tier-1 pass. Cherry-picked onto current origin/development (which had since gained the 4 UI component skills from 707e7a7 — direct push would have nuked them) and pushed as 0634d4d. Diff: 2 files changed, 9 insertions, 4 deletions.

hero_rpc#55 PR merged

PR #61 — squash-merged as cbc2821b.

7 downstream hero_lifecycle rename PRs merged

Each got a one-line pin flip (branch = "issue-55-codegen-alignment"branch = "development") on top of the rename branch, then a squash merge to development:

Repo PR Pin-flip commit
hero_proxy #54 6e340c8
hero_osis #63 f66afd9
hero_index_ui_old #4 49549e9
hero_compute #112 bd9684b
hero_os #149 297e4020
hero_router #107 3a22aff
hero_voice #35 f0c53c5

All merges HTTP 200; all branches mergeable: True before merge. No conflicts encountered.

Status board

  • hero_rpc#55 — merged + 7 downstream rename PRs merged
  • hero_skills cleanup commit pushed
  • hero_rpc#54 — extend scaffolder (in flight per dispatched agent)
  • hero_rpc#59 — Generator per-target refactor (defer until #60)
  • hero_rpc#60 — §2 method translators (in flight)
  • hero_skills#260 — new scaffold/check/refactor skills (in flight)
  • hero_rpc#57 — upgrade recipe_server (blocked on #54)
  • hero_skills#261 — bootstrap hero_service template repo (blocked on #54)

Agents dispatched in parallel against development (now containing the merged #55 work) — they no longer need to coordinate against the feature branch.

## Timur actions — done ### hero_skills cleanup pushed Commit `2a05555` was sitting local since the #260 tier-1 pass. Cherry-picked onto current `origin/development` (which had since gained the 4 UI component skills from `707e7a7` — direct push would have nuked them) and pushed as [`0634d4d`](https://forge.ourworld.tf/lhumina_code/hero_skills/commit/0634d4d). Diff: 2 files changed, 9 insertions, 4 deletions. ### hero_rpc#55 PR merged [PR #61](https://forge.ourworld.tf/lhumina_code/hero_rpc/pulls/61) — squash-merged as [`cbc2821b`](https://forge.ourworld.tf/lhumina_code/hero_rpc/commit/cbc2821b). ### 7 downstream `hero_lifecycle` rename PRs merged Each got a one-line pin flip (`branch = "issue-55-codegen-alignment"` → `branch = "development"`) on top of the rename branch, then a squash merge to `development`: | Repo | PR | Pin-flip commit | |---|---|---| | `hero_proxy` | [#54](https://forge.ourworld.tf/lhumina_code/hero_proxy/pulls/54) | `6e340c8` | | `hero_osis` | [#63](https://forge.ourworld.tf/lhumina_code/hero_osis/pulls/63) | `f66afd9` | | `hero_index_ui_old` | [#4](https://forge.ourworld.tf/lhumina_code/hero_index_ui_old/pulls/4) | `49549e9` | | `hero_compute` | [#112](https://forge.ourworld.tf/lhumina_code/hero_compute/pulls/112) | `bd9684b` | | `hero_os` | [#149](https://forge.ourworld.tf/lhumina_code/hero_os/pulls/149) | `297e4020` | | `hero_router` | [#107](https://forge.ourworld.tf/lhumina_code/hero_router/pulls/107) | `3a22aff` | | `hero_voice` | [#35](https://forge.ourworld.tf/lhumina_code/hero_voice/pulls/35) | `f0c53c5` | All merges HTTP 200; all branches `mergeable: True` before merge. No conflicts encountered. ### Status board - [x] hero_rpc#55 — merged + 7 downstream rename PRs merged - [x] hero_skills cleanup commit pushed - [ ] hero_rpc#54 — extend scaffolder (in flight per dispatched agent) - [ ] hero_rpc#59 — Generator per-target refactor (defer until #60) - [ ] hero_rpc#60 — §2 method translators (in flight) - [ ] hero_skills#260 — new scaffold/check/refactor skills (in flight) - [ ] hero_rpc#57 — upgrade recipe_server (blocked on #54) - [ ] hero_skills#261 — bootstrap hero_service template repo (blocked on #54) Agents dispatched in parallel against `development` (now containing the merged #55 work) — they no longer need to coordinate against the feature branch.
Author
Owner

Tier-3 #54 landed on issue-54-scaffold-extend (review-ready)

Full writeup on hero_rpc#54. Single commit, ~760 LOC in crates/generator/src/build/scaffold.rs.

What landed

All six items in the META's #54 scope:

  • _examples crate generation
  • Dropped Makefile + buildenv.sh (ADR-0001)
  • PURPOSE.md modelled on hero_proc/PURPOSE.md (Binary/Crate tables + Key Features + lab-only Service Management)
  • README.md with lab service ... lifecycle only — no make, no bash, no nu
  • .gitignore
  • .forgejo/workflows/build-linux.yaml per forge-release-workflow skill (self-contained Rust variant, ADR-0001-compatible — no build_lib.sh)

Plus one bonus: pre-#54 the core + _sdk crates had no src/lib.rs, so cargo metadata errored before lab infocheck could validate anything. Added 2-line stubs that the OSchema generator enriches on first build.

lab infocheck clean, zero manual edits

repo: $TMP
crates discovered: 2
  ok   $TMP/crates/hero_demo_admin
  ok   $TMP/crates/hero_demo_server
summary: 2 crate(s) clean, 0 crate(s) with issues, 0 finding(s) total

Test impact

cargo test -p hero_rpc_generator → 110 → 121 passed. 10 new tests against on-disk scaffold artefacts. cargo fmt --check clean.

Branch / merge order

issue-54-scaffold-extend, branched off issue-55-codegen-alignment per the META's authority order. Merge sequence is #55 → development first, then #54 → development (or rebase #54 once #55 lands).

Updated status board

  • hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename (review-ready on branch)
  • hero_rpc#54 — extend scaffolder (review-ready on branch)
  • hero_rpc#59 — Generator per-target refactor (unblocked; defer until #60 lands)
  • hero_rpc#60 — §2 method translators
  • hero_skills#260 — new scaffold/check/refactor skills (now fully unblocked — scaffolder shape is final)
  • hero_rpc#57 — upgrade recipe_server (unblocked by #54)
  • hero_skills#261 — bootstrap hero_service template repo (unblocked by #54)

Open Timur actions

  • Review + merge hero_rpc#55 (and the matching downstream branches).
  • Review + merge hero_rpc#54 after #55 lands.
  • Push the still-local hero_skills cleanup commit 2a05555 from #260 tier-1.
## Tier-3 #54 landed on `issue-54-scaffold-extend` (review-ready) Full writeup on [hero_rpc#54](https://forge.ourworld.tf/lhumina_code/hero_rpc/issues/54#issuecomment-34033). Single commit, ~760 LOC in `crates/generator/src/build/scaffold.rs`. ### What landed All six items in the META's #54 scope: - `_examples` crate generation - Dropped `Makefile` + `buildenv.sh` (ADR-0001) - `PURPOSE.md` modelled on `hero_proc/PURPOSE.md` (Binary/Crate tables + Key Features + lab-only Service Management) - `README.md` with `lab service ...` lifecycle only — no `make`, no bash, no nu - `.gitignore` - `.forgejo/workflows/build-linux.yaml` per `forge-release-workflow` skill (self-contained Rust variant, ADR-0001-compatible — no `build_lib.sh`) Plus one bonus: pre-#54 the core + `_sdk` crates had no `src/lib.rs`, so `cargo metadata` errored before `lab infocheck` could validate anything. Added 2-line stubs that the OSchema generator enriches on first build. ### `lab infocheck` clean, zero manual edits ``` repo: $TMP crates discovered: 2 ok $TMP/crates/hero_demo_admin ok $TMP/crates/hero_demo_server summary: 2 crate(s) clean, 0 crate(s) with issues, 0 finding(s) total ``` ### Test impact `cargo test -p hero_rpc_generator` → 110 → **121 passed**. 10 new tests against on-disk scaffold artefacts. `cargo fmt --check` clean. ### Branch / merge order [`issue-54-scaffold-extend`](https://forge.ourworld.tf/lhumina_code/hero_rpc/src/branch/issue-54-scaffold-extend), branched off `issue-55-codegen-alignment` per the META's authority order. Merge sequence is **#55 → development first, then #54 → development** (or rebase #54 once #55 lands). ### Updated status board - [x] hero_rpc#55 — codegen alignment + hero_rpc2 vendor + rename (review-ready on branch) - [x] **hero_rpc#54 — extend scaffolder (review-ready on branch)** - [ ] hero_rpc#59 — Generator per-target refactor (unblocked; defer until #60 lands) - [ ] hero_rpc#60 — §2 method translators - [ ] hero_skills#260 — new scaffold/check/refactor skills (now fully unblocked — scaffolder shape is final) - [ ] hero_rpc#57 — upgrade recipe_server (unblocked by #54) - [ ] hero_skills#261 — bootstrap hero_service template repo (unblocked by #54) ### Open Timur actions - Review + merge hero_rpc#55 (and the matching downstream branches). - Review + merge hero_rpc#54 after #55 lands. - Push the still-local `hero_skills` cleanup commit `2a05555` from #260 tier-1.
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_skills#262
No description provided.