Skip to content

Session notes — claude-2026-10-14 ​

One person's notes, never rewritten by anyone else. docs/state/HANDOFF.md §22 holds what is NOT done, and STATE.md holds what is true now (the deployed sha's only home is its ✅ DEPLOYED line). This file is WHY each thing was done, and how it was checked.

▶ HANDOFF — the night agent's SAMO-year work: stopped, reviewed, fixed, shipped; Apps Script hardened; Kita's ฝ่าย logos ​

Migrations 0219–0228 are on samo-dev AND production. Full npm run proofs on production: 67/69 — the two red are HANDOFF §16b's dept0177 + team0135, unrelated and older. Apps Script is v16, identical to appscript/prform.gs. PR #23 (Kita) is merged. Every deploy ended <== exit 0 — ran to the end, read back from the VM's HEAD; browser smoke 17/17 and an 11-page production scan (no errors, no failed requests, no broken images, no sideways scroll at 390 px — its control run DID find the broken pictures on an old preview).

Read these before touching the same code ​

If you touch…Read first
the year handover / team_termsmemory samo-year-handover-order; skills/year-rollover.md step 2 — publish → edit → switch, never re-publish mid-edit; 0228 refuses deleting a year in use
any SQL function the site callsdocs/mistakes/supabase-client.md (safeupdate) — a WHERE-less DELETE/UPDATE fails through PostgREST and NO Management-API proof can see it; tools/safeupdate.test.js guards it
a new function that anon must NOT calldocs/mistakes/authz-rls.md (0226) — revoke from anon BY NAME; assert has_function_privilege
appscript/prform.gssrc/js/gas-drive-scope.test.js RUNS the real file against a fake Drive — extend it; fileLivesUnderTop_ needs a REAL top folder (its parent must be the app root or My Drive root)
tools/db-query.mjsit takes --dev since today and refuses unknown flags — it used to ignore --dev and ran on PRODUCTION
pictureAt()PICTURE_CACHE_HOSTS — the /img cache exists only on the VM; previews and npm run dev load lh3 directly
tools/year-export.mjsoutput is real people's data: default ~/samo-exports, an --out inside the repo is refused
vs_scrub_closed_tickets24 months is a FLOOR (master folds into data_admin)

What happened, in order ​

  1. Stopped the night agent at the owner's request (~12:20 ICT) after tasks 1–7. Killed run-night.sh too — killing only its claude child made the runner start the next task. ~/samo-night/STOPPED keeps the timer off. Tasks 8–12 never ran.
  2. Reviewed its branch and fixed 7 bugs before any production write: an export defaulting into the PUBLIC repo; a handover that re-snapshotted (and so destroyed) an existing archive; a drive_layout default that ran ahead of the bundle; a fiscal_year_be backfill that contradicted fiscal-year.js's NULL-means-the-clock design (guarded now); PR hiding the new team's inherited OPEN tickets; 0219's view-grant hole; 0222 grants.
  3. Incident, mine: db-query.mjs x.sql --dev ignored --dev and ran a samo-dev cleanup on PRODUCTION — it cleared PRJ-6CXA's fiscal_year_be (2570). Restored within a minute; its updated_at (now 2026-10-14 05:32 UTC) could not be. Tool fixed; write-up in docs/mistakes/tooling-proofs.md.
  4. "DELETE requires a WHERE clause" on ตั้งเป็นปีปัจจุบัน — the bug was publish_team_term (since 0104), so "เผยแพร่ปีนี้" had failed in production for 2½ months. 0225.
  5. Preview pictures broken (owner's screenshot) — every preview since 2026-09-23; PICTURE_CACHE_HOSTS.
  6. Kita's PR #23 reviewed: clean; added a grid ↔ DEPT_DEFS ↔ public/ agreement test (two homes of the logo path), checked 390/820/1280 in headless Chrome, merged.
  7. Scrutinize → production: 0221's scrub retention became a floor; 0219–0224 applied in dependency order (0219, 0220, 0222, 0221, 0223, 0224) with each proof run against production.
  8. Apps Script scan + deploy: the name-only top-folder gate (it guards every PR/Shop/Team/Projects delete and the signed-หนังสือ read), exact <top>/<year> paths, a year range, PRIVATE archives. Probed live: bad shapes refused; a real PR/2569 upload + delete round-trip; 40 and 100 real project files still resolve. v14 memoised a per-file lookup (the comment's first claim about a 90 s timeout was WRONG — the sweep batches 20; v15 corrected it).
  9. Second scrutinize: 0226 (anon could still call samo_year_for_timestamp).
  10. Workflow review: the handover order became publish → edit → switch (the UI had recommended the worse order); 0227 corrects the live function comment; 0228 makes a year in use undeletable (the UI disabled only the button); the stale-archive badge stopped inviting a re-publish mid-handover.
  11. "Keep checking" pass: the year layout added a container level the public folder handlers did not know — one anonymous deleteProjectFolder or getProjectFolderInfo(share:true) on Projects/2569 would have trashed or published a whole year (latent: no year folder existed). v16 refuses it, probed live (5 refusals in a row once the rollout settled). Also confirmed 0228's trigger fires for a signed-in admin through the authenticated role (its EXECUTE is revoked; triggers do not check it), and fixed a discord-sync.test.js case that timed out under a loaded full suite.

Waiting on the owner ​

  • Tasks 8–12 (ระบบบ้าน, หน้าฝ่าย, Shop, Passport/stats, final scrutinize) never ran — re-queue (skills/night-agent.md) or drop.
  • ฝ่ายรังสีเทคนิค colour: the logo is lavender (#bba6cb), --dept-rt is magenta (#B8449E) — card hover/tool tile disagree with the logo.
  • Exports need the owner's laptop (Management-API PAT) — a non-IT team cannot export a year alone. An in-app export (PR has CSV already) is the fix if wanted.
  • Grants move the moment the live tree is edited during a handover — a per-term draft tree would fix it; not built.
  • A release — PENDING in src/data/changelog.js holds today's notes (docs/VERSIONING.md).

Deliberately NOT verified ​

  • The admin year pickers / PR past-year lock / VS year filter in a signed-in production browser — checked as the served bundle (strings present), the public data source (anon RPC), unit tests, and samo-dev proofs only.
  • A real handover on production — never run; 2569 is current, 2570 seeded, neither published.
  • tools/year-export.mjs --apply / --drive, tools/pr-organize-drive-by-year.mjs, server/supabase-backup.* — written, never run against production.

Working docs. STATE.md is the status file and lives at the repo root, not here.