1. [x] Stream support — all four kinds (unary, server/client/bidi) at the runtime, transport, and extractor level, with the `#[rpc]` macro inferring `OperationKind` from the signature.
2. [x] Remove the hard requirement for the #[rpc] macro on functions to return Result<T, E>, instead we should migrate to a trait of `Responder` that can be implemented for different return types, this allows for empty responses, results, optionals, infallible, etc all in the type system like normal rust! this will also require a trait for error responses aswell to ensure they also can be returned via the transport.
3. [x] Add status code support for responses, mainly error responses but potentially also for successful responses. (Error responses now carry a structured `StatusCode` (flags / predefined / custom sections) plus an arbitrary serialized body via the Actix-style `IntoErrorResponse`/`ErrorResponse`; success path unchanged. Successful-response codes intentionally deferred.)
4. [x] Generate client sdk from descriptors, we need to investigate how this should be done since it can either be a runtime thing or a complete crate we generate. (Depends on status codes (3) + streaming being settled; start with a runtime-vs-generated-crate spike.). One idea is that the proc macros can generate client code inline alongside the descriptors, but that means we always compile in client code next to daemon code.
5. [x] Arc<dyn T>, Vec<Arc<dyn T>>, HashMap<String, Arc<dyn T>> support for dependencies. This is a common pattern for dependency injection, and we should support it out of the box. this includes support for provide = dyn T and provide = [dyn T, dyn Y] on #[component] and #[service], and also adding qualifiers and primary attrs to help usability of injecting deps. (Orthogonal DI track; swap with 4 if richer DI matters more than usable clients.)
6. [x] Migrate Stream types to support impl Stream<Item = T> and impl Stream<Item = Result<T, E>> for more ergonomic stream handling. (Handlers now return/accept `impl Stream<..>` or a generic `S: Stream<..>` — auto-detected by `#[rpc]` and auto-wrapped — plus `#[rpc(stream)]` for concrete return types. Per-item wire format is owned by the `StreamEncode`/`StreamDecode` codecs (blanket postcard impls for `Serialize`/`DeserializeOwned`, overridable `into_frames`/`from_frames`). The generated client is symmetric with the daemon: client-streaming takes the input stream and returns the one response; bidi takes an input stream and returns a response stream, pumped concurrently on its own task (send/recv fully independent). `ResponseStream`/`Streaming` kept as escape hatches.)
7. [x] Add scoped dependencies, connection, request and transient scopes. (Components carry a `scope` (`#[component(scope = connection|request|transient)]`); `#[service]` stays singleton. The container is now a parent-linked `ScopeContainer` chain — request → connection → singleton — built eagerly per scope (connection at accept, request per call) with on-demand `Transient` construction; the factory-facing `resolve` is async so the eager→lazy migration stays internal. Handlers consume scoped deps via the `Inject<H>` extractor; `PeerInfo` is a framework-seeded by-value connection-scoped injectable. The captive-dependency rule (`Singleton > Connection > Request`, transients singleton-only in v1) is enforced via a rank fn in `validate_scopes`. Empty scopes are skipped: a scope with nothing to construct and no seeds reuses its parent container (so a pure-singleton daemon allocates no per-connection/per-call scope), with `PeerInfo` reached by handlers via the `Peer` extractor (off the call context) so the connection scope only materializes when a component actually depends on the peer. The old `ConnectionHandler`/`ConnectionInfo`/`Extension`/`Conn` path is removed. Scope creation funnels through one `open_child` primitive and a numeric rank, so user-defined scopes can generalize the internals later without a rewrite — deferred. The `Scoped<T>` proxy field (Spring-style) is also deferred.)
8. [x] Config system built in for the daemon with optional hot reload support. Must be typed and preferably be able to specify a way to read from env in the config struct like `${ENV_VAR}` where it can be replaced when reading it in. Take spring as inspiration for this. One cool addtion to this would be the ability to script the config, so configs like if this value is set then x, y and z happens aswell and gets configured. (Feeds native daemon support (7).)
9. [x] Rename to `overseerd`.
10. [x] Add builtin components, config structs and more. Only rule is that it should either be common enough to be builtin, or it should be gated behind a feature flag. Things that can be included here is framework primitives for the internal connection, utilities that are seen commonly used or potentially will be used, etc. (v1 ships a minimal infra-only set: `ShutdownHandle` as a seeded singleton injectable, opt-in `ServerConfig`/`LoggingConfig` `ConfigProperties` structs, and a feature-gated (`tracing-subscriber`) `init_tracing` helper. Middleware-shaped builtins — a tracing/metrics middleware, a request-context — depend on (11)'s traits and are deferred to a "builtin middleware" follow-up (10b).)
11. [x] Middleware, dedicated error handler flow (like GlobalExceptionHandler), guards and more request flow management. (Built on the `tower` `Layer`/`Service` model: the dispatch path is a `Service<RpcRequest, RpcOutcome, ErrorResponse>` whose terminal is `RouterService`; global middleware are tower layers registered via `DaemonBuilder::middleware` (any protocol-agnostic tower layer composes), folded into a `BoxCloneService` cloned per call. Guards are a pre-handler admit/reject `Guard` adapted into a `GuardLayer` via `.guard`. The global `ErrorHandler` (`.error_handler`) is an egress hook in `drive_call`, so it also transforms mid-stream errors and errors raised by the layer stack. The `daemon!` macro gained matching `middleware`/`guards`/`error_handler` keys; `tower` is re-exported. The `RpcHandler`/`RpcOutcome` signatures are unchanged. Per-route `#[rpc(middleware = [..])]` is deferred.)
12. [x] Add default_factory = false support to component and service macros, with this also add a factory = SomeService::init instead that then becomes required for auto registration to work, if the factory attr is not present we will just not register this dep automatically and assume that the user wants to construct it manually. This will force us to introduce one or maybe two new traits to define what a factory is and that it must consist of only injectable params and if di-check is on all params must be provided, we can then behind the scenes handle the conversion from ComponentConstructionContext into the individual params, this is similar to how FromContext works. (Done as part of the macro-unification work. Construction is now described by `crates/core/src/construct.rs`: `FromContainer` (per-param extractor + its dependency edge), `FactoryOutput` (normalizes `Self` vs `Result<Self,E>`), and `Factory<Args>` (every async factory fn, keyed on its arg tuple — reports `dependencies()` from its params and `construct()`s them; the FromContext analogue). `#[component(factory = path)]`/`#[service(factory = path)]` register an explicit async factory; `#[component(default_factory = false)]` is the manual case (provided via `with_component`) that replaced the now-removed `#[derive(Component)]`. Each component owns a per-type `{Type}Factories` linkme slice (the field-injection default + any `#[init]`/`factory=` entry); `effective_factory()` picks one (≥2 explicit → `AmbiguousFactory`). `#[init]` moved out of `#[handlers]` into a new `#[methods]` macro and is wired through `Factory`, so it now accepts the full `FromContainer` param range (Cfg/Vec/by-value), not just `Arc<T>`. `#[derive(ConfigProperties)]` also became the `#[config]` attribute. **Deferred:** di-check (compile-time `Wiring: Provide<..>`) for `factory=`/`#[init]` params — their deps are currently validated at build time via `validate_dependencies` only; gating the `FromContainer` impls on `Provide` under `di-check` would restore compile-time coverage. Also deferred: const-generic `Qualified<"q", T>`/`CfgBind<"path", T>` param shapes (needs `adt_const_params`, unstable).)
13. [ ] Native daemon support, i.e. integrate with things like systemd on linux and launchd on macos to send ready signals, handle shutdown signals, and generally be a good citizen on the platform. This would be one of the biggest selling points of this outside of the DI complexity being managed for you.
14. [ ] Health checks to systemd, launchd, etc that can be based on user defined health checks in the code. (Built directly on native daemon support (7).)
15. [ ] Multi-frame messages, see large payloads and handle reading it up to a configurable max frame size or infinity (should be configurable by the user). (Codec hardening; transparent to the SDK, so do when large payloads become a real need.)
16. [ ] Write propper documentation and wiki for the entire project. Both high level but also low level implementation details.
17. [ ] Add TLS support for transports. (Prerequisite for QUIC (11) and independently valuable; pull earlier if secure deployments are needed sooner.)
18. [ ] Add quic transport. (Removes the streaming head-of-line blocking; one transport stream per call. Requires TLS (10).)
19. [ ] Add h3 transport. (Runs on top of QUIC (11).)
20. [ ] Support custom protocols (what is sent over the wire, hard to do but can be powerful). (Deferred — design the pluggable wire format from real examples like status codes (3) and multi-frame (9) rather than speculatively; riskiest item.)
21. [ ] Feature gate things like inventory for platforms or devs that dont want DI to happen via auto-discovery, this would disable just that flow and optimize generated code for manual registration instead. (Build-flexibility polish, low urgency.)
22. [ ] Object-safe `DescriptorRuntime<D>` trait — the dyn-compatible parallel to `Descriptor<D>`: `fn descriptor(&self) -> D`, blanket-impl'd over `Descriptor<D>`, added as a supertrait by `#[injectable]` so a live `dyn Trait` (a resolved provider) can self-report its `ComponentDescriptor` at runtime. Purely post-construction **introspection** — it cannot avoid any framework lookup (descriptors are consumed at build time, before instances exist), so it earns its place only with a consumer: richer `Daemon`/registry `Display`, a `/services`-style introspection RPC, structured logging of the resolved provider, or a plugin registry. Build it *with* that first consumer (likely the native-daemon / health-introspection line, 13/14), not speculatively — adding the supertrait costs a vtable entry and couples user traits to the framework.
23. [ ] Split `crates/core` (~3.7k LOC) into smaller crates along its existing module seams, so the pieces compile/version independently and the dependency direction is explicit. Natural cuts: **descriptors** (`descriptors/`, `error`, the `Descriptor`/`ServiceRpcs`/`ComponentFactories` traits — the metadata contract everything else builds on, no deps), **di/container** (`container`, `construct`, `descriptors/component` runtime, `registry` — the DI engine over descriptors), **config** (`config/` — already a thin layer over `crates/config`), **runtime** (`daemon`, `router`, `extract`, `middleware`, `lifecycle`, `builtins`, `dirs` — the serve loop and request flow), with `overseerd-core` (or just the `overseerd` facade) re-exporting them. Watch-outs: the proc macros emit `::overseerd::<Item>` facade paths (not core-internal paths), so the *facade* re-exports must stay stable — splitting is invisible to generated code as long as the facade surface is unchanged; the big inline `#[cfg(test)]` suites (`registry` ~765 LOC incl. tests, `extract`, `container`) move with their module; and several types are deliberately cross-cutting (`ScopeContainer`↔`ComponentConstructionContext`, `RpcCallContext` used by both runtime and descriptors) so the descriptors/di boundary needs care to avoid a cycle. Low urgency — purely structural, no behavior change — but compile times and mental load both improve as core keeps growing.
