feat(cliloc): import the table from the shard, not from a file someone converted (Phase 2) #36

Merged
whitlocktech merged 1 commits from feat/asset-bridge-p2 into edge 2026-09-10 16:20:14 +00:00
Member

Phase 2 of the Asset Bridge (docs/link/v8.md §9), website half. Pairs with servuo-plugins#29, link#42, and the website / docs PRs.

What changes

The base cliloc table comes over the bridge. clilocBridge.js walks GET /cliloc page by page and the model merges the custom/ overlays over it — overlays stay on disk because ServUO has no server-side notion of a custom cliloc, so there is nothing on the shard to ask for.

The shard wins whenever uo-link is configured and enabled, with no mode setting: there is no version of "which source?" an operator benefits from answering. A file on disk remains the source only where there is no shard link, plus a one-off explicit path — deprecated, not removed, and otherwise unchanged.

Boot no longer imports on the bridge. The file path could hash 5 MB locally and skip in 14 ms; a shard round trip in the boot sequence would be spent answering "no" on every restart but the one after a client patch — and patching a client is an operator action, so importing became one. Admin → Shard → Import. Whatever table is loaded keeps serving until then.

The three checks in the walk

Each is a way a shard can hand back a table that looks complete, which is the failure that matters here — a truncated cliloc table renders some items named and some not, which is exactly what no table looks like.

  • Only cut: 'end' finishes it; a short page can equally be a spent budget.
  • The cursor must advance, or the walk stops rather than spinning.
  • Every page echoes the source's size and mtime, so a client patched mid-import is refused outright (SOURCE_CHANGED) rather than stitched from two files.

The base is exempt from the vanished-source rule

An upgrade detail, not a preference: an install that used the file pipeline carries its base file's label in the stored fingerprint, and on the bridge that label is supposed to disappear. Counting it as vanished would make the first import after the upgrade demand approval for a change the upgrade itself made. Overlays keep the rule in full.

The protocol pin moves 7 → 8

The third declaration site, and the one nothing enforces. Phase 1 moved the sidecar and the overlay together because the installer refuses a mismatched bundle; this one has to be moved by hand, in the phase that first calls a protocol-8 route. The schema block above it is the record of what forgetting costs: two phases of every REST call answered 409.

