How it works, step by step
We tried to break it. Our own test run on this Mac, not an outside audit.
Each step below was run on a real Mac. Under each one is what really came back: the command the Mac refused, and the line it wrote in the record. Where a part could not be run here, the step says so.
Run on 2026-10-18 at 10:37 · macOS 27.0.1 on arm64 · 15 steps ran in full, 2 only in part, 0 did not hold.
- 01 Find the AI tools on this Mac
- 02 Say the task and lock it
- 03 The agent works on a copy
- 04 The Mac's own fence (Seatbelt) around the agent
- 05 Network off
- 06 Hidden files stay hidden, even in git
- 07 Claude Code and Codex: their own fence, their settings, and our pre-step hook
- 08 It wants something outside the task. It's turned away, and you're asked.
- 09 Watch it work on one map
- 10 A second look by a reviewer
- 11 Nothing reaches your folder until you press Keep
- 12 The record, and a checker anyone can run
- 13 A check-up that offers one fix at a time
- 14 Answer yes or no on your iPhone
- 15 Hard lines no one can cross
- 16 The browser add-on's paste check
- 17 Speak instead of typing
Find the AI tools on this Mac
What you do
Open the app. It lists the AI tools it found.
What the Mac does
Looks for each tool's program on this Mac and reads its version. For each one it says which rules the Mac holds, which are caught at the check, and which are only written down.
What really happened
Ran for real on this Mac.- agents (the app's own command)
Claude Code: found 2.1.302 Codex CLI: found 0.162.1 Cursor: found 2026.10.14-941492e Gemini CLI: found 0.64.0 Copilot CLI: found 1.0.98. Model on this Mac: not found A program you name: not found
Say the task and lock it
What you do
Write the task, what the agent may read and change, and what done looks like. Press Lock.
What the Mac does
Saves the task as version 1 and takes its fingerprint (a SHA-256 of the whole task). The fingerprint goes in the record, so any later change shows.
What really happened
Ran for real on this Mac.- task_lock
version 1, fingerprint b29e8ad9df98cf15…
- the record
2026-10-18T17:37:02Z task.locked {"agent": {"agent_file": null, "name": "program", "vendor": "program"}, "by": "owner/you", "client": "Harper & Co.", "content": {"agents": [{"agent_file": null, "role": "does", "vendor": "program"}], "client": "Harper & Co.", "done": [{"by": "mac", "check": "scope", "text": "Nothing outside the task changed"}, {"by": "agen…
The agent works on a copy
What you do
Press Start.
What the Mac does
Makes a separate copy of the client folder (an APFS clone) with only what the task may read. Hidden files are left out. The agent is started inside the copy, never in your folder.
What really happened
Ran for real on this Mac.- your folder
.env, Bank statements/march.txt, Receipts/march.csv, notes/intake.txt, secrets/ssn.txt
- the copy
notes/intake.txt
- the record
2026-10-18T17:37:03Z delegation.opened {"base_branch": null, "copy_method": "clone", "copy_note": null, "delegation": {"dependency_policy": {"allow_new": true, "allowlist": []}, "enforcement_min": {"network": "kernel", "read": "kernel-denylist", "side_effects": "none", "write": "kernel"}, "envelope": {"budget": {"tokens": 0, "tool_calls": 400, "usd_cents"…
The Mac's own fence (Seatbelt) around the agent
What you do
Nothing. It is on for every job.
What the Mac does
Starts the agent under macOS's sandbox (sandbox-exec), with rules built from your task: write only in the copy; never read your folder, hidden files, ~/.ssh or Agent Task Lock's own files; no network; no background jobs, apps or saved passwords.
What really happened
Ran for real on this Mac.- tried: do the task: write notes/summary.md in the copyAllowed
wrote it
- tried: read a hidden file in the copy (.env)Not in the copy
cat: .env: No such file or directory
Without the fence, this worked. - tried: read the original folder's hidden fileRefused
cat: ~/Clients/Harper & Co/.env: Operation not permitted
Without the fence, this worked. - tried: read the original folder's secrets/ssn.txtRefused
cat: ~/Clients/Harper & Co/secrets/ssn.txt: Operation not permitted
Without the fence, this worked. - tried: write into the original folderRefused
sh: ~/Clients/Harper & Co/notes/planted.md: Operation not permitted
Without the fence, this worked. - tried: write outside the copy (home folder)Refused
sh: ~/outside.txt: Operation not permitted
Without the fence, this worked. - tried: cat ~/.ssh/id_ed25519Refused
cat: ~/.ssh/id_ed25519: Operation not permitted
Without the fence, this worked. - tried: edit Agent Task Lock's settingsRefused
sh: ~/atl/settings.json: Operation not permitted
Without the fence, this worked. - tried: edit Agent Task Lock's project listRefused
sh: ~/atl/projects.json: Operation not permitted
Without the fence, this worked. - tried: edit this job's rules (contract.json)Refused
sh: ~/atl/runs/dlg-20261018-173703-ebc6/contract.json: Operation not permitted
Without the fence, this worked. - tried: read the client numbers fileRefused
cat: ~/atl/client-ids.json: Operation not permitted
Without the fence, this worked. - tried: add a line to the recordRefused
sh: ~/atl/ledger/*.jsonl: Operation not permitted
Without the fence, this worked. - tried: press Keep itself (run the app's approve)Refused
{"ok": false, "error": {"code": "bad_input", "message": "That file or folder name can't be used here. Choose another.", "kind": "your_input", "kind_title": "Something in what was sent", "next": "Check what you typed or picked, then try again.", "retryable": false, "help": "your_input/bad_input", "spoken": "That file or folder name can't be used here. Choose another."}, "api": 1} - tried: curl out to the internetRefused
curl: (6) Could not resolve host: example.com
Without the fence, this worked. - tried: curl to a listener on this MacRefused
curl: (7) Failed to connect to 127.0.0.1 port 60555 after 0 ms: Couldn't connect to server
- tried: look up a name (DNS)Refused
/usr/bin/host: isc_socket_bind: unexpected error
Without the fence, this worked. - tried: start a background job (launchctl)Refused
~/bin/scripted-agent: line 2: /bin/launchctl: Operation not permitted
Without the fence, this worked. - tried: open an app on the screen (open)Refused
~/bin/scripted-agent: line 2: /usr/bin/open: Operation not permitted
Without the fence, this worked. - tried: read the saved passwords (security)Refused
~/bin/scripted-agent: line 2: /usr/bin/security: Operation not permitted
Without the fence, this worked. - the job's own events
scripted-agent finished with exit code 0. {"exit": 0, "refused_by_cage": 14} - the listener on this Mac
0 connections from inside the fence (1 without the fence)
Network off
What you do
Nothing. A job has no network unless you allow one port on this Mac.
What the Mac does
The fence has one rule at the end: deny every network connection. Even name lookups fail.
What really happened
Ran for real on this Mac.- tried: curl out to the internetRefused
curl: (6) Could not resolve host: example.com
- tried: curl to a listener on this MacRefused
curl: (7) Failed to connect to 127.0.0.1 port 60555 after 0 ms: Couldn't connect to server
- tried: look up a name (DNS)Refused
/usr/bin/host: isc_socket_bind: unexpected error
Claude Code and Codex: their own fence, their settings, and our pre-step hook
What you do
Pick Claude Code or Codex for the task.
What the Mac does
Writes the tool's own settings for this job: its Seatbelt sandbox (writes only in the copy, hidden paths unreadable, no network), deny rules for its file and web tools, and our hook, which checks every step before it runs and refuses one that reaches a hidden file.
What really happened
Ran for real on this Mac. Not run live with Claude Code.- the settings written for Claude Code
sandbox on: True; network allowed domains: []; write only in: ["$TMPDIR/agent-task-lock-copies/dlg-20261018-173705-2d0c"]; unreadable paths: 54; deny rules for its tools: 217; hooks: PostToolUse, PreToolUse, SessionEnd, Stop
- hook: Read the hidden .envRefused
.env is hidden from agents by Agent Task Lock for this project. Work without it.
- hook: Read the original's secrets/ssn.txtRefused
secrets/ssn.txt is hidden from agents by Agent Task Lock for this project. Work without it.
- hook: Bash: cat ~/.ssh/id_ed25519Refused
~/.ssh/id_ed25519 is hidden from agents by Agent Task Lock for this project. Work without it.
- hook: Bash: git show HEAD:secrets/ssn.txtRefused
secrets/ssn.txt is hidden from agents by Agent Task Lock for this project. Work without it.
- hook: Edit Agent Task Lock's settings.jsonRefused
~/atl/settings.json is hidden from agents by Agent Task Lock for this project. Work without it.
- hook: Write into the original folderRefused
Work only in your copy, $TMPDIR/agent-task-lock-copies/dlg-20261018-173705-2d0c. The original project folder ~/Clients/Harper & Co is off-limits; use the same relative path in the copy.
- hook: WebFetch a pageRefused
WebFetch is turned off in Agent Task Lock jobs: a job has no network, so nothing from this project can be sent out. Work from the files you have.
- hook: Grep for API_KEY across the originalRefused
. holds files hidden from agents, so a search over all of it is refused. Search a narrower folder that has no hidden files in it.
- hook: Read notes/intake.txt in the copy (allowed)Allowed
(no objection)
- the job's own events
Tried to open .env (hidden from agents). Blocked.
- the settings written for Codex
sandbox_mode = "workspace-write"; approval_policy = "on-request"; web_search = "disabled"; network_access = false
- Codex
not run live with Codex: it isn't signed in on this Mac
It wants something outside the task. It's turned away, and you're asked.
What you do
Answer the ask: yes adds it to the task, no keeps it out.
What the Mac does
Every step the hook refused becomes an ask on the task. Yes makes version 2 of the task with a new fingerprint. No is written in the record. Either way, the try is written down with the time.
What really happened
Ran for real on this Mac. Not run live with Claude Code.- hook: Read Bank statements/march.txt (not in the task)Refused
{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "deny", "permissionDecisionReason": "Bank statements/march.txt is hidden from agents by Agent Task Lock for this project. Work without it."}} - task_sync: asks made from refused steps
read: Bank statements/march.txt
- you said yes
version 2, fingerprint 673a4e4e8a10add6… (was e2ac0137bd2908d2…)
- an ask for secrets/ssn.txt
no: recorded
- the record
2026-10-18T17:37:06Z task.changed {"by": "owner/you", "change": "c1", "content": {"agents": [{"agent_file": null, "role": "does", "vendor": "claude-code"}], "client": "Harper & Co.", "done": [], "goal": "Sort the receipts by month.", "keeper": {"name": "You", "who": "you"}, "project": "harper-co-78a093", "schema": "atl.task/1", "steps": [], "title": "Sort… - the record
2026-10-18T17:37:06Z task.change_declined {"by": "owner/you", "change": "c2", "task": "44166534b0af4021", "version": 2, "what": "secrets/ssn.txt"} - a program you name: asks made from the fence's refusals
read: .env; read: secrets/ssn.txt
Watch it work on one map
What you do
Open the task. Watch each step as it happens.
What the Mac does
Reads the job's own event stream and the record into one live map: the lock, the agent, the reviewer and you, with each step and how long it took.
What really happened
Ran for real on this Mac.- stages
locked › handed_out › working › reviewer › ready
- on the map
program (agent): done; reviewer (reviewer): queue; You (you): ready
- feed
Ready for you. Keep or send back. | program asked to read secrets/ssn.txt. The Mac keeps it out until you answer. | program asked to read .env. The Mac keeps it out until you answer. | program started. | The task was locked.
- cost
{"measured": false, "says": "Not measured: this work didn't go through the gateway on this Mac."}
A second look by a reviewer
What you do
Press Check. The reviewer goes down your done list.
What the Mac does
Checks the copy against each done item and says met or missed, with the file and line. It takes the copy's fingerprint before and after: if anything changed, its answers are thrown out.
What really happened
Ran for real on this Mac. AI reviewer not run live.- summary
1 of 2 met. “1099-INT” isn't in notes/summary.md.
- each done item
summary.md is in notes: met (notes/summary.md, line 1) summary.md says "1099-INT": missed (notes/summary.md, line None) record: 2026-10-18T17:37:07Z reviewer.finished {"by": "owner/you", "met": 1, "missed": 1, "missed_items": ["summary.md says \"1099-INT\""], "n": 2, "open": 0} - copy changed while checking?
False
Nothing reaches your folder until you press Keep
What you do
Look at the changes. Press Keep, send it back, or throw it away.
What the Mac does
Until Keep, your folder is exactly as it was (checked file by file). On Keep, only the approved files are copied in, each only if your file still matches what it was at the start.
What really happened
Ran for real on this Mac.- your folder before Keep
same as at the start, file by file
- the agent tried to press Keep itselfRefused
{"ok": false, "error": {"code": "bad_input", "message": "That file or folder name can't be used here. Choose another.", "kind": "your_input", "kind_title": "Something in what was sent", "next": "Check what you typed or picked, then try again.", "retryable": false, "help": "your_input/bad_input", "spoken": "That file or folder name can't be used here. Choose another."}, "api": 1} - what changed in the copy
notes/summary.md
- after Keep
notes/summary.md is now in your folder
- the record
2026-10-18T17:37:05Z gate.run {"changed": [{"added": 1, "path": "notes/summary.md", "removed": 0}], "changed_files": 1, "changed_paths": ["notes/summary.md"], "delegation_ref": "dlg-20261018-173704-c18e", "diff_lines": 1, "examined": 1} - the record
2026-10-18T17:37:07Z delegation.closed {"applied": ["notes/summary.md"], "conflicts": [], "delegation_ref": "dlg-20261018-173703-ebc6", "granted_by": {"channel": "mac", "role": "owner", "who": "you"}, "held_deletes": [], "mode": "folder"}
The record, and a checker anyone can run
What you do
Show the record to a client, or hand it to an auditor.
What the Mac does
Every entry is chained to the one before by a SHA-256 hash. The record can be saved to a folder with a one-file checker (recordcheck.py) that needs only Python.
What really happened
Ran for real on this Mac.- entries in the record after this run
35
- recordcheck.py on the saved record (exit 2)
Every entry checks. No checkpoint given: a cut-off end can't be seen. Run again with --expect FILE:SEQ:HASH (the last entry you saw) or --checkpoints FILE.
- one entry changed, checked again (exit 1)
w-this-mac.jsonl entry : its content doesn't match its hash; record.csv entry : this row doesn't match its entry
A check-up that offers one fix at a time
What you do
After a few tasks, open the check-up. Say yes or no to each fix.
What the Mac does
A program on this Mac (not an AI) reads your kept tasks of one agent with plain rules. Each finding says what it saw. Nothing changes until you say yes.
What really happened
Only part of this ran here. Not run on real kept tasks.- checkup_run
no_file: There's no imported file for that agent.
Answer yes or no on your iPhone
What you do
Pair your iPhone once. Answer an ask from it.
What the Mac does
The phone's answer is signed with the pairing key and must repeat the task's version and fingerprint. A copy of an old answer, a wrong fingerprint or a task that moved on is refused.
What really happened
Ran for real on this Mac. The iPhone app not run in this run.- the ask the phone gets
{"task": "44166534", "version": 2, "fingerprint": "673a4e4e8a10add6", "change": "Call the bank", "label": "written down only"} - an answer with the wrong fingerprintRefused
fingerprint_mismatch: That answer was for a different version, so nothing was done.
- an answer signed with the wrong keyRefused
bad_signature
- the real answer
answered on iPhone by the owner
- the same answer sent againRefused
replayed
Hard lines no one can cross
What you do
The owner sets a few lines, each with a reason.
What the Mac does
Each line must be one the Mac can hold. A task that crosses one can't be locked, and no one can say yes to crossing it, the owner included.
What really happened
Ran for real on this Mac.- hardline_add
added
- a line the Mac can't holdRefused
The Mac can't stop this. Add it as guidance instead.
- lock a task that reads Bank statementsRefused
This task can't be locked. Hard line: AI never opens Bank statements Reason: Bank files stay with the firm.
- the record
2026-10-18T17:37:07Z hardline.changed {"by": "owner/you", "change": "added", "line": {"at": "2026-10-18T10:37:07-0700", "by": "owner/you", "id": "32047ce34d", "kind": "keep_out", "on": true, "path": "Bank statements", "reason": "Bank files stay with the firm.", "text": "AI never opens Bank statements"}}
The browser add-on's paste check
What you do
Paste client text into ChatGPT or another AI website.
What the Mac does
The add-on hands the text to this Mac. It looks for a client's name, a client number you saved, or 8 words in a row from a client file, then throws the text away. You see a warning and choose.
What really happened
Ran for real on this Mac. The add-on in Chrome not run in this run.- pasted: Please draft a letter for Harper & Co. about fees.
warns: Harper & Co. (name)
- pasted: Their EIN is 123456789, can you check it
warns: Harper & Co. (identifier)
- pasted: Write a haiku about autumn leaves falling
no warning
- the record keeps
{"actor": "system/agent-task-lock", "body": {"index_partial": false, "local_only": false, "matches": [{"client": "Harper & Co.", "kinds": ["identifier"], "local_only": false}], "policy": "warn", "site": "chatgpt.com"}, "seq": 25, "ts": "2026-10-18T17:37:07Z",…
Speak instead of typing
What you do
Press the microphone and talk.
What the Mac does
Uses Apple's speech engine on this Mac only. If this Mac can't do your language on its own, it refuses instead of sending sound to Apple. The text goes into the field like typed text.
What really happened
Only part of this ran here. Not run live (no microphone in this run).- voice_status
{"available": false, "on_device": false, "helper": false}
What each AI tool can be held to
Strongest first. Held by the Mac means macOS itself refuses it, even if the tool skips its own checks. The tool's own setting is a rule we write into the tool. Our pre-step hook refuses a step that names the path. Caught at the check means it is found before Keep, and the work waits. This table is made from the code that writes each tool's settings.
| Claude Code | Codex CLI | Cursor | Gemini CLI | |
|---|---|---|---|---|
| Changes outside the job's copy | Held by the Mac | Held by the Mac | Our pre-step hookNot run live with this tool | Held by the MacNot run live with this tool |
| Changes to files marked never change | Held by the MacNot run live with this tool | Our pre-step hook | The tool's own settingNot run live with this tool | Our pre-step hook |
| Reading files marked never change (secrets) | Our pre-step hookNot run live with this tool | Our pre-step hook | The tool's own settingNot run live with this tool | Our pre-step hook |
| Changes inside the copy but outside may change | Caught at the check | Caught at the check | Caught at the check | Caught at the check |
| Network from terminal commands | Held by the Mac | Held by the Mac | Not held | Held by the MacNot run live with this tool |
| The agent's own web tools | The tool's own setting | The tool's own setting | Not held | The tool's own settingNot run live with this tool |
| Tool servers (MCP) listed by the project | The tool's own setting | The tool's own setting | Our pre-step hookNot run live with this tool | The tool's own settingNot run live with this tool |
| The project's own agent settings and hooks | The tool's own setting | The tool's own setting | Not held | Not held |
| Changes to locked tests | Our pre-step hook | Our pre-step hook | Our pre-step hookNot run live with this tool | Our pre-step hook |
| Background jobs, login items and scheduled tasks | The tool's own settingNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool |
| The keychain (saved passwords) | The tool's own settingNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool |
| Opening apps, links or windows on the screen | The tool's own settingNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool |
| The clipboard (what the person copied) | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool | Our pre-step hookNot run live with this tool |
| Writes into iCloud, Dropbox, Google Drive or OneDrive | The tool's own settingNot run live with this tool | Held by the MacNot run live with this tool | Not held | Held by the MacNot run live with this tool |
| Outcomes listed under must never happen | Caught at the check | Caught at the check | Caught at the check | Caught at the check |
| Success checks | Caught at the check | Caught at the check | Caught at the check | Caught at the check |