# BF37 / TX7.2.3 Pro Collaboration Hosting, TexLab & Editor UI implementation state

Date: 2026-08-22
Release: R14.28.18 Build Fix 37
Protocol: TX7.2.3 (TX7 manuscript protocol retained)

## Objective

BF37 hardens collaboration session creation as a signed-in Pro/Admin capability while keeping shared-link joining available to collaborators, and completes the requested editor/product UX pass: new desktop branding, larger Visual manuscript typography, TexLab naming/iconography, shared Terminal/TexLab chrome, toolbar/CTA adjustments, a portal-based shared account menu, and dismissible Projects three-dot menus.

Google OAuth is intentionally unchanged in BF37. The working BF36 authentication/session implementation is preserved.

## Collaboration hosting entitlement

Creating a new live collaboration room is now server-authoritative:

- anonymous host: denied;
- signed-in Free user: denied;
- blocked Pro account: denied;
- signed-in Pro account: allowed;
- Admin role: allowed through the existing effective-Pro entitlement path.

Joining an already-authorized room remains available to normal/anonymous guests through the existing TX7 shared Project link. Guests do not acquire Pro entitlement.

### Signed host grant

The browser creates the normal TX7 room descriptor and derives the opaque SHA-256 room key locally. It then requests:

`POST /api/collaboration/host-grant`

The trusted API requires the authenticated session, CSRF validation and effective non-blocked Pro entitlement. It issues a short-lived HMAC-SHA256 grant bound to:

- authenticated user ID;
- exact room key;
- shared-review capability version;
- issued/expiry time;
- nonce.

The collaboration secret itself is never sent to this API.

`/collab-live` verifies the grant only when creating a room that does not yet exist. Existing authorized rooms continue accepting normal TX7 guests/reconnects. The test relay has an explicit test-only unsigned-host option and production fails closed by default.

The service-level host reconnect path obtains a fresh host grant before recreating a host session. Normal short provider reconnects to a retained relay room do not require a second grant.

## Collaboration UI

The collaboration modal now treats hosting as Pro/Admin-only:

- eligible Pro/Admin account: normal Start collaboration action;
- signed-out user: sign-in requirement;
- signed-in Free user: Pro-feature gate;
- authenticated account identity remains the collaboration identity, with no manual host-name field.

Anonymous guest naming remains preserved in the link-join flow.

## Branding

The newly supplied desktop logo is installed unchanged as:

`/texise-logo.png`

SHA-256:

`bf20e9926881af7ef40c34cda89a12b61c6340c607ad366cf63a6a1235bc62fc`

The existing compact/mobile `/texise-logo-mobile.png` remains unchanged. The shared responsive `<picture>` brand implementation introduced in BF36 is retained.

## Visual editor typography

Visual manuscript typography is increased slightly without changing Source/editor chrome typography:

- base manuscript size: `1.05rem`;
- H1: `1.9rem`;
- H2: `1.65rem`;
- H3: `1.38rem`.

Paragraphs, lists and normal manuscript content inherit the larger Visual base sizing while existing manuscript line-height/font-family rules remain intact.

## TexLab and Terminal

The Pro server Linux terminal is now branded **TexLab** in active product UI and uses the Lucide `FlaskConical` lab icon. Backend/API/service identifiers remain stable (`linuxTerminal`, `/api/terminal/...`, Console Gateway) to avoid an unnecessary protocol migration.

The logged-out gate copy is exactly:

> The TexLab server Linux terminal requires a signed-in TeXise Pro account so terminal sessions can be isolated and owned by one user.

Browser-local Terminal and TexLab now use a shared terminal-shell implementation with the same dark console chrome, header geometry and panel treatment.

Removed from the Local Terminal header:

- `Python: not-loaded`;
- `R: not-loaded`;
- `C/C++: not-loaded`;
- `Browser local`.

Runtime readiness remains available through terminal commands such as `runtime doctor`, `pyodide info`, `webr info`, and `wasix info`. The scientific-runtime Playwright contract was updated accordingly so it no longer depends on retired header pills.

The floating local launcher remains **Terminal**. TexLab uses `TEXLAB · PRO`; Local Terminal uses `TERMINAL`.

## Editor toolbar and CTAs

- Navigator and Tools positions are swapped while their commands/panels remain unchanged.
- Active `Start Writing` CTAs are renamed to `Open Workspace`.
- The public desktop header adds the shorter `Open` link to `/projects` immediately after the account/avatar control.

## Shared account dropdown

The shared `TexiseAccountPopover` now renders its popup through a portal, preventing `/ws#route=editor` titlebar overflow/clipping while preserving the same contents as the public header.

Authenticated:

- Projects;
- Settings;
- Logout.

Anonymous:

- Login only.

The shared dismissible-popover behavior closes on outside pointer interaction and Escape, returns focus on Escape, and recalculates portal placement on resize/scroll.

## Projects menu dismissal

Projects three-dot menus use the shared dismissible behavior. They close when:

- clicking outside;
- pressing Escape;
- selecting an action;
- opening another menu.

This covers top-level project actions, local project rows and account-only/missing project rows.

