Initial spec: AGENTS.md build spec + archived original notes

This commit is contained in:
2026-10-11 17:24:04 +11:00
commit de0e6366d0
4 changed files with 297 additions and 0 deletions

214
AGENTS.md Normal file
View File

@@ -0,0 +1,214 @@
# Compass / NHS (school)
> Build spec for Paperclip. Follow the phases in section 11 in order. Do not skip a
> phase's Definition of Done. When something is unclear, ask Sam — do not guess.
---
## 1. Purpose and outcome
Two school systems, for Harry and Finn:
- **Compass** — the daily schedule and planner: what is on, what is overdue, notices.
- **Teams** — homework and assignments.
Store both, surface overdue and pending work, write important events to Sam's Home
Assistant calendar, and send the morning briefs.
**Outcome (the single success statement):**
> Sam sees, in one page, what each child has due and what is overdue — without
> logging into Compass — and the family is told before work is late.
## 2. Scope
**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.
- Store and display per child.
- Detect overdue and pending work.
- Write important events to Sam's Home Assistant calendar.
- Send the morning briefs via Apprise.
- Answer the Hub.
**Out of scope**
- The **React calendar** — that is a separate project. Do not build a calendar UI here.
- The school's own systems. Read-only.
## 3. Users and roles
| User | Can do |
|---|---|
| **Sam** | Everything. Session login. |
| **Jo / Harry / Finn** | Receive notifications. Read-only. |
## 4. Functional requirements
| ID | Requirement |
|---|---|
| FR-1 | Scan Compass with the **pi-browser-harness** on an n8n schedule, once per child. |
| FR-2 | Log in and reuse a stored session. A manual step is allowed when the school demands it. |
| FR-3 | Parse messages, homework, due dates, and calendar events into structured items. |
| FR-4 | Use JEV or the LLM to structure the page content and classify importance. |
| 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-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. |
## 5. Screens and UX flow
**Screens**
1. **Login** — session form.
2. **Child dashboard** — a tab per child: overdue, due today, due this week, messages.
3. **Item detail** — subject, teacher, due date, link, and full text.
4. **Send panel** — choose recipients, preview the brief, send.
5. **Scan history** — last scans, items found, errors.
**Main flow**
```
n8n triggers the morning scan → items stored
→ each boy gets his own morning brief (today, overdue, pending, notices)
→ Jo and Sam get one combined brief
→ important events are written to Sam's Home Assistant calendar
```
**Output style:** brief, concise, lists only. No fluff. Overdue first.
## 6. Look and feel
Reuse the Family Home Lab design system.
- Source: `/home/sam/Docker/Containers/family-home-lab/DESIGN.md`
- Tokens: `/home/sam/Docker/Containers/family-home-lab/portal/static/tokens.css`
- Copy `tokens.css` into this project.
Canvas `#f6f5f4`, one action blue `#0075de`, Inter, 8px grid, pill CTAs, hairline
borders. Dark mode. Works on a phone browser.
## 7. Data model
SQLite inside the service. Suggested tables:
| Table | Holds |
|---|---|
| `children` | id, name, year, compass id |
| `items` | child, type (`message`, `task`, `event`), subject, teacher, title, body, due-at, url |
| `scans` | started-at, child, pages fetched, items found, error |
| `notifications` | recipient, summary text, sent-at |
| `session` | harness session state per child |
Retention: keep items while the term is current. Scans are append-only and size-capped.
## 8. Integrations
| System | Use |
|---|---|
| **pi-browser-harness** | Log in and fetch Compass pages. Already built and working. |
| **JEV** | Structure page content; classify importance. HTTP API. |
| **OmniRoute** | All other models. |
| **n8n** | Triggers the daily scan. |
| **Apprise** | Per-boy morning briefs, and one combined brief to Jo and Sam. Running on `.35:8210`. |
| **Calendar** | **Sam's Home Assistant calendar.** The Hub or Jervis pushes into HA. |
| **Hub** | `POST /ask`, `POST /notify`, `GET /capabilities`. |
The Hub interface is frozen in `central_ai_llm_master/docs/ask-contract.md`.
`/ask` is read-only.
## 9. Technology (locked)
| Item | Value |
|---|---|
| Backend | **Go** |
| UI | **HTMX** + server-rendered HTML |
| Database | **SQLite** |
| Scraper | **pi-browser-harness** (Python fallback allowed if the harness cannot do it) |
| Design | Family Home Lab `tokens.css` |
| Host | `.13`, Docker |
| Container | **This project's own** image and compose file. |
| Port | Allocate one (suggest **8792**). Record it once chosen. |
| URL | `school.lab.audasmedia.com.au` via Caddy on `.35` |
| Auth | **Separate session login.** |
## 10. Rules and constraints
1. **Read-only against the school.** Never post, message, or submit anything.
2. **A failed scan must be loud.** Never show an empty day as "nothing due".
3. School credentials and session state are secrets. Never commit them.
4. Models go through **OmniRoute**, except JEV.
5. `/ask` is read-only.
6. Output is brief: lists, no fluff, overdue first.
7. Writing a calendar event needs **no** approval.
8. Own folder, own container, own port.
## 11. Build order
**Phase 1 — Skeleton**
Go service, SQLite, config, session login, Dockerfile, compose, Caddy route.
*DoD:* the app runs on `.13`, login works, `/health` returns ok.
**Phase 2 — Prove the login and the fetch**
Point the pi-browser-harness at Compass. Log in once. Fetch the pages needed for one
child. Store the raw pages.
*DoD:* a real Compass page for one child is fetched and stored. **This is the risk
phase — a failed login stops the project, so prove it early.**
**Phase 3 — Parse into items**
Turn pages into structured items: messages, tasks, events, due dates, links.
*DoD:* real homework and messages for one child appear as structured rows.
**Phase 4 — Both children**
Repeat for Harry and Finn, with per-child sessions.
*DoD:* both children's items are stored and separated.
**Phase 5 — Dashboard**
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.
**Phase 7 — Notify and send**
Apprise notifications, recipient selection, and the Send panel.
*DoD:* a brief is sent to a real recipient.
**Phase 8 — Hub**
`/capabilities`, `/ask`, `/notify`.
*DoD:* the Hub asks "what does Harry have on today at school?" and gets a correct answer.
**Phase 9 — Documentation**
*DoD:* project-docs run; Gitea, Obsidian, Outline, Vikunja, and the map are updated.
## 12. Acceptance criteria
- The scan runs daily and stores real items for both children.
- Overdue work is detected and shown first.
- A failed login shows an error, not an empty day.
- A school event can be written to the calendar.
- A brief can be sent to a real recipient from the app.
- The Hub answers a school question correctly.
- Runs in its own container on its own port, behind Caddy.
## 13. Decisions and remaining questions
Resolved:
1. **React calendar dropped.** Separate project.
2. **Login** is on-screen, via the **pi-browser-harness** or JEV.
3. **Go + HTMX + SQLite**, own container, `school.lab.audasmedia.com.au`, session login.
4. **Calendar = Home Assistant (Sam's).** Important events are written there.
5. **Recipients:** each boy gets his own morning brief; Jo and Sam get one combined brief.
6. **Focus:** Compass gives the daily schedule; Teams gives homework and assignments.
7. **Trigger time: 6:00 am.**
8. **Apprise channels: Email and WhatsApp.**
Remaining:
1. **Teams scope:** find the smallest section that answers "what is overdue". Teams
may be hard to reach. This is a decision for the brief and for Phase 2.
2. If Compass or Teams uses two-factor auth, what is the manual step?