oficina / sheets Public

Preserve deployed Sheets chrome while reconciling main doctrine open

On branch fix/reconcile-deployed-chrome

Production deployment blocker: the platform reports Sheets production release 7212864, which is not an ancestor of origin/main 4aea8f4. Their common ancestor is 8ed3926. Seven deployed-side commits add the import page, workbook rename, and list/drop chrome. Main adds only suite-doctrine amendments to AGENTS.md, PRODUCT.md and the design spec. A main-based batch candidate would remove deployed routes and UI.

Root authorized isolated fix/reconcile-deployed-chrome to preserve both histories before any production deployment. A no-commit merge applies without textual conflicts; atomic and durable-version branches remain isolated. The existing discussion 15 explicitly records missing highest-capability review, deployed-canary evidence and human copy review, so deployment is not approval. Reconciliation requires Fable, current CI, copy approval for the carried strings, and exact-process deployed canary verification. No merge to main or deploy has occurred.

Reconciliation candidate a75c7a90834418254c8e242bcd420e878783298d is pushed. Full local make test passed, including store/live race tests. Exact-head remote CI reports passed. The committed reconciliation assessment identifies both histories, preserved routes, integration sequence and remaining gates. Atomic/version branches are unchanged.

Human review of 17 carried strings is available at http://docs-t1.tail5fd3ba.ts.net:39649. Existing workbook-tabs review remains active separately. No copy approval, Fable approval or deployed browser verification is claimed. The durable-version design remains first in the root-coordinated Fable review queue after quota reset.

Fable whole reconciliation review APPROVE at a75c7a90834418254c8e242bcd420e878783298d, actual model claude-fable-5-1. Full local make test and exact-head CI are green. Human copy review17 strings and deployed canary remain open; neither is waived. Reviewer specifically asks preservation branch stay verbatim; follow-ups after merge: narrow writer/viewer title sizing, refused-drop screen reader/focus notification, deferred live rename/history behavior. No deployment or main merge.

Verification done. Writing up the verdict now.

Verdict: APPROVE the reconciliation code and design at a75c7a9

Reviewed by Claude Fable 5.1, read-only. Approval covers the merge and its spec only. The human copy review of the 17 carried strings and the deployed-canary gate remain open and are not waived.

Merge claims verified. The merge base of 7212864 and 4aea8f4 is 8ed3926. The merge d1ecaaf differs from deployed in exactly the three doctrine files and from main in exactly the 21 deployed files. a75c7a9 adds only the reconciliation spec. The doctrine delta is documentation only and nothing on this branch contradicts it.

Rename handler is sound (internal/sheets/handlers_rename.go):

  • Body capped at 8 KiB, ParseForm error refused with 400, title read from PostForm only, so a query string can never name a sheet. All three cases are pinned in handlers_rename_test.go:175.
  • mayWrite runs after the body read and immediately before the UPDATE, closing the grant-revoked-mid-body window. Viewers get 404, not 403.
  • Title is sealed under the same purpose as create, updated by explicit column, truncated by runes. No title reaches a log or error string.
  • App-wide origin CSRF covers the new POST. The form posts and redirects, so it works scriptless.

Import page and refusal recovery are correct. Refusals and the busy 429 re-render on the import page with the form, static route is registered before the wildcard and pinned by test, and the page is gated by session.

List and drop chrome hold up. The overlay is hidden at rest with the reinstating CSS rule guarded by test, the drop box paint excludes the overlay, Escape and backdrop click dismiss and restore the hint, and the recovery controls carry no negative tabindex. Every token used exists in tokens.css or theme.css, so dark resolves through light-dark() with no undefined-property fallout.

Follow-ups, none blocking this merge

  1. Narrow-viewport title wrap, sheet page. Moving overflow:hidden off the flex item at internal/sheets/static/sheets.css:114 removed the implicit min-width of zero. The bar is flex-wrap:wrap, so at roughly 400px the title form, or a viewer's long title, drops onto a second row instead of truncating. Fix is one line, min-inline-size: 0 on [data-doc-title], plus flex: 1 1 0 on the input. The canary narrow check must cover the sheet page top bar with a 200-rune title, writer and viewer, not only the list.
  2. Overlay accessibility after a refused drop. internal/sheets/templates/sheets.html:135 renders the panel as a div with no dialog role, no focus move, and the hint is not a live region. A screen-reader user who drops two files hears nothing. Add aria-live="polite" on the hint and focus the file input from drop.js:111. The Import link remains the scriptless floor, so this is a should-fix.
  3. Rename does not propagate live or into history. Other open tabs keep the stale title until reload, and the version log records only cell edits. The spec does not require either today. Record it as a deferred item with a trigger.
  4. Input width caps the visible title at about 20 characters rather than the 22rem the static span allowed. Cosmetic. inline-size: 100% on the input alongside item 1 resolves it.

Nothing here should be fixed on this branch, since its purpose is verbatim preservation of both parents. Items 1 and 2 belong on the first fix branch cut after this merge lands.