Staging batch: Library AI by book count, Opus 5.5 default, Copilot on the relay - #245
Conversation
Thinking is disabled explicitly on every Claude call, since Sonnet 5 runs adaptive thinking when the field is omitted, and the reply caps grow from 600 to 800 and 360 to 480 tokens for its larger tokenizer. Authorized by Wolf on 2026-09-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The concierge and landing routes no longer hold a paid Anthropic key. They ask claude-sonnet-5 at low effort through the relay, which moves a call from track t1 to t2 to t3 on a rate limit, and read the reply JSON out of the text since the relay runs one turn without tools. A streaming caller now gets the whole reply at once. Authorized by Wolf on 2026-09-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude through the subscription relay is the only model the concierge and landing routes call. When every track is spent the reply is empty and the widget stays quiet instead of switching to a paid key. Authorized by Wolf on 2026-09-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cover's buildings were bound to usernames. Two owners renamed themselves on production (Mary13 is now Mary, alinamarg is now Alina), so their buildings matched no library and the hover card showed only a name with no About or object counts. Hotspots now carry the owner's account id, which survives a rename and is the same on staging, whose database is a copy of production's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hout a rebuild POST /api/ai-atlas/guide takes the Terminal's full guide behind a bearer key (AI_ATLAS_PUSH_KEY), cuts it to the fields the page renders, refuses one the adapter cannot draw, stores it on the container's persistent mount and revalidates /ai-atlas in every locale. One journal line per push. The page reads the stored guide in getStaticProps and falls back to the bundled one, so the guide leaves the client chunk and is still never a standalone public file. A tile the Terminal removes is left off the map instead of crashing the render. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hout a rebuild POST /api/ai-atlas/guide takes the Terminal's full guide behind a bearer key (AI_ATLAS_PUSH_KEY), cuts it to the fields the page renders, refuses one the adapter cannot draw, stores it on the container's persistent mount and revalidates /ai-atlas in every locale. One journal line per push. The page reads the stored guide in getStaticProps and falls back to the bundled one, so the guide leaves the client chunk and is still never a standalone public file. A tile the Terminal removes is left off the map instead of crashing the render. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A failed store write is journaled and answered with a 500. Requests without the key leave no journal line, so strangers cannot grow it. The page re-checks the stored guide against the adapter it ships and falls back to the bundled guide. An empty system.nodes gets a clear refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A failed store write is journaled and answered with a 500. Requests without the key leave no journal line, so strangers cannot grow it. The page re-checks the stored guide against the adapter it ships and falls back to the bundled guide. An empty system.nodes gets a clear refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(ai-atlas): Terminal pushes the Atlas guide, no rebuild needed
…s the cross-vendor review Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A push may carry cards (card id to paragraphs); a card listed there replaces its copy in features.ts, so text edits reach /ai-atlas without a build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s the cross-vendor review Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A push may carry cards (card id to paragraphs); a card listed there replaces its copy in features.ts, so text edits reach /ai-atlas without a build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A push may now carry, beside cards: - stages: per stage, in step order, a label and up to three tiles; - copy: any page text key (copy.json strings, ring and node labels, SEO title and description) mapped to new text. Each is validated before storing; the map keeps its built-in selection and words for anything the push leaves out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A push may now carry, beside cards: - stages: per stage, in step order, a label and up to three tiles; - copy: any page text key (copy.json strings, ring and node labels, SEO title and description) mapped to new text. Each is validated before storing; the map keeps its built-in selection and words for anything the push leaves out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…243) feat(ai-atlas): the push sets the map, the cards and every page word
The AI shelf and the magic books now open to an owner who holds the library-ai flag or whose library holds more than 15 books (type book, every shelf). One check, opensLibraryAi, decides for the page and both routes; the count is read from the library on each check, nothing is stored. The AI shelf keeps its own 30-book lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @manager's task in 8m 1s —— View job Review of PR #245
One inline comment posted on Everything else looked solid
I was not able to run |
| steps: input.steps.map((s: any) => | ||
| pick(s, ['id', 'title', 'location', 'text', 'children']), | ||
| ), | ||
| entries: input.entries.map((e: any) => | ||
| pick(e, ['id', 'title', 'text', 'detail', 'children']), | ||
| ), | ||
| system: { | ||
| nodes: input.system.nodes.map((n: any) => | ||
| pick(n, ['id', 'title', 'role', 'detail', 'basis']), | ||
| ), | ||
| }, |
There was a problem hiding this comment.
Correctness: title/text/detail/children on entries, steps and system.nodes aren't type-checked, so a malformed push can slip past this "guide it cannot draw is refused" gate.
isRecordList (line 21-26) only checks that id is a string; everything else is copied through pick() unchanged. The comment at line 132 says "the page must be able to draw what is stored; a guide it cannot draw is refused," relying on adaptGuide(guide) throwing to catch bad data — but adaptGuide mostly assigns these fields raw (e.g. title: entry.title at adapter.ts:84) and only throws for a handful of hardcoded ids that happen to call a string method (node(id).title.toLowerCase() for layerIds, adapter.ts:217). A title that's an object on an arbitrary entry sails through stripGuide → gets stored → gets served, and only breaks when a visitor opens that specific dossier, since ai-atlas.tsx renders {data.title} directly as a JSX child (e.g. line 745) with no error boundary around the page — a full client-side crash for that visitor rather than a push-time refusal.
Worth adding an explicit string+length check for title/text/detail (and that children is an array of strings) on entries/steps/system.nodes, mirroring the rigor already applied to isCards/isCopy/stagesError just below.
There was a problem hiding this comment.
Fixed in 20428ab: title, location, text, role and basis must be text, detail and children lists of texts, each up to 4000 characters, on steps, entries and system nodes. A guide that fails is refused at push time and the page keeps the last stored one. Checked against the bundled guide (accepted), an object title and a number in a detail list (both refused).
Titles, texts and the detail and children lists on steps, entries and system nodes are now checked as text before the guide is stored. Before, an object in a title passed adaptGuide and broke the page only when a visitor opened that dossier. Raised by the review on #245. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @manager's task in 1m 15s —— View job Review of PR #245 (updated push)
This push (commit
|
* feat(library): more than 15 books opens the AI without the flag The AI shelf and the magic books now open to an owner who holds the library-ai flag or whose library holds more than 15 books (type book, every shelf). One check, opensLibraryAi, decides for the page and both routes; the count is read from the library on each check, nothing is stored. The AI shelf keeps its own 30-book lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(widget): quieter Ask-UX-Core pill The idle pill drops to 34px, smaller label, 0.7 opacity, and loses the orange pulse glow, so it stops burying the host page's bottom-corner buttons and text. Full opacity returns on hover, while the panel is open, and in the relevance-nudge state, whose pulse is also toned down. Opacity stops at 0.7 because the 12px label must keep the 4.5:1 contrast floor over light pages. Mobile pill shrinks in step. Bundle rebuilt, so the change is live on every locale. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> (cherry picked from commit d957e9b) * feat(uxcore): Arc of Self nav item, navbar single-row fit, Our Projects modal pass Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 7fcd5ec) * fix(auth): cover the login hand-off with a branded loader, stop the grey banding The /auth, magic-link and email-change pages hold almost no markup while the provider handshake runs. Two defects came out of that: - The body gradient is propagated to the canvas but sized against the root box, so on those near-empty documents it tiled down the viewport as grey bands. The root now holds viewport height and the gradient no longer repeats. - /auth rendered the shared Spinner without its visible prop, so it drew nothing at all and left the bare document on screen. All three pages now render AuthLoader: a full-viewport paper surface with the house brain loader, dark-theme aware, honouring prefers-reduced-motion. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> (cherry picked from commit 55af48d) * fix(library): restore the branch's own fixes on top of prod's Library The merge took prod's side on every conflicted file, which dropped three fixes this branch had made against the August structure. Rebuilt on the new one: - The info panel again sits in a host that is transparent to layout on desktop and a fixed clipping layer at the drawer breakpoints, so the panel parked off the right edge stops counting towards the page's scrollable width. Without it Safari measures a library page about two screens wide on a phone. The CSS for it had survived the merge with no element to apply to. - The Add controls pulse again while the library holds no objects. Prod rewrote the empty-shelf area out of Shelf, so only the header control carries it now, and the round-control animation goes with the control it belonged to. - The avatar boxes declare their own widths again (48px panel, 152px edit dialog) instead of paying for the home card's headroom. The fourth, the single-request library load, is not rebuilt: prod paints the library on the server, so the two round trips it removed no longer happen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 45a2db7) * library: AI shelf and Magic default to Claude Opus 5.5 (Wolf, 2026-09-22) (cherry picked from commit 9db1dc7) * widget: Copilot defaults to Claude Sonnet 5 Thinking is disabled explicitly on every Claude call, since Sonnet 5 runs adaptive thinking when the field is omitted, and the reply caps grow from 600 to 800 and 360 to 480 tokens for its larger tokenizer. Authorized by Wolf on 2026-09-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit cd740e3) * widget: Copilot's Claude calls go through the subscription relay The concierge and landing routes no longer hold a paid Anthropic key. They ask claude-sonnet-5 at low effort through the relay, which moves a call from track t1 to t2 to t3 on a rate limit, and read the reply JSON out of the text since the relay runs one turn without tools. A streaming caller now gets the whole reply at once. Authorized by Wolf on 2026-09-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit d6c6b74) * widget: drop the paid OpenAI fallback from Copilot Claude through the subscription relay is the only model the concierge and landing routes call. When every track is spent the reply is empty and the widget stays quiet instead of switching to a paid key. Authorized by Wolf on 2026-09-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit bac80e9) * fix(library): cover hotspots find their library by owner id The cover's buildings were bound to usernames. Two owners renamed themselves on production (Mary13 is now Mary, alinamarg is now Alina), so their buildings matched no library and the hover card showed only a name with no About or object counts. Hotspots now carry the owner's account id, which survives a rename and is the same on staging, whose database is a copy of production's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit c1aaa5f) * fix(library): phone width and avatar sizing from the cybersecurity branch * fix(ai-atlas): a pushed guide with a field of the wrong shape is refused Titles, texts and the detail and children lists on steps, entries and system nodes are now checked as text before the guide is stored. Before, an object in a title passed adaptGuide and broke the page only when a visitor opened that dossier. Raised by the review on #245. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 20428ab) * fix(release): Arc of Self keeps its name below 1160px, drop a dead doc link The Arc of Self link carries aria-label, so it keeps an accessible name when its label is hidden on narrow screens, and its tooltip also shows on keyboard focus. CLAUDE.md no longer links a voice guide that is not in the tree. Raised by the review on #246. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Staging batch. Everything on this branch goes to staging; OffSec stays behind its dev-only gate there as it does now. Authorized by Wolf on 2026-09-25.
New on staging with this merge:
Checks run on the merged tree:
node scripts/release/library-batch-check.cjsPASS,tsc --noEmitclean.🤖 Generated with Claude Code