diff --git a/docs/superpowers/specs/2026-05-25-commitment-os-design.md b/docs/superpowers/specs/2026-05-25-commitment-os-design.md index e56d217..1d14404 100644 --- a/docs/superpowers/specs/2026-05-25-commitment-os-design.md +++ b/docs/superpowers/specs/2026-05-25-commitment-os-design.md @@ -4,15 +4,24 @@ Date: 2026-05-25 ## Purpose -AntiDrift should evolve from a session timer and window-rating tool into a commitment operating system: a personal agency layer that makes computer use explicit, constrained, observable, and resistant to tampering. +AntiDrift should evolve from a session timer and window-rating tool into a commitment operating system: a personal agency layer that makes computer use explicit, constrained, observable, and resistant to casual tampering. -The system should address distraction as unconscious context switching, not only as access to bad websites. The guiding rule is: +The system addresses distraction as unconscious context switching, not only as access to bad websites. The guiding rule is: ```text No unchosen transitions. ``` -The computer should not silently enter unconstrained use. It should be in an active commitment, a deliberate transition, planning/review, locked state, or delayed administrative override. +The computer should not silently enter unconstrained use. It should be in one of these explicit modes: + +- active commitment; +- deliberate transition; +- constrained planning; +- review; +- locked state; +- delayed administrative override. + +Tamper resistance is a friction gradient against the user's impulsive self. It is not a perfect security boundary. The goal is to defeat impulsive and casual bypasses, delay deliberate bypasses, and make drift visible. ## Architecture @@ -20,189 +29,437 @@ The system has five layers that share a common commitment model. 1. Orientation: projects, responsibilities, values, tasks, next actions, energy constraints. 2. Commitment: a concrete next action, success condition, allowed context, timebox, and transition policy. -3. Live work mode: desktop, browser, terminal, files, ActivityWatch, window tracking, and future presence sensors. +3. Live work mode: desktop, browser, terminal, files, ActivityWatch, window tracking, and future evidence sources. 4. Containment: a privileged guardian that enforces the selected commitment across the live environment. 5. Reflection: session outcomes, drift events, transition reasons, rule adjustments, and planner updates. -The commitment model sits between planning and enforcement. Planner integration can later create commitments from tasks. Enforcement can already operate on policy snapshots derived from commitments without understanding the entire planner. +The commitment model sits between planning and enforcement. Planner integration can later create commitments from tasks. Enforcement operates on policy snapshots derived from commitments without understanding planner internals. + +## Threat Model And Scope + +The adversary is the same person in a less reflective state. The system should be honest about what local software can and cannot enforce. + +| Tier | Bypass effort | Examples | Realistic goal | +| --- | --- | --- | --- | +| 0: impulse | less than 1 second | Alt-tab, open browser, type URL, leave desk without choosing transition | Defeat with blocking, prompts, overlays, and explicit transitions | +| 1: casual | seconds | Kill process, stop user service, close app, quit ActivityWatch | Defeat with watchdogs, privilege separation, and restart behavior | +| 2: determined | minutes | Use sudo, edit config, disable systemd units, reboot, manipulate clock | Delay and audit through delayed admin path and break-glass flow | +| 3: premeditated | unconstrained | Boot live USB, GRUB recovery, second device, phone, hardware removal | Out of scope for local software | + +In-scope bypasses: + +- opening disallowed domains or apps; +- quitting AntiDrift or ActivityWatch; +- stopping user-level services; +- entering unconstrained planning; +- changing rules without delayed admin access; +- crash-looping the user agent; +- malformed policy snapshots; +- clock manipulation attempts visible to the running system; +- unmonitored desk absence after future presence sensing exists. + +Out-of-scope or explicitly limited: + +- second phones, tablets, or other computers; +- booting from external media or recovery shell; +- physical tampering; +- fully premeditated bypasses with unlimited time; +- coercive monitoring of another person. + +Known edge cases to address or scope per implementation stage: + +- switching TTYs or desktop sessions; +- Wayland compositor limitations; +- VMs and nested display servers; +- SSH into the same machine; +- browser profiles and extensions; +- Flatpak/Snap application identity; +- multi-user machines; +- multiple monitors, virtual desktops, and tiling window managers; +- direct modification of ActivityWatch data. + +Stage 1 does not need to solve every edge case, but it must not pretend they are solved. + +## Linux Target Environment + +The first target is the user's Linux workstation. + +Stage 1 should support the current X11-style active-window model already used by AntiDrift through `xdotool`, plus ActivityWatch evidence when available. If the session is Wayland and active window metadata cannot be collected reliably, the system must surface that as a degraded evidence mode rather than silently reporting false confidence. + +Stage 2 should choose concrete Linux enforcement mechanisms per target environment: + +- systemd system service for the privileged guardian; +- systemd user service or normal user process for the agent; +- nftables or DNS-level controls for domain blocking; +- window-class interruption where active window details are available; +- ActivityWatch watchdog where ActivityWatch is installed and expected. + +Wayland support should be compositor-specific. GNOME Wayland, KDE Wayland, Sway, and Hyprland may need separate adapters. Unknown or unsupported environments should fail into a conservative mode: planning/review may work, but enforcement claims are limited. ## Domain Model -The core domain object is `Commitment`. +The first-pass `Commitment` concept should be split into three related records. + +### Commitment + +User-facing intent and planning artifact. ```text Commitment id created_at - source: manual | planner | recurring | recovery + source: manual | planner | recurring | recovery | template project_id: optional initially, planner-backed later + template_id: optional next_action: concrete executable action success_condition: what counts as done or meaningfully advanced - allowed_context: - apps - domains - files/repos - commands/processes timebox - transition_policy: - allowed breaks - pause reasons - max break duration - return ritual - enforcement_level: observe | warn | block | locked + transition_policy_id state: draft | active | paused | completed | abandoned | violated ``` -This contract is used by all layers: +Only one commitment may be active at a time. Task switches go through `Transition` and either resume the current commitment, abandon it, or create/select a new one. -- The session UI creates or selects a commitment. -- The guardian enforces the active commitment. -- ActivityWatch and window tracking evaluate behavior against the commitment. -- The planner later generates commitments from project tasks. -- Reflection writes outcomes back into history and eventually into the planner. +### PolicySnapshot -## Runtime States +Versioned enforcement contract consumed by the guardian. -The runtime state machine is intentionally small. +```text +PolicySnapshot + id + commitment_id + schema_version + created_at + runtime_state: locked | planning | active | transition | review | admin_override + enforcement_level: observe | warn | block | locked + allowed_context + required_monitors + violation_actions + expires_at + generated_by_agent_version +``` + +The guardian consumes `PolicySnapshot`, not planner internals. + +### SessionRecord And EventLog + +Append-only history of what happened. + +```text +SessionRecord + id + commitment_id + started_at + ended_at + outcome: completed | partial | abandoned | violated + review_rating + review_notes + +EventLog + sequence + timestamp + event_type + commitment_id + runtime_state + payload + previous_hash + hash +``` + +The event log is the source for review, audit, and later planner writeback. + +## Allowed Context Semantics + +Allowed context should be explicit and conservative. Stage 1 may only observe or warn, but the matching rules should be defined early so Stage 2 can enforce the same contract. + +```yaml +allowed_context: + window_classes: + match: exact_lowercase + values: + - code + - alacritty + window_titles: + match: substring + values: + - antidrift + domains: + match: exact_or_subdomain + values: + - github.com + - docs.python.org + repos: + match: canonical_path_prefix + values: + - ~/dev/antidrift + commands: + match: executable_basename + values: + - cargo + - git + - rg +``` + +Rules: + +- Domains include subdomains unless explicitly marked exact-only. +- Full URLs should not be stored by default; store domain and coarse path only when needed. +- Window classes are preferred over titles because titles can contain private data and change frequently. +- Unknown windows are handled by `enforcement_level`: record in `observe`, prompt in `warn`, interrupt in `block`, and force `Locked` on repeated or severe violations in `locked`. +- Terminals are hard to classify. Stage 1 may treat terminal windows as allowed based on window class and record command evidence later only when a shell integration exists. +- Child process handling is deferred until command/process enforcement is designed. Stage 2 should not claim process-level policy without cgroups, namespaces, AppArmor, seccomp, or equivalent mechanisms. +- Commitments may use per-resource actions. Example: block social domains, warn on unfamiliar apps, observe unknown terminal commands. + +Commitment templates and project defaults should reduce manual allowlist construction: + +- `deep coding`; +- `writing`; +- `admin`; +- `research`; +- `rest`; +- project-specific default repos, apps, and documentation domains. + +Time-limited context expansion should be allowed when work legitimately discovers a new need. Expansion must be explicit, audited, and bounded, such as "allow `docs.rs` for 20 minutes for this commitment." + +## Runtime State Machine + +Runtime state controls what the machine is allowed to do now. ```text Locked No valid active commitment. Distracting/default computer use is blocked. Planning - The user can inspect tasks/projects and create or choose a commitment. + Constrained UI for inspecting tasks/projects and creating or choosing a commitment. Active A commitment is running. Allowed context is available; disallowed context is blocked or interrupted. Transition - The user is intentionally changing state: bathroom, water, reset, task switch, or end session. + Intentional state change: bodily break, reset, task switch, or session end. Requires reason, expected duration, and return target. Review Session ended. The user rates relevance, marks outcome, and records drift/avoidance patterns. Admin Override - Privileged changes only. Requires delayed admin path and leaves audit evidence. + Privileged change path. Requires delayed admin access and leaves audit evidence. ``` -The system should record all state changes. Leaving the desk, quitting monitors, changing rules, opening unrelated websites, or switching tasks should become explicit transitions or violations. +Legal transitions: -## Enforcement Boundary +| From | To | Guard | Side effects | +| --- | --- | --- | --- | +| Locked | Planning | Planning UI requested | Apply planning policy, start planning timer | +| Planning | Active | Valid commitment and policy snapshot accepted by guardian | Create session record, apply active policy | +| Planning | Locked | Cancel, timeout, invalid policy, or idle | Apply locked policy | +| Active | Transition | Reason, expected duration, and return target provided | Record transition start, apply transition policy | +| Active | Review | Commitment completed, abandoned, or timebox expired | Stop active policy, collect evidence summary | +| Active | Locked | Severe violation, policy failure, or monitor failure | Record violation, apply locked policy | +| Transition | Active | Return before timeout to same commitment | Record return, reapply active policy | +| Transition | Planning | Task switch requested | Mark current commitment paused/abandoned as chosen, apply planning policy | +| Transition | Review | End session requested | Collect review data | +| Transition | Locked | Timeout exceeded or transition policy failure | Record violation, apply locked policy | +| Review | Planning | Continue working | Store review, apply planning policy | +| Review | Locked | End work period | Store review, apply locked policy | +| Any | Admin Override | Delayed admin path completed | Record override, apply requested privileged change | +| Admin Override | Previous/new state | Override ends | Record result, apply selected policy | -The system has two main runtime processes. +Planning must never become unconstrained browsing. It has its own policy: + +- only the planning UI, local task data, and approved references are available; +- planning is time-limited; +- evidence collection remains active; +- opening arbitrary browser tabs from Planning is a violation unless explicitly allowed. + +Suspend/hibernate and reboot should resume into `Locked` unless a valid policy can be restored and verified. A violated commitment may be resumed only through `Review` or `Planning`; resumption should create a visible event. + +## Commitment Lifecycle + +Commitment state is distinct from runtime state. + +| From | To | Guard | Notes | +| --- | --- | --- | --- | +| draft | active | Runtime enters `Active` with accepted policy | Only one active commitment at a time | +| active | paused | Runtime enters `Transition` with return target | Paused does not imply unconstrained use | +| paused | active | User returns before transition timeout | Same commitment resumes | +| active | completed | Success condition met or user completes in review | Requires review | +| active | abandoned | User chooses task switch/end without completion | Requires reason | +| active | violated | Severe or unresolved violation | May force runtime `Locked` | +| paused | abandoned | Transition becomes task switch/end | Requires reason | +| violated | active | Explicit recovery flow | Audited; not automatic | +| violated | abandoned | Review confirms abandonment | Stored in history | + +## Guardian IPC Contract + +The user agent and guardian communicate through a narrow local API. + +Recommended transport: root-owned Unix domain socket with a small JSON-lines protocol. D-Bus can be reconsidered later if desktop integration requires it, but the first design should avoid unnecessary framework surface. + +Authentication and integrity: + +- The socket path is owned by root and writable only by the expected user/group. +- The guardian checks peer credentials with `SO_PEERCRED`. +- Messages include `schema_version`, monotonic sequence, and request id. +- The guardian rejects malformed, unknown-version, stale, or unauthenticated messages. +- Policy changes are logged before and after application. + +Minimal API: ```text -User agent - TUI/UI, session flow, window/activity collection, prompts, local status. - -Privileged guardian - systemd-managed service, watchdog, block rules, policy application, - tamper detection, restart behavior, admin-only config. +ApplyPolicy(PolicySnapshot) -> Result +ReportEvent(Event) -> Ack +GetStatus() -> SystemState +RequestOverride(OverrideRequest) -> OverrideResult ``` -The user agent owns interaction and local evidence collection. The privileged guardian is narrow and boring: it applies policy snapshots, keeps required monitors alive, records tamper evidence, and refuses easy shutdown. +Failure behavior: -The Linux machine can use the existing delayed admin-account mechanism as part of the hardening story. Configuration changes and service shutdown should require delayed privileged access. +- If the agent disconnects while `Active`, the guardian keeps the last valid policy for a short grace period, then moves to `Locked`. +- If the agent sends malformed policy, the guardian rejects it and keeps the previous valid policy; repeated malformed policy escalates to `Locked`. +- If IPC is unavailable, the agent should show degraded state and the system should not claim enforcement. +- If guardian and agent schema versions are incompatible, the system should enter `Locked` with an actionable error and break-glass instructions. -## Data Flow +## Enforcement Mechanism Matrix + +Stage 2 enforcement should be explicit about feasibility. + +| Resource | Stage 1 | Stage 2 candidate | Notes | +| --- | --- | --- | --- | +| Domain | observe from ActivityWatch/browser data if available | nftables or DNS-level blocking | Prefer domains over full URLs for privacy | +| App/window | active-window tracking, minimize or overlay | window-class interruption, minimize, SIGSTOP only where safe | Depends on X11/Wayland adapter | +| Agent health | local process check | systemd restart and guardian watchdog | Casual process killing should fail | +| ActivityWatch health | observe availability | guardian restart and escalation after repeated failure | Direct DB tampering only audited if detectable | +| Config changes | local file checks | root-owned config, delayed admin required | Config writes must be audited | +| Commands/processes | mostly out of scope | future shell integration, cgroups, AppArmor, seccomp, namespaces | Do not overclaim early | +| Files/repos | local path metadata | future filesystem policy only if needed | Path allowlists are mostly planning/evidence initially | +| Presence | out of scope | future opt-in sensor events | Requires separate ethics/design review | + +Stage 1 should include Tier 0 friction even without privileged blocking: + +- full-screen or high-priority overlay on violation where feasible; +- dismissal requires entering a reason; +- explicit transition prompts; +- local event logging tied to the active commitment. + +## Delayed Admin And Break-Glass Recovery + +The delayed admin mechanism is load-bearing and must be concrete before Stage 2 hardening. + +Initial assumption: + +- daily work happens in a non-admin user account; +- admin access exists in a separate admin account or equivalent path; +- admin access already has a delay, currently about 10 minutes, and can be lengthened; +- privileged enforcement changes require that delayed path. + +Actions requiring delayed admin: + +- disabling guardian service; +- changing locked policy files; +- changing blocklists or allowlists outside explicit time-limited context expansion; +- uninstalling enforcement; +- disabling watchdog behavior; +- emergency break-glass. + +Override requests should be logged at request time and completion time: ```text -Planner or manual input - -> Commitment draft - -> Active commitment - -> Guardian policy snapshot - -> Live evidence stream - windows, ActivityWatch, process health, future sensors - -> Violations / transitions / completions - -> Review - -> Event log + history + planner updates +OverrideRequest + id + requested_at + requester_user + reason + requested_action + earliest_allowed_at + completed_at + result ``` -The guardian consumes policy snapshots derived from the active commitment. A snapshot answers: +Pre-scheduled instant overrides weaken the system. The guardian should reject override tokens or sentinel files created before the current request window unless they are part of the audited delayed-admin protocol. -- What runtime state is active? -- What apps, domains, processes, files, or commands are allowed? -- Which monitoring processes must be running? -- What should happen on violation? -- Which changes require admin override? +Break-glass recovery must be independent of the normal agent UI. Example: a privileged command or root-owned sentinel file disables enforcement for 10 minutes after delayed admin access. It must: -This keeps enforcement independent from planner internals. +- be simple enough to trust under failure; +- be audited; +- have automatic expiry; +- restore normal policy after expiry unless explicitly uninstalled; +- not depend on the user agent being healthy. -## Staged Implementation +## Event Log, Tamper Evidence, And Retention -### Stage 1: Commitment Kernel +Events should be append-only and bounded. -Build the shared commitment model and local runtime loop. +Recommended initial format: JSON lines with hash chaining. -- Commitment schema. -- Runtime state machine. -- Local event log. -- Session UI using commitment fields. -- Activity/window evidence linked to `commitment_id`. -- Review flow. +```text +event_hash = hash(schema_version, sequence, timestamp, event_type, payload, previous_hash) +``` -The current AntiDrift app can become the first client of this model. +The log should include: -### Stage 2: Linux Hardening +- policy applications; +- state transitions; +- violations; +- process/monitor failures; +- override requests and completions; +- review outcomes. -Move enforcement into system-level mechanisms. +Retention and storage: -- systemd user service for the agent. -- Privileged guardian service. -- Watchdog checks for AntiDrift and ActivityWatch. -- Tamper-evident event log. -- Admin-only policy config. -- Delayed override path. -- Basic network, browser, and app blocking. +- rotate logs by size and time; +- enforce max disk usage; +- define behavior when disk is full; +- support export and deletion through delayed admin if enforcement logs are involved; +- include schema version and migration path. -### Stage 3: Planner Integration +If logging fails: -Replace ad hoc intentions with a live planning layer. +- non-critical review notes may be skipped with visible warning; +- enforcement/audit events should fail conservative, usually `Locked`, unless doing so would create an unsafe machine lockout; +- break-glass must still work even when normal logging is impaired, with best-effort emergency log. -- Projects. -- Tasks. -- Next actions. -- Recurring responsibilities. -- Task selection during Planning state. -- Session outcomes written back to tasks. -- Review suggestions based on drift history. +## Privacy, Ethics, And Data Retention -### Stage 4: Embodied And Presence Sensing +This is voluntary self-use software. It must not become bossware, parental control software, or coercive monitoring. -Add physical-context evidence after the core system is useful. +Principles: -- Desk presence detection. -- Posture warnings. -- Phone pickup or away detection, if feasible. -- Transition prompts when leaving unexpectedly. +- local-first storage by default; +- no network transmission unless explicitly configured; +- minimum necessary observation; +- prefer domain over full URL; +- prefer window class over title where possible; +- treat window titles as sensitive because they can contain private messages, documents, or secrets; +- encrypt logs/history at rest if feasible, especially once planner and presence data exist; +- provide retention, deletion, and export tools; +- make data collection visible to the user; +- include first-class `rest` and `exploration` commitments so legitimate openness and recovery are not treated as failure. -Presence sensing should be another evidence source that emits events such as `desk_absence_started`. It should not be a core dependency. +The system should increase agency, not create surveillance anxiety. Presence sensing, camera use, posture detection, and phone pickup detection require a separate opt-in design and ethics review after the core system is useful. ## Failure Handling -The system should assume failures and tampering attempts are normal. +Failures should have explicit fail-open or fail-closed behavior. -```text -Agent crash - Guardian restarts it and records the crash. - -ActivityWatch stopped - Guardian restarts it; repeated failure escalates to Locked. - -Policy apply failure - System refuses Active state and stays Locked or Planning. - -Unknown app/window/domain - observe/warn: record and prompt - block/locked: interrupt or minimize - -Unexpected desk absence later - Emit transition-needed event; if not resolved, mark violation. - -Admin override - Allowed only through delayed admin path and always recorded. -``` +| Failure | Default behavior | +| --- | --- | +| User agent crash | Guardian restarts agent; if repeated, enter `Locked` | +| User agent crash loop | Enter `Locked`, show recovery instructions | +| Guardian crash | systemd restarts guardian; until restored, user agent shows enforcement degraded | +| Guardian crash loop | Fail conservative where possible, but keep break-glass available | +| ActivityWatch stopped | Guardian restarts it; repeated failure escalates to `Locked` if ActivityWatch is required | +| ActivityWatch unavailable | Run degraded if policy does not require it; otherwise refuse `Active` | +| ActivityWatch data corrupted | Mark evidence degraded, preserve raw error, continue only if policy allows | +| Policy apply failure | Refuse `Active`; stay `Planning` or move `Locked` | +| Malformed policy | Reject, keep previous valid policy, escalate after repeated failures | +| Disk full/log write failure | Warn; fail conservative for enforcement events; keep break-glass available | +| System reboot | Start in `Locked` until state is restored and verified | +| Suspend/hibernate | On resume, revalidate timebox and policy; otherwise enter `Locked` | +| Clock manipulation | Prefer monotonic timers for timeboxes; record wall-clock anomalies | +| OS updates | Require delayed admin or maintenance commitment | +| Emergency interruption | Use transition or break-glass depending on severity | +| Schema migration failure | Enter `Locked` with recovery instructions | The primary invariant is: @@ -210,20 +467,208 @@ The primary invariant is: Without an active valid commitment, the machine cannot silently enter unconstrained use. ``` +## Locked, Planning, Transition, And Review UX + +Locked state should show a small, reliable UI: + +- current status; +- reason for lock; +- option to enter constrained Planning; +- option to review last session if pending; +- break-glass instructions that require delayed admin. + +Planning should be useful but constrained: + +- local project/task list; +- commitment templates; +- recent commitments; +- allowed local notes or references; +- time limit; +- no arbitrary browsing unless a planning policy explicitly allows it. + +Transition should force consciousness into state changes: + +- reason; +- expected duration; +- return target; +- optional note; +- timeout behavior. + +Review should be difficult to skip: + +- mark outcome; +- rate relevance; +- record drift or transition failures; +- update commitment/task state; +- generate next suggested commitment where useful. + +## Staged Implementation + +### Stage 1a: Commitment Kernel + +- Commitment schema. +- PolicySnapshot schema without privileged enforcement. +- Runtime and commitment state machines. +- Append-only local event log. +- Unit tests for legal and illegal transitions. + +### Stage 1b: Session UI And Evidence + +- Session UI using commitment fields. +- Review flow. +- Activity/window evidence linked to `commitment_id`. +- Degraded evidence reporting when ActivityWatch or window metadata is unavailable. + +### Stage 1c: Tier 0 Friction + +- Full-screen or high-priority overlay on violation where feasible. +- Dismissal requires deliberate reason entry. +- Explicit transition prompts. +- Unknown-window/domain behavior based on enforcement level. + +### Stage 2a: Guardian Skeleton + +- systemd system service for guardian. +- systemd user service or launcher for agent. +- Watchdog restart behavior for user agent and ActivityWatch. +- Minimal status reporting. + +### Stage 2b: IPC And Policy Delivery + +- Root-owned Unix domain socket. +- JSON-lines protocol. +- `ApplyPolicy`, `ReportEvent`, `GetStatus`, `RequestOverride`. +- Schema versioning and malformed-message handling. + +### Stage 2c: Domain Blocking + +- nftables or DNS-level policy application. +- Domain matching semantics. +- Policy rollback on failure. + +### Stage 2d: App/Window Interruption + +- X11 adapter first if current environment is X11. +- Compositor-specific Wayland adapters only after verification. +- Minimize, overlay, or interrupt based on policy. + +### Stage 2e: Tamper-Evident Logs And Retention + +- Hash-chained events. +- Rotation and max disk usage. +- Export/delete path. +- Log failure handling. + +### Stage 2f: Delayed Admin And Config Lockdown + +- Root-owned policy/config. +- Delayed override protocol. +- Break-glass command. +- Uninstall/rollback tooling. + +### Stage 3a: Project And Task Model + +- Projects. +- Tasks. +- Next actions. +- Recurring responsibilities. + +### Stage 3b: Commitment Templates From Tasks + +- Project defaults. +- Work-mode templates. +- Task selection during Planning state. +- Time-limited context expansion. + +### Stage 3c: Outcome Writeback + +- Session outcomes written back to tasks. +- Review suggestions based on drift history. +- Next commitment suggestions. + +## Future Direction: Embodied And Presence Sensing + +Presence sensing is not part of the core roadmap. It may be considered later only if: + +- the core system has proven useful; +- the user explicitly opts in; +- data minimization is defined; +- psychological safety is reviewed; +- retention and deletion behavior are explicit. + +Potential future events: + +- `desk_absence_started`; +- `desk_absence_resolved`; +- `posture_warning`; +- `phone_pickup_detected`. + +These should be evidence events, not core dependencies. + +## Uninstall And Rollback + +The system must have a clean removal path. + +Uninstall should: + +- disable guardian service; +- disable user agent service; +- remove nftables or DNS rules; +- remove root-owned policy/config files after delayed admin confirmation; +- export or delete logs; +- restore normal admin behavior if it was modified for AntiDrift; +- verify that no blocking policy remains active. + +Rollback should support returning from a failed upgrade to the previous known-good policy and guardian version. + ## Testing Strategy -Testing should happen at three levels. +Testing must include bypass resistance, not only happy paths. -```text -Unit tests - commitment validation, state transitions, policy snapshot generation, scoring. +Unit tests: -Integration tests - user agent writes state; guardian reads policy; simulated ActivityWatch/window events produce expected violations. +- commitment validation; +- legal and illegal runtime transitions; +- legal and illegal commitment transitions; +- PolicySnapshot generation; +- allowed context matching; +- event hash chaining. -Manual system tests - quit agent, quit ActivityWatch, open blocked site, change config, trigger delayed override, - verify logs and recovery behavior. -``` +Property tests: -The first implementation plan should focus on Stage 1 while preserving the process boundary and data contracts needed for Stage 2 and Stage 3. +- no unconstrained use without valid active commitment; +- illegal transitions do not mutate state; +- expired policy snapshots are rejected. + +Integration tests: + +- user agent writes state; +- guardian reads policy; +- simulated window/ActivityWatch events produce expected violations; +- malformed policy is rejected; +- agent disconnect triggers grace period then `Locked`; +- timebox expiry moves to `Review` or `Locked` as configured. + +Adversarial VM/manual tests: + +- kill agent; +- stop ActivityWatch; +- attempt blocked domain; +- malformed policy; +- guardian restart; +- guardian crash loop; +- timebox expiry; +- config change attempt; +- reboot during active commitment; +- suspend/resume during active commitment; +- disk full or log write failure. + +Soak and upgrade tests: + +- 24-48 hour run with normal use; +- log rotation; +- schema migration; +- downgrade/rollback; +- IPC fuzz tests. + +The first implementation plan should target Stage 1a through Stage 1c while preserving the process boundary and data contracts needed for Stage 2 and planner integration.