Phase 10: publish the documentation set + tick AGENTS.md 9 of 10

Phase 10 (the last phase of this project) is the project-docs pass. Update the
Gitea README, add the Mermaid source and rendered PNG, build the interactive
Archify map, add the Vikunja board tasks, and write the Outline AI-context
collection in Simplified Technical English.

Deliverables:
- README.md: status header, Phase 4 gap statement, "Architecture" section with
  embedded Mermaid + image + Archify link, "Documentation set" table, an
  explicit two-plane MQTT section (1883 plain+anonymous, 8883 TLS+ACLs), and
  the Android client's Usage Access and VpnService paths.
- AGENTS.md section 11: tick Phase 10, leave Phase 4 unticked, status line now
  "9 of 10 done - only Phase 4 outstanding".
- docs/architecture.mmd + docs/diagrams/architecture.png (mmdc).
- docs/archify/architecture.architecture.json + docs/architecture-map.html
  (Archify, showcase, 9/9 checks, 0 errors).
- docs/outline/00-index.md .. 04-agent-runbook.md (STE).
- docs/vikunja-tasks.json (Vikunja project "Internet Use Control", id 20).
- Obsidian note written to 010 inbox on .27; the obsidian-sorter proposed a
  folder and waits for the vault owner's approval.

Phase 4 (Python Windows computer client) is deliberately deferred and is NOT
built. Every document says so.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-10-14 12:13:21 +11:00
parent 5a9e56bb1f
commit eb300b6701
12 changed files with 14593 additions and 11 deletions

101
README.md
View File

