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>
98 lines
4.4 KiB
Markdown
98 lines
4.4 KiB
Markdown
# 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
|
|
|
|
1. Sam changes a rule in the dashboard or the admin app.
|
|
2. The Control Service writes the change to SQLite and to the audit log.
|
|
3. The Control Service publishes the device config to MQTT, retained.
|
|
4. The device receives its own config topic and applies the rule.
|
|
5. The device reports status and telemetry on its own topics.
|
|
6. 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.md` section 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/`.
|