Prompt log
Raw record of conversations driving FotA system design. Newest at the bottom. Excludes secrets and tokens.
Each entry: date / context / what was decided.
→ Back to Initial review of the operating system.
2026-05-02 — Initial planning + Phase 0 + Phase 1
Context
First conversation. Trevor sketched the system on paper (initial plan + master plan). Goals:
- Master Gantt sheet (Dream Team, structured task list with bar visualization)
- HTML dashboard (SLT, “where are the numbers and what are we planning”, Thursday weekly)
- Data hygiene on master enrollment sheet (paying weeks per segment)
What was decided in this conversation
- 5 canonical segments × 2 products. See
schemas/segments.jsonandADR-0002. - Hosting: GitHub Pro, two private repos (
fota-ops,fota-dashboard), Pages from dashboard. - Refresh: Wed EOD enrollment update → Wed 23:00 hygiene rebuild → Thu morning SLT view.
- Conflict policy: last-write-wins + audit log column.
- Auth: link-based v1, OAuth elc.ac.th post-v1.
- Dashboard inflection: Aug 7 2026 = inaugural SLT view.
- Out of MVP scope: pricing, competition, capacity %, financial KPIs, FotA Allocations tracker, paying-weeks edge cases.
- Caveman: installed as output-style compressor; codebase tightness handled separately via repo structure + per-area
CLAUDE.md. - 26 seed tasks pre-loaded for Gantt (kickoff actions + SLT touches + build phase).
- Retrospective on dashboard surfaces “92 K1 drop” framed as the problem to offset, not the total root cause.
- Tokens posted in chat by Trevor → flagged for rotation, not used.
- Memo for Neung drafted but not sent yet (per Trevor 2026-05-02).
Artifacts created (Phase 0 + Phase 1)
docs/architecture.mddocs/data-sources.mddocs/slt-asks.mddocs/memo-neung-tracker-fields.md(draft, not sent)docs/decisions/0001-0008(8 ADRs)docs/prompts.log.md(this file)schemas/segments.jsonschemas/gantt.schema.jsonschemas/metrics.schema.jsonseed/gantt-seed.tsv(26 tasks)README.md,CLAUDE.md,.gitignore
Still to come
gantt_masterGoogle Sheet creation (gdrive MCP doesn’t support sheet creation; Trevor creates empty sheet, this script populates fromseed/gantt-seed.tsv).fota-dashboardrepo + Apps Script setup._hygienerebuild logic.- HTML dashboard.
Notable surfaced corrections
- Caveman ≠ codebase manager; corrected before any code.
gdriveMCP cannot create Sheets — only read/update. Workaround: Trevor creates empty sheet manually, agent populates.
2026-05-02 (continued) — Phase 1 execution
Done
- Initialized
C:\Users\trevo\Desktop\FotA\as git repo, first commit, pushed to github.com/Tr3v0r86/fota-ops (private). - Scaffolded sibling repo
C:\Users\trevo\Desktop\fota-dashboard\: README, CLAUDE.md, .gitignore, vendored schemas, vendor.sh, apps-script/SETUP.md, dashboard/SETUP.md, .github/workflows/deploy-pages.yml. Pushed to github.com/Tr3v0r86/fota-dashboard (private). - Installed all 12 Matt Pocock skills via
npx skills@latest add mainreturn-0/mattpocock-skills --yes --global. Located at~\.agents\skills\and symlinked to Claude Code:caveman,diagnose,grill-me,grill-with-docs,improve-codebase-architecture,setup-matt-pocock-skills,tdd,to-issues,to-prd,triage,write-a-skill,zoom-out.
Confirmed limitation
gdriveMCP has read + update-cell, no create-spreadsheet.gantt_mastersheet creation is a manual handoff to Trevor.
Pending Trevor action (blocks Phase 2)
- Create empty Google Sheet titled “FotA Gantt Master 2026”.
- File → Import → Upload
seed/gantt-seed.tsvfrom this repo → “Replace current sheet”. - Verify column headers match
schemas/gantt.schema.json. - Share sheet with edit access (Apps Script will run as Trevor’s account).
- Paste sheet ID into the next session.
What Phase 2 covers (after gantt_master exists)
- Apps Script project (
fota-dashboard/apps-script/) deployed via clasp _hygienerebuild logic:s\d+w\d+tokenizer + Samakee form parser, rolled up by segment- Wed 23:00 scheduled trigger
GET /dataendpoint returning the metrics payload perschemas/metrics.schema.json- Verify: paying-weeks per segment matches manual count for one segment
2026-05-02 (continued) — gantt_master live
gantt_master Google Sheet now exists with all 26 seed tasks imported.
ID: 1F06eNR3jFuNAAUoGMQzZgD0U-dyYt5NxqPH9b_9puE8
Verified via gdrive_read_file: headers match schemas/gantt.schema.json, 26 rows present.
MCP gotcha logged
gsheets_readMCP tool errors with “Google Sheets API has not been used in project 961657893488 before or it is disabled” — Sheets API not enabled on the MCP’s GCP project.gdrive_read_fileworks fine for reading sheet content (returns CSV-style).gsheets_update_celllikely has the same Sheets-API-disabled issue — will hit when Phase 2 needs writes.- Resolution path: enable Sheets API at the linked console URL before Phase 2 writes. Or pivot all writes through Apps Script (which has its own auth and bypasses the MCP entirely). Phase 2 plan already routes writes through Apps Script — no blocker.
Trevor handed off to run Matt Pocock skills
Pause here. Resume Phase 2 after skills runs land any reframing or doc updates.
2026-05-02 (continued) — Phase 2 design grilling + ops scaffold
Long session. Restarted Claude Code mid-way to activate caveman + Matt Pocock skills. Trevor invoked /grill-me to stress-test the Phase 2 plan before any code.
Major design shift: 4 products × 9 segments
Original (ADR-0002): 2 products, 5 segments. New (ADR-0009, supersedes 0002): 4 products, 9 segments + Dove placeholder.
- Samakee split out of PE — its Nonthaburi context, T1-K2 unique cross-age coverage, and own internal/external/local/overseas dynamics warrant a distinct product line.
- Dove split out of ELC-Internal — special needs / SSW umbrella, currently 12 internal students, capacity + external-yes-or-no questions need their own surface.
- PE renamed PE39 to disambiguate from Samakee. PE39 is Thong Lor; pulls from PE39, PE49, PE55 campuses.
- Symmetric 3×3 grid: each of {PE39, Samakee, ELC} × {Internal, External-Local, External-Overseas} = 9 segments. Plus
Dove-Internalplaceholder.
Other locked decisions
- Internal definition (Parse 1): org-wide. Currently in any PE/CS/Samakee/Dove campus = Internal to destination. External otherwise.
- Attribution: destination-tab. Tab→product mapping replaces per-row routing. Bridging T2→K1 student counts to ELC-Internal.
- Counting model: lifetime, two-flavor per cell —
committed(P1+P2) andpaid(P2). metrics.schema.json bumped to v1.1.0. - Local vs Overseas: new
INTLY/N column on fota_master grade tabs (Neung-maintained). SCH-name string parsing rejected as unreliable. - Cadence: Wed 23:00 + Thu 08:00 Asia/Bangkok triggers (was Wed 23:00 + Thu 06:00).
- Failure mode: fail-loud, keep prior
_hygiene, email Trevor. - Auth:
Anyone with elc.ac.th account+ Execute as Trevor (was link-based v1). OAuth post-v1 with Anat (IT). - Test row filter: per-source. fota_master =
/test|trial/ionly (Marissa-clean). Samakee form =/test|trial|^[A-Z]{1,3}$/i(form pollution). - Date-anchored parser: discover paying-week columns by date-range header (e.g.
22/6-26/6), NOT by inconsistentS\d+W\d+labels. - Source-of-truth risk surfaced: Sumeet/Amanda may be working from a separate PE doc (
1U9Jx...), Neung suspected of transcribing into fota_master. Resolution open as issue. - Mel reconciliation surfaced: legacy “Non-ELC / Early FoTA Interest” sheet has families NOT yet on fota_master. Sarah-led reconciliation.
Renamed: enrollment_master → fota_master
Same Sheet ID. Trevor preferred a name aligned with how the team refers to it day-to-day.
Vocabulary system
Two-layer artifact strategy locked because most SLT are teachers (limited experience with software jargon). Tauquil + Adam + Melissa + Federico + Poom can read the technical layer; rest of SLT see only simplified language. Translation map in docs/vocab.md.
Org map locked
docs/staff.md captures 18 people: Dream Team (Trevor, Mark, Sarah, Neung, Marissa), product owners (Sumeet/Amanda for PE39, Isabella for Samakee, April for Dove), school SLT (Tauquil, Payal, Heather, Jem, Melissa, Adam, Poom, Federico), and Anat (IT).
Important relationship: Trevor wants Melissa “in the lead at the front” with him; Tauquil + Adam are final approvers; Sarah shields Federico so he stays focused on broader marketing.
Engineering-skills setup
/setup-matt-pocock-skills ran for this repo:
- Issue tracker: GitHub on
Tr3v0r86/fota-ops - Triage labels: defaults
- Domain layout: single-context, ADRs at
docs/decisions/(non-standard path documented indocs/agents/domain.md)
Architecture-deepening sweep (/improve-codebase-architecture)
Two passes. First surfaced 6 candidates; CONTEXT.md (ARCH-3), hygiene.schema.json (ARCH-2), and test infra (ARCH-6) folded into Phase 2 implementation. Second sweep surfaced 4 more friction points, of which parking-lot drift, HANDOFF staleness, architecture↔CONTEXT duplication, and config module fold-in landed this session. Vendoring CI (ARCH-1), gantt_migrations (ARCH-4), and audit-log split (ARCH-5) deferred per priority lean.
PRD published
/to-prd ran. PRD captured with 36 user stories, full implementation + testing decisions, schema migration sequence. Published as fota-ops#1.
22 vertical slices + prereqs published
/to-issues decomposed PRD into 14 vertical slices (#2, #11-#18, #20-#23) and 8 external-owner prerequisites (#3-#10, #19). Critical-path graph in HANDOFF.md.
Triage state
/triage walked all 23 issues. 13 marked ready-for-agent with Agent Brief comments (scope boundaries, key interfaces, module depth, cross-cutting context). 10 marked ready-for-human (PRD parent, 8 external prereqs, 1 acceptance test).
MVP 0.1 deliverables
For Tauquil + Adam Tuesday review:
- ADR-0009, segments.json v2.0.0, gantt.schema.json, metrics.schema.json v1.1.0, gantt-seed.tsv migrated
- Architecture.md trimmed (vocab moved to CONTEXT.md, system-level only)
- CONTEXT.md, docs/staff.md, docs/parking-lot.md, docs/vocab.md, docs/exec-one-pager.md, docs/prd.md
- docs/agents/{issue-tracker,triage-labels,domain}.md
- HANDOFF.md rewritten for cold-start truth
- Mockup HTML at
fota-dashboard/dashboard/mockup.html
Acceptance test reassigned
Originally Marissa hand-counts on 2026-05-23. Trevor corrected: Neung hand-counts; Marissa supports (scope to be defined).
Trevor handoff
Asked for one commit + push to share with a fellow dev, plus an email to Tauquil + Adam summarizing the system in his voice. Sharing this prompt log too — transparency of work + democratization of practice.
2026-05-03 — Brand guideline + 16-item idea dump
Brand guideline .pptx shared at C:\Users\trevo\Desktop\FotA\ELC brand guideline_shared .pptx (45 MB). External marketing aesthetic; intended as reference for internal-tool aesthetic (same language, internal purpose) when dashboard reaches aesthetic-design phase.
Trevor dumped 16 ideas for the backlog — all logged in docs/parking-lot.md under “Ideas backlog (added 2026-05-03)” with IDEA-01 through IDEA-16. No triage; revisit when ready.
Notable threads:
- Per-user Todoist integration (IDEA-01) — sign-in-with-Todoist or API-key dump UI in gantt or dashboard.
- Two-way-sync ideas dump (IDEA-02) — capture-anywhere widget routing to a low-friction Gantt tab.
- Pre-meeting email reminders (IDEA-04) — 24h before ops sync / SLT meeting, personalized to task owners, with reply-or-forward-to-Trevor + Gantt link.
- Schema renames (IDEA-06, IDEA-10) —
counterparty→others;PE39→Thonglor PEs(covers 39 + 49 + 55). - Dove full-product (IDEA-09) — replace placeholder cell with 3 segments now (end-state visibility).
- Dashboard layout (IDEA-14) —
last week+weeks booked+next weekin a single horizontal triptych. - Gantt aesthetic (IDEA-15) — hide
id/segment/phase/sourcein default view; separate tab for timeline. - Gamification light (IDEA-12, IDEA-13) — most-open-tasks visual, weekly closed-task leaderboard, overdue list framed as supportive.
Trevor reframed Section 5 of the Pages one-pager: dropped the “millions of baht” line, replaced with: “The Festival of the Arts has three primary goals: increase revenue at a time of low cashflow, build brand reputation, and deliver great educational experiences.” PR #25 merged.
2026-05-04 — Phase 2 full build + go-live
The big one. Entire Phase 2 built and deployed in one session. Dashboard is live.
Timeline reframe
Trevor clarified the build deadline: not two months of work — Wednesday ops meeting and Thursday SLT view are the launch targets. Everything ships this week.
Apps Script (fota-dashboard)
All code written and deployed via clasp to trevorc@elc.ac.th Apps Script project:
config.gs— segment registry, tab routing, payment enum, phase/weekOf helperslib/parsing.gs—parseFotaMaster(): finds actual header row (rows 1-2 are title rows), matchesS1W1-style week col labels, classifies students (SCH→Internal/External, INTL→Overseas), counts all Y as booked (P-status filters paid only), weekly per-product headcount aggregationlib/hygiene.gs—rebuildHygiene()writes_hygiene+ appends_hygiene_history, fail-loud + email Trevor on errorlib/gantt.gs—readTasks()+bucketTasks()(lastWeek/thisWeek/nextWeek/backlog by due-date window)api.gs—doGet()servesdashboard.htmlshell;getPayload()called viagoogle.script.runfrom clienttriggers.gs— Wed 23:00 + Thu 08:00 triggers installed and running;setupIntlColumn()+freezeGradeTabColumns()one-time setup functionsdashboard.html— full SLT dashboard rendered client-side fromgetPayload()response
Key parser decisions locked in session
- Header detection: scan first 8 rows for “SCH” or “STUDENT” — fota_master has 2 title rows before actual headers
- Week columns:
S1W1/S1W2/S2W4style labels (not date-range headers as originally designed) - Program structure confirmed: T1/T2 = PE39 (6 weeks, 3+3); K1 = ELC via bridging (6 weeks, PE campus); K2/Y1/Y2-Y6 = ELC City School (4 weeks, 2+2)
- Counting model corrected: all Y = booked (payingWeeks), P2/P2T/P2S filters paid (payingWeeksPaid). Prior design incorrectly excluded P0/blank rows.
- Y2-Y6 had
S2W1/S2W2headers (naming inconsistency) — Trevor fixed manually - Y2-Y6 has dual accounting columns (“ACCOUNTING” at V, “Accounting Status-Payment” at W) — parser updated to prefer “accounting status” match
Dashboard features
google.script.runpattern (not template injection — HtmlService<?= ?>escapes JSON)- Booking-weeks section with per-week children count strip per product
- Dove row in grid (TBD × 3, matching Samakee)
- Task due dates shown on activity panel
- Section renamed to “Booking-weeks” with clarifying footnote
- Banner: “+50% better.” stays (Tauquil’s target, experience + revenue)
Deployment
- Apps Script deployed with elc.ac.th domain restriction (ANYONE disabled by domain admin — cannot create new
/execdeployments, using test/devURL) - Short URL:
tr3v0r86.github.io/fota-dashboard→ redirects to/devendpoint - Triggers installed: Wed 23:00 + Thu 08:00 (Asia/Bangkok)
- fota_master: INTL column header added to all 6 grade tabs (T1/T2 at T3, K1 at X3, K2/Y1 at T3, Y2-Y6 after last contact column); A-C frozen on all tabs
Grill session (10 questions)
- Access — Anat contacted, editor access workaround;
/execblocked by domain admin - Week structure — 6-week PE39, 4-week ELC confirmed correct; S2W1/S2W2 = naming-only hygiene fix
- Banner — “+50% better” stays
- Gantt hygiene — Trevor does Mon-Wed; Thursday shows real tasks
- PE39-External-Local = the funnel — most important segment, T1/T2 N/A students are hot leads for K1 conversion
- Pre-registration tab — different structure, not parsed; Issue #44 created; blocked on Sarah+Mel cleanup
- Samakee TBD — P0 Tuesday; Sarah→Isabella→Neung cadence is the unlock
- Triggers — installed
- Thursday review — Trevor 08:30 spot-check; Anat dead-man’s switch
- Booking-weeks vs headcount — renamed section + per-week strip added
Data source discovery
- Pre-registration tab structure is completely different from grade tabs (Country/Session/Week columns)
- fota_master accounting notes decoded: colour-coded (green = paid, red = partial),
^= from another school,**= allergy - Revenue context: 2025 total = THB 8.38M (-14.5% vs 2023). +50% target ≈ THB 12.5M.
Renames + housekeeping
- “Dream Team” → “FotA Ops Team” across 9 docs files (PR #45, merged)
- Gantt row 28 added via MCP: Neung touchpoint re blank Accounting Status + Y counting definition
- Sheets writes confirmed working via
gsheets_update_cellMCP - Phase 2 issues #2, #11–#23 closed
Pending before Wednesday
- Trevor: Gantt hygiene pass (Mon-Wed)
- Trevor: add Sarah→Isabella→Neung Samakee cadence task to Gantt
- Tuesday: lock Samakee with Sarah (#4)
- Neung: confirm blank + Y = booked (Gantt row 28, due Thu 7 May)
- Neung: fill INTL column Y for overseas students → next rebuild picks up
- Thursday 08:30: Trevor spot-checks dashboard before SLT 13:30
2026-05-04 — v3 design handoff
Design session: two new surfaces designed and handed off for implementation.
What was designed
Gantt — timeline-first (option B) Swimlane Gantt with collapsible rows, today-line, weekend shading. Group by Product | Owner | Phase. Zoom Day | Week | Month. Bar status encoded as fill (solid/hatched/outlined/checked). Hover → full task card. Theme toggle.
SLT Dashboard v2
Seven sections top-to-bottom: Masthead (weekOf + phase pill + refresh marker), North-star row (Tauquil +50% callout, committed paying-weeks, vs 2025 placeholder), Numbers Grid (4×3 + Dove placeholder + _pending_dove bucket), Activity (3 pivots: Timeline / By owner / By dept), Open dependencies table, Retrospective (gated on phase === "inaugural"), Footer (schema version citations).
Two-way sync activity surface (headline change in v0.3)
Every task in the Activity section now carries a SyncBadge (● SHEET in info-blue / ● DASH in gold) derived from audit_log last entry, falling back to source. Filter chip narrows the whole section by write direction. Dept pivot shows counterparty arrow for SLT-touch tasks. Edit count shown when audit_log.length > 1.
Design tokens locked
tokens.css is the single source of truth. Key additions vs Phase 2: --gold (#AC9D71, inaugural/dash badge), --info (#4D6B86, sheet badge), product tints (four pastel fills). Type: Inter Tight 300–700 + Fraunces display-only. Spacing: 4px baseline, --s-1 through --s-10. Radii: 3/6/10/pill. Shadow: one quiet shadow only.
Artifacts created
design_handoff_v3/README.md— full design specdesign_handoff_v3/tokens.css— design tokensdesign_handoff_v3/option-b-timeline.jsx— Gantt prototypedesign_handoff_v3/option-dashboard.jsx— dashboard prototypedesign_handoff_v3/shared.jsx— chrome + utilitiesdesign_handoff_v3/seed.js— illustrative data (do not ship)design_handoff_v3/screenshots/gantt-timeline.png+dashboard-full.pngdesign_handoff_v3/CLAUDE_CODE_PROMPT.md— implementation prompt for next session
Bundle added to both repos: fota-dashboard/design_handoff_v3/ (primary) and fota-ops/design_handoff_v3/ (reference copy).
Issues created
- #49 — parent tracking: implement Gantt + SLT dashboard (Phase 3)
- #50 — Gantt timeline-first view
- #51 — SLT dashboard v2 surface
- #52 — two-way sync activity surface (SyncBadge + filter chip)
Open questions deferred to v3 implementation
Samakee segments (#4 · Sarah · 6 May), Dove segments (#5 + #28 · April · TBD), 2025 backfill (#6 · Mark + Neung · 15 May), INTL Y/N column (#3 · Neung · ASAP), source-of-truth lock (#7 · Trevor + Sumeet/Amanda + Neung), OAuth (#47 · Anat post-MVP).
Next step
Open fota-dashboard/ in Claude Code, paste design_handoff_v3/CLAUDE_CODE_PROMPT.md, implement. Target: Thursday before SLT or Friday after.
2026-05-05 — Historical ELC data folded in
Trevor shared the Summer Revenue 2023-2025 sheet (1T07DYVXB2uMBM5lKakYqUybJy8TkNvLkJ2wp5zDL6lM). Contains ELC paying-weeks by grade (K1-Y6) per week across 2022-2025.
What was derived
ELC year totals: 2022=466 / 2023=339 / 2024=400 / 2025=293. The 92 K1 drop (176→84) is confirmed from primary data. Weekly breakdown for 2024 and 2025 captured.
Segment mapping from this data:
ELC-Internal= K1 only (84 weeks in 2025) — K1 bridging students are definitionally Internal per ADR-0009.deltaLastYearnow live for this segment.- K2-Y6 combined = 209 weeks in 2025 — cannot split Local vs Overseas without INTL column backfill. Still blocked on #6.
- PE39 and Samakee: no historical data in this sheet.
What was built
seed/history-2022-2025.json— full raw data (grade × year × week), 2022–2025metrics.schema.jsonv1.2.0 — addshistoricalTotalsfield (elcByYear, grades, segmentRef25)config.gs—HISTORICAL_2025,HISTORICAL_ELC_BY_YEAR,HISTORICAL_GRADESconstantsapi.gs—deltaLastYearcomputed fromHISTORICAL_2025(live for ELC-Internal; null for others);historicalTotalsadded to payload
Issues
- #53 — tracking issue; partially closes #6 and #23
Still open
ELC-External split + PE39 history still needs Mark + Neung (#6, due 2026-05-15). When that lands, update HISTORICAL_2025 in config.gs and deltaLastYear populates automatically.
2026-05-04 — v2 merge recovery + bug fixes + “The Bar” target metric
Same session, later in the day. Three issues surfaced and fixed.
Bug 1: Gantt reading wrong sheet
readTasks() was calling getActiveSheet(), which is editor-state-dependent in a web-app context (returns whichever tab the script editor had open last, not reliably the data sheet). Fixed to getSheets()[0].
Bug 2: clasp push overwrote live v2 dashboard
Local main branch had the older ~265-line dashboard.html; the live Apps Script project had been running the full v2 facelift (~1500 lines). Running clasp push from main overwrote it.
Fix: git merge origin/v2, resolved conflicts by taking v2’s dashboard.html wholesale and manually merging the historical-data additions into api.gs and config.gs. Clasp pushed all 12 files. Dashboard restored.
Bug 3: deltaLastYear not rendering
metricCellHtml() in dashboard.html had the delta-last-year span hardcoded to —. Wired it up to read seg.deltaLastYear from the payload: positive = green, negative = red, null = dash.
“The Bar” north-star target metric
Added a target block to the north-star section: 440 = round(293 × 1.5) (ELC 2025 realized × +50% Tauquil target). Shows:
- Committed paying-weeks vs 440 (e.g. “95 of 440”)
- Progress bar (capped at 100%)
- “N% of the way there · M to go · 2025 was 293 (ELC only)”
Numerator uses totalCommit (all products, committed payingWeeks) — not ELC-only — because the goal is to celebrate all bookings as they land. Finance-lag reasoning: Trevor’s position is show committed and then chase finance to collect; don’t gate the dashboard headline on payment speed. Memory saved.
Deployed state
Clasp pushed 12 files. Live at /dev endpoint. No new issues created (all fixes in-flight on existing work).
2026-05-07 — V2 launch day
New laptop pickup + V2 SLT-ready batch + Todoist dump. SLT meeting at 13:30 Bangkok was the first time the V2 surface was seen externally.
Context
Trevor on a fresh MacBook with no Homebrew, no gh, no clasp, no .clasp.json, no Node. Goal: ship V2 dashboard live before 13:30 SLT meeting. Constraint: Workspace admin policy disables ANYONE and ANYONE_ANONYMOUS web-app deployment access — the Apps Script editor’s Deploy dialog rejects every save.
What was decided + built
Setup gap (laptop migration).
- Installed Homebrew, Node (v25),
gh,claspvia brew + npm. gh auth login(SSH) +clasp login(browser OAuth) on the new laptop.- Created
apps-script/.clasp.jsonwith the Script ID (gitignored, so it didn’t follow over from the old machine). - Added a
fota-deploy [description]shell function to~/.zprofilefor one-line push + deploy from anywhere.
Per-repo skill config (mattpocock skills). /setup-matt-pocock-skills ran in fota-dashboard for the first time. Wrote docs/agents/issue-tracker.md (GitHub on Tr3v0r86/fota-dashboard, implementation issues only), docs/agents/triage-labels.md (defaults), docs/agents/domain.md (redirects skills to ../fota-ops/ for CONTEXT.md + ADRs since fota-dashboard intentionally has none locally per ADR-0001). Added ## Agent skills block to fota-dashboard CLAUDE.md.
2025 ELC audience baselines wired (issue #6 / T-NEW-I closed).
- Mark + Neung’s INTL backfill landed early (due 2026-05-15, arrived 2026-05-06).
- Read Mark’s “Summer Revenue 2023-2025” sheet via Drive MCP — 4 tabs identified by metadata:
CS Attendance,CS 2025 Internal external,PE Attendance,Samakee Attendance(latter empty). - Replaced the prior
K1=Internal: 84shorthand with audience-true totals: ELC-Internal 233 / ELC-External-Local 38 / ELC-External-Overseas 22 (reconciles to 293). - PE Attendance tab carries
Session 1: 14, Session 2: 29, Total: 43with Mark’s “children or weeks?” flag — wired as PE39 row-level anchor with caveat. Audience split not available (product-aggregate only). - Corrected a labeling mistake: prior commit had annotated the 43 as
_samakee2025; actual tab isPE Attendance. Renamed to_pe2025. - Added
_provenanceblock toseed/history-2022-2025.jsondocumenting that ALL historical numbers are retroactive end-state reconstructions; FotA had no live tracking system before May 2025.
Realization that drove IDEA-17. Trevor surfaced the structural reality: there was no FotA tracking system, no live commitment counts, no audience field anywhere in 2025. This means historical 2025 numbers are anchors (where last year landed), never a pace reference. deltaLastYear semantic of current − 2025_total is therefore structurally meaningless during build phase — it would read ▼ ~200 vs '25 all summer. Captured in parking-lot IDEA-17 with three options; recommended option (d): hide the YoY chip during build phase, restore at inaugural. Implemented in V2. Same-week-of-season parity (option c) was previously listed but is structurally impossible — that data never existed.
Schema renames landed in canonical source. counterparty → others (#27) and PE39 label → Thonglor PEs (#29) had been applied to fota-dashboard’s vendored schemas at the time of the 2026-05-04 grill but never propagated back to fota-ops as the canonical source. Fixed: updated fota-ops/schemas/gantt.schema.json, seed/gantt-seed.tsv, docs/staff.md, and schemas/segments.json (label-only rename for PE39, internal keys stay). Also caught a separate gantt.schema.json v1.1.0 vendoring drift (fota-dashboard had bumped to v1.1.0 with the dept column per ADR-0010, fota-ops never received it) and synced. #29 closed; #27 moved to ready-for-human for Trevor’s manual gantt_master Sheet header rename.
Domain auth. Workspace admin disabled ANYONE web-app access. Trevor’s existing /dev URL was being shared with SLT, which doesn’t work for non-editors. Resolution path:
- Switched deployment “Who has access” to “Anyone within ELC International Schools”.
- Manifest required
webapp.access: DOMAIN(wasANYONE_ANONYMOUS— admin policy rejection). - Switched
executeAs: USER_DEPLOYING(Trevor) so script reads fota_master/gantt_master with Trevor’s permissions. - Existing 1.9.9 deployment had ANYONE persisted in its config — couldn’t be edited (admin block). Created a fresh deployment with explicit DOMAIN settings; old one archived. Updated
index.html(root +dashboard/) to redirect to the new/execURL. - Documented
clasp deploy -i <deploymentId>as the canonical deploy path; Apps Script editor UI is now permanently unusable for this project. Codified infota-dashboard/CLAUDE.md+ a feedback-style memory.
Live /exec deployment ID: AKfycbwqnU-iy23rq_3ZO476A7l62HWaixiY-4MaT8WR775Wm_VDGEWfXk_UvmxaJ_kU7Rha
SLT-ready dashboard polish (16 fota-dashboard versions today, v1.9.7 → v1.9.17).
- IDEA-17 phase-aware
vs '25chip rendering. - PE39 row-level baseline strip with
'25 was 43 (children or weeks?)caveat. - “What needs you” moved below “What the team is doing” + wrapped in collapsible
<details>with summary stats. - Past-due rows fully editable: title (contenteditable), due date (native input), owner (click →
openGlobalPickermodal). Required wiring change/focusin/keydown/focusout listeners on#you-section+#overdue-section(was activity-only). - Activity timeline “Last week” lane is now a collapsible
<details>that shrinks the column via:has()selector, giving This/Next more breathing room. - Retrospective parser made header-aware. Mark’s sheet sometimes had 2026 content in column C with B empty; new parser detects column positions from row 0 headers (‘2025’/’2026’/’2027’) instead of trusting positional indices.
- “Weeks booked” cold-start delta.
_hygiene_historyhad no prior-weekOf snapshots (system deployed Mon 2026-05-04, so all snapshots share that weekOf).readPriorSnapshotnow falls back to the earliest meaningful snapshot of the current week. Masthead chip label adapts: “wk-over-wk” when prior-week data exists; “since {date}” during cold-start. Auto-flips next Wed when the second weekOf snapshot lands. - OPEN_DEPS pruned to live entries (Dove segment, PE39 audience split, Samakee historicals); resolved entries removed.
- “Scheduled” subsection in Backlog & Ideas renamed to “Ideas”.
- Email-PDF card compacted; added recipient input (server-validated to @elc.ac.th); switched
GmailApp.sendEmail→MailApp.sendEmailto avoid per-user Gmail OAuth re-authorization.
Todoist one-shot dump. New sendTasksToTodoist(targetName, token) server function. User pastes their Todoist API token (one-time per session; no persistence), button POSTs each open task to their Inbox via the v2 REST API. Each task gets [FotA] content prefix, due_date if present, notes as description. Token never logged or stored; audit row records count + first error only. Uses existing script.external_request scope. No per-user reauth.
Triage cleanup.
- Closed: #29 (Thonglor PEs label rename), #53 (historical seeded — fully superseded).
- Moved to
ready-for-human: #3 (awaits Neung verification), #6 (Trevor decides A/B path on_hygiene_historywrite), #27 (manual sheet rename remains), #44 (Neung-led pre-reg tab cleanup; updated owner from Sarah+Mel to Neung), #47 (waits on #5 to close). - Added IDEA-18 to parking-lot for per-user gating.
- Refined IDEA-17 with the structural-impossibility framing.
Schema bumps
metrics.schema.jsonv1.2.0 → v1.3.0: addshistoricalTotals.productRef25+ top-leveldeltaBaseline. Updated descriptions ondeltaLastYear(flags the structural caveat) anddeltaLastWeek(cold-start fallback). Documented previously-undocumented payload fields:tasksByDept,canEdit,currentUser,weeklyTotals.gantt.schema.json: re-synced fota-ops with v1.1.0 +deptcolumn from fota-dashboard.segments.json: PE39 label → “Thonglor PEs” in canonical source.
Issues touched
- Closed: #29, #53
- Commented + relabeled: #3, #6, #27, #44, #47
- Parking-lot: IDEA-17 refined, IDEA-18 added
Still open
- #5 (April + Sarah) — Dove segment list. Blocks #28 + #47 closure.
- #3 (Neung) — INTL verification sign-off due today (Gantt T-20260504-0028).
- PE39 unit (Mark) — “children or weeks?” needs answer before the 43 baseline can be trusted as paying-weeks.
- Mockup file —
fota-dashboard/dashboard/mockup.htmlline 195 still hasPE39product label (cosmetic; mockup not served).
Deployed state
Live at the new /exec URL @18 (clasp deploy version 18). Domain auth on. SLT meeting at 13:30 today is the first external view of V2. Default deploy workflow going forward is fota-deploy "<description>" — no editor UI.
2026-05-08 — V2.1 PM-tool pivot + dashboard development door closed
Day after V2 launch. Trevor pivoted the dashboard’s role.
Context
V2 SLT meeting went well. Trevor reframed: dashboard = PM tool for him, not a team operating surface. People won’t email themselves tasks; people won’t link Todoist. Last/this/next week is good. New requirement: list tasks per user, email-with-note. Sarah on holiday after EOD 5/8 for 2 weeks. PE Heads (Sumeet + Amanda) treated as a single entity. April leads Dove with Mark supporting; Neung point on Isabella for Samakee. Trevor’s framing: “the dashboard is not the work, the work is the work.” V2.1 closes dashboard development.
What was decided + built
Grilled the pivot via /grill-with-docs. 9 design-tree branches resolved one at a time:
- Audience — single dashboard, full content for all (SLT keeps task visibility), condensed presentation. No role-gated views. CONTEXT.md updated.
- PE Heads — coined as canonical term for Sumeet + Amanda jointly. Server-side
OWNER_ALIASEScollapses Sumeet/Amanda/Sumeet/Amanda → “PE Heads” in per-owner views; gantt rows keep their literal owner string (no historical retag). - YouSection repurpose — same physical location, eyebrow “What needs you” → “Per-person view”; h2 from “{name}’s desk” → just “{name}”. Drop email-self / Todoist; add email-with-note.
- Email-with-note design — textarea + this-week tasks (overdue + due-within-7d, drop backlog) + inline HTML body + server-side recipient lookup via
STAFF_EMAILS(PE Heads → Sumeet + Amanda; @elc.ac.th validation server-side) + cc-toggle off-by-default. - Decision log → IDEA-19 (deferred — not enough decisions to justify; ties into existing retrospective surface when ripe).
- Sarah-out coverage → time-bounded notes in
docs/staff.md(5/22 checkpoint task), not permanent CONTEXT changes. April + Mark on Dove; Neung point on Isabella; Mark covers Mel reconciliation; Trevor + Mark cover parent comms. - Sprint cadence not seeded in gantt — Trevor’s PM rhythm lives in his calendar, invisible to SLT by design.
seedSprintCadence()deleted from seed-tasks.gs. - UI compaction (a) merge North star + The Bar into a single row (saves ~120px); (d) Overdue collapsed-when-empty to a single muted line; (e) Retrospective wrapped in
<details>at the bottom — closed by default. - Ideas redesign — scrollable list (max-height 340px, all ideas visible not top-6) + inline-expand
<details>per row exposing owner picker + due-date input + Promote button. NewpromoteIdea(taskId, owner, due)server function: atomic status=’idea’ → ‘not-started’ with owner/due/updated_at write, single audit row.
Dashboard surfaces touched (apps-script/dashboard.html):
- Masthead unchanged
- North star + The Bar merged into single horizontal row
- Audience grid unchanged
- Activity unchanged (last-week stays collapsible from V2)
- YouSection redesigned (eyebrow + filter logic + push card)
- Overdue collapsed-when-empty
- Backlog & ideas redesigned (scrollable + inline promote)
- Sync health unchanged
- Open dependencies unchanged
- Retrospective wrapped collapsible at bottom
Removed:
triggerEmailPDF,triggerTodoistSyncclient functionssendTasksToTodoistserver function- PDF generation in
emailMyTasks(now thin wrapper overemailToPerson) - Stale “Thonglor PEs / Samakee / Dove targets land once 2025 backfill arrives (Mark + Neung · 5/15)” caveat (backfill landed 5/6)
STAFF_EMAILS table added to dept-mapper.gs. Confirmed entries: Trevor, Mark, Adam, PE Heads (→ both). Other entries are guesses pending verification — won’t break anything (server validates @elc.ac.th + manual override is always available in the form).
Schema bumps
metrics.schema.json v1.2.0 → v1.3.0 (already landed previous session): adds historicalTotals.productRef25, top-level deltaBaseline, documents previously-undocumented payload fields.
Issues touched
- Coverage notes in
docs/staff.mdfor Sarah-out window (5/9 → 5/22). - Parking-lot:
- IDEA-19 (decision log, deferred — connects to retrospective)
V2.1 deploy
Live at /exec deploy version @19. Clasp-deployed via fota-deploy flow. Same URL across versions.
Door closed
Trevor explicit: “The dashboard is not the work, the work is the work.” V2.1 is the final dashboard ship for FotA Summer 2026. Going forward, dev attention reallocates to:
- Neung — data hygiene ASAP (operational, fota_master)
- PE Heads — own lead conversion + enrolment funnel (Adam’s directive)
- Payal + Heather — educational experience execution
- Trevor — sprint cadence + cross-team coordination
Dashboard receives no new features without an explicit reopen decision. Bug fixes only.
2026-05-09 — V2.2 final lock; the dashboard is the rolling document
Same-day continuation after V2.1 ship. Trevor closed all remaining gaps + locked V2.2 as the final dashboard ship.
Trevor’s framing
“The work is the work now. Dev ideas stay hidden on the dashboard but logged in the git. Only a few tweaks to make as data gets cleaned but this is the rolling document until FotA ends. Daily touches by me. Pushes to get the ball rolling. Work visible, data is the anchor.”
What landed in V2.2
Per-person view extensions
- Adam + Tauquil now selectable in picker (Tauquil email TODO; manual paste until provided)
- Recipient input autopopulates from the canonical
STAFF_EMAILSmap server-side; PE Heads expands to both Sumeet + Amanda - cc-toggle defaults to checked (Trevor wants himself cc’d on every push for record)
- Mini-stats panel adds Next week tile alongside Overdue + Due-this-week — gold accent, “look ahead” caption
- Email body extends to include a Next-week section (8-14 days out); empty state only fires when all three buckets empty
- Open/close state of
<details>now persists across re-renders (changing picker no longer collapses) - Idea rows: text-input + Save button (rename in place), inline-expand Promote (auto-renames first if text edited), red × Delete (server-guarded — only
status='idea'rows). NewdeleteIdeaserver function
The Bar reworked
- Now spans ELC + Thonglor PEs combined (was ELC-only). Target = (293 + 100) × 1.5 = 590
- Numerator = elcCommit + peCommit
- Reference line: “2025 was 393 (ELC 293 + PEs 100)”
- New caption: “K1 cross-over — PE Heads accountable · City School responsible” (RACI made visible)
Wk-over-wk delta — anchor-always
PROJECT_START_ANCHOR = { date: '2026-05-04', weeksBooked: 27 }hardcoded inconfig.gs- Masthead shows
▲ +N since 5/4regardless of whether_hygiene_historyhas a true prior weekOf yet - Once Wed 2026-05-13 23:00 fires the next weekOf snapshot, real wk-over-wk auto-takes-over (priority: priorWeek → anchor)
readPriorSnapshotDate-vs-string comparison bug also fixed (was classifying every row as prior-week, picking latest = current = 0)
Numbers grid — visible accountability
- Per-product
PRODUCT_LEADSchips in leftmost column: “Amanda + Sumeet lead (also K1 ELC enrolment)” / “Isabella leads” / “Trevor leads” / “April leads” - Column-header
Mel + Fede leadchips on External-Local + External-Overseas headers (cross-product accountability) - Samakee + Dove segments flipped active (
TBD→0); tabs are live infota_master, parser wired, just awaiting Isabella + April to populate - Dove-External-Local activated to pressure April to define what the external-local cohort means for SEN
- Samakee tagline
Nonthaburi · cross-age→Nonthaburi · T1-K2(concrete)
Refresh + email + log
- Editor-only
↻ Refresh nowbutton in masthead — callsmanualRebuildFromDashboard→rebuildHygiene. ~5-15s. Audit row each press MailApp.sendEmail(replaces GmailApp — no per-user reauth)STAFF_EMAILSconfirmed handles for all 17 staff (Trevor, Mark, Sarah, Neung, Marissa, April, Heather, Payal, PE Heads → Sumeet + Amanda, Mel, Federico, Jem, Adam, Poom, Isabella). Tauquil pending- New
_email_logtab ongantt_mastercapturing FULL note text + per-bucket counts + recipients + cc-flag + subject — Trevor-only context for memory + history. Append-only backfillEmailLog()recovers ts + meta from historical_gantt_auditrows.backfillNotesFromGmailSnippets()overlays note text from Gmail snippets (truncated; Trevor extends manually)
UI cleanup
- North star + The Bar reverted to original 3-column layout (V2.1 merge didn’t actually save space)
- Overdue collapsed-when-empty (single muted line)
- Retrospective wrapped in
<details>at the bottom — closed by default - “What needs you” → “Per-person view”
- Removed all OAuth references (domain auth = the OAuth resolution; nothing further wires)
- Two playbook docs at top: Simple (educator-friendly) and Technical (ethos + architecture). Served via
?page=simple/?page=technical. URLs absolute (built fromScriptApp.getService().getUrl()in payload — relative URLs land in the Apps Script iframe panel) - Footer adds clickable links: roadmap + prompt log + issues, all pointing to
Tr3v0r86/fota-opson GitHub - Mobile banner removed (replaced by playbook buttons)
Public site ingest
seed/website-2026-summer-school.json— structured snapshot ofelc.ac.th/summer-school/. Programmes mapped to schema, sessions/weeks dated, themes captured, parent CTAs (Inquire → Visit → Apply), measurement gaps flaggeddata-sources.mdregisters public site + Veracross + per-programme detail sub-pagesCONTEXT.mdadds Parent-facing programme themes (2026) section — non-schema, but anchored for YoY diff- IDEA-20 in parking-lot — parent-journey funnel ingestion + wireframe for 2027 cycle. Sept-Dec 2026 design project
Decisions locked
- Dashboard development is closed for FotA Summer 2026. Bug-fix-only ship cadence.
- Future enhancements / new features go to GitHub issues for the post-summer cycle.
- Daily ownership: Trevor pushes from the per-person view, the team works from their own systems but reads the dashboard Wed (Ops Team) + Thu (SLT 13:30).
- Door re-opens for design work Sept-Dec 2026 for the 2027 cycle (parent-journey ingestion + Node.js evaluation).
Deployed state
Live at /exec deploy version @35. Domain auth on. Same URL across all V2.x versions.
2026-05-12 — V2.2.20 lock; What is FotA narrative + strategy critique loop + done-week visibility + 2025 PE baselines
V2.2 was supposed to be the final ship, but five days of dashboard touches surfaced enough operational polish that V2.2.20 becomes the new lock point. Same freeze rule applies: bug fixes only after this.
Trevor’s framing
Two-week sprint of operational tightening. The strategy page “what is fota” is the spine; the dashboard surfaces are the rhythm. Status chips open to everyone so people close their own work. The work is the work; the dashboard supports the work, it is not the work.
The strategy spine — What is FotA + Data Pack pages
Three new gated surfaces alongside the dashboard, all DOMAIN-auth, served via Apps Script’s HtmlService.
?page=whatisfota— narrative document, anchored to the ELC vision/mission refresh (Jan 18 deck). Belief → cornerstone principle → strategic purpose (three family audiences) → shape (4 products × 3 audiences with Mandarin Immersion sub-product) → annual rhythm (Jan ramp → Mar launch → Apr-May push → Jun-Aug delivery → Sep retrospective) → accountability (orchestrator + proactive remit, no naming) → how-we-read-the-season (tour-voice = internal-voice, ops weekly inventory, SLT Thursday 15-min slot through the four questions, dashboard, plus the “work is the work” callout) → multi-year horizon.?page=data— reference pack. Appendix A tables from the April 29 strategic pack inlined as HTML (revenue, cohort, session attendance, ASA growth, parent survey, programme enrollment, competitor pricing, instructional days, 2026 pricing). Source-file links to Mark / Tauquil / Poom / Ammi sheets.- Top bar expanded to 4 buttons:
What is FotA · Simple · Technical · Data Pack. Mobile collapses to 2-col. - Voice rules locked: no em dashes, no sentence fragments, no “not X, it’s Y” pivots. Strict.
- Versions frozen at v1.8 narrative / v1.1 data pack until FotA 2026 retrospective.
Strategy critique widget (server pipe + side rail)
Anyone signed in with an @elc.ac.th account can submit a strategy critique from the What is FotA page.
- Side-rail launcher (fixed bottom-right, scroll-follows). Click → 340px panel with textarea + Submit.
- Submissions append to
gantt_masterwithstatus='strategy',source='whatisfota', owner = submitter’s canonical name. Cmd+Enter submits. Logged-as id displayed on success. - New
appendStrategyNote(text)server function. No editor gate. Domain auth alone. bucketTasksfiltersstatus='strategy'out of every dashboard surface — these rows live only in gantt for manual triage. Future triage UI = post-summer work.
Parser bugs (P0) caught in deployment
- ENG/MAN parser fix. K1+K2 cells changed from
YtoENG/MAN(English regular vs Mandarin immersion). Parser was silently zeroing all those rows. Now countsY/ENG/MANall as paying weeks; ENG vs MAN tracked separately per row. - Mandarin Immersion sub-product surface. ELC audience cells with
manWeeks > 0get a sub-lineMandarin Immersion · MAN N wks · ENG M wks. Caption beneath grid explains the first-year framing. Renders across all three ELC audience cells (Internal / External-Local / External-Overseas), since real MAN students span all three at City School + Shuang-Lien + AISB + Heathfield + Japan. - Per-column product routing. K1 tab has
City | City | PE49 | City | City | PE49column tags in the row above the SCH header. Parser was routing every K1 cell to ELC. NewdetectColumnProducts()reads the row above the header and tags each week column with its product. A single K1 student row can now contribute paying weeks to both ELC and Thonglor PEs depending on which columns are booked. Fix landed after Trevor: “city school doesn’t have 3 weeks”. debugSegment(segmentId)helper. Editor-side function that dumps every cell contributing to a given segment with tab/row/SCH/INTL/column-product/value detail. Used to confirm the “1 PE39-External-Overseas week” was Nanato Sakai (Nursery schools in Japan) → 2 City weeks + 1 PE week, working as designed.
Hygiene loud-fail email
Each rebuild compares derived per-week column-sums against each grade tab’s “Total Students Per Week” footer row. Mismatches written to _hygiene as a JSON sidecar and emailed to trevorc@elc.ac.th with Subject: [FotA Dashboard] hygiene FAIL · N mismatches · YYYY-MM-DD. Silent when totals agree. First-fire diagnosis: row-76 formula counts ENG only, not MAN — to be fixed sheet-side.
Calendar-week semantics for “Done this week”
Switched from rolling 7-day window to true calendar week (Monday 00:00 BKK onward) per Trevor: “This week is this week.”
bucketTasksnow splits done items two ways:doneThisWeek(anchor ≥ Mon this week) andlastWeek(anchor in previous calendar week).- Timeline pivot: “Last week · done” lane collapsed by default, count + green border visible when closed. This-week lane stays primary + always open, with a collapsible “Done this week” sub-block in its footer. Next-week lane collapsed by default for symmetry.
- 8-row
slicecap removed from all lanes — full lists render. - Dept pivot: new green “Done this week · N ✓” band between Next-week and Last-week, with 0.82 opacity wrapping.
- YouSection: 4th mini-stat tile “Done this week ✓ N” in green, plus collapsible “Done this week · N ✓” list below the open-task feed. Summary line appends
· N done ✓. - Email push: “Done this week” section in the email HTML body, green-accented, “Momentum logged. Nice work this week.” tagline.
Status chips opened to all domain users
writeTaskField permission gate now branches on field:
status→ any signed-in @elc.ac.th user. Domain auth + non-empty session email = pass.- Anything else (title, owner, due, etc.) → still requires editor allowlist.
Client: status chips always clickable now (no canEdit gate). New .clickable class. Audit log captures the user email on every write, so non-editors closing their own work have full traceability.
Date editing reliability
Original invisible-overlay pattern (opacity-0 input on top of friendly chip) stopped reliably opening native picker in the timeline this-week lane after the lane restructure. Two failed attempts:
- v2.2.18 — added
onDateChipClickhandler withinput.showPicker()+z-index: 1on the overlay. Still flaky. - v2.2.20 — replaced overlay with explicit modal date picker. Click on
.date-displayopens existing modal with a real visible<input type="date">inside. Native picker opens on direct click in the modal. “Save / Clear / Cancel” buttons commit through the existingcallWriteWithRetrypath. Works reliably across the timeline pivot, dept pivot, owner pivot, YouSection, and past-due surfaces.
2025 PE audience baselines
Adam-style per-cell baseline → target chips now render on all three Thonglor PEs audience cells.
HISTORY_2025extended with:PE39-Internal: 90,PE39-External-Local: 4,PE39-External-Overseas: 6.- Numbers from the “Fota Historical Data” sheet: PE49 2025 was 77 weeks all internal, PE39 2025 was 23 weeks split 13 internal + 4 ext-local + 6 ext-overseas. Combined Thonglor PEs 2025 = 100, matches
PRODUCT_HISTORY_2025['PE39']. - K1 Bonus weeks (12+8=20) stay under ELC-Internal per the per-cell PE-column routing.
- Once Trevor updates the source sheet numbers, edit
HISTORY_2025inconfig.gsand redeploy.
What’s locked at v2.2.20
- Strategy page (
?page=whatisfota) — v1.8 narrative, frozen until FotA 2026 retrospective. - Data Pack (
?page=data) — v1.1, frozen. - Dashboard surfaces: timeline pivot (this-week-primary, last + next collapsed, done-this-week sub-block), dept pivot (green done-this-week band), per-person desk (4-tile mini-stats + done collapse), strategy critique widget on the What is FotA page.
- Parser: ENG/MAN/Y all count, per-column product routing, hygiene loud-fail Thursday alert.
- Permissions: status chips open to all domain users, other fields editor-only.
- Date editing: modal picker on all task rows.
Decisions locked
- Dashboard development stays closed. Any work after this = bug fix only.
- Strategy and data-pack copy edits welcome (text file edits in
whatisfota.html/datapack.html). New surfaces or new features go to GitHub issues. - v2.2.20 = the rolling document until FotA 2026 retrospective. Daily touches by Trevor. Updates land via
fota-deployshell function.
Deployed state
Live at /exec deployment @56. Domain auth on. Same URL across all v2.x versions.