host: relations-as-posts slice 2 — relation metadata lives on relation-posts
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
is-a/subtype-of/tagged/related are now POSTS (each is-a a new `relation` root),
owning their metadata in a :rel slot {:symmetric :label :inverse-label}. The static
host/blog-rel-kinds registry is gone: kind-spec/rel-kinds/kind-symmetric? read the
relation-posts (via an in-memory cache), and the relation list derives from
host/blog-in "relation" "is-a".
Perform-budget fixes (a durable read inside the http-listen render VM raises
VmSuspended; too many per request 500s the page):
- relation metadata is loaded into a cache at boot (host/blog-load-rel-kinds!,
like load-edges!), so kind-spec is pure on render paths;
- the initial edit page renders its pickers EMPTY (the load trigger fills each) —
only the relate/unrelate FRAGMENT server-renders candidates (with-cands flag).
Previously every edit page render did candidate-get × 4 pickers and 500'd.
host conformance 287/287 (+4 slice-2: kind-spec reads :rel, kind-symmetric? off the
post, unknown kind has no spec, rel-kinds derived from the graph). run-picker-check
3/3 (edit page boots, relate/unrelate flow works, no client errors).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -40,11 +40,22 @@ the relation's object-end declaration from the anchor**, which includes the root
|
||||
`host/blog--candidate-pool` to be declaration-driven. `:candidates` becomes vestigial.
|
||||
- Wrinkle fixed: the type roots now appear as `is-a` candidates.
|
||||
|
||||
### Slice 2 — relations as first-class posts
|
||||
- Seed `is-a`/`subtype-of`/`tagged`/`related` as posts that own their metadata
|
||||
(`:symmetric`, `:label`, `:inverse-label`, **cardinality**, **end roles**). The registry
|
||||
`host/blog-rel-kinds` melts into reads off these posts. A relation can declare its
|
||||
*subject*-end anchor too (who may be the source), not just object.
|
||||
### Slice 2 — relations as first-class posts — DONE
|
||||
- `relation` root + `is-a`/`subtype-of`/`tagged`/`related` seeded as posts (each is-a
|
||||
relation) owning their metadata in a `:rel` slot (`:symmetric :label :inverse-label`).
|
||||
`host/blog-rel-kinds` / `kind-spec` / `kind-symmetric?` now read it; the static registry
|
||||
is gone. `host/blog--rel-slugs` = `host/blog-in "relation" "is-a"` (cheap, flat).
|
||||
- **Perform budget under http-listen (the hard lesson):** a durable read inside the
|
||||
render VM raises `VmSuspended`, and too many per request 500s the page. Two fixes:
|
||||
(1) relation metadata is loaded into an in-memory cache at boot (`host/blog-load-rel-kinds!`,
|
||||
like `load-edges!`) so `kind-spec` is pure; (2) the initial edit page renders its pickers
|
||||
EMPTY (the load trigger fills each) — only the relate/unrelate FRAGMENT server-renders
|
||||
candidates (`with-cands` flag), so one page render doesn't do `candidate-get × every
|
||||
picker`. Benign single-perform suspend/resume still logs `VmSuspended` but returns 200.
|
||||
- **Follow-up (Slice 2.5):** `relate-candidates` does a `host/blog-get` per pool member
|
||||
(O(posts) for `related`). A boot-time **title cache** (updated on put!/delete!) would make
|
||||
the picker O(1)-perform and cut the suspend/resume churn. Subject-end declarations + a
|
||||
proper relation-subtype closure (when relations get subtyped) also belong here.
|
||||
|
||||
### Slice 3 — typed relations (target-type constraints)
|
||||
- A declaration carries a **target-type constraint**: the *other* end must be (an instance
|
||||
|
||||
Reference in New Issue
Block a user