diff --git a/AGENTS.md b/AGENTS.md index 383c81a..8e99135 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,13 +7,15 @@ ## 1. Purpose and outcome -Two school systems, for Harry and Finn: +**Compass carries everything we need**, for Harry and Finn: the daily timetable, the +**learning tasks** (what is due), and notices. -- **Compass** — the daily schedule and planner: what is on, what is overdue, notices. -- **Teams** — homework and assignments. +Store it, surface overdue and pending work, write the day's periods and due work to a +dedicated Home Assistant calendar, and send the morning briefs. -Store both, surface overdue and pending work, write important events to Sam's Home -Assistant calendar, and send the morning briefs. +**Teams is DEFERRED — do not build it.** The Phase 2 fetch proved Compass's **Learning +Tasks** already carries the due work: `learning-tasks-all.json` holds **70 structured +tasks** with names, dates and descriptions. Teams is not on the critical path. **Outcome (the single success statement):** > Sam sees, in one page, what each child has due and what is overdue — without @@ -23,8 +25,7 @@ Assistant calendar, and send the morning briefs. **In scope** - Scan **Compass** per child: the daily schedule, notices, and due dates. -- Scan **Teams** per child: homework and assignments. **Scope may be limited** — pick - the smallest section that still answers "what is overdue". Decide in Phase 2. +- Scan **Compass Learning Tasks** per child: what is due, overdue, and coming up. - Store and display per child. - Detect overdue and pending work. - Write important events to Sam's Home Assistant calendar. @@ -33,6 +34,7 @@ Assistant calendar, and send the morning briefs. **Out of scope** - The **React calendar** — that is a separate project. Do not build a calendar UI here. +- **Teams** — deferred. Revisit only if work is found that exists nowhere in Compass. - The school's own systems. Read-only. ## 2a. Prerequisites (verify before Phase 1) @@ -81,14 +83,14 @@ Items marked **not verified** need a decision or a test. | FR-5 | Store every item with its child, source page, type, subject, due date, and link. | | FR-6 | Detect overdue work and work due today and this week. | | FR-7 | Show a per-child view: overdue, due today, due this week, and messages. | -| FR-8 | Write **important school events** to **Sam's Home Assistant calendar**. The Hub or Jervis may also push into it. | -| FR-9 | Send a **morning brief to each boy** (Harry, Finn): what is on today, overdue work, pending work, and school notices. | +| FR-8 | Write to a **dedicated Home Assistant calendar** (suggested name `School`), per child: (a) **that day's periods**, (b) **work due today**, (c) **overdue work**, (d) **major events** (excursions, exams). **Idempotent** — an item already in the calendar is **never re-inserted**. | +| FR-9 | Send a **morning brief to each boy** (Harry, Finn) **by email**: (a) today's classes — period, subject, room, teacher, **decoded**; (b) **overdue** work; (c) **due today**; (d) **due this week**; (e) notices. Overdue first. Lists only, no fluff. | | FR-10 | Provide a **Delete** action and a **Send** action on items and summaries. | | FR-11 | Hub API: `GET /capabilities`, `POST /ask` (read-only), `POST /notify`. | | FR-12 | Fail **loudly** on a scrape failure. Never report "nothing due" when the scan failed. | | FR-13 | Log every scan: time, child, pages, items, errors. | | FR-14 | Send a **combined brief** for both boys to **Jo and Sam** via Apprise. | -| FR-15 | Scan **Teams** for homework and assignments, with the smallest useful scope. | +| FR-15 | **Teams — DEFERRED.** Do not build. Compass Learning Tasks supplies the due work (see §13). | ## 5. Screens and UX flow @@ -131,9 +133,42 @@ SQLite inside the service. Suggested tables: | `scans` | started-at, child, pages fetched, items found, error | | `notifications` | recipient, summary text, sent-at | | `session` | harness session state per child | +| `calendar_index` | what has already been written to the HA calendar (child, kind, uid, date) — this is what keeps writes **idempotent** | +| `codes` | the **editable decode map** — subject codes, room codes, teacher initials. Never hardcode these; they change. | Retention: keep items while the term is current. Scans are append-only and size-capped. +### How to read a Compass timetable entry + +Format: + +``` +[Period Number] - [Subject Code] - [Room Code] - [Teacher Initials] +``` + +Real examples from the Phase 2 capture: + +``` +8:55: 1 - 11XMUSA6 - A1 - JBR +9:54: 2 - 11XMUSA6 - A1 - JBR +11:23: 3 - 11SBIOA1 - M4 - AFR +1:07: RLE GROUP D - IM1 - RLE +1:07: 4 - 11HLEGB5 - D8 - LHT +``` + +| Component | Meaning | Example | +|---|---|---| +| **Period** | The slot in the school day. Text blocks like `C` or `RLE GROUP D` are tutorials, Connect, or assembly. | `1`, `2`, `C`, `3` | +| **Subject code** | VCE unit / class identifier. ``. | `11MGMAC2` | +| **Room code** | ``. | `B11`, `M6`, `A1` | +| **Teacher initials** | Internal 3-letter staff code. | `GT`, `ANE`, `JBR` | + +Decoding `11MGMAC2`: `11` = Year level · `M` = Faculty (Maths) · `GM` = Subject +(General Maths) · `AC2` = timetable block. + +**Store this as the editable `codes` map.** Do not hardcode it — teacher initials and +room codes change between years, and new subject codes appear each term. + ## 8. Integrations | System | Use | @@ -156,7 +191,8 @@ The Hub interface is frozen in `central_ai_llm_master/docs/ask-contract.md`. | Backend | **Go** | | UI | **HTMX** + server-rendered HTML | | Database | **SQLite** | -| Scraper | **patchright** (headless Playwright). The **pi-browser-harness** cannot do the daily scan: it gets a Cloudflare **403 managed challenge** on the login POST. | +| Scraper | **patchright** (headless Playwright). The **pi-browser-harness** cannot do the daily scan — Cloudflare 403 managed challenge on the login POST. | +| Data source | **Structured JSON, not HTML scraping**: `learning-tasks-all.json` (~70 tasks: name, start, description, category) plus the timetable string `time: period - SUBJECT - ROOM - TEACHER`. | | Design | Family Home Lab `tokens.css` | | Host | `.13`, Docker | | Container | **This project's own** image and compose file. | @@ -200,8 +236,20 @@ Per-child view with overdue, due today, due this week, and messages. *DoD:* Sam can see, per child, what is overdue and due, on a phone. **Phase 6 — Calendar write** -Write school events to the calendar. -*DoD:* a real school event appears in the calendar. +Write to a **dedicated HA calendar** (suggested `School`), per child: +- that day's **periods** +- **work due today** +- **overdue work** +- **major events** (excursions, exams) + +**Idempotent:** never re-insert something already present. Track what has been written +in `calendar_index`. + +*DoD:* a real day's periods and due work appear in the calendar, and running the scan +**twice adds nothing the second time**. + +NOTE: this calendar is **not spoken** by Jervis — it will only speak if Sam creates an +automation for it. Google Calendar is separate and already speaks. **Phase 7 — Notify and send** Apprise notifications, recipient selection, and the Send panel. @@ -237,6 +285,15 @@ Resolved: 8. **Apprise channels: Email and WhatsApp.** 9. **Scraper = patchright.** The daily scan uses patchright (headless Playwright). The pi-browser-harness cannot pass the Cloudflare managed challenge on the login POST. +11. **Teams dropped from v1.** Compass Learning Tasks already carries the due work + (`learning-tasks-all.json`, 70 structured tasks). Teams is deferred, not cancelled. +12. **Calendar rule.** A **dedicated HA calendar** gets: the day's periods, due work, + overdue work, and major events — per child, and **idempotently**. The timetable + is written to the calendar (not brief-only). +13. **Not spoken unless asked.** The HA calendar stays silent unless Sam adds an + automation. Google Calendar is separate and already speaks. +14. **Email is the report channel.** Each boy gets his own by email; Jo and Sam get + one combined brief. WhatsApp is optional. 10. **2FA:** the Compass parent login required no two-factor or one-time code during the Phase 2 proof.