--- id: key-extraction-in-h name: Extract key from props in h() status: pending depends_on: [key-on-uelement] created: 2026-05-18T16:22:57.111275411Z modified: 2026-05-18T16:22:57.111275823Z scope: narrow risk: low impact: component level: implementation --- # Description Modify `h()` and `createRoot()` to extract `key` from props and promote it to the element-level `key` field. This ensures component functions never receive `key` in their props — it is stripped during construction, not during component invocation. Per ADR-004: `key` is a reconciler concern, not a prop. The factory layer is where the extraction happens, so that every downstream consumer (components, hosts, transforms) sees `key` only on the element, never in `props`. ## Acceptance Criteria - [ ] `h()` extracts `key` from `props` before constructing the element - [ ] `key` is promoted to the returned element's `key` field (top-level) - [ ] `key` is removed from `resolvedProps` so component functions never see it - [ ] `createRoot()` does NOT extract `key` (URoot has no key field) - [ ] `h("root", { key: "x" })` — `key` stays in props for URoot (no promotion) - [ ] Existing tests pass (`npm run test`) - [ ] New test: `h("div", { key: "a" })` produces `UElement` with `key: "a"` and no `key` in `props` - [ ] New test: `h("div", { key: "b", class: "x" })` — `key` promoted, `class` remains in props - [ ] New test: `h("div", null)` — `key` is `undefined`, no `key` in props ## References - docs/architecture/element-factory.md — Known Gaps: `key` prop not extracted - docs/architecture/decisions/004-key-as-first-class-field.md — ADR-004 decision and consequences - docs/architecture/reconciler.md — Fiber Node `key` field ## Notes > To be filled by implementation agent ## Summary > To be filled on completion