fix(assets): a busy shard is not a broken one, and a column that reached no existing install (Phase 9a) #42

Merged
whitlocktech merged 1 commits from feat/asset-bridge-p9 into edge 2026-09-14 22:26:31 +00:00
Member

Two defects the Phase 9 acceptance walk found on the real rig — one ours, one released (docs/link/v8.md §17.14, docs#244).

1. "The shard is not answering for client files" — about a shard that was answering fine

The status call exhausts its 425 backoff whenever something else holds the shard's single asset slot: an import the operator started, or the item-art warm pass refilling itself after a client patch. Phase 8's panel rendered that with the same banner as a shard that is down or has the plane switched off, and left it standing, because the page only re-reads after an action.

On the rig the banner was up for about fifteen minutes while the warm pass refilled 313 item pictures — and every direct call to the same route in that window returned a full, healthy status (40/40 in one sample).

BUSY now says what it is, and one automatic re-read four seconds later clears the ordinary case. One per mount, guarded by a ref: a page that retried forever would be holding the slot it is waiting for. DOWN, DISABLED and NO_IMAGING read exactly as they did.

2. Every spawn-atlas import on an upgraded install has failed since v1.2.0

Unknown column 'unique_id' in 'INSERT INTO'
  sql: INSERT INTO shard_spawn_points (id, facet, name, unique_id, x, y, …)

shard_spawn_points.unique_id (Events Phase 12b, 10fde87, 2026-09-07) was added to the CREATE TABLE and nowhere else. CREATE TABLE IF NOT EXISTS does not add a column to a table that already exists — which is what the twenty-odd ADD COLUMN IF NOT EXISTS lines in that same file are for — so it reached fresh installs and no existing one, while replaceAtlas inserts the column unconditionally.

Blast radius on an upgraded install: no bestiary refresh, no spawn map, no champion altars, no landmarks. In released v1.2.0, v1.2.1, v1.2.2.

A fresh install cannot reproduce it, and neither can a test whose schema is this file applied to an empty database. It took a rig whose tables predate 12b. That is the same blind spot the protocol-pin block above it records — two phases running.

Org lead, weighing that it is already released: it ships here on edge rather than as a hotfix to main.

Verified by dropping the column, rebooting, watching the fragment replay put it back (schema ensured for module "uo" {"statements":75}), then importing 6,455 spawners / 387 regions / 558 landmarks / 25 champion altars in 1.29 s over the bridge.

This branch does not fix it: edge is missing main's #35 ("keep the UniqueId"), so the walk measured 0 of 6,455 spawners carrying one even after the column existed. main must be synced into edge before the cutover or it ships a regression — recorded in v8.md §16 row 9b.

Checks

npm test --prefix server 720 passing, npm test --prefix client 45 passing, client chunk rebuilt and the new branches confirmed present in it.

AI disclosure

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

🤖 Generated with Claude Code

https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4

Two defects the Phase 9 acceptance walk found on the real rig — one ours, one released (`docs/link/v8.md` §17.14, docs#244). ## 1. "The shard is not answering for client files" — about a shard that was answering fine The status call exhausts its 425 backoff whenever something else holds the shard's **single asset slot**: an import the operator started, or the item-art warm pass refilling itself after a client patch. Phase 8's panel rendered that with the **same banner as a shard that is down or has the plane switched off**, and left it standing, because the page only re-reads after an action. On the rig the banner was up for about **fifteen minutes** while the warm pass refilled 313 item pictures — and every direct call to the same route in that window returned a full, healthy status (40/40 in one sample). `BUSY` now says what it is, and **one** automatic re-read four seconds later clears the ordinary case. One per mount, guarded by a ref: a page that retried forever would be holding the slot it is waiting for. `DOWN`, `DISABLED` and `NO_IMAGING` read exactly as they did. ## 2. Every spawn-atlas import on an upgraded install has failed since v1.2.0 ``` Unknown column 'unique_id' in 'INSERT INTO' sql: INSERT INTO shard_spawn_points (id, facet, name, unique_id, x, y, …) ``` `shard_spawn_points.unique_id` (Events Phase 12b, `10fde87`, 2026-09-07) was added to the `CREATE TABLE` **and nowhere else**. `CREATE TABLE IF NOT EXISTS` does not add a column to a table that already exists — which is what the twenty-odd `ADD COLUMN IF NOT EXISTS` lines in that same file are for — so it reached fresh installs and no existing one, while `replaceAtlas` inserts the column unconditionally. Blast radius on an upgraded install: no bestiary refresh, no spawn map, no champion altars, no landmarks. In released **v1.2.0, v1.2.1, v1.2.2**. **A fresh install cannot reproduce it, and neither can a test whose schema is this file applied to an empty database.** It took a rig whose tables predate 12b. That is the same blind spot the protocol-pin block above it records — two phases running. Org lead, weighing that it is already released: **it ships here on `edge`** rather than as a hotfix to `main`. Verified by dropping the column, rebooting, watching the fragment replay put it back (`schema ensured for module "uo" {"statements":75}`), then importing **6,455 spawners / 387 regions / 558 landmarks / 25 champion altars in 1.29 s** over the bridge. ## Related, and a 9b blocker This branch does **not** fix it: `edge` is missing `main`'s #35 ("keep the UniqueId"), so the walk measured **0 of 6,455** spawners carrying one even after the column existed. `main` must be synced into `edge` before the cutover or it ships a regression — recorded in `v8.md` §16 row 9b. ## Checks `npm test --prefix server` **720 passing**, `npm test --prefix client` **45 passing**, client chunk rebuilt and the new branches confirmed present in it. ## AI disclosure Written with Claude Code (Claude 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-14 18:10:54 +00:00
fix(assets): a busy shard is not a broken one, and a column that reached no existing install (Phase 9a)
All checks were successful
PR Checks / client-build (pull_request) Successful in 21s
PR Checks / frozen-manifest (pull_request) Successful in 1m20s
PR Checks / server-tests (pull_request) Successful in 8m4s
3c087a43cd
Two defects the Phase 9 acceptance walk found on a real rig, one of them ours and
one of them released (docs/link/v8.md §17.14).

## "The shard is not answering for client files" about a shard that was fine

The status call exhausts its 425 backoff whenever something else holds the
shard's single asset slot -- an import the operator started, or the item-art warm
pass refilling itself after a client patch. Phase 8's panel rendered that with
the same banner as a shard that is down or has the plane switched off, and left
it standing, because the page only re-reads after an action. On the rig it was up
for a quarter of an hour while the warm pass refilled 313 pictures and every
direct call to the same route answered normally.

BUSY now says what it is, and one automatic re-read four seconds later clears the
ordinary case. One per mount, guarded by a ref: a page that retried forever would
be holding the slot it is waiting for. DOWN, DISABLED and NO_IMAGING read exactly
as they did.

## Every spawn-atlas import on an upgraded install has failed since v1.2.0

`shard_spawn_points.unique_id` (Events Phase 12b) was added to the CREATE TABLE
and nowhere else. `CREATE TABLE IF NOT EXISTS` does not add a column to a table
that already exists -- which is what the twenty-odd `ADD COLUMN IF NOT EXISTS`
lines in this same file are for -- so it reached fresh installs and no existing
one, and `replaceAtlas` inserts the column unconditionally:

    Unknown column 'unique_id' in 'INSERT INTO'

No bestiary refresh, no spawn map, no champion altars, on every install whose
tables predate 12b. A fresh install cannot reproduce it and neither can a test
whose schema is this file applied to an empty database; it took a rig with old
tables. Org lead, weighing that it is already released: it ships here on edge
rather than as a hotfix to main.

Verified by dropping the column, rebooting, watching the replay put it back, and
importing 6,455 spawners over the bridge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
whitlocktech merged commit e7b3412b36 into edge 2026-09-14 22:26:31 +00:00
whitlocktech deleted branch feat/asset-bridge-p9 2026-09-14 22:26:32 +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#42
No description provided.