# 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/`.
