Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/controller-sovereignty/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Controller Sovereignty Toolkit

This directory defines the SourceOS controller-sovereignty lane for `sourceos-syncd`.

The motivating observation is that modern machines are governed by autonomous controllers rather than by a simple process list. A controller is any actor that can consume material resources or mutate user/system state without a direct foreground user command.

Examples include metadata indexing, media analysis, cloud sync, filesystem maintenance, network policy, wireless telemetry, software update, and third-party application updaters.

The SourceOS standard is:

> No hidden autonomous controller may consume material resources without registration, budget, logging, and revocation.

## Contents

- `case-file-template.md` — sanitized evidence template for controller incidents.
- `controller-registry.schema.yaml` — draft controller registry schema.
- `sovereignty-dashboard.md` — first dashboard/product model.

## Non-goals

This lane does not store raw private diagnostic logs, device identifiers, account identifiers, serial numbers, local IPs, Wi-Fi identifiers, packet payloads, or personal file paths. Evidence should be summarized and redacted before it becomes a repository artifact.

## Relationship to sourceos-syncd

`sourceos-syncd` is the state integrity daemon. Controller sovereignty extends that mission from replicated state to operating-system behavior: state changes must be observable, attributable, budgeted, repairable, and explainable before automation is allowed to act.
78 changes: 78 additions & 0 deletions docs/controller-sovereignty/case-file-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Controller Case File Template

Use this template for redacted controller-sovereignty evidence. Repository artifacts should contain summaries, not private device records.

## Summary

- Case ID: `<case-id>`
- Date range: `<start> to <end>`
- Machine class: `<redacted>`
- OS family/build: `<OS family and build>`
- Primary finding: `<one sentence>`

## Controller

- Controller name: `<Spotlight / Photos / APFS / CoreWiFi / Network Extension / updater / other>`
- Owner: `<first-party | third-party | user | unknown>`
- Representative services:
- `<service name>`
- Resource coalition: `<if known>`

## Trigger model

- Foreground user action observed: `<yes | no | unknown>`
- Background scheduler observed: `<yes | no | unknown>`
- Network trigger observed: `<yes | no | unknown>`
- Filesystem trigger observed: `<yes | no | unknown>`
- Cloud/sync trigger observed: `<yes | no | unknown>`

## Observed behavior

Describe what the controller did in plain language.

Example:

> Metadata controller compacted index payloads and dirtied several GB of file-backed memory while running non-frontmost background work.

## Resource impact

- CPU: `<duration / average / peak if available>`
- Disk writes: `<MB/GB and duration if available>`
- Memory: `<RSS/footprint if available>`
- Network: `<interfaces, tunnels, or traffic-class evidence if available>`
- Power state: `<AC / battery / idle / active>`
- Platform action: `<none / managed / unknown>`

## Evidence summary

| Evidence | Sanitized value |
|---|---|
| Event type | `<disk writes / cpu usage / telemetry loop / network policy / other>` |
| Command | `<process name>` |
| Time window | `<redacted or normalized>` |
| Stack family | `<Spotlight compaction / Photos database rewrite / APFS traversal / Wi-Fi telemetry>` |
| User activity | `<active / idle / unknown>` |
| Power source | `<AC / battery / unknown>` |

## User-control gap

- Was the behavior visible in the UI?
- Could the user defer it?
- Could the user budget it?
- Could the user audit what file class, interface, or service was touched?
- Could the user revise the capability safely?

## Classification

- Evidence confidence: `<low / medium / high>`
- Resource impact: `<low / medium / high>`
- User-control gap: `<low / medium / high>`
- Recommended design response: `<observe / budget / governed profile / redesign>`

## SourceOS design requirement

Translate the case into a requirement.

Example:

> A metadata indexer that exceeds a configured write budget must emit a ControllerBudgetExceeded event with file-class attribution and user-visible policy state.
106 changes: 106 additions & 0 deletions docs/controller-sovereignty/controller-registry.schema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
version: 0.1
controller:
id: com.sourceos.example
name: Example Controller
owner:
organization: SourceOS
trust_domain: first_party

