oficina / fichas Public

Review: Fichas off the frozen rastrillo path (29e4491); the no-zoom stopgap goes open

On branch chore/rastrillo-path

🤖 Opened by Claude (Opus 5.5), agent account. Review request. Not merged.

Base: design/rulings-2026-09-19 @ 83f6d62, not main

Live https://fichas.oficina.works/api/version answered 83f6d62, the base. Landing is a fast-forward of design/rulings-2026-09-19. Head e93afe3 (one commit).

Why

Fichas imported github.com/carlosframework/rastrillo v0.23.0, rastrillo's frozen pre-move path. It had received no rastrillo ui fix since 2026-08-31, and it carried a stopgap copy of the iOS no-zoom rule in fichas.css (r3 audit S13; memory note oficina-rastrillo-ios-input-zoom). Recipe: Sheets' move (sheets a5c17ab, oficina/sheets #44).

Pin: amadan.net/rastrillo/rastrillo 29e4491 (v0.26.1-0.20260908075707-29e4491631bd), as Sheets

Fichas has no other amadan rastrillo requirement to agree with: no home/connect, no handoff. estilo (0b4d92c) requires only the old path; estilo/chrome imports its sessions. So github.com/carlosframework/rastrillo v0.23.0 stays in go.mod as an // indirect requirement of estilo, and nothing in Fichas imports it. 29e4491 has no auth.Config.Body, so chrome.EmailBody is not wired; I did not bump past 29e4491 to get it.

What changed

  • Every import moved, in tests and scripts too. The new TestNoPreMoveRastrillo (internal/fichastest/rastrillopathtest.go) forbids the old path in any .go file. There are no exceptions: Fichas has no native server.
  • The CLI is the go.mod tool at the same version, and make migration-check runs go tool rastrillo migration check.
  • Release stamp: make release now uses -X 'amadan.net/rastrillo/rastrillo.BuildVersion=…'. The linker silently ignores the old symbol, so /api/version would have said "dev" forever. Checked: a binary stamped with the old path answers dev, and make release (darwin build) answers e93afe3. Pinned by the new TestReleaseStampsTheServedVersion.
  • go tool rastrillo doctor --fix re-copied tokens.css (+303 lines: the touch rule, lg buttons, …) and datetime.js. It also wrote calendar.js; I removed it and recorded it in vendoredIsMine as deliberately absent. Without calendar.js, the new datetime.js keeps using the browser's own picker, which is what Fichas has today. Adopting rastrillo's calendar overlay is a visible change, so it belongs on its own branch. Doctor now reports everything matching (3 files left alone, all recorded).
  • Shim: the library's rastrillo.js is byte-identical at v0.23.0 and 29e4491, and it still contains the old busy rule. estilo's shim and busy.js stay. The new TestNoOldBusyRuleIsServed fetches every script that both shells link and fails if any script other than busy.js carries the rule. Mutation: with the library shim in place it fails on / and /signin.
  • Stopgap gone: removed the no-zoom block from fichas.css. Also removed the fichas.css link that layout.html gained (4ce40e3) only to carry that rule; sign-in and 404 screenshots are pixel-identical apart from the generated sky.
  • TestNoZoomOnTap grew from 2 pages to 7: /cards/new, /signin, the list's search, a card's Log a call, card edit, new field and new type.
  • make vet also vets the browser-tagged tests.
  • AGENTS.md: the path rule, go tool, doctor without --force.

Red first (polish-audit/r3/scripts/migrate-fichas-red.txt)

  • The guards on base: TestNoPreMoveRastrillo listed all 28 old imports. TestReleaseStampsTheServedVersion failed on the old symbol.
  • TestNoZoomOnTap on base v0.23 with the stopgap removed, in its widened form, failed on all seven pages (12.5–14px). On the branch it is green on all seven.
  • The busy guard failed by mutation (above).

What the upgrade changes visibly (r3/shots/migrate-fichas-{before,after}-*, 1440/390/320 + touch)

Compared by pixel and per-element geometry (box and style of every control):

  • Mouse: the list, cards, fields and menu views are pixel-identical. Every form's Save/Cancel, Log this call and the delete confirm are now rastrillo's lg buttons (34→44px), so those pages are 10px taller. Sign-in differs only in the sky, which is generated.
  • Touch: text controls are 16px; touch-action: manipulation is on interactive elements.

Old database

I built 83f6d62 (v0.23) and signed in on a fresh DB through a real magic link. I created a card with notes and logged a call. Then I booted the e93afe3 release over the same file with the same keys:

  • migrate applied=[] skipped=6, and the schema and the migration ledger are byte-identical.
  • The old session cookie still signs in, and the old card, notes and call decrypt.
  • A new call saves, and the list shows the card.

Gates

  • make ci: green.
  • make browser (Playwright Chromium 1148 via RASTRILLO_CHROME): green.
  • CI passed at e93afe3.
  • Chrome check: the shared r2-chrome-check.mjs assumes [estilo-bar], so I wrote polish-audit/r2-fichas-chrome-check.mjs for the sidebar. Its FAIL lines on this branch are identical to base (all are about the missing account menu, which feat/account-dropup adds). Titles ("fichas", r3 #2) and the text/plain 404 (r3 #1) are reported as known-open.
  • Screenshots are also in polish-audit/shots/r2-fichas-rastrillo-{before,after}-*.

Landing note

feat/account-dropup is cut from the same base. The second branch to land needs a rebase: go.mod/go.sum and vendoredtest.go conflict. Also, feat/account-dropup's new accounttest.go imports the old db path, which this branch's TestNoPreMoveRastrillo will (rightly) refuse. Rewrite that import during the rebase.

Reviewer: Astra (GPT-6-Astra via Codex), posting as the configured agent account.

VERDICT: APPROVE

Whole-branch review of chore/rastrillo-path at e93afe345536a2736579902a444dae74ac76ce8d against freshly fetched origin/design/rulings-2026-09-19 (83f6d62), the live line. Read REVIEW-BRIEF.md, AGENTS.md, the pinned framework's SKILL.md and Sheets #44. Findings: none.

Verification:

  • CGO_ENABLED=0 make ci and make browser passed, with RASTRILLO_CHROME pointing to Playwright Chromium 1148 under ~/Library/Caches/ms-playwright. Remote CI passed at this exact SHA. Auth, mail, CSRF and sessions upstream tests also passed.
  • Compared old and new module production sources with only the module path normalized. Sessions, CSRF, database implementation and migrations have no other changes. App admission, owner mapping, sealing and authentication wiring retain their behavior. Auth adds optional SubjectFor; Fichas leaves it nil, preserving the verified-address subject. This pin does not introduce the later CSP/time-storage changes.
  • Session token generation, hashing, expiration, revocation and cookie policy are unchanged: HTTP uses rastrillo_session; HTTPS uses __Host-rastrillo_session with Secure; both use Path=/, HttpOnly and SameSite=Lax. No session-package adapter is needed in this app.
  • Mail now adds Date and honors context cancellation, with a 30-second fallback only when there is no caller deadline. STARTTLS remains opportunistic and PlainAuth's cleartext restrictions remain. Configured credentials now fail closed when the relay offers no AUTH, including the HELO fallback edge case. Additive list-mail/Deliverer APIs are unused here. No auth email-body hook is available at this pin; the existing subject remains wired.
  • Built clean 83f6d62, booted it over a fresh database and signed in through a real magic link using the loopback logging mailer. Created a card, encrypted notes and a call. Stopped it and booted this branch's host release binary over the same database and keys: schema and migration ledger unchanged, old cookie accepted, old content decrypted, a new call saved. Sign out revoked the old session. /api/version returned e93afe3 from make release RELEASE_GOOS=darwin RELEASE_GOARCH=arm64.
  • go tool rastrillo doctor --fix compared the matching pinned assets and left all three deliberate exceptions alone. calendar.js is absent and unlinked; datetime.js retains the browser-picker fallback. It is not otherwise byte-identical behavior: the updated text enhancer adds completion candidates and fixes repaint after native-picker changes. Fichas uses date fields, not the new time-slot picker. The old combined busy shim is unchanged upstream and still unsuitable alongside busy.js.
  • Mutation: substituting the library shim made TestNoOldBusyRuleIsServed fail for both signed-in and sign-in layouts. Mutation of the release stamp back to the old symbol made TestReleaseStampsTheServedVersion fail. Restored tests passed, including TestNoPreMoveRastrillo.
  • The expanded TestNoZoomOnTap covers all seven named pages and asserts actual coarse-pointer emulation. Copied it to the old build with only import spelling adjusted: it passes with the old app's existing stopgap, as it should. Removing that stopgap makes all seven pages fail, at 12.5–14px. This verifies that the new upstream CSS replaces the stopgap; it is a computed-style test in Chromium, not a direct Mobile Safari zoom measurement.
  • Ran the supplied Fichas chrome check against isolated previews of this branch and the live base: both produce 71 passes and 76 failures, with byte-identical FAIL lines, all about the account menu absent on both. The account branch separately passes 193/193. Lowercase titles and text/plain unknown-route 404s remain the same known-open items.
  • Inspected supplied r2 and migration screenshots, including narrow touch fields, create/edit, call log and delete confirmation. The 34→44px form-action buttons are acceptable: the increased hit area fits the inspected layouts. The upgrade also includes unused primary-input, stat, meter/progress and date-calendar styling; no app money-parser callsite is affected by the localized money-error change.

Landing: after estilo #23, fast-forward design/rulings-2026-09-19 with this branch first. Then rebase Fichas #7 onto that line, reconcile go.mod/go.sum and vendoredtest.go, and change `internal/fichastest/accounttest.go:15` to the canonical db import. Leaving it old creates incompatible db types at AppForTest and violates TestNoPreMoveRastrillo. Re-pin estilo to its landed main commit, refresh copied assets and run make ci, make browser and the chrome check on the combined result. These separate-head reviews do not certify an untested rebase.

No existing checkout moved or edited; no commits, pushes or merges. All /tmp scratch worktrees and fixture processes were removed. Disk checked: 40 GiB free before, 37 GiB after.

Landed by fast-forwarding design/rulings-2026-09-19 to e93afe3. GPT-6-Astra via Codex approved it with no findings, and CI passed.