plan: types define the UI — editor maps onto the metamodel (cards-as-types)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s

Capture the vision refinement: a type drives BOTH sides of the UI from one definition —
fields {name, value-type, widget} drive the edit form (widget per value-type) AND the
render template (parameterised SX on the type-post, instantiated with field-values). An
instance is just field-values; add a field -> editor + page update, no code. kg-cards
become type-posts (the content-on-sx block vocabulary is the seed set); the editor becomes
a generic field-editor defined by the metamodel (the relation-editors already prove the
pattern). Render template = data (meta-circular); only widgets are platform pieces, selected
by value-type. Refined build order: /meta DONE -> Slice 8 typed fields (KEYSTONE) -> generic
instance form -> render template -> cards-as-types + migrate; plus create-type/create-relation
on /meta + clear-and-reseed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 11:40:53 +00:00
parent 7b9aece52d
commit 360acbe33c

View File

@@ -117,6 +117,42 @@ So the complete picture: the metamodel expresses **structure + validation** of t
platform's domain model uniformly; **behaviour composes from the substrate loops**;
**integrations stay referenced services**. It's the convergence point of every loop in the repo.
### Types define the UI — the editor maps onto the metamodel
The payoff of typed fields (Slice 8): **a type drives both sides of the UI from one definition.**
Beyond name + schema, a type carries **fields** `{name, value-type, widget}` and **templates**:
- **Fields drive the edit UI** — the editor renders one input per field, the widget chosen by the
field's `value-type` (`Date`→date-picker, `URL`→link input, `String`→text, `Image`→uploader).
- **Fields drive the render** — the type's **render template** (a parameterised SX template stored
on the type-post, instantiated with the instance's field-values) references those fields by name.
- An **instance** is then just *field-values* on a post. Add a field to the type → it appears in
the editor *and* the page, **no code touched**. Same definition, both surfaces.
**"kg-cards become types."** Each Koenig/Ghost card — image, gallery, callout, embed, bookmark,
heading — becomes a **type-post** with fields + a render template. We've already enumerated that
whole vocabulary: `[[project_content_on_sx]]` modelled heading/text/code/quote/image/embed/divider/
list/table/callout/media as block types — **that list is the seed set of card-types.** "The old
blog posts get typed" = migrate Ghost content into typed blocks, one type-post per block kind.
**"The editor maps onto the types."** The editor stops being hardcoded card handlers and becomes a
**generic field-editor**: given a type, emit an input per field; on save, store the values; render
through the type's template. A new card = a new type-post, **zero editor code — the editor is
defined by the metamodel.** Proof the pattern works: the edit page's relation-editors are already
*generated* from relation definitions, not hand-coded (one level up from fields).
Honest layer: the **render template is data** (editable, meta-circular); only the irreducible
**widgets** (the date-picker, the image-uploader) are platform pieces, and `value-type` is what
*selects* the widget — the same decidable-core / fenced-frontier line as everywhere else.
**Refined build order** (this is what `/meta` is the on-ramp to):
1. `/meta` overview — DONE (the *see*; `host/blog-type-defs` + `host/blog-meta-index`).
2. **Slice 8 — typed fields** `{name, value-type, widget}` on a type — the **keystone** (drives form + template).
3. **Generic instance form** — input per field ("the editor maps onto types").
4. **Render template per type** — data, field-placeholders.
5. **Cards-as-types + migrate** — seed the card-type vocabulary from content-on-sx; type the old posts.
Plus the editor surfaces on `/meta`: **create-type** / **create-relation** forms, then **clear-and-reseed**.
## Behaviour as data — lifecycles + ECA over an effect vocabulary (DESIGN — Slice 9)
Structure is inert; "place an order / ship goods" is the dynamic part. The principle: