diff --git a/README.md b/README.md index ff09905..c36f290 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,98 @@ # iOS Advanced Parental Controls -An experimental, self-hostable family policy and learning-reward system, with native iPhone Screen Time enforcement. +**v0.1: shared family policies, maths rewards, and native iPhone enforcement scaffolding.** -Initial scope: one family, shared policies with child overrides, one paired iPhone per child, and server-verified maths challenges that earn bounded daily usage credit. +The parent interface is a standards-based web dashboard, usable from a Mac or phone. Each child's iPhone runs **Family Quests**, a SwiftUI companion using FamilyControls, ManagedSettings, and a DeviceActivity monitor extension. A self-hosted Python API owns policy inheritance, pairing, grading, and the reward ledger. -This is development scaffolding, not a production child-safety product. Apple signing, Family Controls entitlements, and physical-device acceptance tests are required. Build pipelines and distribution are intentionally left to the repository owner. +**This is a development MVP, not a production child-safety product.** The backend and pure Swift quota logic have been exercised here. The iOS app has not been built with an Apple SDK or tested on a physical iPhone. Signing, CI, provisioning, and distribution are deliberately left to the repository owner. + +## Included + +- One household, multiple child profiles, one active iPhone per child. Shared rules with sparse per-child overrides and revision conflict detection. +- Daily entertainment allowance, configurable allowed hours, and capped daily bonuses. Example: five correct arithmetic answers earn ten usage minutes. +- Server-generated addition/subtraction challenges, server-side grading, expiring attempts, and transactional, idempotent reward issuance. +- Single-use pairing/configuration codes, scoped device tokens, parent cookie sessions, revocation, Keychain storage, and explicit device acknowledgements. +- Native app selection and shielding, usage-threshold monitoring, custom shield UI, and a Close action. Cached rules and expired-bonus handling do not require the backend to run continuously. +- Docker/Compose, pinned Python dependencies, XcodeGen specification, tests, and a physical-device acceptance checklist. No build pipeline or signing secrets. + +## Start the backend and parent dashboard + +Python 3.12+ is required for local development (tested with 3.13). Docker uses Python 3.13. + +```sh +git clone git@github.com:felixfoertsch/ios-advanced-parental-controls.git +cd ios-advanced-parental-controls +cp .env.example .env +python3 -c 'import secrets; print(secrets.token_urlsafe(32))' +# Put the generated value into APC_ADMIN_TOKEN in .env. +# Set APC_ORIGIN to the exact browser origin, e.g. https://family.example.net. +docker compose up --build +``` + +The default loopback dashboard is `http://localhost:8000`. Sign in using `APC_ADMIN_TOKEN`. Add child profiles; there are **no seeded real children, credentials, or family records**. + +For a non-Docker development process: + +```sh +make bootstrap +set -a; . ./.env; set +a +make serve +``` + +`make serve` binds only to loopback. For physical phones, put the service behind your HTTPS reverse proxy, use a certificate trusted by the phone, and set `APC_ORIGIN` to that HTTPS origin. Compose also binds to host loopback; attach your proxy appropriately. There is no automatic TLS/proxy configuration. The native Release app refuses plain HTTP; Debug permits HTTP only on loopback, not arbitrary LAN addresses. + +## Generate and build the iPhone project + +On the Mac build server, install XcodeGen (2.42+) and use an Xcode version suitable for the device OS. The deployment target is iOS 18.0; no unverified iOS 27-specific API is assumed. + +```sh +cp ios/Config/Local.xcconfig.example ios/Config/Local.xcconfig +# Set your development team, bundle prefix, and App Group in Local.xcconfig. +make ios-project +xcodebuild -project ios/AdvancedParentalControls.xcodeproj \ + -scheme FamilyQuests -configuration Debug \ + -destination 'generic/platform=iOS' build +``` + +The generated project contains the app, DeviceActivity monitor, Shield Configuration, and Shield Action targets. It is intentionally not checked into git; `ios/project.yml` is the source of truth. Configure **Family Controls and the same App Group on all four App IDs/profiles**. Read [Apple setup](docs/APPLE_SETUP.md) before attempting an install or archive. Icons, distribution privacy declarations, entitlement approval, and signing are still owner tasks. + +In the web dashboard, create a pairing code. On the child's phone, enter the HTTPS server origin and code, obtain guardian approval, and select **individual entertainment apps**. Leave Family Quests, Phone, messaging needed for safety, and school apps accessible. Whole categories and websites are intentionally rejected in v0. Later selection changes need a new configuration code from the parent dashboard. + +## Tests + +```sh +make bootstrap +make test # Python API tests + Swift package tests + JS syntax +# Optional real Chromium DOM / real ASGI-backend smoke test, without a network deployment: +.venv/bin/pip install playwright==1.57.0 +.venv/bin/playwright install chromium +.venv/bin/python scripts/browser_smoke.py +``` + +For an existing Chromium installation, set `CHROMIUM_PATH=/path/to/chromium` for the smoke script. `APC_SCREENSHOT=/path/to/screenshot.png` optionally captures its synthetic family dashboard. This script bridges browser fetches to TestClient; it is not a deployed HTTP/TLS or real-device test. + +Initial verification: **21 Python tests, 10 Swift tests, browser/ASGI smoke, JavaScript syntax, Swift syntax, and plist/YAML checks passed.** The networking Swift source was also type-checked with Linux Foundation. **Xcode generation/build, Docker image execution, and physical Screen Time behavior were not validated in this environment.** See [acceptance checklist](docs/ACCEPTANCE.md). + +## Important v0 boundaries + +Rules sync when the child app opens, returns to the foreground, or the child taps Sync. There is no APNs/background remote sync yet. The parent sees the last reported revision and status, not a promise of immediate enforcement. A stricter native Apple restriction can still block an app after this app grants credit. + +Time credits are **usage allowance**, not a wall-clock unlock period. The native monitor registers a ladder of cumulative thresholds, including the daily cap. Earning a normal reward does not restart monitoring. Exact remaining usage is not exposed as a fake live countdown. DeviceActivity callback reliability and cumulative counting after a policy/selection change require physical testing. + +One same-day allowed window applies every day. There are no separate weekend rules, multi-device pooled budgets, manual chores, learning-app integrations, Android agent, cloud accounts, telemetry dashboards, or native Screen Time-settings import. The family timezone becomes immutable after the first reward in v0 to prevent accidental double-day issuance; proper timezone migration is deferred. + +## Repository map + +```text +backend/src/apc/ API, SQLite persistence, validation, parent web dashboard +backend/tests/ API, authorization, concurrency, cap and timezone tests +packages/PolicyCore/ Platform-independent Swift policy/quota logic and tests +ios/App/ SwiftUI companion, API client, Keychain credentials +ios/Shared/ App Group state and Apple enforcement adapter +ios/Monitor/ DeviceActivity callbacks +ios/Shield*/ Shield presentation and Close action +ios/project.yml Reproducible XcodeGen project specification +docs/ Architecture, Apple setup, acceptance and security notes +``` + +The API schema is served at `/openapi.json`; its v0 return envelopes are described in [architecture](docs/ARCHITECTURE.md). Read [security and operations](docs/SECURITY.md) before putting real family data into the service.