binaries:
- path: <controller-binary-path>
signing_id: <signing-id>
team_id: <team-id>

launchd_services:
system: []
user: []

trigger_model:
startup: false
login: false
scheduled_activity: false
push_event: false
network_event: false
filesystem_event: false
foreground_user_action: false
schedule_policy: maintenance_window_only

capabilities:
network:
physical_wifi: false
peer_to_peer_wifi: false
low_power_network_presence: false
tunnels: false
dns: false
proxy: false
outbound_sockets: false
inbound_sockets: false
bssid_queries: false
location_inference: false
storage:
read_user_files: false
write_user_files: false
mutate_database: false
index_files: false
filesystem_traversal: false
cache_management: false
cloud:
sync: false
push_receive: false
push_send: false
private_cloud_compute: false
cross_device_pairing: false
compute:
cpu_allowed: true
gpu_allowed: false
neural_engine_allowed: false
background_threads: true
power:
allowed_while_idle: false
allowed_on_battery: false
allowed_during_sleep: false
may_wake_device: false

budgets:
cpu:
max_percent: 10
max_duration_seconds: 300
action_on_exceed: pause_and_notify
memory:
max_rss_mb: 512
action_on_exceed: notify
disk_writes:
max_mb_per_hour: 100
max_mb_per_day: 500
action_on_exceed: pause_and_notify
network:
max_mb_per_hour: 100
allowed_destinations: []
action_on_exceed: pause_and_notify

allowed_states:
foreground: true
background: false
idle: false
locked: false
sleep: false

observability:
audit_log: <controller-audit-log-path>
metrics:
- cpu
- memory
- disk_writes
- network_bytes
- files_touched
- sockets_opened
- wake_events
user_visible: true
dashboard_group: Example

controls:
pause: true
resume: true
disable: true
require_user_approval_for_budget_excess: true
require_user_approval_for_new_capability: true
100 changes: 100 additions & 0 deletions docs/controller-sovereignty/sovereignty-dashboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Sovereignty Dashboard Model

The dashboard presents a machine by controller class rather than by raw process. It should answer four questions:

1. Who is acting?
2. What authority do they have?
3. What resource budget did they consume?
4. What can the user inspect, defer, budget, or revise?

## Controller cards

### Network

Shows:

- physical interfaces
- peer wireless interfaces
- tunnel interfaces
- proxy state
- Network Extension state
- per-process socket summary
- observed traffic classes
- low-power network presence

### Spotlight / Metadata

Shows:

- indexed volumes
- active metadata workers
- recent write and CPU events
- high-churn paths
- excluded paths
- budget status

### Photos / Media

Shows:

- media library services
- photo/media analysis services
- cloud photo services
- recent database/write events
- cloud sync state
- analysis workloads

### Filesystem

Shows:

- filesystem traversal events
- APFS service state
- metadata maintenance
- recent CPU reports

### Updates

Shows:

- platform update services
- application updater services
- recent update write events
- pending update state
- maintenance-window status

### Security / Policy Extensions

Shows:

- system extensions
- Network Extensions
- EndpointSecurity clients
- firewall/filter state
- trust and attestation status

## Minimum viable terminal view

| Controller | State | Last event | Impact | User action |
|---|---|---|---|---|
| Spotlight / Metadata | Active | disk writes | budget exceeded | inspect / budget |
| Photos / Media | Idle | database rewrite | high | quarantine profile |
| Filesystem | Idle | CPU usage | medium | schedule |
| Wireless | Active | telemetry loop | persistent | policy view |
| Application Updater | Idle | disk writes | medium | maintenance window |
| Network Policy | Active | extension authority | unknown | inspect |

## Required SourceOS events

- `ControllerRegistered`
- `ControllerCapabilityDeclared`
- `ControllerBudgetExceeded`
- `ControllerTouchedFileClass`
- `ControllerOpenedNetworkSurface`
- `ControllerEnteredIdleWork`
- `ControllerExitedIdleWork`
- `ControllerPolicyChanged`

