host: relations-as-posts slice 2.5 — picker title reads are O(page), not O(pool)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s

relate-candidates computes the available candidate SLUGS (slug-sorted, no per-candidate
read), then reads titles only for the page it returns. On the unfiltered path (q="" —
the initial picker load AND every editor server-fill, the common case) that's ~limit
durable reads instead of one-per-post, cutting the http-listen suspend/resume churn. A
filter (q≠"") still resolves titles across the pool since it matches on the title.

(A boot slug→title cache would make the filter O(1)-perform too, but it's blocked: no
bulk KV read, and a per-post host/blog-get loop at boot hits the JIT 'durable read in a
boot loop drops all-but-first' bug — see plans/relations-as-posts.md.)

conformance 291/291, run-picker-check 3/3 (incl. the title filter + paging).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 07:50:31 +00:00
parent 90190346aa
commit f94b9d0b93
2 changed files with 43 additions and 25 deletions

View File

@@ -58,10 +58,20 @@ the relation's object-end declaration from the anchor**, which includes the root
`host/blog-rel-kinds` is a VALUE the boot populates and the cache loads are UNROLLED.
**Conformance green ≠ correct live — verify the rendered edit page.** (Re-fold the
enumeration once plans/jit-bytecode-correctness.md lands.)
- **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 2.5 — picker title reads are O(page), not O(pool) — DONE
- `relate-candidates` computes the available candidate SLUGS (slug-sorted, no per-candidate
read), then reads titles ONLY for the page it returns. On the unfiltered path (q="" — the
initial picker load AND every editor server-fill, the common case) that's ~`limit` reads
instead of one-per-post — killing the durable-read churn under http-listen. A filter
(q≠"") still resolves titles across the pool (it matches on the title), but that's the
interactive path.
- A boot-time slug→title **cache** would make even the filter O(1)-perform, BUT it's blocked
for now: there's no bulk KV read, and a per-post `host/blog-get` loop **at boot** hits the
JIT bug (a durable read inside a boot loop drops all-but-first — `load-edges!` only works
because its loop body is perform-free). Revisit with a bulk read or once the JIT lands.
**Remaining follow-ups:** subject-end declarations (who may be the *source*); a proper
relation-subtype closure when relations get subtyped; the boot title cache above.
### Slice 3 — typed relations (target-type constraints) — DONE
- The declaration's `declares`-anchor IS the target-type constraint: `is-a`/`subtype-of`