garrickCAUTION
An AI chief of staff for knowledge work: remembers your work and knows whose confidences you hold. Runs on Claude Code or Codex, in files you own.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://github.com/iamvenuti/garrick/actions/workflows/tests.yml) [](LICENSE)
Garrick remembers your work and knows whose confidences you hold.
An AI chief of staff for your knowledge work, running on the agent you already use. Everything stays in files you own.
Underneath, Claude Code or Codex does the work, in its desktop app or a terminal. Ask Garrick to file a conversation, prepare a brief or close a session. It keeps the record in plain folders on your Mac, so the next session picks up from the saved notes, whichever agent runs it.
Your work may involve customers, partners under NDA and internal projects. Garrick records whose information you hold, gives the agent rules for using it, and checks project files for specific signs of information crossing a declared boundary.
https://github.com/user-attachments/assets/7c05ec23-577d-4bf2-9275-81f9b70767cc
The walkthrough, 98 seconds, with captions. Dramatised with fictional data; it illustrates the intended workflow.
Start small
![Start small. Climb when you want to. Level 1, Organise: Claude or Codex in its desktop app and the Garrick folders, for a resume point for every piece of work, meetings and knowledge kept locally, and walls between the parties you declare. Level 2, Feed it: inbox folders, mail alias ingestion and recorder transcripts, so conversations and mail are filed for you. Level 3, Own the interface: Obsidia
2020671123e9OBSERVED · 2026-10-10Install
Commands as the repository documents them. They are shown, not run.
git clone https://github.com/iamvenuti/garrick.git ~/garrick-source
git clone https://github.com/iamvenuti/garrick.git ~/garrick-source
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| claude-desktop | mentioned | |
| codex | mentioned | |
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
--- name: desk description: > Open, close, wrap and bring back the cmux tabs the user works in, one per thread, by voice. Installed with the cmux extra. Use when the user says "open X", "start a session on X", "new tab for X", "close X", "close the X tab", "close for the day", "I'm done for today", "shut everything down", "start the day", "restore my tabs", "bring everything back", "what tabs are open", "new workspace X", or asks to take up where they left off. Where this skill is installed it takes these phrases first; the session in each tab runs the threads skill. --- # Desk One cmux tab per thread, each an assistant session started in that thread's folder and named after it, grouped into one cmux workspace per zone. The `desk` command does the plumbing; you turn what the user says into the right verb. The session in each tab is where the thread's conversation lives, so that session opens and wraps the thread, through the `threads` skill. ```sh desk status # every live assistant tab: workspace, state, folder desk open X --prompt "open X" # X's tab, started on "open X"; an idle tab already there gets the phrase desk open X --agent codex # Codex instead of the default assistant desk close X [--wrap] [--yes] # close X's tab; --wrap has it wrap its thread first desk workspace NAME # a new workspace in cmux's sidebar desk end [--yes] # check nothing is busy, then quit cmux desk shutdown [--yes] # wrap each tab used today, one at a time, then quit cmux desk start # start or restore cmux, resume tabs that came back empty ``` If `desk` is not on the PATH, run `python3 <garrick>/extras/cmux/desk.py` with the same arguments, where `<garrick>` is the Garrick download. ## What the user says | The user says | Run | Then | |---|---|---| | "open X", "start a session on X" | `desk open X --prompt "open X"` | The session in the tab answers in two sentences. Already open: desk brings it forward and sends the phrase only if the tab is idle. Say which tab it was. | | "close X" | `desk close X --wrap`, read it back, then `desk close X --wrap --yes` | X's own session wraps the thread, then the tab closes. | | "close the X tab" | `desk close X`, read it back, then `--yes` | Closes without a wrap. | | "close for the day", "I'm done for today" | `desk shutdown`, read it back, then `desk shutdown --yes` | Each tab used today wraps its own thread, then cmux quits. It ends this session too. | | "shut everything down" | `desk end`, read it back, then `desk end --yes` | Quits without wrapping. Every tab comes back on `start`. | | "start the day", "restore my tabs", "bring everything back" | `desk start` | Read back what came back and anything it did not resume, with the reason. | | "what tabs are open" | `desk status` | Spoken: how many, then the busy ones by name. | | "new workspace X" | `desk workspace X` | | `--yes` and `--force` are the user's to give, never yours. Read the dry run back first, and say everything you need to say before a quit: it lands three seconds after `--yes` and takes this session with it. **"Close X" from X's own tab.** This session is mid-turn while it runs `desk`, so desk refuses to close it. Wrap here with the `threads` skill, then tell the user the tab can be closed. ## Names desk resolves a heard name as the `threads` skill does: an alias from the Aliases table in `System/context.md` (and any in `System/desk.json`), then a thread's name, then "project thread", then a project, a wiki or System, then a part of a name, initials, and a name that sounds close. When it lists several, ask which in one line, naming them. Never pick, and never pick between zones. `open` refuses a folder that holds projects instead of being one: the workspace root, `Zones/`, a zone's folder, `Wikis/`. A session there reaches every project below it. The root opens only when named by its full path, for work that files into every zone, such as processing the inboxes. `close` finds an open tab by its whole name or folder, or by a part of one at least four letters long that no other tab shares. When it refuses a short or shared part, ask which tab in one line. ## Busy, idle and unknown A tab's state is read from its assistant's transcript, never from its title: Claude Code ends a turn with a `turn_duration` or `stop_hook_summary` record (`local_command` for a slash command), Codex with `task_complete` or `turn_aborted` for the same turn. A tab whose transcript is missing or unreadable is `?`. - `close` refuses a tab that is busy or `?`, and closes nothing when it does. - `shutdown` refuses while any tab is busy or `?`. With `--yes` it wraps one tab at a time, because wraps write shared files. Each wrap has 90 seconds to start and 15 minutes to finish; one that does not stops the shutdown with cmux still running, and a notification says which tab. - Each tab is checked again the moment its wrap is sent. One that has started a turn since, or stopped on a question, gets nothing typed into it: the wrap's Enter would answer the question. `shutdown` wraps the rest, then stops with cmux still running and names the tab; `close --wrap` leaves it open. After the wraps, the commands under `before_quit` in `System/desk.json` run, in order, from the workspace root, such as a backup. Progress goes to `desk-shutdown.log` in the jobs folder. - `end` refuses a busy or `?` tab unless the user says `--force`. ## Bringing tabs back Quitting keeps every tab in cmux's restore set; closing one takes it out. cmux does not always bring the assistant back inside a tab, so every quit writes `desk-snapshot.json` in the jobs folder: which session sat in which tab. `start` waits until cmux has stopped reopening sessions, then types the assistant's own resume command into each recorded tab that came back at a bare prompt. It types only into a tab that this `start` brought back, by launching cmux or
Trust audit
CAUTIONgrade B · trust 82/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (5 observation(s))
- Network
- declared (2 observation(s))
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (22)
lines = text.lstrip("").splitlines()if text.startswith(""):if text.startswith(""):sent = hashlib.sha1(listing.encode("utf-8")).hexdigest()return agent().jobs_dir() / ("ask-%s.sock" % hashlib.sha1(str(ws).encode("utf-8")).hexdigest()[:8])return hashlib.sha1(line.rstrip().encode("utf-8")).hexdigest()[:16]WS="${GARRICK_WORKSPACE:-$(cd "$HERE/../../.." && pwd)}""python3 ../../System/tools/check.py --staged --walls-only" % zone)
+ "\n[call](../../../Wikis/Meetings/wiki/sources/260312-birch-kickoff.md)\n")
write(self.work / "AGENTS.md", "# Work\n\nSee `../../System/rules.md`.\n")
write(self.acme / "Notes.md", "See [plan](../../Personal/Garden/Plan.md).\n")
src: url(data:font/woff2;base64,d09GMgABAAAAAAaAABIAAAAADMwAAAYdAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoBmA/U1RBVIEgJx4AdC9MEQgKhGSEAAsgADCDOgE2AiQDOgQgBYdGB4EUGw8LIxEmZHIexT8PYyJTH6s540K0vrtCWaIRpUzR
src: url(data:font/woff2;base64,d09GMgABAAAAACK8ABIAAAAARmAAACJTAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoE1G4JgHIFaBmA/U1RBVIEgJx4AgkwvTBEICrporgMLggoAMKw6ATYCJAOEBAQgBYdGB4kHG7Q9RQdy2DiAAS7vZkS1alhU/18T1Iqx
src: url(data:font/woff2;base64,d09GMgABAAAAABqQABIAAAAANggAABopAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGnwbHhyBWgZgP1NUQVSBICceAIFiL0wRCAqrfKMTC4FmADCgXAE2AiQDg0QEIAWHRgeHQRt7L1UHctg4AONHDw/J/98StCEx8OvQuaoS
src: url(data:font/woff2;base64,d09GMgABAAAAABbwABIAAAAAP8wAABaJAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoEYG4YcHIIWBmA/U1RBVIEgJx4AgwQvTBEICrBAp3ILgjgAMKEmATYCJAOEKAQgBYdGB4xOGw05JeOYFbBxAJizfwap/v9LAidj5+rg
src: url(data:font/woff2;base64,d09GMgABAAAAAC1MABIAAAAAdAQAACzjAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoJLG4ouHIM+BmA/U1RBVIEgJx4AhTovTBEICuBkzjkLhAwAMMVKATYCJAOIEgQgBYdGB5FVG4xnNXjTMeV2EEi463Muilo1Semz//9z
expect(atob(markCells()).length).toBe(6 * 3 * 3 * 4)
const bytes = Uint8Array.from(atob(markCells()), (c) => c.charCodeAt(0))
p = write(Path(tmp) / "a.md", "---\ntype: project\n---\n")
1. In cmux, open **Settings › Automation**, set socket access to password, and set a password.
- The sign-in check asks the assistant whether it is signed in (`claude auth status`, `codex login status`), with no model call. A scheduled job's access to the login keychain can fail now and then; t
- Refer to a secret by where it is stored, never by its value. Do not open a credential file unless that is the task.
Gates applied: no_behavioural_pass.
2020671123e9full audit observations/trust-audit/skill/iamvenuti__garrick.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-10 | 2020671123e9 | CAUTION | B | 82 | first audit |
Questions
What does the garrick skill do?
An AI chief of staff for knowledge work: remembers your work and knows whose confidences you hold. Runs on Claude Code or Codex, in files you own.
Is garrick safe to install?
With care. The audit graded it B (82/100) and found 22 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can garrick access on my machine?
The audit observed that it reaches the network and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: none found.
Which assistants does garrick work with?
Its documentation mentions claude-code, claude-desktop, codex and cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (2020671123e9), read on 2026-10-10. The repository is watched, and a new audit runs when it changes — this is the first audit.