You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Four independent upstream primitives for the trusted-server -> EdgeZero migration. Delivered in #306; base is the #300 branch and auto-retargets to main when #300 merges.
Specs:
docs/superpowers/specs/2026-07-02-edgezero-state-and-nested-secrets-design.md (A + B)
State<T> extractor (FromRequest by type from request extensions; Deref/into_inner; 500 when unregistered); composes in #[action] with no macro change.
RouterBuilder::with_state<T> stores state in a single state_extensions: Extensions bag; dispatch extends it into every request. Shipped State<T> + with_state only (no Extension alias, no ctx.state() accessor).
B-3 (const -> fn):AppConfigMeta::secret_fields() -> Vec<SecretField> -- cross-crate const concat was not expressible, so the fn form was taken; every impl (incl. test impls) flipped.
Router uses the crate::http::Extensions facade; no lib.rs re-export; validate_excluding_secrets got true nested/list-aware pruning; a purpose-built KeyInNamedStore fixture was added.
Acceptance criteria
All 5 CI gates green (fmt, clippy, workspace tests, feature check, spin wasm32) -- plus the nested-AppConfig audit, app-demo (own workspace) tests + clippy, and Fastly wasm32-wasip1 + Viceroy tests.
Unit + trybuild UI + integration tests per spec 3.4 / 4.7.
app-demo builds/serves on all four adapters; top-level #[secret] api_token still resolves.
edgezero-cli config validate/push/diff work over nested + array secrets.
Status: implemented in #306 (stacked on #300)
Four independent upstream primitives for the trusted-server -> EdgeZero migration. Delivered in #306; base is the #300 branch and auto-retargets to
mainwhen #300 merges.Specs:
docs/superpowers/specs/2026-07-02-edgezero-state-and-nested-secrets-design.md(A + B)docs/superpowers/specs/2026-07-03-edgezero-p0cd-fastly-dispatch-and-appstate-design.md(P0-C + P0-D)Task-by-task plans under
docs/superpowers/plans/.Workstream A --
State<T>extractorState<T>extractor (FromRequestby type from request extensions;Deref/into_inner;500when unregistered); composes in#[action]with no macro change.RouterBuilder::with_state<T>stores state in a singlestate_extensions: Extensionsbag; dispatchextends it into every request. ShippedState<T>+with_stateonly (noExtensionalias, noctx.state()accessor).Workstream B -- nested / array
#[secret]SecretField { kind, path: Vec<SecretPathSegment>, optional };AppConfigMeta::secret_fields() -> Vec<SecretField>(const -> fn).#[app_config(nested)]object +Vec<_>fields; acceptsOption<String>; path/renameguards;AppConfigRootassertion.secret_walkpath navigator; nested/list-awarevalidate_excluding_secretspruning; CLI path-aware TOML collector for validate/push/diff; inverted nested-AppConfig CI guard.P0-C -- Fastly
run_appdispatch fidelitySet-Cookie(response + proxy response/request); C2 platform-neutralHooks::owns_logging()gated across all four adapters +app!(owns_logging = <bool>); C3run_app_with_request_extensions, a generic pre-dispatch hook for raw-request signals.P0-D --
app!app-state injectionapp!(state = <expr>)makes the macro-generated router call.with_state(...), reusing A's dispatch injection. Macro-only; app-demo example + e2e test.Open questions -- resolved during implementation
State<T>+with_stateonly; noExtensionalias, noctx.state()accessor.ArrayEachfrom day one (spec's own inventory haspartners[*].api_key).#[app_config(nested)]opt-in (type-heuristic rejected).AppConfigMeta::secret_fields() -> Vec<SecretField>-- cross-crate const concat was not expressible, so thefnform was taken; every impl (incl. test impls) flipped.crate::http::Extensionsfacade; nolib.rsre-export;validate_excluding_secretsgot true nested/list-aware pruning; a purpose-builtKeyInNamedStorefixture was added.Acceptance criteria
app-demobuilds/serves on all four adapters; top-level#[secret] api_tokenstill resolves.edgezero-cli config validate/push/diffwork over nested + array secrets.docs/guide/handlers.md,docs/guide/configuration.md).