## Preserved TX7.2 review architecture

BF37 does not alter manuscript or collaborative-review ownership:

```text
CodeMirror
  ↕
y-codemirror.next
  ↕
Y.Text
  ↕
y-websocket

Project Y.Doc
├── files
├── review-comments
├── review-changes
└── review-events
```

Visual collaborative editing remains disabled. Comments/Track Changes remain shared Yjs review metadata outside `.tex`. BF35/BF36 file-bound anchors, capability isolation, exact Undo correlation, quotas, local-review privacy and Stop/drain behavior remain preserved.

## Release/source identity

- package version: `1.28.18`;
- service-worker cache: `texise-app-shell-r14-28-18-buildfix37-v1`;
- diagnostics: `R14.28.18 Build Fix 37 / TX7.2.3`;
- installer/deploy source guard: `repair-buildfix37-source.mjs`;
- focused regression: `r14-28-18-regression.test.mjs`.

## Verification observed in this source-only environment

- BF37 focused regression/source guard: **14/14 PASS**.
- BF36 regression: **8/8 PASS**.
- BF35 regression: **16/16 PASS**.
- BF34 regression: **14/14 PASS**.
- Historical R14.28.14/BF33 regression: **22/22 PASS**.
- Runtime hardening: **101/101 PASS**.
- Repository static release audit: **354/354 PASS**.
- SaaS/product/security static audit: **43/43 PASS**.
- Native server Node tests: **73/73 PASS**.
- Native deployment/template script tests: **18/18 PASS**.
- Frozen-lock verification: **69 workspace importers / 1171 reachable snapshots PASS**.
- Workspace dependency consistency: **68 packages PASS**.
- Public barrels: **67 entries across 68 workspace packages PASS**.
- Template/compiler requirements: **13/13 PASS**.
- BF37-changed TypeScript/TSX parse/transpile, Node syntax, shell syntax and package JSON parsing: PASS.

Dependency-backed production evidence now confirms custom validation, strict `tsgo`, mobile typecheck, root `tsgo --noEmit`, Biome lint, BusyTeX provisioning and the Vite production build all pass. The production installer also passed SaaS preflight, trusted API, Cloud Compile, TexLab Console Gateway and collaboration signaling health. It then exposed one deployment-health mismatch: the BF36-era live Yjs health host attempted to create a BF37 room without the newly required signed host grant and therefore timed out. Relay Health Hotfix 2 mints a short-lived synthetic signed host grant inside the root-owned health subprocess while leaving public unsigned new-room creation fail-closed. Vitest/Playwright execution remains dependent on the deployment/CI environment and is not claimed from this source-only tree.


## Typecheck Hotfix 1

Production dependency-backed `tsgo` exposed 16 BF37 checked-JavaScript integration errors after custom validation passed. The hotfix:

- adds strict JSDoc parameter contracts to `server/collaboration-host-grant.mjs`;
- narrows `validReviewVersion()` from `unknown` before numeric comparisons;
- declares `allowUnsignedCollaborationHosts?: boolean` and the signing-secret shape on the signaling server configuration;
- adds `server/collaboration-host-grant.mjs` to the root `tsconfig.json` include list so the composite/strict project owns the imported module;
- adds BF37 regression/source-guard assertions for all three integration requirements.

No collaboration wire format, grant cryptography, entitlement rule, room lifecycle, guest behavior, or browser UX changed.

## Deployment smoke priorities

After installation succeeds through dependency-backed typecheck/Biome/build gates, verify:

1. Pro/Admin can start collaboration; Free/anonymous users cannot host.
2. Anonymous and Free guests can join a valid existing shared link.
3. TexLab launches for eligible Pro/Admin users and remains denied to Free/anonymous users.
4. Browser Terminal retains local runtime functionality without the retired status pills.
5. `/ws#route=editor` account menu renders outside the titlebar and dismisses correctly.
6. Projects three-dot menus close on outside click/Escape.
7. Desktop/mobile logo switching and larger Visual typography render correctly.

## Relay Health Hotfix 2

Production deployment reached the live collaboration document-relay health check after all compiler/lint/build and trusted-service gates above passed. BF37 correctly rejected the health checker because it still created its synthetic host without a signed grant. The hotfix:

- imports the production host-grant signer/config into `scripts/check-collaboration-live.mjs`;
- mints a two-minute room/review-bound synthetic grant and supplies it only to the health host provider;
- keeps guest providers unsigned, preserving the real join model;
- runs the checker through `texise_collaboration_live_health_check`, which exports `/etc/texise/texise.env` only inside the subprocess so the root-owned signing secret never appears in command arguments;
- does **not** enable `allowUnsignedCollaborationHosts` in production;
- adds source/regression/release-audit contracts for the signed health path.

Source-only post-hotfix verification: BF37 **14/14**, BF36 **8/8**, BF35 **16/16**, BF34 **14/14**, BF33 **22/22**, runtime hardening **101/101**, release audit **354/354**, SaaS audit **43/43**, server **73/73**, deployment/config **16/16**, lock/dependency/barrel/template checks PASS.
