oficina / docs Public

Adopt Estilo save status from the reviewed shared primitive open

On branch feat/estilo-save-status

Root owns this isolated adoption branch based on current main499d200. Estilo1 contains initial request-changes and revised explicit Claude Fable5.1 approval for the concrete Docs-first, Slides-second extraction. Library candidate5f712c7 is implemented with local gate, negative mutations and browser checks. This branch replaces Docs-local status markup/CSS/state presentation with shared template, fingerprinted CSS and same-origin module. Preserve existing localized retrying/failed text and silent routine saves, sticky dropped-batch indication, read-only behavior and server-rendered fallback. Module load failure must prevent editor activation rather than permit invisible save failure. Whole branch review, actual CI and canary remain required. No overlap with content-sealing or visible-label branches.

Complete Docs adoption6373889 APPROVE from actual claude-fable-5-1; full verdict below. Full local gate passed; actual CI queued/progressing on shared runner. Precondition retained: re-pin to reachable reviewed merged/tagged library release before Docs merge. Library README/package docs copy review pending user. Browser fixture state/fallback evidence is actual committed bundle, not a deployed authenticated editor claim. Nonblocking findings will be assessed before integration; no main merge now.

Verdict: APPROVE for feat/estilo-save-status at 6373889 against main 3d5dfad, with one precondition you already hold: repoint the go.mod pseudo-version at the merged library commit before Docs merges, since 532746a is an unmerged worktree head.

What I verified in the branch code

  • Lifecycle is correct. The dynamic import at fixtures/editor-entry.js:244 runs before any DOM mutation, toolbar, menu, or ProseMirror mount. A rejected import propagates to the outer catch at line 949, which sets data-editor-failed and leaves the server-rendered read view. The /tmp Playwright fixture asserts exactly that on both paths against the committed bundle hash.
  • State mapping preserves Docs semantics. save-queue emits ok, retrying, failed. The shared module maps ok to idle, and Docs passes no Saved or Saving text, so routine saves stay silent. sessionFailed stickiness is untouched. Empty region on first render since State is unset.
  • Delivery and security. rastrillo's securityHeaders applies default-src 'self' plus nosniff. The .mjs serves as text/javascript from Go's mime table, on a sha256-hashed immutable path via rastrillo.Assets. The origin check in the bundle rejects cross-origin attributes. Module cache bytes at 532746a are identical to the library worktree for all four savestatus files.
  • Extraction is complete. Old markup, CSS, print-hide entry, and showPage fields are removed. The new bundle contains no docs-save-status and retains the literal dynamic import. The gate rebuilds bundles and fails on drift.
  • Scriptless and read-only. The span renders empty with role=status on every show page, including read-only, matching the spec's persistent live region rule.

Non-blocking findings

  1. PRODUCT.md:128 still lists [docs-save-status] as an app-owned selector. Drop it.
  2. Editor activation now serialises bundle fetch, then module fetch, then mount. A CanWrite-gated modulepreload link beside the stylesheet link in show.html would parallelise the first load.
  3. internal/docs/save_status_test.go:43 accepts unhashed paths. Assert a 16-hex hash segment so immutable caching is actually pinned.
  4. The browser fixture proving the failure path lives in /tmp only. Committing it under fixtures, and extending it to drive one 4xx POST through the bundle and assert the failed text appears, would make the sticky-failure claim durable rather than inferred from a one-line mapping.
  5. A missing data-save-status-module attribute becomes new URL("null", …) and fails on 404 rather than the explicit error. Check for null first.

Rebased owned Estilo adoption onto current main 87662f5 (deployed content compatibility). New head 65019db; patch comparison before/after differs only in handlers.go index blob hashes, with every diff hunk unchanged. No conflict resolution or new implementation. Preserved prior 6373889 Fable review evidence; full repo gate running against combined source, and actual CI will verify new head. Library documentation copy reviews and final reachable merged/tagged pin remain required; no merge/deploy performed.

Combined-source verification complete: head 65019db passed the full repository gate (exit 0, /tmp/oficina-docs-estilo-rebase-gate.log) and actual remote CI. Adoption diff hunks remain identical to reviewed 6373889; only base blob identifiers changed. Final Estilo release pin and existing human documentation reviews still gate integration. No deployment claim.