MASON

What the films say, and where it is true

Every claim in the technical walkthrough, with the code it rests on and the test that checks it. Run the tests with cd apprentice && npm test: the file is test/claims.test.mjs.

The film saysWhere it is trueChecked by
Events, not pixels. A native Mac app; Accessibility gives the app, the window title and the prompt. 0 screenshots, 0 keystrokes.The reader is native/ApprenticeReader.swift: it asks macOS Accessibility and nothing else. Each change is stored as an event marked event-not-image in src/collector.mjs. No screen-capture or keyboard API is linked anywhere in native/ or src/.events, not pixels
Refused before it is written. Private apps are refused.The list of refused apps and title words is at the top of src/collector.mjs. The reader turns a refused app away before it looks at the window, and a private title before anything is returned. The count on screen ("refused today") is privateRefusals: counted, never named. Since the films, chat and mail can be kept by name and time when that is switched on in Settings; it is off until asked for, and password managers, banking, health and private windows are never named.refused before it is written; chat and mail are named only when that is switched on in chats.test.mjs
Secrets are redacted.src/redact.mjs runs before an excerpt is stored: mail addresses, passwords, keys, tokens.redacts local secrets before persistence in core.test.mjs
The memory is stored on this Mac.Everything is written under apprentice/data/, set in src/store.mjs, which is not in this repository. The same memory is written as plain Markdown notes in apprentice/wiki/ (src/wiki.mjs), which opens as an Obsidian vault. The server listens on 127.0.0.1 only.the memory is served to this Mac only, and the memory is also a folder of linked Markdown notes in vault.test.mjs
He decides what I see.Go private stops all capture at once (/api/control in src/server.mjs); the island's eye closes. Sound, summaries, the ElevenLabs voice and the name are under Settings (src/settings.mjs).a setting is kept in settings.test.mjs
It waits for the pause. Six seconds still, then ninety seconds quiet.limits() in src/question-engine.mjs: pause 6000 ms, cooldown 90 000 ms, five questions at most in a session.it waits for the pause, and asks a guardrail question only after a pause in core.test.mjs
One memory, every agent. The rules come out of the agent logs.src/projects.mjs reads the Claude Code logs; src/memory.mjs turns a correction given twice into a rule, and keeps it only when the quote is really something that was said.the rules come out of the agent logs
Three ElevenLabs agents.Debrief, tutor and recall in src/agent.mjs, each with its own prompt and tools.three ElevenLabs agents
MCP.src/mcp-handler.mjs: eight tools, among them how_was_it_built, guardrails_for_agents and check_decision.mcp.test.mjs, three tests
Work today in per cent.aggregateActivity in src/activity.mjs: work, social and other always sum to 100; idle time over a minute is left out; time inside a project counts as work.The activity tests in core.test.mjs

What it cannot do yet

The film says these too. They are true.

The film saysIn the code
Mac only.The reader and the island are Swift, AppKit and macOS Accessibility.
Claude Code logs only.src/projects.mjs reads ~/.claude/projects. Cursor gives a project its time, not its memory. Chats in ChatGPT or on claude.ai are not on disk and are not read.
The voice is in the cloud.Speech, the calls and dictation go to ElevenLabs (src/voice.mjs, src/agent.mjs). Summaries go through the Claude CLI on your own login (src/llm.mjs). The memory itself stays on the Mac. Both can be switched off in Settings (src/settings.mjs); then nothing leaves it.
It does not ask in the background yet.Off by default in src/store.mjs: questions are asked only inside a capture session.

Every jump, every decision

TodayNext
Every jump between appsEach change of app, window and project is an event, and moves between projects are counted (src/projects.mjs). In a session a move can be asked about (rankSwitch).The same in the background, at a real pause.
Every decisionDecisions and rules are kept from the debrief call, from live answers and from corrections repeated to agents.A decision it has not seen before is noticed and asked about once.
Saying how it was builtThe recall call asks what you remember and fills in what you left out; how_was_it_built gives the same memory to any agent.The memory follows the project, not the Mac.

Since the films

Added after the submission, which is the tag hack-nation-7.

WhatWhereChecked by
Built. Mason asks its owner about their own projects, one question at a time, and holds the answer: how it is put together, what was decided, what was built last, where it was left.src/built.mjs, from what is remembered of each project; the memory now also keeps the decisions that were made (src/memory.mjs). No model is asked when a question is shown.built.test.mjs, two tests
The look back. After three days of real work, how it was done: what followed a prompt, how long finished answers waited, the pace. Nothing is asked for and no aim is declared.lookBack in src/coach.mjs, written by src/days.mjs and kept as it was. An answer is finished when the agent's log says the turn ended (absorb in src/projects.mjs); it waits until an app where answers are read is in front again.coach.test.mjs, three tests; turns.test.mjs; a look back is due after three finished days in days.test.mjs
Proposals. A rule said in several projects is proposed for every agent, with the words it rests on.src/suggest.mjs. The model only says which rules belong together; the evidence is the quotes themselves. Mason writes the rule nowhere: it hands it to an agent as a prompt its owner reads and sends, and a rule about publishing or deleting without asking is never proposed.suggest.test.mjs, four tests
Flow. How a day moved between tools: the jumps, the habits between two tools, the longest unbroken stretch.src/flow.mjs. A glance under five seconds, a pause in the same tool and a break of fifteen minutes are not jumps. A tool in a browser is known by the site of the front tab: the reader gives its host and nothing more of the address (native/ApprenticeReader.swift).flow.test.mjs, five tests; a browser tab is kept with the host of its site in chats.test.mjs
A picture to share. The flow of a day or a week as one picture, with only the names of tools on it.Drawn in the window, written by src/share.mjs beside the memory. Mason posts nothing.share.test.mjs
Logos from the web. A site's own icon, asked for once, only when switched on.src/site-icons.mjs: public names over https only, redirects followed by hand, pictures only.site-icons.test.mjs, seventeen tests; site-logos.test.mjs
Days. Every day worked and its projects, back to the first day of each.src/days.mjs, from the agents' logs, kept in data/days.json so the days outlast the logs.days.test.mjs, three tests
Any model. The summaries can be written by any model, one on the Mac included.src/llm.mjsllm.test.mjs, two tests
A switch on everything read and sent.Agent logs, chat and mail by name, summaries and ElevenLabs in src/settings.mjs.settings.test.mjs, three tests
The tools' own icons.native/MasonIcons.swift asks macOS for an app's icon by its name and reads nothing else.

The numbers on screen in the film (87% work, 50 refused) were read from the running app on 4 October 2026 at 14:35. They are that day's own data and are not in this repository.