diff --git a/PLAN.md b/PLAN.md
index ed58428..bfd85d5 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -21,7 +21,7 @@
- [ ] **State:** In progress — the package-native capped xtask entry point is reachable, rejects unknown packages, propagates mutest failure, and mutation-tests `hemx-axum`, `hemx-core`, `hemx-js`, and the full `hemx-test` package cleanly; full package closure remains.
- **User value:** maintainers can run one bounded repository command and trust that meaningful Rust logic across every mutation-applicable library is either killed or explicitly justified.
- **Build:** add a capped `hemx-xtask` mutation command that invokes `/opt/repositories/mutest`/`mutest` through package-native test targets rather than the broken workspace-wide example path; enumerate only current mutation-applicable library/proc-macro packages; finish adversarial tests or simplify code until every survivor is classified; keep equivalent, invariant-only, and infrastructure-inapplicable classifications inspectable and minimal; document the exact local release command in the existing readiness surface.
-- **Blocked by:** none; broad survivors currently remain in `hemx-build`, `hemx-derive`, and `hemx-lsp` outside already-clean focused contracts. The current `hemx-build` frontier now also mutation-proves all 59 placement-diagnostic mutants with exact `InvalidData` paths, attributes, and guidance for navigation, boost containers, client modules, and SSE roots, plus their valid placements. The remaining package frontier starts at static attribute-value and keyed-scope diagnostics. The complete 470-mutant `hemx-axum` package gate now passes with 262 caught and 208 unviable after public page/form/multipart/registry/response/runtime proofs and narrow classification of infallible header parsing and streamed multipart unwrap-equivalent mutants.
+- **Blocked by:** none; broad survivors currently remain in `hemx-build`, `hemx-derive`, and `hemx-lsp` outside already-clean focused contracts. The current `hemx-build` frontier now also mutation-proves all 112 static attribute-value mutants and all 21 keyed-scope ancestry mutants: exact `InvalidData` diagnostics cover missing/empty/invalid values, valid boundaries reach `AppBuilder::run`, nested keyed resources lower as keyed, and invalid/sibling scopes stay unkeyed or fail closed. The remaining package frontier starts at unknown/selector attributes and unkeyed-loop diagnostic formatting. The complete 470-mutant `hemx-axum` package gate now passes with 262 caught and 208 unviable after public page/form/multipart/registry/response/runtime proofs and narrow classification of infallible header parsing and streamed multipart unwrap-equivalent mutants.
- **Proof:** the new xtask mutation command exits zero within its documented bound, covers each applicable package, emits no unexplained missed mutant, and a deliberate adjacent mutation makes it fail. `cargo run -p hemx-xtask -- test` remains green. req: test/020 req: test/021
## 3. Elect and enforce the release license policy
diff --git a/hemx-build/src/lib.rs b/hemx-build/src/lib.rs
index 89643ce..23d8cad 100644
--- a/hemx-build/src/lib.rs
+++ b/hemx-build/src/lib.rs
@@ -3639,6 +3639,18 @@ fn main() {{
"data-hemx-handle=\"delete\"",
"ui::delete",
),
+ (
+ "nested-handle",
+ r#""#,
+ "data-hemx-handle=\"delete\"",
+ "ui::delete",
+ ),
+ (
+ "atom",
+ r#"Selected"#,
+ "data-hemx-atom=\"selected\"",
+ "ui::selected",
+ ),
] {
let base = test_dir(&format!("hemx-build-unkeyed-for-{case}-test"));
let templates = base.join("templates");
@@ -3662,6 +3674,87 @@ fn main() {{
let _ = std::fs::remove_dir_all(&base);
}
+
+ let base = test_dir("hemx-build-keyed-nested-resources-test");
+ let templates = base.join("templates");
+ let out = base.join("out");
+ let _ = std::fs::remove_dir_all(&base);
+ std::fs::create_dir_all(&templates).unwrap();
+ let keyed_source = r#"
+
+