Verified

  • 651 tests pass (29 new: the paging walk's invariants, and which source runs).
  • Live, against a real ServUO + sidecar + site: 12 pages, 67,496 rows imported in 1.68 s, the operator's three-row overlay overriding stock strings on top of it, the next import correctly unchanged, and the boot log reading cliloc table comes from the shard; import is admin-triggered.

AI disclosure

Written with Claude Code (Opus 5); commits carry the Co-Authored-By trailer.

🤖 Generated with Claude Code

https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4

Phase 2 of the **Asset Bridge** (`docs/link/v8.md` §9), website half. Pairs with servuo-plugins#29, link#42, and the website / docs PRs. ## What changes The base cliloc table comes over the bridge. `clilocBridge.js` walks `GET /cliloc` page by page and the model merges the `custom/` overlays over it — overlays stay on disk because ServUO has no server-side notion of a custom cliloc, so there is nothing on the shard to ask for. **The shard wins whenever uo-link is configured and enabled**, with no mode setting: there is no version of "which source?" an operator benefits from answering. A file on disk remains the source only where there is no shard link, plus a one-off explicit `path` — deprecated, not removed, and otherwise unchanged. **Boot no longer imports on the bridge.** The file path could hash 5 MB locally and skip in 14 ms; a shard round trip in the boot sequence would be spent answering "no" on every restart but the one after a client patch — and patching a client is an operator action, so importing became one. Admin → Shard → Import. Whatever table is loaded keeps serving until then. ## The three checks in the walk Each is a way a shard can hand back a table that *looks* complete, which is the failure that matters here — a truncated cliloc table renders some items named and some not, which is exactly what **no** table looks like. - Only `cut: 'end'` finishes it; a short page can equally be a spent budget. - The cursor must advance, or the walk stops rather than spinning. - Every page echoes the source's size and mtime, so a client patched mid-import is refused outright (`SOURCE_CHANGED`) rather than stitched from two files. ## The base is exempt from the vanished-source rule An upgrade detail, not a preference: an install that used the file pipeline carries its base file's label in the stored fingerprint, and on the bridge that label is *supposed* to disappear. Counting it as vanished would make the first import after the upgrade demand approval for a change the upgrade itself made. Overlays keep the rule in full. ## The protocol pin moves 7 → 8 The third declaration site, and the one nothing enforces. Phase 1 moved the sidecar and the overlay together because the installer refuses a mismatched bundle; this one has to be moved by hand, in the phase that first calls a protocol-8 route. The schema block above it is the record of what forgetting costs: two phases of every REST call answered `409`. ## Verified - **651 tests pass** (29 new: the paging walk's invariants, and which source runs). - **Live**, against a real ServUO + sidecar + site: 12 pages, **67,496 rows imported in 1.68 s**, the operator's three-row overlay overriding stock strings on top of it, the next import correctly `unchanged`, and the boot log reading `cliloc table comes from the shard; import is admin-triggered`. ## AI disclosure Written with Claude Code (Opus 5); commits carry the `Co-Authored-By` trailer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
wtclaude added 1 commit 2026-09-10 16:15:25 +00:00
feat(cliloc): import the table from the shard, not from a file someone converted (Phase 2)
All checks were successful
PR Checks / client-build (pull_request) Successful in 34s
PR Checks / frozen-manifest (pull_request) Successful in 53s
PR Checks / server-tests (pull_request) Successful in 8m18s
893a36618b
The base cliloc table now comes over the bridge. `clilocBridge.js` walks
`GET /cliloc` page by page and the model merges the `custom/` overlays over it —
overlays stay on disk because ServUO has no server-side notion of a custom
cliloc, so there is nothing on the shard to ask for.

**The shard wins whenever uo-link is configured and enabled**, with no mode
setting: there is no version of "which source?" an operator benefits from
answering. A file on disk remains the source only where there is no shard link,
plus a one-off explicit `path` — deprecated, not removed, and unchanged.

**Boot no longer imports on the bridge.** The file path could hash 5 MB locally
and skip in 14 ms; a shard round trip in the boot sequence would be spent
answering "no" on every restart but the one after a client patch — and patching a
client is an operator action, so importing became one. Admin → Shard → Import.
Whatever table is loaded keeps serving until then.

Three checks in the walk, each for a way a shard can hand back a table that looks
complete:

  * only `cut: 'end'` finishes it — a short page can equally be a spent budget,
    and a truncated table renders some items named and some not, which is exactly
    what NO table looks like;
  * the cursor must advance, or the walk stops rather than spinning;
  * every page echoes the source's size and mtime, so a client patched mid-import
    is refused outright rather than stitched from two files.

**The base is exempt from the vanished-source rule**, which is an upgrade detail
rather than a preference: an install that used the file pipeline carries its base
file's label in the stored fingerprint, and on the bridge that label is *supposed*
to disappear. Counting it as vanished would demand an approval for a change the
upgrade itself made. Overlays keep the rule in full.

**The protocol pin moves 7 → 8** — the third declaration site, and the one
nothing enforces. Phase 1 moved the sidecar and the overlay together because the
installer refuses a mismatched bundle; this one has to be moved by hand, in the
phase that first calls a protocol-8 route. The schema block above it is the
record of what forgetting costs: two phases of every REST call answered 409.

Verified against a live shard, sidecar and site: 12 pages, 67,496 rows imported
in 1.68 s, the operator's three-row overlay overriding stock strings on top of
it, and the next import correctly `unchanged`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
whitlocktech merged commit 55df03496d into edge 2026-09-10 16:20:14 +00:00
whitlocktech deleted branch feat/asset-bridge-p2 2026-09-10 16:20:15 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Module-uo#36
No description provided.