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>
4.4 KiB
Internet Use Control — System Overview
Target: AI agents. Writing style: ASD-STE100 Simplified Technical English.
Purpose
The project limits the screen use of two children, Harry and Finn. It applies per-device weekly schedules, blocklists and allowlists. It collects usage. It lets Sam override a rule in seconds. The work applies to the children's devices only. No router change, no Pi-hole and no house-wide rule.
Components
| Component | What it is | Where it runs | Language |
|---|---|---|---|
| Control Service | The brain and the source of truth. Schedules, blocklists, state and usage. | .13, Docker, port 8791 |
Go + SQLite |
| Web dashboard | The admin screen in a browser. HTMX, server-rendered. | Served by the Control Service | HTMX |
| Broker | The message bus. Pushes state to devices and collects their reports. | .13, Mosquitto |
— |
| Kids' phone client | Enforces the rules on a phone and shows the blocked state. | The children's phones | Kotlin |
| Admin app | The remote override surface. A separate project. | Sam's phone | Kotlin |
| Hub | A peer. It asks questions only. It never controls. | .13, port 8788 |
separate project |
Data Flow
- Sam changes a rule in the dashboard or the admin app.
- The Control Service writes the change to SQLite and to the audit log.
- The Control Service publishes the device config to MQTT, retained.
- The device receives its own config topic and applies the rule.
- The device reports status and telemetry on its own topics.
- The Control Service writes the report to SQLite.
The Control Service is the only writer of config. Everything else writes to the Control Service over HTTP.
MQTT Has Two Planes
The shared Mosquitto on .13 has two listeners. State them correctly.
| Plane | Port | Security | Use |
|---|---|---|---|
| Plain | 1883 |
Plain text, anonymous | Legacy and other consumers. Unchanged. |
| TLS | 8883 |
TLS, per-device credentials, topic ACLs | The Control Service and every kid device. |
On the TLS plane a device reads only its own restrict/<device>/config topic. It
writes only its own restrict/<device>/status and
restrict/<device>/telemetry topics. The Control Service is the only identity
that may publish config. deploy/mosquitto/ holds the ACL, the accounts and the
verifier.
One caveat: per_listener_settings true is deprecated in Mosquitto 2.1 and is
removed in 3.0. Pin the broker image tag, or rework the two planes.
Enforcement Model (the phone client)
The phone client blocks by interruption. It does not suspend an app.
- An Accessibility Service detects the foreground app.
- A full-screen overlay covers a blocked app.
- Usage Access supplies telemetry.
- A device-local VpnService filters sites.
The client is not a Device Owner. There is no factory reset and no managed profile. A child can disable the client. That is accepted. The enforcement is the tamper alert: when the Accessibility Service stops, the app is force-stopped, or the overlay permission is revoked, the client reports the event and Sam gets an alert (FR-17).
Fail Safe
The device keeps its last config when it cannot reach the broker (FR-14). An outage changes nothing. The device caches its config on disk. One shared admin keycode overrides the state.
What Is Missing (state this plainly)
Phase 4, the Windows computer client, is deliberately deferred and NOT built.
No Python computer client exists in this repository. No Windows process blocking
is implemented or tested. The docs and the README name this gap on purpose.
Do not describe the computer client as complete.
Interfaces
| Interface | Shape | Consumer |
|---|---|---|
| Admin API | GET /api/v1/admin/devices, and lock, unlock, grant and override under the same prefix. Bearer token. |
The separate project kotlin_phone_app_admin. |
| Hub API | GET /capabilities, read-only POST /ask, POST /notify. Bearer token. |
The Hub. Control never goes through the Hub. |
| Dashboard | Session login with a signed cookie and CSRF tokens. | Sam in a browser. |
The admin API shape is small on purpose. Another project consumes it. Keep it stable and versioned.
Related
- Build spec and phase checklist:
AGENTS.mdsection 11. - Component names:
SYSTEM_MAP.md. - MQTT design and payloads:
TRANSPORT_DESIGN.md. - Interactive map:
https://maps.lab.audasmedia.com.au/internet_use_control/docs/.