stabilize architecture docs: address review findings and advance to stable

Critical fixes:
- Restructure pointers.md: move setNode prop-key writes section under
  its own heading (was incorrectly nested under selectNode)
- Add Context/Density/Direction/RenderContext documentation section
  to host-config.md (was only a brief constraint bullet)
- Advance all 5 ADRs from Status: Proposed → Accepted and frontmatter
  from status: draft → status: stable (decisions are driving implementation)
- Add error handling philosophy section to README

Warning/suggestion fixes:
- Add isUElement null check (node !== null) to schema.md discriminator table
- Add UjsxEnvelope convenience type documentation to events.md
- Add Direction Unicode arrow naming note to transforms.md
- Standardize all cross-references from absolute docs/research/ paths
  to relative ../research/ paths across all architecture docs
- Fix schema.md ADR references to use relative paths
- Reduce redundancy between transforms.md and host-config.md Direction notes
- Update all architecture doc frontmatter from draft → stable

Deferred:
- Performance model section (reconciler not yet built)
- Concepts/glossary document (low ROI at current scale)
- Line counts in source references (would date quickly)
This commit is contained in:
2026-05-18 16:10:24 +00:00
parent 23659233ca
commit 0d5b9d5ea8
16 changed files with 167 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
---
status: draft
status: stable
last_updated: 2026-05-18
---
@@ -124,7 +124,7 @@ function isUPrimitive(node: UNode): node is UPrimitive
| Guard | Logic | Discriminator |
|-------|-------|---------------|
| `isUElement` | `typeof === "object" && "type" in node && "props" in node && "children" in node && node.type !== "root"` | Has `type`/`props`/`children` keys AND `type` is not `"root"` |
| `isUElement` | `typeof node === "object" && node !== null && "type" in node && "props" in node && "children" in node && node.type !== "root"` | Has `type`/`props`/`children` keys, is not null, and `type` is not `"root"` |
| `isURoot` | `typeof === "object" && "type" in node && node.type === "root"` | `type === "root"` |
| `isUPrimitive` | `typeof === "string" \|\| typeof === "number" \|\| typeof === "boolean" \|\| node === null` | Not an object |
@@ -151,7 +151,7 @@ The reconciler architecture (see [reconciler.md](reconciler.md) and [ADR-004](de
## Open Questions
1. **Should `key` accept numbers?** React coerces number keys to strings. The current proposal enforces `string` only — simpler, no implicit coercion. Users can wrap in `String()`. See [ADR-004](decisions/004-key-as-first-class-field.md) and research: [00-KEY-FIELD-DESIGN.md](../../research/reconciler/00-KEY-FIELD-DESIGN.md).
1. **Should `key` accept numbers?** React coerces number keys to strings. The current proposal enforces `string` only — simpler, no implicit coercion. Users can wrap in `String()`. See [ADR-004](decisions/004-key-as-first-class-field.md) and research: [00-KEY-FIELD-DESIGN.md](../research/reconciler/00-KEY-FIELD-DESIGN.md).
2. **Should `UPrimitive` include `undefined`?** Currently `null` represents an explicitly empty value. `undefined` means "absent" and should not appear as a tree node. This is consistent with how JSX treats `undefined` children (rendered to nothing), but some hosts might benefit from an explicit "missing" sentinel. No current use case justifies this.
3. **Should `UniversalProps` constrain value types per-host?** The open schema allows any `PropValue` for any key. A host that wants stricter prop contracts (e.g., `onClick` must be a function, `className` must be a string) must validate at its own boundary. A future host-typed props system could be layered on top without changing the base schema.
@@ -160,6 +160,6 @@ The reconciler architecture (see [reconciler.md](reconciler.md) and [ADR-004](de
- Source: `src/core/schema.ts`
- Key field ADR: [decisions/004-key-as-first-class-field.md](decisions/004-key-as-first-class-field.md)
- Reconciler architecture: [reconciler.md](reconciler.md)
- Key field design research: `docs/research/reconciler/00-KEY-FIELD-DESIGN.md`
- TypeBox Module as type registry: `docs/architecture/decisions/002-typebox-module-as-registry.md`
- HTML-agnostic core: `docs/architecture/decisions/001-html-agnostic-core.md`
- Key field design research: `../research/reconciler/00-KEY-FIELD-DESIGN.md`
- TypeBox Module as type registry: [decisions/002-typebox-module-as-registry.md](decisions/002-typebox-module-as-registry.md)
- HTML-agnostic core: [decisions/001-html-agnostic-core.md](decisions/001-html-agnostic-core.md)