Spec: precise calendar rule (daily periods + due + overdue + events, written once seen every pass); brief order; codes NOT decoded yet

This commit is contained in:
2026-10-16 09:30:16 +11:00
parent 9a89f61d13
commit 315a82000b

View File

@@ -83,8 +83,8 @@ 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 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-8 | Write to a **dedicated Home Assistant calendar** (suggested `School`), per child, on **EVERY pass**: (a) **that day's periods**, (b) **work due** — any future date, (c) **work overdue**, (d) **major events** (concerts, excursions, exams). Every item carries a **date from Compass**, so the same item is seen on many passes — a piece of work due in two weeks, or a concert, appears on **every** pass until it passes. **It must never be re-inserted.** Identity is a **stable per-item key**, not the date. |
| FR-9 | Send a **morning brief to each boy** (Harry, Finn) **by email**, in this order: (a) **today's periods**; (b) **today's major events**; (c) **work overdue**; (d) **work due in the future**. 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. |
@@ -166,8 +166,12 @@ Real examples from the Phase 2 capture:
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.
**Decoding is OPTIONAL and NOT yet instructed.** The raw codes are what Compass
supplies, and rendering them as-is (`11XMUSA6 · A1 · JBR`) is acceptable.
If Sam later asks for readable names, store them as an **editable `codes` map** —
never hardcode, because initials and room codes change between years. An unknown code
must render as the **raw code**, never blank.
## 8. Integrations
@@ -236,17 +240,21 @@ 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 to a **dedicated HA calendar** (suggested `School`), per child:
Write to a **dedicated HA calendar** (suggested `School`), per child, on **every pass**:
- that day's **periods**
- **work due today**
- **overdue work**
- **major events** (excursions, exams)
- **work due** — any future date
- **work overdue**
- **major events** (concerts, excursions, exams)
**Idempotent:** never re-insert something already present. Track what has been written
in `calendar_index`.
**The critical property: written once, seen every pass.**
*DoD:* a real day's periods and due work appear in the calendar, and running the scan
**twice adds nothing the second time**.
Work due and major events carry dates from Compass, so the *same* item shows up on
every scan — a task due in two weeks, a concert next month. Each pass must **check**
it and **not re-insert** it. Identity is a **stable per-item key** (Compass item id),
**not** the date or the title.
*DoD:* a real day's periods, due work, overdue work and a major event all appear; and
running the scan on **three consecutive days** adds **nothing** after the first.
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.
@@ -287,9 +295,15 @@ Resolved:
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).
12. **Calendar rule.** A **dedicated HA calendar**, written per child on EVERY pass:
that day's **periods**, **work due** (any future date), **work overdue**, and
**major events**. All of these carry Compass dates, so the same item is seen on
every pass. **Written once, seen every pass** — identity is a stable per-item
key, never the date or title.
15. **Brief order (FR-9):** today's periods → today's major events → work overdue →
future due. Lists only.
16. **Codes are NOT decoded (yet).** Raw Compass codes (`11XMUSA6 · A1 · JBR`) are
acceptable. Decoding was raised as a question, not an instruction — see §7.
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