@@ -5,8 +5,13 @@ Internet Use Control project (`SYSTEM_MAP.md`). It holds schedules, blocklists,
per-device state and usage, and serves the web dashboard. Only it publishes
device config.
This repository currently contains **Phase 9 — Hub and alerts** (AGENTS.md §11),
on top of Phases 1–8:
**Project status: 9 of 10 phases done.** Phases 1–3 and 5–10 are complete (Phase 10,
this documentation set, included). **Phase 4 — the Windows computer client — is
deliberately deferred and is NOT built.** There is no Python computer client and
no Windows process blocking in this repository. The only enforcement client is
the kids' Android app in `android/`. See `AGENTS.md` §11.
This repository contains **Phases 1–3 and 5–10** (AGENTS.md §11):
- Go service with its own image (`Dockerfile`) and compose file.
- SQLite schema for the whole data model (§7), applied through versioned
@@ -53,8 +58,54 @@ on top of Phases 1–8:
applied) or has been offline too long. Every alert is recorded in `alerts`
and the audit log, with its delivery outcome.
Enforcement itself (the kids' clients) arrives in later phases. Nothing here
touches the router, Pi-hole, or DNS.
Nothing here touches the router, Pi-hole, or DNS. Enforcement is device-side and
kids-only.
## Architecture
![Internet Use Control architecture](docs/diagrams/architecture.png)
```mermaid
flowchart LR
SAM["Sam<br/>browser dashboard"]
ADMIN["Admin app<br/>kotlin_phone_app_admin"]
HUB["Hub :8788<br/>read-only /ask"]
CADDY["Caddy on .35<br/>webrestrict.lab.audasmedia.com.au"]
CS["Control Service<br/>Go + SQLite :8791"]
APPRISE["Apprise :8210<br/>alerts + tamper reports"]
subgraph MQ["Mosquitto on .13 - two planes"]
TLS["8883 TLS<br/>per-device creds + topic ACLs"]
PLAIN["1883 plain + anonymous"]
end
PHONE["Kids' Android client<br/>Kotlin, Accessibility + overlay"]
SAM -->|HTTPS| CADDY
CADDY --> CS
ADMIN -->|"Bearer token /api/v1"| CS
HUB -->|"Bearer token /ask"| CS
CS -->|"retained config"| TLS
TLS -->|"own config topic"| PHONE
PHONE -->|"status + telemetry"| TLS
TLS -->|reports| CS
CS --> APPRISE
```
**Interactive map:** <https://maps.lab.audasmedia.com.au/internet_use_control/docs/>
(Archify, 9/9 showcase checks). The Mermaid source is `docs/architecture.mmd`,
the rendered image is `docs/diagrams/architecture.png`, and the Archify
specification is `docs/archify/architecture.architecture.json`.
## Documentation set
| Layer | Artefact | Audience |
|---|---|---|
| Gitea | this `README.md` | developers |
| Obsidian | portfolio note in `010 inbox/` on `.27`, filed by the sorter | humans |
| Mermaid + Archify | `docs/architecture.mmd`, `docs/diagrams/architecture.png`, `docs/architecture-map.html` | architects |
| Vikunja | project **Internet Use Control** (id 20), copy in `docs/vikunja-tasks.json` | humans |
| Outline | `docs/outline/00-index.md` … `04-agent-runbook.md` (Simplified Technical English) | AI agents |
## Quick start (on `.13`)
@@ -133,7 +184,24 @@ with per-device credentials and a topic ACL
## MQTT (Phase 3)
Broker: the shared **Mosquitto on `.13`**. A second broker is not added
(§10 rule 6).
(§10 rule 6). **The broker has two planes. They are separate listeners on the
same container, and only one of them is trusted.**
| Plane | Port | Security | Who uses it |
|---|---|---|---|
| **Plain** | **1883** | Plain text, **anonymous** | Legacy and other house consumers. Unchanged, and not used by this project. |
| **TLS** | **8883** | **TLS**, per-device credentials, topic ACLs | The Control Service and every kid device. |
On the 8883 plane a device may read **only** its own
`restrict/<device>/config` topic, and write **only** its own
`restrict/<device>/status` and `restrict/<device>/telemetry` topics. The Control
Service is the only identity that may publish config. Without that ACL a child
could publish a fake "unlocked". The listener, the password file and the ACL are
in `deploy/mosquitto/conf.d/webrestrict.conf` and `webrestrict.acl`;
`deploy/mosquitto/README.md` holds the design, the live apply and the rollback.
Caveat to carry forward: `per_listener_settings true` is deprecated in Mosquitto
2.1 and is removed in 3.0. Pin the broker image tag before an upgrade.
| Topic | Direction | Retained | Payload |
|---|---|---|---|
@@ -480,6 +548,14 @@ while the device is locked (FR-16). There is **no Device Owner**, no factory
reset and no managed profile; the child can disable it, and the enforcement is
the tamper alert (FR-17).
- **Telemetry** comes from **Usage Access** (`UsageCollector.kt`), reported per
app and per day over the device's own telemetry topic.
- **Site filtering** uses a device-local **`VpnService`** (`SiteFilterVpnService.kt`,
`SiteFilter.kt`, `DnsMessage.kt`, `IpPacket.kt`). No router, no Pi-hole, no
change to the house DNS (FR-18).
- **The block decision** is in `BlockEngine.kt`, from the config payload in
`DeviceConfig.kt`.
A tamper report rides the device's own status topic, because that is the only
topic its broker ACL may write:
@@ -533,6 +609,12 @@ deploy/caddy/ Caddy vhost for webrestrict.lab.audasmedia.com.au
deploy/mosquitto/ TLS listener, credentials, topic ACL, verifier
deploy/verify-phase8.sh lock latency proof
deploy/verify-phase9.sh Hub + alerts proof
docs/architecture.mmd Mermaid source for the diagram in this README
docs/diagrams/ rendered Mermaid PNG
docs/archify/ Archify specification for the interactive map
docs/architecture-map.html interactive Archify map (published to the maps site)
docs/outline/ AI-context collection (Simplified Technical English)
docs/vikunja-tasks.json copy of the Vikunja board tasks
```
## Caddy
@@ -541,13 +623,16 @@ deploy/verify-phase9.sh Hub + alerts proof
`webrestrict.lab.audasmedia.com.au`. The terminating Caddy runs on `.35`
(sam-Ubuntu1); see that file for the two proxy patterns and the apply commands.
## Non-goals (Phase 9)
## Non-goals (Phase 10)
- **Phase 4, the Windows computer client, is not built.** It is deliberate. The
Python client, process blocking, and the Windows overlay warning do not exist.
The project stands at **9 of 10** because of this single gap.
- No grant button in the dashboard. Grant is on the admin API; the dashboard has
lock and unlock. Adding the button is a later UI change.
- No per-child or per-device keycode. One code, every device (§10 rule 3).
- No HTTP telemetry ingest and no kids' clients (Phases 4–5). The topic and
payload contract above is what they implement.
- No HTTP telemetry ingest. Telemetry arrives over MQTT only. The kids' phone
client exists (Phase 5). The kids' computer client does not (Phase 4, deferred).
- No Alerts screen in the dashboard yet. The alert history is in `alerts` and is
readable with `control alerts`; the screen is a later UI change.
- The Hub is wired to this service: the running Hub on `.13:8788` routes