## Product rule

If a controller can act without a foreground user command, it must have a visible registry entry, a declared resource budget, and a human-readable audit trail.
77 changes: 77 additions & 0 deletions tools/controller-inventory.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env bash
# Read-only SourceOS controller inventory collector.
# This script is intentionally non-mutating and does not require sudo.
# It writes a local text report for operator review. Do not commit raw output.

set -u

OUTDIR="${1:-$HOME/Desktop}"
STAMP="$(date +%Y%m%d-%H%M%S)"
OUT="$OUTDIR/controller-inventory-$STAMP.txt"
mkdir -p "$OUTDIR"

section() {
printf '\n\n### %s\n' "$1"
}

{
section "time / system"
date
sw_vers 2>/dev/null || true
uname -a 2>/dev/null || true
uptime 2>/dev/null || true

section "active controller processes"
ps axww -o pid,ppid,user,%cpu,%mem,rss,etime,command \
| egrep 'photolibraryd|photoanalysisd|mediaanalysisd|cloudphotod|cloudd|fileproviderd|mds|mdworker|mds_stores|spotlight|corespotlight|apfsd|airportd|wifip2pd|wifianalyticsd|symptomsd|networkserviceproxy|nesessionmanager|Firefox|updater|softwareupdated|nsurlsessiond|rapportd|sharingd|mDNSResponder|apsd|LuLu|BlockBlock' \
| egrep -v 'egrep' || true

section "top cpu processes"
ps axww -o pid,ppid,user,%cpu,%mem,rss,etime,command | sort -nrk4 | head -40

section "recent diagnostic report names"
ls -lt /Library/Logs/DiagnosticReports "$HOME/Library/Logs/DiagnosticReports" 2>/dev/null \
| egrep 'photolibraryd|photoanalysisd|mediaanalysisd|cloud|mds|spotlight|corespotlight|apfsd|fileproviderd|Firefox|firefox|updater|airportd|networkserviceproxy|shutdown_stall|Jetsam|cpu_resource|diag|ips' \
| head -160 || true

section "spotlight indexed volumes"
mdutil -as 2>&1 || true

section "system launchd controller services"
launchctl print system 2>/dev/null \
| egrep -i 'metadata|mds|spotlight|corespotlight|photo|cloudphoto|photolibrary|mediaanalysis|privatecloud|cloudd|cloudkit|fileprovider|searchparty|airport|wifi|corewifi|wifip2p|wifianalytics|networkserviceproxy|nesession|mDNSResponder|rapport|sharingd|apsd' \
| head -320 || true

section "user launchd controller services"
launchctl print "gui/$(id -u)" 2>/dev/null \
| egrep -i 'metadata|mds|spotlight|corespotlight|photo|cloudphoto|photolibrary|mediaanalysis|privatecloud|cloudd|cloudkit|fileprovider|searchparty|BluetoothCloud|BTServer.cloud|airport|wifi|corewifi|wifip2p|wifianalytics|networkserviceproxy|nesession|mDNSResponder|rapport|sharingd|apsd' \
| head -420 || true

section "interfaces"
ifconfig -a 2>&1 | egrep '^[a-z0-9]+:|status:|ether |inet |inet6 |media:|nd6 options|flags=' || true

section "active network paths"
scutil --nwi 2>&1 || true

section "routes ipv4"
netstat -rn -f inet 2>&1 || true

section "routes ipv6"
netstat -rn -f inet6 2>&1 | head -220 || true

section "dns"
scutil --dns 2>&1 || true

section "network services"
networksetup -listallhardwareports 2>&1 || true
networksetup -listallnetworkservices 2>&1 || true

section "system extensions"
systemextensionsctl list 2>&1 || true

section "network extension connections"
scutil --nc list 2>&1 || true

} | tee "$OUT"

echo "WROTE $OUT"
Loading
Loading