Transparency
Effective October 26, 2026.
Code Maverick is built on a simple promise: candidates should know exactly what is captured during an interview, why it is captured, and what is not. The sync client is interview-scoped and inspectable.
This document is the source of truth for what the Code Maverick sync client does and does not do. If the product ever contradicts this document, this document is the contract. The Privacy Policy at codemaverick.dev/privacy explains who is responsible for the data once it is captured.
What we capture
When you run npx code-maverick@alpha join <interview-public-id> from your exercise directory, the client captures:
- File contents for files inside the directory you ran the command in, when those files change.
- File path and content hash for each synced file, so the interviewer can see what changed.
- Sync events: when the connection starts, when it disconnects, when files are updated, when files are deleted, and when sync errors occur.
- A periodic heartbeat (every 10 seconds) so the interviewer can see whether your sync client is currently connected.
- Your name and email, which you provide on the candidate page before downloading the interview package. They are matched against what the interviewer entered when planning the interview.
- AI Provenance, when supported by the candidate's local tools: attribution metadata such as line ranges, tools, models, prompt counts, and related contribution statistics.
- Prompt Evidence, when supported by the candidate's local tools: prompt and message content tied to AI-assisted work in the interview.
That's it. Everything captured is interview-scoped, and the sortie packet reports the AI Usage Policy and supported AI capture behavior for that interview.
Local processing state
To compute diffs, line ranges, and AI Provenance, the client may create a temporary local Maverick Provenance Ledger under the Code Maverick state directory:
- macOS:
~/Library/Application Support/Code Maverick - Windows:
%LOCALAPPDATA%\Code Maverick - Linux:
${XDG_STATE_HOME:-~/.local/state}/code-maverick
CODE_MAVERICK_STATE_DIR can override this location.
The ledger mirrors eligible interview files while the client is running. It is Code Maverick processing state, not Candidate git history, and it is not created inside the Sortie Packet. Beside it sit the capture spool (what the AI tool hooks recorded) and a small capture-health journal. Once the server confirms an upload of AI tool activity and the turn records built from it, the client rewrites the spool: prompts, replies, and tool-call inputs and outputs it already uploaded are removed, and only the edit facts the attributor still needs (which file, which tool call, when, the edit text) stay until the sortie ends. When the sortie ends, the client deletes all of it once the server has confirmed every file change, the final AI labels, every batch of AI tool activity and every turn record. For an hour after the sortie ends, the server still accepts those final uploads from this client, and nothing else: it never lets a final label overwrite one it already settled. If something wasn't confirmed, it keeps the data and tells you; the next connect or code-maverick cleanup finishes the upload first. If the client wasn't running when the sortie ended, the next join, connect or doctor run cleans up after it, and stops retrying after that hour. Ending one sortie never removes another sortie's data or the hooks another sortie still needs. Code Maverick remembers which exercise folders you ran doctor in, and the hooks stay until the last of those interviews ends, whenever you installed them.
AI tool hooks
code-maverick doctor asks which AI tools you'll use. For each one you pick and say yes to, it installs a hook so the tool tells Code Maverick what it did. Before it changes any file of yours, it saves a copy so the file can be put back byte for byte. All Code Maverick's own files (hook scripts, install records, saved copies) live in the Code Maverick state directory, never in the exercise folder.
The hooks write nothing unless a sortie is running for a folder that is, or sits inside, the session's working folder. A session started in the exercise folder is captured in full. A session started in a parent of the exercise folder (or anywhere else) can also do unrelated work, so for that session only the turns that touch the exercise folder count: a turn that edits a file inside it, or runs a shell command that names it. Its other turns are dropped before upload: their prompts, replies, tool calls and activity never leave your machine, they don't affect AI labels, and the client deletes them from the spool once the turn is over.
What each tool gets:
- Claude Code: a user-level Claude Code plugin, added with Claude Code's own
claude plugincommand, which copies it into~/.claude/plugins/cacheand records it in~/.claude/settings.json,plugins/installed_plugins.jsonandplugins/known_marketplaces.json(all under$CLAUDE_CONFIG_DIRif set). If the plugin install fails, hook entries in~/.claude/settings.jsoninstead. - Codex:
[[hooks.*]]entries appended to~/.codex/config.toml(or$CODEX_HOME/config.toml), plus the trust records Codex needs before it will run them, written into the same file using the hook hashes Codex's owncodex app-serverreports. The rest of the file isn't touched. - GitHub Copilot: one file of our own,
~/.copilot/hooks/code-maverick.json(or under$COPILOT_HOME). Copilot CLI and the VS Code Copilot agent both load it. - Cursor: Code Maverick's entries added to
~/.cursor/hooks.json. Your other hooks stay as they are. - Grok Build: one file of our own,
~/.grok/hooks/code-maverick.json(or under$GROK_HOME). Grok only runs it in a folder you've trusted; doctor checks Grok's trust list and asks you to open Grok once in the exercise folder, but never edits that list itself. - OpenCode: one plugin file,
~/.config/opencode/plugins/code-maverick.js(or under$XDG_CONFIG_HOME). Doctor won't overwrite a file at that path it didn't write.
When a turn ends, the hook reads that turn's token usage and model from the tool's own records: Claude Code's session transcript, the Codex rollout file, Copilot's session-state events file (which also gives the reply), grok usage for Grok, and the usage OpenCode and Cursor pass to the hook. Under the Traditional policy, usage and replies never leave your machine.
The exercise folder ships CLAUDE.md and AGENTS.md telling AI agents this is an interview folder. Those two files, at the folder root, are not synced while they still match what Code Maverick shipped. Once you edit one, it syncs like any other file, because it steers the AI and the interviewer sees what the AI was told.
Session metadata the client reads
While the client runs, it also checks each tool's local session store for a session in the exercise folder that the hooks missed. It reads metadata only, never prompts, replies or code:
- Claude Code: session id, working folder and timestamps from
~/.claude/projects. - Codex: the
session_metaline at the top of each recent rollout file under~/.codex/sessions(session id, working folder, start time, which Codex app started it), plus the file's last-modified time. - GitHub Copilot: the
id,cwdandcreated_atfields of eachworkspace.yamlunder~/.copilot/session-state, plus when that session's files last changed. - Cursor: the names of the conversation folders under
~/.cursor/projects/<exercise folder>/agent-transcripts, and when the files in them were created and last changed. It doesn't open those files. - Grok Build: the session folder names under
~/.grok/sessions, the working folder recorded in each group's.cwdfile (or its folder name), and when each session's activity file last changed. It doesn't open the activity file. - OpenCode: the session id, working folder and created and updated times from the session tables of OpenCode's databases (
opencode.db, anyopencode-*.db, or the one$OPENCODE_DBnames), opened read-only.
A session it finds this way, with no matching hook events, marks that tool's capture as missing a session for the time it was active. The interviewer sees that, not what the session did.
Removing hooks and local data
Everything Code Maverick installed or stored is removed automatically when the interview ends. To remove it yourself at any time, run npx code-maverick cleanup. For every tool above it removes the hooks, plugin and hook files, and puts back each file it edited: if nothing changed it since, the saved copy goes back byte for byte; if you or the tool changed it, cleanup cuts out only Code Maverick's entries (for Codex, that includes only the trust records it added), checks the result, and leaves any file it can't parse or verify alone, telling you which. A file Code Maverick created, it deletes. It also deletes ledgers, spools, markers, probes, cached runtimes and your AI tool picks, and prints exactly what it removed. It asks first if a sortie is still live or if the server hasn't confirmed some captured data (--yes skips the questions). It never deletes your exercise folders unless you pass --include-packets and confirm in the terminal, even with --yes, and it only deletes a folder that still holds that interview's .maverick/session.json. If CODE_MAVERICK_STATE_DIR points at a folder Code Maverick didn't create, cleanup removes nothing there.
Setup check
Before an interview, code-maverick doctor may create and delete a local probe ledger under the same state directory to verify that sync, diffing, and supported AI attribution can work. The probe uses synthetic files, not the exercise contents. The setup report it uploads carries health and status metadata, not raw agent hook payloads: the operating system, the versions of Node, git, and the attribution tooling, the absolute paths of the exercise folder and the state directory, which usually include your local username, whether Cursor, Claude Code and Codex have a configuration folder in your home directory (even if you didn't pick them), and, for each AI tool you picked, its version and whether its hooks are in place, so the interviewer knows whether attribution can work.
AI tooling policy
Each interview has an interviewer-selected AI Usage Policy:
- AI-Native: AI tooling is allowed and encouraged for this interview. Supported AI metadata and Prompt Evidence may be captured so the Evaluator can understand how the Candidate worked.
- Traditional: AI tooling is not allowed for this interview. If supported AI tooling is used anyway, AI Provenance may be captured and reviewed: which lines AI changed, the tool, model, timing, and turn count. Prompt Evidence is not captured. Prompt text, assistant replies, tool-call arguments and results, and token usage never leave the Candidate's machine, and the server discards them if they arrive.
The candidate page and sortie packet should show the active AI Usage Policy before the candidate downloads the packet or starts the sync client.
What we do not capture
The sync client does not capture:
- Keystrokes
- Clipboard contents
- Screen recordings
- Browser history
- Private AI prompts outside the watched interview project or made with tools that AI provenance capture does not support
- Editor telemetry
- Files outside the watched exercise directory
- Environment secret files (
.env,.env.local,.env.*.local,*.pem,*.key) - Any process or activity unrelated to the watched directory
The client does not run as a background daemon. It only runs while you have it running, and it stops automatically when the interview ends.
Skipped files and directories
The following are skipped from sync by default and never uploaded:
- Directories:
node_modules,.git,.claude,.cursor,.vscode,.maverick,.code-maverick,dist,build,coverage,logs,tmp,temp,test-results,playwright-report,.playwright,.nyc_output,.next,.turbo - Files:
.env,.env.local,.env.*.local,*.pem,*.key,*.log,.DS_Store,Thumbs.db,Desktop.ini,*.swp,*.swo,*~,.gitignore,.gitattributes,MAVERICK.md, andCLAUDE.mdandAGENTS.mdat the folder root while they still match what Code Maverick shipped
.env.example is intentionally not skipped. It is treated as a starter template file.
Where data goes
Synced file content and metadata are sent to the Code Maverick backend, hosted on Convex in the United States, where the interviewer can view them during the live session and review them after the interview ends. The sortie packet names the backend the client will connect to.
Heartbeat and session events
The client sends a small heartbeat every 10 seconds so the interviewer can see your connection status. The heartbeat carries no payload beyond a timestamp.
The client also writes session events for connection lifecycle and file changes. These power the lightweight session timeline the interviewer sees, and they are part of the durable interview record after the interview ends.
Retention and deletion
During the beta, interview data is retained until the Base that owns it deletes it or asks us to. There is no automated retention window: nothing expires on a timer, and nothing is deleted without a person asking for it.
A Base asks us in writing to delete a sortie, naming the sortie and the reason, once it has landed or been aborted; there is no delete button in the app, because the record belongs to the company, not to one interviewer. Deleting a sortie removes everything recorded under it: the session record itself, the candidate's name and email, the flight log and every sync event, every synced file and its stored contents, AI Provenance and Prompt Evidence attached to those files, the sortie's starter-file list, setup preflight reports, the evaluator's assessment, connection records, and the candidate's join tokens. Nothing the sortie recorded is kept. There is no archive, soft delete, or recovery window. One row survives, visible to the Base in its Sortie Archive: the sortie's callsign, the exercise name, whether a debrief had been submitted, and when it was removed. It holds nothing about you, and exists so a deletion cannot erase the fact that the interview happened. Two things sit outside that record. The exercise's own loadout bytes stay, because the starter files a sortie hands out are the exercise's files, shared with every other sortie flown from that exercise; they are the hiring company's content, not the candidate's, and they go when the exercise's Base goes. And a file upload the sync client started but never finished reporting (the sortie landed mid-sync, or the report failed a size or hash check) is bytes nothing points at: the record never references it, no one can look it up, and deleting the sortie does not find it.
A Base can also ask us to delete the whole Base. That removes every sortie as above, plus the Base's exercises and their files (loadout bytes included), squadrons and their settings, memberships, and the Base record. Member accounts (name, email, callsign) stay, because an account can belong to more than one Base; an account that belonged only to the deleted Base gets a fresh empty Base on its next sign-in. Removing an account is a separate request: we delete the sign-in identity in WorkOS and our copy of the profile, once the account belongs to no Base.
Candidates do not have accounts with us. A candidate who wants their interview data deleted should ask the company that ran the interview; that company owns the record and is the one who can delete it. If the company asks us to delete it on their behalf, we do.
Waitlist signups are an email address and the page it came from. Email us and we remove the row.
How to inspect the client
The candidate sync client ships as an inspectable npm package. The published bundle is minified, so reading it line by line is hard; what you can do is:
- unpack the published package (
npm pack code-maverick@alpha) and check which hosts it talks to and which files it reads - audit exactly what is sent over the network during an interview
- run
code-maverick doctorbefore joining to see the setup checks, and read the watched directory and ignored folders the client prints when it starts
If something looks wrong, contact the security email below before the interview starts.
Security disclosure
If you find a security or privacy issue, please email security@codemaverick.dev rather than filing a public issue.
Questions
If you are a candidate and have any concerns about what Code Maverick captures, you should be able to ask the interviewing team or contact us directly. The product is intentionally narrow in scope; if it ever feels otherwise, that is a bug we want to know about.