Files
internet_use_control/docs/outline/01-system-overview.md
Sam Rolfe eb300b6701 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>
2026-10-14 12:13:21 +11:00

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

  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.

  • 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/.