diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json
index 4217c33..3563f0e 100644
--- a/.obsidian/workspace.json
+++ b/.obsidian/workspace.json
@@ -210,8 +210,9 @@
"templater-obsidian:Templater": false
}
},
- "active": "7066c9273c6fb936",
+ "active": "26813e16e829b798",
"lastOpenFiles": [
+ "010 inbox/Internet Use Control — Kids' Screen Time Limits.md",
"010 inbox/Email Agent — Family Inbox Triage.md",
"100 inbox/Local LLM Infrastructure & Qwen2.5 Deployment.md",
"010 inbox/Email & DNS Setup — Domains, Mailboxes & Records.md",
@@ -239,7 +240,6 @@
"010 inbox/Alibaba Code Review AI Tool.md",
"300 areas/395 AI Tools to try/Alibaba Code Review AI Tool.md",
"Clippings/alibabaopen-code-review Secure, fast, efficient, battle-tested at Alibaba's scale. Hybrid architecture code review tool deterministic pipelines + LLM Agent, precise line-level comments, built-in multi-language ruleset (NPE, thread-safety, XSS, S.md",
- "300 areas/395 AI Tools to try/Tools to try with AI.md",
"010 inbox/_WATCHER",
"300 areas/355 AI Research and Techniques",
"300 areas/355 Ai Research and Techniques",
diff --git a/010 inbox/Internet Use Control — Kids' Screen Time Limits.md b/010 inbox/Internet Use Control — Kids' Screen Time Limits.md
new file mode 100644
index 0000000..a62c069
--- /dev/null
+++ b/010 inbox/Internet Use Control — Kids' Screen Time Limits.md
@@ -0,0 +1,151 @@
+---
+type: note
+proposed_folder: 200 projects/Tools Software WebUI
+proposed_toc: "100 Table of Contents/Projects.md → Tools & Software"
+proposed_tags:
+ - project
+ - family
+ - architecture
+ - go
+ - kids
+ - time
+ - internet-control
+ - mqtt
+ - android
+ - sqlite
+ - htmx
+confidence: 0.8
+approved: false
+proposed_for: ca730e053cc5
+created: "2026-10-14 12:12"
+tags:
+ - project
+ - family
+ - internet-control
+ - go
+ - mqtt
+ - android
+ - sqlite
+ - htmx
+aliases:
+ - Internet Use Control
+ - Kids Screen Time
+skills:
+ - Go backend development
+ - HTMX server-rendered dashboard UI
+ - SQLite data modelling and versioned migrations
+ - MQTT transport with TLS and per-device topic ACLs
+ - Android Accessibility Service and full-screen overlay (Kotlin)
+ - Android VpnService for device-local site filtering
+ - Versioned HTTP API design for a separate consumer
+ - Docker and Caddy deployment
+tools:
+ - Go
+ - SQLite
+ - HTMX
+ - Mosquitto
+ - Docker
+ - Caddy
+ - Apprise
+ - Kotlin
+ - Android Accessibility Service
+ - Android VpnService
+---
+
+# [[Internet Use Control — Kids' Screen Time Limits]]
+
+## What is this project?
+
+This project limits screen time on the children's own devices. Harry's phone and
+Finn's computer should follow their weekly schedule with nobody touching them. Sam
+sees their usage on one page, and Sam changes a limit from his phone in seconds.
+
+The rules apply to the kids' devices only. Nothing changes for the rest of the
+house. There is no router change, no Pi-hole and no DNS change.
+
+The main piece is the **Control Service**. It runs on `.13` in Docker. It holds the
+schedules, the block lists, the allow lists and the usage in SQLite. It serves a
+small web dashboard. It is the one place that writes the rules.
+
+A device gets its rules over **MQTT**. The Control Service publishes the wanted
+state for each device as a *retained* message, so a phone that reconnects is
+limited again at once. The device also sends its status and its usage back over
+MQTT. If a device cannot reach the broker, it keeps its last rules.
+
+## What it does
+
+- **Weekly schedules.** A grid per device, Monday to Sunday. A window means the
+ rules are on. A window can cross midnight.
+- **Block lists.** An app (Android package name) or a site (hostname).
+- **Allow lists.** Spotify at night, school sites. The device blocks everything
+ on the block list **except** the allow list.
+- **Usage.** The dashboard shows a week per device: the daily total, the top apps
+ and the top sites.
+- **Overrides.** A versioned HTTP API for the admin app (`lock`, `unlock`,
+ `grant`), plus one shared keycode that a child can type on the device for a
+ short exemption.
+- **Alerts.** Apprise tells Sam when a limit is reached or a device is offline
+ too long.
+- **A Hub answer.** The family Hub can ask "how long have the kids been on
+ screens today?" and gets a real answer. That question path is read-only.
+
+## Why it matters (what it shows)
+
+This is a full home-lab product, not a script. It shows a Go service with no
+heavy framework, an HTMX dashboard with no build step, a small SQLite store with
+versioned migrations, real MQTT with TLS, per-device accounts and topic access
+control, and a versioned API that another project consumes.
+
+The Android side is the interesting part. **Device Owner was rejected**, because
+it needs a factory reset of the children's phones. Instead the phone blocks by
+**interruption**: an Accessibility Service watches the foreground app, and a
+full-screen overlay covers a blocked app. The child **can** disable it, and that
+is accepted. The real enforcement is the **tamper alert**: when the Accessibility
+Service stops, the app is force-stopped, or the overlay permission is removed,
+the phone reports it and Sam gets an alert. Site filtering uses a device-local
+`VpnService`. There is no wipe, no Device Owner and no managed profile.
+
+## Architecture
+
+```mermaid
+flowchart LR
+ SAM["Sam
browser dashboard"] --> CADDY["Caddy on .35"]
+ CADDY --> CS["Control Service
Go + SQLite :8791"]
+ ADMIN["Admin app"] -->|"/api/v1"| CS
+ HUB["Hub"] -->|"read-only /ask"| CS
+ CS -->|"retained config"| MQ["Mosquitto on .13
8883 TLS + topic ACLs"]
+ MQ -->|"own config topic"| PHONE["Kids' Android client
Kotlin"]
+ PHONE -->|"status + telemetry"| MQ
+ MQ -->|reports| CS
+ CS --> APPRISE["Apprise
alerts + tamper"]
+```
+
+A picture of the two MQTT planes: port **1883** stays plain and anonymous for
+legacy consumers, and port **8883** is TLS with per-device credentials and topic
+ACLs. A device on 8883 may read only its own config topic and write only its own
+status and telemetry topics. Without that rule a child could publish a fake
+"unlocked".
+
+## What is still missing (state it plainly)
+
+**The Phase 4 Windows computer client is deliberately deferred and is not
+built.** There is no Python client and no process blocking on a computer. The
+project stands at **9 of 10** phases for that single reason. Everything else in
+the build spec is done and running.
+
+## Where it lives
+
+- **Code**: Gitea repo `sam/internet_use_control`.
+- **Live**: (container on `.13`, port
+ 8791, behind Caddy on `.35`).
+- **Interactive map**:
+- **AI context**: `docs/outline/` in the repo (00-index and four documents).
+- **Tasks**: Vikunja project **Internet Use Control** (id 20).
+- **Diagram source**: `docs/architecture.mmd`, rendered to
+ `docs/diagrams/architecture.png`.
+
+## Status
+
+Built and deployed. Phases 1, 2, 3, 5, 6, 7, 8, 9 and 10 are done. The phones
+are limited by the Android client. Only the Windows client (Phase 4) remains, and
+it is deferred on purpose.
diff --git a/010 inbox/_sort log.md b/010 inbox/_sort log.md
index 6fa5eb9..7414eeb 100644
--- a/010 inbox/_sort log.md
+++ b/010 inbox/_sort log.md
@@ -20062,3 +20062,6 @@ What the watcher did, newest last.
### 2026-10-13 10:44:03
- **proposed** `Email Agent — Family Inbox Triage.md` → `200 projects/Tools Software WebUI` (confidence 0.82)
+
+### 2026-10-14 12:12:45
+- **proposed** `Internet Use Control — Kids' Screen Time Limits.md` → `200 projects/Tools Software WebUI` (confidence 0.80)