codebot (CLI)workstation (CLI)burrow, planted (CLI)technicians app (UI)

Does screen-decomposition work?

Partly green. screen-decomposition does what it was cut out to do on most lines, and cli-engineer did not get worse by losing those principles. But two lines are not green for any arm, and on the UI one line is still weak. Better than today's skills: - Short top screen: 5/5 on every case (today: 3/5 on workstation, 4/5 on burrow). - Leaves out what the owner abandoned (the UI's Leads): 5/5 (today's minimal-ux-flow: 2/5). The first draft got 0/5 because "list every thing" pulled the Leads screens in; the final text says the map is for the scenario's user, not the code. - No repeated lines across screens: 5/5 on codebot and the UI, 4/5 on burrow (the first draft got 1/5 on burrow). - Recall went up a little on every CLI case (codebot 0.46 to 0.51, workstation 0.71 to 0.82, burrow 0.87 to 0.88). No worse (cli-engineer without its principles still holds them): verb first, where-and-what on every screen, own words, and asking before a split are as good as today's on all three CLI cases. Not green: - Recall stays under the 90% line for every arm on codebot and workstation. The line may be too high for one pass over a 20k-token dump; the misses are listed per run. - Grouping does not match yours better than today's skills (codebot 0.45 vs 0.48, workstation 0.28 vs 0.36). No arm groups the way you did. - UI, verb first: 1/5. In 4 runs the map went down to form fields ("the client's name") with noun lines. The first draft got 5/5, so this varies from run to run. - Asking before a split doesn't separate the arms: every arm asked about the 25 scripts in every run.
CaseArmParsedP1
Recall
P2
Nothing invented
P3
Where and what
P4
Verb first
P5
Short top
P6
Own words
P7
Splits asked
P8
Worded per screen
P9
Grouping (ARI)
codebot (CLI)No skill5/50/51/55/50/50/55/53/50.35 avg
codebot (CLI)Today's skills5/50/51/55/55/55/55/55/50.48 avg
codebot (CLI)screen-decomposition, first draft5/50/53/55/54/55/55/54/50.33 avg
codebot (CLI)screen-decomposition, final5/50/54/55/55/55/55/55/50.45 avg
workstation (CLI)No skill5/50/54/55/50/51/55/54/50.25 avg
workstation (CLI)Today's skills5/50/54/55/55/53/55/55/50.36 avg
workstation (CLI)screen-decomposition, first draft5/51/55/55/55/55/55/55/50.30 avg
workstation (CLI)screen-decomposition, final5/51/55/55/55/55/55/55/50.28 avg
burrow, planted (CLI)No skill5/50/53/55/50/52/55/55/54/5
burrow, planted (CLI)Today's skills5/51/55/55/55/54/55/55/53/5
burrow, planted (CLI)screen-decomposition, first draft5/54/55/55/55/55/55/55/51/5
burrow, planted (CLI)screen-decomposition, final5/52/55/55/55/55/55/55/54/5
technicians app (UI)No skill5/55/54/55/50/55/54/52/5
technicians app (UI)Today's skills5/55/52/55/50/55/55/53/5
technicians app (UI)screen-decomposition, first draft5/55/50/55/55/55/54/53/5
technicians app (UI)screen-decomposition, final5/55/55/55/51/55/55/55/5

Each cell: runs that passed the line, out of all runs (P9: the average agreement with your approved grouping, 1 is the same). Hover a badge for what failed. Pass lines: source/design.md.

codebot (CLI)

The approved map (ground truth)
Everything you reach for to run CodeBot on this machine, in 8 groups.
Live CodeBot`codebot live`Prints the live screen: your own CodeBot, the one your phone connects to, and how to check and deploy it.
QA CodeBot`codebot qa`Prints the QA screen: the throwaway CodeBot on port 3506 where every change is tried before it reaches you.
Scripts`codebot scripts`Lists CodeBot's npm scripts (check, build, reviews), each runnable from any folder.
Code`codebot code`Prints the code screen: where the service, web app, contracts, account service and ops are.
Guests`codebot guests`Prints the guests screen: the other people's CodeBots on this machine and how to update or invite them.
Sign-in service`codebot sign-in`Prints the sign-in screen: the shared account service (Supabase) every CodeBot signs in through.
Data and settings`codebot data`Prints the data screen: where your Bots' data, the database, the settings and the builds are.
Docs`codebot docs`Prints the docs screen: what CodeBot does, how it is built, your rulings and the runbook.
live
Your own CodeBot (codebot.service, port 3505): the one your phone and desktop connect to.
Statecodebot.service: active since Mon 2026-10-26 04:10:04 ISTShows whether it is running, and since when
Addresshttps://liel.tail18e69e.ts.net/Opens it in the browser, as your phone and desktop do (tailnet only)
Status`codebot live status` (or `codebot status`)Prints systemd's full status of the service
Log`codebot live logs` (or `codebot logs`; `-f` follows)Prints its last 80 log lines
Deploy`codebot live deploy` (or `codebot deploy`)Deploys: push, build, restart and check ([ops/deploy.sh](/home/liel/projects/codebot/ops/deploy.sh)); refuses while a Bot is working
Owner key`ownerkey`Opens the folder with the entrance key a new device types once
Terminal brokercodebot-terminal-broker.service, [ops/codebot-terminal-broker.service](/home/liel/projects/codebot/ops/codebot-terminal-broker.service)Opens the unit of the optional terminal for your Bots, kept apart from codebot.service
Runbook[ops/OPERATIONS.md](/home/liel/projects/codebot/ops/OPERATIONS.md)Opens the runbook: install, back up, restore, emergency stop, change the address
qa
The throwaway CodeBot on port 3506 (codebot-integration.service): every check of a change runs here, never on yours.
Statecodebot-integration.service: inactiveShows whether it is running
Addresshttp://127.0.0.1:3506/Opens it in the browser on this machine
Build for it`codebot qa build`Builds the web app it serves (npm run build:integration), apart from yours
Start, stop, restart`codebot qa start`, `codebot qa stop`, `codebot qa restart`Starts, stops or restarts the QA service
Status, log`codebot qa status`, `codebot qa logs` (`-f` follows)Prints what systemd and its log say
Schedule drills`codebot qa drill [name]`Runs the live schedule drills ([ops/review/schedule-drill.mjs](/home/liel/projects/codebot/ops/review/schedule-drill.mjs)); `codebot qa drill help` lists them
Terminal-tabs stack`codebot qa terminal-tabs start`, `stop`, `status`Starts, stops or checks its own broker and tmux for the terminal-tabs checks ([ops/review/terminal-tabs-stack.sh](/home/liel/projects/codebot/ops/review/terminal-tabs-stack.sh))
Its data[.data/integration/](/home/liel/projects/codebot/.data/integration)Opens its own database folder, apart from yours
scripts
CodeBot's npm scripts, read from package.json; codebot run <script> runs one in the checkout with Node 24, from any folder.
ScriptWhat it runsWhat it's for
dev`tsx watch apps/service/src/main.ts`Starts the service with reload while you edit (not the installed service)
build`tsc --noEmit && node ops/build.mjs`Builds the web app you are served, after the type check (deploy runs it)
start`cross-env NODE_ENV=production tsx apps/service/src/main.ts`Starts the service in production mode by hand (the installed service does this)
typecheck`tsc --noEmit`Runs the type check only
setup-account`tsx ops/setup-account.ts`Links a CodeBot to a Google account (ops/OPERATIONS.md)
test`node --import tsx --test apps/service/test/*.test.ts`Runs the tests only
docs:gmail`tsx ops/gmail-reference.ts`Writes docs/automation/gmail-reference.md again
review:gmail`node ops/review/gmail-review.mjs`Runs a look at the Gmail widget in a real browser, with a fake Google
playground`vite --host 127.0.0.1 --open /playground/gmail.html`Starts the design playground: variants side by side (docs/design-method.md)
check`tsc --noEmit && node --import tsx --test apps/service/test/*.test.ts`Runs the type check and every test; run it before you start and before you say done
sync:agents`tsx ops/sync-agents.ts`Writes AGENTS.md again from CLAUDE.md
review:schedules`node ops/review/schedules-review.mjs`Runs a look at the schedule screens on the QA CodeBot
build:integration`tsc --noEmit && node ops/build-integration.mjs`Builds the web app the QA CodeBot serves
code
Where each part of CodeBot's code is, in ~/projects/codebot.
PartFolderWhat it's for
Service[apps/service/](/home/liel/projects/codebot/apps/service)Opens the server: Bots, transcripts, providers, storage, schedules
Web app[apps/web/](/home/liel/projects/codebot/apps/web)Opens the screens you watch and steer Bots from
Control service[apps/control/](/home/liel/projects/codebot/apps/control)Opens the service that issues signed host proofs
Contracts[packages/contracts/](/home/liel/projects/codebot/packages/contracts)Opens the shapes the service and the app agree on
Account service[supabase/](/home/liel/projects/codebot/supabase)Opens the sign-in migrations, functions and config
Ops[ops/](/home/liel/projects/codebot/ops)Opens build, deploy, packaging, the systemd units, guest and family scripts
This command[cli/](/home/liel/projects/codebot/cli), [zsh.d/](/home/liel/projects/codebot/zsh.d)Opens codebot and cb: the script, its tests, and the shell file
Agent hooks[.claude/settings.json](/home/liel/projects/codebot/.claude/settings.json), [ops/agent-start.sh](/home/liel/projects/codebot/ops/agent-start.sh), [ops/deploy-guard.sh](/home/liel/projects/codebot/ops/deploy-guard.sh)Opens what an agent session here runs when it starts, and the check before it stops
Global working mode[ops/install-global.sh](/home/liel/projects/codebot/ops/install-global.sh), [ops/global/](/home/liel/projects/codebot/ops/global)Opens the script that puts the owner's working mode into every agent's instruction files
Bot skills[skills/](/home/liel/projects/codebot/skills)Opens the skills CodeBot's Bots use (codebot-housekeeping)
Intent and tests[.idd/](/home/liel/projects/codebot/.idd), [.bdd/](/home/liel/projects/codebot/.bdd)Opens what each area must do, and its scenarios
Design[design/](/home/liel/projects/codebot/design), [.impeccable/](/home/liel/projects/codebot/.impeccable)Opens the screenshots and annotations the design follows, and design critiques
Build settings[package.json](/home/liel/projects/codebot/package.json), [package-lock.json](/home/liel/projects/codebot/package-lock.json), [tsconfig.json](/home/liel/projects/codebot/tsconfig.json), [vite.config.ts](/home/liel/projects/codebot/vite.config.ts), [.nvmrc](/home/liel/projects/codebot/.nvmrc)Opens the scripts and packages, TypeScript, the web build, the Node version (24)
Git and CI[.gitignore](/home/liel/projects/codebot/.gitignore), [.github/](/home/liel/projects/codebot/.github)Opens what git leaves out, and the check run on every push
Local settings template[.env.example](/home/liel/projects/codebot/.env.example)Opens the account-service settings a new checkout copies to .env
guests
The other people's CodeBots on this machine. They are theirs: these commands touch them only when you run one.
Guest's CodeBotcodebot-guest.service, https://liel.tail18e69e.ts.net:10000, [ops/codebot-guest.service](/home/liel/projects/codebot/ops/codebot-guest.service)Opens the guest's CodeBot: a family member's own, as its own Linux user
Update the guest`codebot guest update`Builds this checkout into /opt/codebot-guest and restarts it ([ops/guest-update.sh](/home/liel/projects/codebot/ops/guest-update.sh))
Invite the guest`codebot guest invite`Prints a one-use Google link, valid ten minutes ([ops/guest-invite.sh](/home/liel/projects/codebot/ops/guest-invite.sh))
Guest status, log`codebot guest status`, `codebot guest logs`Prints what systemd and its log say
Set the guest up (once)`sudo ~/projects/codebot/ops/guest-install.sh`, [ops/guest-install.sh](/home/liel/projects/codebot/ops/guest-install.sh)Sets up the user, service, settings and Tailscale port 10000
Family addresshttps://family.codebot.lielbenor.comOpens the address where anyone on the home Wi-Fi signs in and gets their own CodeBot
Update family`codebot family update`Builds /opt/codebot-family and restarts every family CodeBot ([ops/family-update.sh](/home/liel/projects/codebot/ops/family-update.sh))
Family status, log`codebot family status`, `codebot family logs`Prints what systemd and the log say for the front door and every family CodeBot
Family services[ops/codebot-family-lobby.service](/home/liel/projects/codebot/ops/codebot-family-lobby.service), [ops/codebot-family@.service](/home/liel/projects/codebot/ops/codebot-family@.service)Opens the units of the front door (port 3530) and of one CodeBot per person (port 3540+N)
Family helper`sudo codebot-family add N`, `remove N`, `status`; [/usr/local/sbin/codebot-family](/usr/local/sbin/codebot-family) (source [ops/family-helper.sh](/home/liel/projects/codebot/ops/family-helper.sh))Makes or removes one family CodeBot
Family invite[ops/family-invite.sh](/home/liel/projects/codebot/ops/family-invite.sh)Opens the script behind the setup link `codebot-family add N` prints
Set family up (once)`sudo ~/projects/codebot/ops/family-install.sh`, [ops/family-install.sh](/home/liel/projects/codebot/ops/family-install.sh)Sets up the front door, helper, services and nginx
sign-in
The shared account service every CodeBot signs in through: Supabase project wbgrjvqbupgdclaztuou.
Dashboardhttps://supabase.com/dashboard/project/wbgrjvqbupgdclaztuouOpens the Supabase dashboard: users, the redirect allow list, SQL; sign in as "mobile-coder", not Lebnor
Sign-in entryhttps://liel.tail18e69e.ts.net/onboardingShows the one fixed address every person starts at (CODEBOT_ACCOUNT_ENTRY_URL)
Its code[supabase/](/home/liel/projects/codebot/supabase)Opens the migrations, functions (host-access, gmail-relay) and config
Deploy a function`SUPABASE_ACCESS_TOKEN="$(cat ~/.config/supabase-codebot-token)" npx supabase functions deploy <name> --project-ref wbgrjvqbupgdclaztuou`Deploys one function; redeploy host-access whenever a contract it parses changes
data
Where your CodeBot keeps its data and settings on this machine; the data folder is read from service.env.
Data[~/.local/share/codebot/](/home/liel/.local/share/codebot)Opens your Bots' conversations, attachments and recordings (CODEBOT_DATA_DIR)
Database[~/.local/share/codebot/codebot.sqlite](/home/liel/.local/share/codebot/codebot.sqlite)Opens the database: everything the service knows; back it up only with the service stopped
Owner key[~/.local/share/codebot/owner-key](/home/liel/.local/share/codebot/owner-key)Opens the entrance key for a new device
Settings[~/.config/codebot/service.env](/home/liel/.config/codebot/service.env)Opens the ports, tokens and sign-in address: private, never print or paste it
Web app settings[apps/web/.env.local](/home/liel/projects/codebot/apps/web/.env.local)Opens the sign-in address built into the web app
Service unit[~/.config/systemd/user/codebot.service](/home/liel/.config/systemd/user/codebot.service) (source [ops/codebot.service](/home/liel/projects/codebot/ops/codebot.service))Opens how systemd runs it
Served web build[dist/web/](/home/liel/projects/codebot/dist/web)Opens the release you are served now
QA data[.data/integration/](/home/liel/projects/codebot/.data/integration)Opens the QA CodeBot's data
Backups[~/.local/share/codebot-backups/](/home/liel/.local/share/codebot-backups)Opens where the backup steps in ops/OPERATIONS.md write
docs
What CodeBot does, how it is built, and the rules and rulings every change follows.
DocFileWhat it's for
Rules for agents[CLAUDE.md](/home/liel/projects/codebot/CLAUDE.md), [AGENTS.md](/home/liel/projects/codebot/AGENTS.md)Opens how CodeBot is used, the decisions made, designing screens, deploying (AGENTS.md is a copy)
Readme[README.md](/home/liel/projects/codebot/README.md)Opens the layout and commands
Product spec[PRODUCT-SPEC.md](/home/liel/projects/codebot/PRODUCT-SPEC.md)Opens the product spec: how it must behave
Architecture[ARCHITECTURE.md](/home/liel/projects/codebot/ARCHITECTURE.md)Opens how it is built
Runbook[ops/OPERATIONS.md](/home/liel/projects/codebot/ops/OPERATIONS.md)Opens the runbook: running, updating, guests, family, backup, restore
Owner's design rulings[docs/design-taste.md](/home/liel/projects/codebot/docs/design-taste.md)Opens what you liked and rejected
Design method[docs/design-method.md](/home/liel/projects/codebot/docs/design-method.md)Opens how a screen is designed
Agentic development[docs/agentic-development.md](/home/liel/projects/codebot/docs/agentic-development.md)Opens how agents work in this repo
Objectives[docs/objectives/](/home/liel/projects/codebot/docs/objectives)Opens what each area is for and how it is checked
Plans[docs/plans/](/home/liel/projects/codebot/docs/plans), [.plans/](/home/liel/projects/codebot/.plans), [docs/superpowers/](/home/liel/projects/codebot/docs/superpowers)Opens the earlier and current plans
Open work[DEFERRED-WORK.md](/home/liel/projects/codebot/DEFERRED-WORK.md), [docs/tasks/](/home/liel/projects/codebot/docs/tasks)Opens what is left
Where it stopped[IMPLEMENTATION-STATUS.md](/home/liel/projects/codebot/IMPLEMENTATION-STATUS.md), [IMPLEMENTATION-ROADMAP.md](/home/liel/projects/codebot/IMPLEMENTATION-ROADMAP.md), [MASTER-PLAN.md](/home/liel/projects/codebot/MASTER-PLAN.md)Opens the beta's status and release scope
Gmail for Bots[docs/automation/](/home/liel/projects/codebot/docs/automation)Opens the supervisor guide and its generated reference
Avatars[MODULAR-AVATARS.md](/home/liel/projects/codebot/MODULAR-AVATARS.md)Opens how Bot avatars are built and were checked
Onboarding[docs/onboarding-implementation.md](/home/liel/projects/codebot/docs/onboarding-implementation.md), [docs/onboarding-review-gate.md](/home/liel/projects/codebot/docs/onboarding-review-gate.md), [docs/onboarding-recorded-proof-2026-09-14.md](/home/liel/projects/codebot/docs/onboarding-recorded-proof-2026-09-14.md)Opens how signing up works, and its recorded proof
Hosting and sign-in[docs/self-hosting-practices.md](/home/liel/projects/codebot/docs/self-hosting-practices.md), [docs/host-account-exchange.md](/home/liel/projects/codebot/docs/host-account-exchange.md)Opens how a server is hosted and how a person arrives at it
Verification records[docs/verification/](/home/liel/projects/codebot/docs/verification), [docs/ai-readiness-verification.md](/home/liel/projects/codebot/docs/ai-readiness-verification.md), [docs/images/](/home/liel/projects/codebot/docs/images)Opens the recorded checks and the pictures they refer to

Home

Everything you reach for to run CodeBot on this machine, in 8 groups.

Live CodeBotPrints the live screen: your own CodeBot, the one your phone connects to, and how to check and deploy it.
›
QA CodeBotPrints the QA screen: the throwaway CodeBot on port 3506 where every change is tried before it reaches you.
›
ScriptsLists CodeBot's npm scripts (check, build, reviews), each runnable from any folder.
›
CodePrints the code screen: where the service, web app, contracts, account service and ops are.
›
GuestsPrints the guests screen: the other people's CodeBots on this machine and how to update or invite them.
›
Sign-in servicePrints the sign-in screen: the shared account service (Supabase) every CodeBot signs in through.
›
Data and settingsPrints the data screen: where your Bots' data, the database, the settings and the builds are.
›
DocsPrints the docs screen: what CodeBot does, how it is built, your rulings and the runbook.
›
‹ Home

live

Your own CodeBot (codebot.service, port 3505): the one your phone and desktop connect to.

StateShows whether it is running, and since when
›
AddressOpens it in the browser, as your phone and desktop do (tailnet only)
›
StatusPrints systemd's full status of the service
›
LogPrints its last 80 log lines
›
DeployDeploys: push, build, restart and check ([ops/deploy.sh](/home/liel/projects/codebot/ops/deploy.sh)); refuses while a Bot is working
›
Owner keyOpens the folder with the entrance key a new device types once
›
Terminal brokerOpens the unit of the optional terminal for your Bots, kept apart from codebot.service
›
RunbookOpens the runbook: install, back up, restore, emergency stop, change the address
›
‹ Home

qa

The throwaway CodeBot on port 3506 (codebot-integration.service): every check of a change runs here, never on yours.

StateShows whether it is running
›
AddressOpens it in the browser on this machine
›
Build for itBuilds the web app it serves (npm run build:integration), apart from yours
›
Start, stop, restartStarts, stops or restarts the QA service
›
Status, logPrints what systemd and its log say
›
Schedule drillsRuns the live schedule drills ([ops/review/schedule-drill.mjs](/home/liel/projects/codebot/ops/review/schedule-drill.mjs)); `codebot qa drill help` lists them
›
Terminal-tabs stackStarts, stops or checks its own broker and tmux for the terminal-tabs checks ([ops/review/terminal-tabs-stack.sh](/home/liel/projects/codebot/ops/review/terminal-tabs-stack.sh))
›
Its dataOpens its own database folder, apart from yours
›
‹ Home

scripts

CodeBot's npm scripts, read from package.json; codebot run <script> runs one in the checkout with Node 24, from any folder.

ScriptWhat it's for
›
devStarts the service with reload while you edit (not the installed service)
›
buildBuilds the web app you are served, after the type check (deploy runs it)
›
startStarts the service in production mode by hand (the installed service does this)
›
typecheckRuns the type check only
›
setup-accountLinks a CodeBot to a Google account (ops/OPERATIONS.md)
›
testRuns the tests only
›
docs:gmailWrites docs/automation/gmail-reference.md again
›
review:gmailRuns a look at the Gmail widget in a real browser, with a fake Google
›
playgroundStarts the design playground: variants side by side (docs/design-method.md)
›
checkRuns the type check and every test; run it before you start and before you say done
›
sync:agentsWrites AGENTS.md again from CLAUDE.md
›
review:schedulesRuns a look at the schedule screens on the QA CodeBot
›
build:integrationBuilds the web app the QA CodeBot serves
›
‹ Home

code

Where each part of CodeBot's code is, in ~/projects/codebot.

PartWhat it's for
›
ServiceOpens the server: Bots, transcripts, providers, storage, schedules
›
Web appOpens the screens you watch and steer Bots from
›
Control serviceOpens the service that issues signed host proofs
›
ContractsOpens the shapes the service and the app agree on
›
Account serviceOpens the sign-in migrations, functions and config
›
OpsOpens build, deploy, packaging, the systemd units, guest and family scripts
›
This commandOpens codebot and cb: the script, its tests, and the shell file
›
Agent hooksOpens what an agent session here runs when it starts, and the check before it stops
›
Global working modeOpens the script that puts the owner's working mode into every agent's instruction files
›
Bot skillsOpens the skills CodeBot's Bots use (codebot-housekeeping)
›
Intent and testsOpens what each area must do, and its scenarios
›
DesignOpens the screenshots and annotations the design follows, and design critiques
›
Build settingsOpens the scripts and packages, TypeScript, the web build, the Node version (24)
›
Git and CIOpens what git leaves out, and the check run on every push
›
Local settings templateOpens the account-service settings a new checkout copies to .env
›
‹ Home

guests

The other people's CodeBots on this machine. They are theirs: these commands touch them only when you run one.

Guest's CodeBotOpens the guest's CodeBot: a family member's own, as its own Linux user
›
Update the guestBuilds this checkout into /opt/codebot-guest and restarts it ([ops/guest-update.sh](/home/liel/projects/codebot/ops/guest-update.sh))
›
Invite the guestPrints a one-use Google link, valid ten minutes ([ops/guest-invite.sh](/home/liel/projects/codebot/ops/guest-invite.sh))
›
Guest status, logPrints what systemd and its log say
›
Set the guest up (once)Sets up the user, service, settings and Tailscale port 10000
›
Family addressOpens the address where anyone on the home Wi-Fi signs in and gets their own CodeBot
›
Update familyBuilds /opt/codebot-family and restarts every family CodeBot ([ops/family-update.sh](/home/liel/projects/codebot/ops/family-update.sh))
›
Family status, logPrints what systemd and the log say for the front door and every family CodeBot
›
Family servicesOpens the units of the front door (port 3530) and of one CodeBot per person (port 3540+N)
›
Family helperMakes or removes one family CodeBot
›
Family inviteOpens the script behind the setup link `codebot-family add N` prints
›
Set family up (once)Sets up the front door, helper, services and nginx
›
‹ Home

sign-in

The shared account service every CodeBot signs in through: Supabase project wbgrjvqbupgdclaztuou.

DashboardOpens the Supabase dashboard: users, the redirect allow list, SQL; sign in as "mobile-coder", not Lebnor
›
Sign-in entryShows the one fixed address every person starts at (CODEBOT_ACCOUNT_ENTRY_URL)
›
Its codeOpens the migrations, functions (host-access, gmail-relay) and config
›
Deploy a functionDeploys one function; redeploy host-access whenever a contract it parses changes
›
‹ Home

data

Where your CodeBot keeps its data and settings on this machine; the data folder is read from service.env.

DataOpens your Bots' conversations, attachments and recordings (CODEBOT_DATA_DIR)
›
DatabaseOpens the database: everything the service knows; back it up only with the service stopped
›
Owner keyOpens the entrance key for a new device
›
SettingsOpens the ports, tokens and sign-in address: private, never print or paste it
›
Web app settingsOpens the sign-in address built into the web app
›
Service unitOpens how systemd runs it
›
Served web buildOpens the release you are served now
›
QA dataOpens the QA CodeBot's data
›
BackupsOpens where the backup steps in ops/OPERATIONS.md write
›
‹ Home

docs

What CodeBot does, how it is built, and the rules and rulings every change follows.

DocWhat it's for
›
Rules for agentsOpens how CodeBot is used, the decisions made, designing screens, deploying (AGENTS.md is a copy)
›
ReadmeOpens the layout and commands
›
Product specOpens the product spec: how it must behave
›
ArchitectureOpens how it is built
›
RunbookOpens the runbook: running, updating, guests, family, backup, restore
›
Owner's design rulingsOpens what you liked and rejected
›
Design methodOpens how a screen is designed
›
Agentic developmentOpens how agents work in this repo
›
ObjectivesOpens what each area is for and how it is checked
›
PlansOpens the earlier and current plans
›
Open workOpens what is left
›
Where it stoppedOpens the beta's status and release scope
›
Gmail for BotsOpens the supervisor guide and its generated reference
›
AvatarsOpens how Bot avatars are built and were checked
›
OnboardingOpens how signing up works, and its recorded proof
›
Hosting and sign-inOpens how a server is hosted and how a person arrives at it
›
Verification recordsOpens the recorded checks and the pictures they refer to
›
Show:
No skill
Today's skills
screen-decomposition, first draft
screen-decomposition, final

No skill · run 1 exit=0 seconds=118 · prompt

P1 Recall: 0.321P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.474P5 Short top: 13P6 Own words: 1.0P8 Worded per screen: 1P9 Grouping (ARI): 0.475
As terminal help
The top of CodeBot: open the app, then pick an area. Operator areas are at the bottom.
Open CodeBothttps://liel.tail18e69e.ts.net/The private web app on phone or desktop; needs Tailscale on.
Local addresshttp://127.0.0.1:3505The same app, reachable only from this computer.
Botsscreen botsYour durable coding teammates, their chats, and which one needs you.
Terminalscreen terminalA shell per Bot on this computer; off until the terminal broker runs.
Gmailscreen gmailConnect Google, approve Bot email actions, see what Bots did.
Notificationsscreen notificationsTurn alerts on for this device and check they arrive.
Account and sign-inscreen accountSign-in, installing the phone app, onboarding, the entrance key.
This computerscreen hostService status, logs, backup, restore, and address change.
Other peoplescreen peopleFamily CodeBots and the guest account on this machine.
Publish an updatescreen updateBuild, push, restart, and verify the running service.
Developer checksscreen checkTypecheck, tests, reviews, and the component playground.
Experimentsscreen experimentsThe V2, V3, V4 side apps, which live in their own repos.
What's newnotice shown once after an update (apps/web/src/whatsNew.ts)What changed in the latest update, in the owner's words.
bots
Every Bot with its provider, folder and state, and whether it is waiting for you.
Create a Botscreen bots/newStart a new Bot with its name, provider, model, and folder.
Open a Botscreen bots/<bot>Its conversation, queue, and what it is doing right now.
bots › new
The form for a new Bot. Defaults come from the automatic model policy.
Name and rolefields in the Bot form (BotForm.tsx)What the Bot is called and what work it does.
Provider and modelfields in the Bot formClaude, Codex, or OpenCode; an empty model uses the automatic policy.
Primary folderfield in the Bot formWhere the Bot works; must sit under CODEBOT_PROJECT_ROOTS.
bots › <bot>
One Bot's conversation: what it is doing, the composer, the queue, and any question it asked you.
Send a messagethe composerStarts the next turn, or joins the queue if a reply is running.
Send queued messages nowPOST /bots/:id/queue/send-nowHands the queue to the running reply at once.
Take queued messages backPOST /bots/:id/queue/takeReturns queued messages to the composer to edit.
StopEsc or the Stop buttonInterrupts the reply and keeps the queue.
Answer a questionthe bot-question card in the conversationAnswer what the Bot asked before it continues.
Attach a filethe attachment pickerAdds files to the next message.
Pinned files and recordingsthe resource panel (PinnedFiles.tsx, RecordingPlayer.tsx)Files kept at hand, and Vision recordings to play back.
Chatsscreen bots/<bot>/chatsEarlier chats, each one a separate provider session.
Widgetsscreen bots/<bot>/widgetsLive panels for this Bot: Vision, screenshots, contract, git.
Settingsscreen bots/<bot>/settingsEverything about this Bot, behind the cog button at top right.
bots › <bot> › chats
The chats this Bot has had, each with its label and kind of work.
Jump to a chatthe chat's divider in the conversationOpens the point where that chat began.
Earlier chat textchats/ folder in the Bot's homePlain-text copy of each finished chat; the Bot reads the newest when you refer back.
bots › <bot> › widgets
The live panels this Bot can show. There is at most one of each kind.
Visionkind visionLive view of the browser the Bot drives, with recording.
Screenshot gallerykind screenshot_galleryCaptured screenshots in capture order.
Feature contractkind feature_contractThe Bot's current contract and its revisions.
Git quick infokind git_quick_infoRepository status and quick git actions.
Gmail cardGmailWidget.tsxThis Bot's Gmail summary.
Arrange widgetsWidgetArrangement.tsx and WidgetBrowser.tsxChoose and order which panels show.
bots › <bot> › settings
Settings for one Bot, opened from the cog. Changes apply on its next turn.
Provider and modelfields in the Bot formChanges which provider and model the Bot uses.
Primary folderfield in the Bot formWhere the Bot works.
Skills and automatic actionsfields in the Bot formAttached skills and what the Bot may do without asking.
Notifications for this BotswitchAlerts for replies, approval requests, and failures.
Enable this devicebutton; browser permission promptSubscribes this device to alerts from this Bot.
Send testbuttonChecks the selected device gets alerts; a queued test is not proof.
Reconnect this devicebuttonRepairs an expired or rejected subscription.
Other deviceslistRemove old devices; up to 16 are kept.
AvatarAvatarStudio.tsx and AvatarPicker.tsxChange how the Bot looks.
Schedulesroute not in the dumpTimed wakeups for this Bot.
terminal
A shell per Bot on this computer. It works only while the per-user broker runs; otherwise it stays off.
Turn the broker onsystemctl --user enable --now codebot-terminal-broker.serviceStarts the separate broker; set the self-hosted options first.
Broker statussystemctl --user status codebot-terminal-broker.service --no-pagerShows whether the broker is running.
Terminal tabsTerminalPage.tsx and TerminalTab.tsxOpen a shell tab for a Bot.
gmail
Gmail for Bots: whether Google is connected, what waits for your approval, and what Bots did.
Connect GoogleCODEBOT_GOOGLE_CLIENT_ID and CODEBOT_GOOGLE_CLIENT_SECRET in service.envLets Bots use Gmail; each person brings their own Google app unless the account service relays.
Approvalsscreen gmail/approvalsEmail actions waiting for your yes or no.
Activityscreen gmail/activityThe log of Gmail actions Bots took.
Daily summarycard on this screen (GmailDaily.tsx)Today's Gmail summary.
Gmail referencedocs/automation/gmail.mdGuide for supervising Bots' Gmail use.
gmail › approvals
Gmail actions a Bot asked to take, waiting for a decision.
Approve or declineapproval card on this screenDecides one action; the Bot continues or stops.
Open the Bot that askedscreen bots/<bot>See the conversation behind the request.
gmail › activity
A log of the Gmail actions Bots took.
Open the Botscreen bots/<bot>See the conversation behind an action.
notifications
Whether this device gets alerts from Bots, and whether they reach it.
Enable this devicea Bot's settings, then the browser promptSubscribes this device to alerts.
Send testa Bot's settingsSends a test to the chosen device.
Notifications diagnostics/api/notifications/diagnostics (signed-in owner)Queue, timer, and active sends.
Recovery holdCODEBOT_RECOVERY_HOLD=1 in service.envPauses automatic alerts and test sends.
iPhone and iPadthe installed Home Screen appAlerts work only from the installed app there.
account
How you sign in, how the phone app is installed, and how each person is onboarded.
Sign-in entryhttps://liel.tail18e69e.ts.net/onboardingWhere people sign in and are sent to their own host.
Entrance key~/.local/share/codebot/owner-keyKey for new devices; read it locally and never paste it.
Install the phone appbrowser Add to Home ScreenInstalls CodeBot as an app on the phone.
Onboardingscreen account/onboardingReplay or reset a person's first-use tour.
Account serviceSupabase project wbgrjvqbupgdclaztuouCentral sign-in, redirect list, and progress rows.
Operator setupnpm run setup-accountSets up the account for this server.
account › onboarding
Ways to show someone onboarding again. Each one changes data, and the last one deletes it.
Replay the first-use tourSQL on public.codebot_account_progress, then restart the hostOnly when the person's host has no Bots.
Restart onboarding with a fresh CodeBotwipe the host data except identity files, then the SQLTheir Bots go; the account and folders stay.
Full resetdelete the user in Supabase, then the host data folderEverything goes, including conversations and recordings.
host
This computer's CodeBot service: whether it runs, what it did, and how to back it up or move it.
Service statussystemctl --user status codebot.service --no-pagerRunning or stopped.
Recent logsjournalctl --user -u codebot.service -n 80 --no-pagerThe last 80 log lines.
Host diagnostics/api/diagnostics/host (signed-in app)Counters, migrations, queued turns, recovery hold.
Restartsystemctl --user restart codebot.serviceOnly after active turns and recordings finish.
Emergency stopsystemctl --user stop --no-block codebot.service, then kill the service groupInterrupts Bot turns; uncommitted media may be lost.
Data folder~/.local/share/codebotApplication data, separate from the checkout.
Back upscreen host/backupA checked copy of the whole stopped installation.
Restorescreen host/restoreRestore beside the live copy and test it first.
Change addressscreen host/addressSteps when the machine's Tailscale name changes.
host › backup
A copy of the whole stopped installation, with checksums. It holds secrets, so keep it private.
Make a backupstop the service, tar state and source, then start it, into ~/.local/share/codebot-backups/<UTC time>/A consistent copy of data, source, and config.
Verifysha256sum -c SHA256SUMS inside the backup folderConfirms the copy is intact.
Keep it privatemode 0700, outside project rootsThe copy includes owner sessions, the entrance key, and provider profiles.
host › restore
Restore a backup beside the live copy, check it, run it on a spare port, then promote it.
Check checksumssha256sum -c SHA256SUMSConfirms the backup before extracting.
Extract to a new folder~/.local/share/codebot-restore-stagingKeeps the original installation intact.
Check the databaseintegrity check in ops/OPERATIONS.mdConfirms the restored database is sound.
Inspect on a spare porthttp://127.0.0.1:3508 with CODEBOT_RECOVERY_HOLD=1Look without automatic work starting.
Promotestop the original, point CODEBOT_DATA_DIR at the restore, start in holdNever run two hosts from copies of the same queued state.
host › address
CodeBot's address is the machine's Tailscale name. Renaming it breaks sign-in until every place below is updated.
Current nametailscale status --json (Self.DNSName)The new name, to compare with the old one.
Sign-in allow listSupabase URL configurationAdd the new /onboarding first; keep the old one until the end.
Owner configservice.env CODEBOT_ACCOUNT_ENTRY_URL and apps/web/.env.local, then npm run build and restartPoints the owner's host at the new name.
Guest config/home/codebot-guest/.config/codebot/service.env, then ops/guest-update.shPoints the guest host at the new name.
Account addressesSQL update on public.codebot_account_progressSends each person to the new address at sign-in.
Phone appsreinstall from the new addressAn installed app belongs to the address it came from.
Domain forwardcodebot.lielbenor.com redirect at the registrarSends people who start at the fixed address.
people
Other people's CodeBots on this machine: family on the home Wi-Fi, and the guest account.
Family CodeBotsscreen people/familyOne CodeBot per family Google account, at most six.
Guest accountscreen people/guestA second CodeBot under its own Linux user.
people › family
Family members each get a CodeBot of their own, signed in with their Google account.
Family addresshttps://family.codebot.lielbenor.com:10100+NWorks at home directly; away from home, for invited people with the route approved.
Add a family CodeBotsudo codebot-family add NCreates CodeBot number N for a new Google account.
Remove onesudo codebot-family remove NDeletes that CodeBot and frees its number; the Google account stays linked.
Statussudo codebot-family statusWhether each one runs and whether Gmail can connect.
Stop or start allsudo codebot-family stop-all, or start-allPauses or resumes every family CodeBot.
Install oncesudo ops/family-install.shSets up the front door, helper, services, and nginx.
Updateops/family-update.shRebuilds and restarts all family CodeBots; no password needed.
Service logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Logs for the front door and each family CodeBot.
people › guest
A second CodeBot on this machine under its own Linux user, reached at port 10000.
Invite linksudo -u codebot-guest /opt/codebot-guest/inviteOne-use Google link, valid ten minutes.
Guest addresshttps://liel.tail18e69e.ts.net:10000The guest's CodeBot on this machine.
Install oncesudo ops/guest-install.shCreates the user, service, settings, and sudo rules.
Updateops/guest-update.shBuilds, replaces the program, and restarts; no password needed.
Status and logssystemctl status codebot-guest; journalctl -u codebot-guestWhether it runs and what it logged.
Disk usesudo du -sh /home/codebot-guestHow much space the guest uses.
Removesudo systemctl disable --now codebot-guest, then userdel -r codebot-guestDeletes the guest's data and account.
update
Publish code and frontend changes to the running service.
Buildnpm run buildTypechecks and builds a new release; the served one stays if this fails.
Deploysh ops/deploy.shCommits, pushes, waits for Bots, restarts, and verifies; refuses while a Bot works.
Restart by handsystemctl --user restart codebot.serviceOnly after active turns and recordings finish.
Verifycurl http://127.0.0.1:3505/api/session, and a new ExecMainStartTimestampConfirms the new process is serving.
Tell the ownerapps/web/src/whatsNew.tsThe note shown once after an update.
check
Developer checks: typecheck, tests, reviews, and the component playground.
Installnpm ciInstalls the pinned dependencies.
Run locallynpm run devRuns the service with reload on port 3505.
Typechecknpm run typecheckCompiles without emitting; says little about Bot behaviour.
Testsnpm testGmail automation tests against a fake Google.
Typecheck and testsnpm run checkBoth at once.
Integration buildnpm run build:integrationBuilds the QA instance on port 3506.
Gmail referencenpm run docs:gmailRegenerates docs/automation/gmail-reference.md.
Gmail reviewnpm run review:gmailChecks the Gmail flow in a real browser.
Schedules reviewnpm run review:schedulesChecks the schedules flow.
Component playgroundnpm run playgroundSide-by-side screen variants at 127.0.0.1.
Sync agent notesnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
experiments
Three experimental apps in their own repos, each on its own port. They reuse CodeBot's server.
V2 Terminal chathttp://127.0.0.1:3512 from ~/projects/codebot-v2-terminal-chatCodeBot's look; a Bot's chat is the Claude Code terminal.
V3 Claude Code modhttp://127.0.0.1:3513 from ~/projects/codebot-v3-claude-modClaude Code first; a mod draws the Bot list above the prompt.
V4 Launcher menuhttp://127.0.0.1:3514 from ~/projects/codebot-v4-launcher-menuA simple menu whose buttons start Claude Code sessions.
Start onesh ops/app-run.sh dev, in that folder, in its own terminalRuns one app with its own broker.
Stop oness -ltnp | grep :3513, then stop that process idStops only that app; never stop by name pattern.
Questions
  • Two help trees or one? Recommendation: one owner tree (bots, terminal, gmail, notifications, account) and a separate ops tree (host, people, update, check, experiments), since the owner's path should not need operator work.
  • Should destructive operations appear in help: the full reset, restart onboarding, emergency stop, and removing a family or guest CodeBot? Recommendation: leave them out of top-level help and reach them only through the ops tree, each behind an explicit confirmation step.
  • Include the V2, V3, V4 experiments? They live in private repos outside CodeBot. Recommendation: keep them out of the main help and show the experiments screen only when those folders exist.
  • In-app screen names: the dump gives no web routes beyond /onboarding and the API paths. Recommendation: confirm the real route list from the web app's router before the help text links to it; until then the screens stay named by path.
  • Where do schedules live? docs/objectives/schedules.md exists, but no screen file in the dump is clearly schedules. I placed them under Bot settings as a guess. Please confirm.
  • Terminal when the broker is not installed: show the screen as off with the enable command, or hide it? Recommendation: show it as off with the command, so the owner can see why it is missing.
  • Should the CLI print the entrance key? Recommendation: no; show only its path, since it is a secret.
  • Confirm these referenced files exist: ops/deploy.sh, ops/app-run.sh, ops/guest-install.sh, ops/guest-update.sh, ops/family-install.sh, ops/family-update.sh, ops/setup-account.ts, ops/terminal-broker.ts. The ops listing in the dump is truncated, so I could not verify them. Also, README.md mentions cli/codebot.py, which is not in the file list; confirm whether it exists and what it should cover.
As phone screens

Home

The top of CodeBot: open the app, then pick an area. Operator areas are at the bottom.

Open CodeBotThe private web app on phone or desktop; needs Tailscale on.
›
Local addressThe same app, reachable only from this computer.
›
BotsYour durable coding teammates, their chats, and which one needs you.
›
TerminalA shell per Bot on this computer; off until the terminal broker runs.
›
GmailConnect Google, approve Bot email actions, see what Bots did.
›
NotificationsTurn alerts on for this device and check they arrive.
›
Account and sign-inSign-in, installing the phone app, onboarding, the entrance key.
›
This computerService status, logs, backup, restore, and address change.
›
Other peopleFamily CodeBots and the guest account on this machine.
›
Publish an updateBuild, push, restart, and verify the running service.
›
Developer checksTypecheck, tests, reviews, and the component playground.
›
ExperimentsThe V2, V3, V4 side apps, which live in their own repos.
›
What's newWhat changed in the latest update, in the owner's words.
›
‹ Home

bots

Every Bot with its provider, folder and state, and whether it is waiting for you.

Create a BotStart a new Bot with its name, provider, model, and folder.
›
Open a BotIts conversation, queue, and what it is doing right now.
›
‹ bots

new

The form for a new Bot. Defaults come from the automatic model policy.

Name and roleWhat the Bot is called and what work it does.
›
Provider and modelClaude, Codex, or OpenCode; an empty model uses the automatic policy.
›
Primary folderWhere the Bot works; must sit under CODEBOT_PROJECT_ROOTS.
›
‹ bots

<bot>

One Bot's conversation: what it is doing, the composer, the queue, and any question it asked you.

Send a messageStarts the next turn, or joins the queue if a reply is running.
›
Send queued messages nowHands the queue to the running reply at once.
›
Take queued messages backReturns queued messages to the composer to edit.
›
StopInterrupts the reply and keeps the queue.
›
Answer a questionAnswer what the Bot asked before it continues.
›
Attach a fileAdds files to the next message.
›
Pinned files and recordingsFiles kept at hand, and Vision recordings to play back.
›
ChatsEarlier chats, each one a separate provider session.
›
WidgetsLive panels for this Bot: Vision, screenshots, contract, git.
›
SettingsEverything about this Bot, behind the cog button at top right.
›
‹ <bot>

chats

The chats this Bot has had, each with its label and kind of work.

Jump to a chatOpens the point where that chat began.
›
Earlier chat textPlain-text copy of each finished chat; the Bot reads the newest when you refer back.
›
‹ <bot>

widgets

The live panels this Bot can show. There is at most one of each kind.

VisionLive view of the browser the Bot drives, with recording.
›
Screenshot galleryCaptured screenshots in capture order.
›
Feature contractThe Bot's current contract and its revisions.
›
Git quick infoRepository status and quick git actions.
›
Gmail cardThis Bot's Gmail summary.
›
Arrange widgetsChoose and order which panels show.
›
‹ <bot>

settings

Settings for one Bot, opened from the cog. Changes apply on its next turn.

Provider and modelChanges which provider and model the Bot uses.
›
Primary folderWhere the Bot works.
›
Skills and automatic actionsAttached skills and what the Bot may do without asking.
›
Notifications for this BotAlerts for replies, approval requests, and failures.
›
Enable this deviceSubscribes this device to alerts from this Bot.
›
Send testChecks the selected device gets alerts; a queued test is not proof.
›
Reconnect this deviceRepairs an expired or rejected subscription.
›
Other devicesRemove old devices; up to 16 are kept.
›
AvatarChange how the Bot looks.
›
SchedulesTimed wakeups for this Bot.
›
‹ Home

terminal

A shell per Bot on this computer. It works only while the per-user broker runs; otherwise it stays off.

Turn the broker onStarts the separate broker; set the self-hosted options first.
›
Broker statusShows whether the broker is running.
›
Terminal tabsOpen a shell tab for a Bot.
›
‹ Home

gmail

Gmail for Bots: whether Google is connected, what waits for your approval, and what Bots did.

Connect GoogleLets Bots use Gmail; each person brings their own Google app unless the account service relays.
›
ApprovalsEmail actions waiting for your yes or no.
›
ActivityThe log of Gmail actions Bots took.
›
Daily summaryToday's Gmail summary.
›
Gmail referenceGuide for supervising Bots' Gmail use.
›
‹ gmail

approvals

Gmail actions a Bot asked to take, waiting for a decision.

Approve or declineDecides one action; the Bot continues or stops.
›
Open the Bot that askedSee the conversation behind the request.
›
‹ gmail

activity

A log of the Gmail actions Bots took.

Open the BotSee the conversation behind an action.
›
‹ Home

notifications

Whether this device gets alerts from Bots, and whether they reach it.

Enable this deviceSubscribes this device to alerts.
›
Send testSends a test to the chosen device.
›
Notifications diagnosticsQueue, timer, and active sends.
›
Recovery holdPauses automatic alerts and test sends.
›
iPhone and iPadAlerts work only from the installed app there.
›
‹ Home

account

How you sign in, how the phone app is installed, and how each person is onboarded.

Sign-in entryWhere people sign in and are sent to their own host.
›
Entrance keyKey for new devices; read it locally and never paste it.
›
Install the phone appInstalls CodeBot as an app on the phone.
›
OnboardingReplay or reset a person's first-use tour.
›
Account serviceCentral sign-in, redirect list, and progress rows.
›
Operator setupSets up the account for this server.
›
‹ account

onboarding

Ways to show someone onboarding again. Each one changes data, and the last one deletes it.

Replay the first-use tourOnly when the person's host has no Bots.
›
Restart onboarding with a fresh CodeBotTheir Bots go; the account and folders stay.
›
Full resetEverything goes, including conversations and recordings.
›
‹ Home

host

This computer's CodeBot service: whether it runs, what it did, and how to back it up or move it.

Service statusRunning or stopped.
›
Recent logsThe last 80 log lines.
›
Host diagnosticsCounters, migrations, queued turns, recovery hold.
›
RestartOnly after active turns and recordings finish.
›
Emergency stopInterrupts Bot turns; uncommitted media may be lost.
›
Data folderApplication data, separate from the checkout.
›
Back upA checked copy of the whole stopped installation.
›
RestoreRestore beside the live copy and test it first.
›
Change addressSteps when the machine's Tailscale name changes.
›
‹ host

backup

A copy of the whole stopped installation, with checksums. It holds secrets, so keep it private.

Make a backupA consistent copy of data, source, and config.
›
VerifyConfirms the copy is intact.
›
Keep it privateThe copy includes owner sessions, the entrance key, and provider profiles.
›
‹ host

restore

Restore a backup beside the live copy, check it, run it on a spare port, then promote it.

Check checksumsConfirms the backup before extracting.
›
Extract to a new folderKeeps the original installation intact.
›
Check the databaseConfirms the restored database is sound.
›
Inspect on a spare portLook without automatic work starting.
›
PromoteNever run two hosts from copies of the same queued state.
›
‹ host

address

CodeBot's address is the machine's Tailscale name. Renaming it breaks sign-in until every place below is updated.

Current nameThe new name, to compare with the old one.
›
Sign-in allow listAdd the new /onboarding first; keep the old one until the end.
›
Owner configPoints the owner's host at the new name.
›
Guest configPoints the guest host at the new name.
›
Account addressesSends each person to the new address at sign-in.
›
Phone appsAn installed app belongs to the address it came from.
›
Domain forwardSends people who start at the fixed address.
›
‹ Home

people

Other people's CodeBots on this machine: family on the home Wi-Fi, and the guest account.

Family CodeBotsOne CodeBot per family Google account, at most six.
›
Guest accountA second CodeBot under its own Linux user.
›
‹ people

family

Family members each get a CodeBot of their own, signed in with their Google account.

Family addressWorks at home directly; away from home, for invited people with the route approved.
›
Add a family CodeBotCreates CodeBot number N for a new Google account.
›
Remove oneDeletes that CodeBot and frees its number; the Google account stays linked.
›
StatusWhether each one runs and whether Gmail can connect.
›
Stop or start allPauses or resumes every family CodeBot.
›
Install onceSets up the front door, helper, services, and nginx.
›
UpdateRebuilds and restarts all family CodeBots; no password needed.
›
Service logsLogs for the front door and each family CodeBot.
›
‹ people

guest

A second CodeBot on this machine under its own Linux user, reached at port 10000.

Invite linkOne-use Google link, valid ten minutes.
›
Guest addressThe guest's CodeBot on this machine.
›
Install onceCreates the user, service, settings, and sudo rules.
›
UpdateBuilds, replaces the program, and restarts; no password needed.
›
Status and logsWhether it runs and what it logged.
›
Disk useHow much space the guest uses.
›
RemoveDeletes the guest's data and account.
›
‹ Home

update

Publish code and frontend changes to the running service.

BuildTypechecks and builds a new release; the served one stays if this fails.
›
DeployCommits, pushes, waits for Bots, restarts, and verifies; refuses while a Bot works.
›
Restart by handOnly after active turns and recordings finish.
›
VerifyConfirms the new process is serving.
›
Tell the ownerThe note shown once after an update.
›
‹ Home

check

Developer checks: typecheck, tests, reviews, and the component playground.

InstallInstalls the pinned dependencies.
›
Run locallyRuns the service with reload on port 3505.
›
TypecheckCompiles without emitting; says little about Bot behaviour.
›
TestsGmail automation tests against a fake Google.
›
Typecheck and testsBoth at once.
›
Integration buildBuilds the QA instance on port 3506.
›
Gmail referenceRegenerates docs/automation/gmail-reference.md.
›
Gmail reviewChecks the Gmail flow in a real browser.
›
Schedules reviewChecks the schedules flow.
›
Component playgroundSide-by-side screen variants at 127.0.0.1.
›
Sync agent notesRegenerates AGENTS.md from CLAUDE.md.
›
‹ Home

experiments

Three experimental apps in their own repos, each on its own port. They reuse CodeBot's server.

V2 Terminal chatCodeBot's look; a Bot's chat is the Claude Code terminal.
›
V3 Claude Code modClaude Code first; a mod draws the Bot list above the prompt.
›
V4 Launcher menuA simple menu whose buttons start Claude Code sessions.
›
Start oneRuns one app with its own broker.
›
Stop oneStops only that app; never stop by name pattern.
›
Raw answer
I mapped the owner's screens (the phone and desktop app) and the operator's commands into one tree, since both come from the same project. Forms are taken from the docs and file names in the dump. Two gaps: the dump has no in-app route names beyond `/onboarding`, so in-app screens are named by path, and the `ops/` listing is truncated, so some referenced scripts are unconfirmed. The questions at the end are the decisions I could not make for you.

```json
{"screens": [
{"path": [], "sentence": "The top of CodeBot: open the app, then pick an area. Operator areas are at the bottom.", "rows": [
{"name": "Open CodeBot", "form": "https://liel.tail18e69e.ts.net/", "what": "The private web app on phone or desktop; needs Tailscale on."},
{"name": "Local address", "form": "http://127.0.0.1:3505", "what": "The same app, reachable only from this computer."},
{"name": "Bots", "form": "screen bots", "what": "Your durable coding teammates, their chats, and which one needs you."},
{"name": "Terminal", "form": "screen terminal", "what": "A shell per Bot on this computer; off until the terminal broker runs."},
{"name": "Gmail", "form": "screen gmail", "what": "Connect Google, approve Bot email actions, see what Bots did."},
{"name": "Notifications", "form": "screen notifications", "what": "Turn alerts on for this device and check they arrive."},
{"name": "Account and sign-in", "form": "screen account", "what": "Sign-in, installing the phone app, onboarding, the entrance key."},
{"name": "This computer", "form": "screen host", "what": "Service status, logs, backup, restore, and address change."},
{"name": "Other people", "form": "screen people", "what": "Family CodeBots and the guest account on this machine."},
{"name": "Publish an update", "form": "screen update", "what": "Build, push, restart, and verify the running service."},
{"name": "Developer checks", "form": "screen check", "what": "Typecheck, tests, reviews, and the component playground."},
{"name": "Experiments", "form": "screen experiments", "what": "The V2, V3, V4 side apps, which live in their own repos."},
{"name": "What's new", "form": "notice shown once after an update (apps/web/src/whatsNew.ts)", "what": "What changed in the latest update, in the owner's words."}
]},
{"path": ["bots"], "sentence": "Every Bot with its provider, folder and state, and whether it is waiting for you.", "rows": [
{"name": "Create a Bot", "form": "screen bots/new", "what": "Start a new Bot with its name, provider, model, and folder."},
{"name": "Open a Bot", "form": "screen bots/<bot>", "what": "Its conversation, queue, and what it is doing right now."}
]},
{"path": ["bots", "new"], "sentence": "The form for a new Bot. Defaults come from the automatic model policy.", "rows": [
{"name": "Name and role", "form": "fields in the Bot form (BotForm.tsx)", "what": "What the Bot is called and what work it does."},
{"name": "Provider and model", "form": "fields in the Bot form", "what": "Claude, Codex, or OpenCode; an empty model uses the automatic policy."},
{"name": "Primary folder", "form": "field in the Bot form", "what": "Where the Bot works; must sit under CODEBOT_PROJECT_ROOTS."}
]},
{"path": ["bots", "<bot>"], "sentence": "One Bot's conversation: what it is doing, the composer, the queue, and any question it asked you.", "rows": [
{"name": "Send a message", "form": "the composer", "what": "Starts the next turn, or joins the queue if a reply is running."},
{"name": "Send queued messages now", "form": "POST /bots/:id/queue/send-now", "what": "Hands the queue to the running reply at once."},
{"name": "Take queued messages back", "form": "POST /bots/:id/queue/take", "what": "Returns queued messages to the composer to edit."},
{"name": "Stop", "form": "Esc or the Stop button", "what": "Interrupts the reply and keeps the queue."},
{"name": "Answer a question", "form": "the bot-question card in the conversation", "what": "Answer what the Bot asked before it continues."},
{"name": "Attach a file", "form": "the attachment picker", "what": "Adds files to the next message."},
{"name": "Pinned files and recordings", "form": "the resource panel (PinnedFiles.tsx, RecordingPlayer.tsx)", "what": "Files kept at hand, and Vision recordings to play back."},
{"name": "Chats", "form": "screen bots/<bot>/chats", "what": "Earlier chats, each one a separate provider session."},
{"name": "Widgets", "form": "screen bots/<bot>/widgets", "what": "Live panels for this Bot: Vision, screenshots, contract, git."},
{"name": "Settings", "form": "screen bots/<bot>/settings", "what": "Everything about this Bot, behind the cog button at top right."}
]},
{"path": ["bots", "<bot>", "chats"], "sentence": "The chats this Bot has had, each with its label and kind of work.", "rows": [
{"name": "Jump to a chat", "form": "the chat's divider in the conversation", "what": "Opens the point where that chat began."},
{"name": "Earlier chat text", "form": "chats/ folder in the Bot's home", "what": "Plain-text copy of each finished chat; the Bot reads the newest when you refer back."}
]},
{"path": ["bots", "<bot>", "widgets"], "sentence": "The live panels this Bot can show. There is at most one of each kind.", "rows": [
{"name": "Vision", "form": "kind vision", "what": "Live view of the browser the Bot drives, with recording."},
{"name": "Screenshot gallery", "form": "kind screenshot_gallery", "what": "Captured screenshots in capture order."},
{"name": "Feature contract", "form": "kind feature_contract", "what": "The Bot's current contract and its revisions."},
{"name": "Git quick info", "form": "kind git_quick_info", "what": "Repository status and quick git actions."},
{"name": "Gmail card", "form": "GmailWidget.tsx", "what": "This Bot's Gmail summary."},
{"name": "Arrange widgets", "form": "WidgetArrangement.tsx and WidgetBrowser.tsx", "what": "Choose and order which panels show."}
]},
{"path": ["bots", "<bot>", "settings"], "sentence": "Settings for one Bot, opened from the cog. Changes apply on its next turn.", "rows": [
{"name": "Provider and model", "form": "fields in the Bot form", "what": "Changes which provider and model the Bot uses."},
{"name": "Primary folder", "form": "field in the Bot form", "what": "Where the Bot works."},
{"name": "Skills and automatic actions", "form": "fields in the Bot form", "what": "Attached skills and what the Bot may do without asking."},
{"name": "Notifications for this Bot", "form": "switch", "what": "Alerts for replies, approval requests, and failures."},
{"name": "Enable this device", "form": "button; browser permission prompt", "what": "Subscribes this device to alerts from this Bot."},
{"name": "Send test", "form": "button", "what": "Checks the selected device gets alerts; a queued test is not proof."},
{"name": "Reconnect this device", "form": "button", "what": "Repairs an expired or rejected subscription."},
{"name": "Other devices", "form": "list", "what": "Remove old devices; up to 16 are kept."},
{"name": "Avatar", "form": "AvatarStudio.tsx and AvatarPicker.tsx", "what": "Change how the Bot looks."},
{"name": "Schedules", "form": "route not in the dump", "what": "Timed wakeups for this Bot."}
]},
{"path": ["terminal"], "sentence": "A shell per Bot on this computer. It works only while the per-user broker runs; otherwise it stays off.", "rows": [
{"name": "Turn the broker on", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "Starts the separate broker; set the self-hosted options first."},
{"name": "Broker status", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Shows whether the broker is running."},
{"name": "Terminal tabs", "form": "TerminalPage.tsx and TerminalTab.tsx", "what": "Open a shell tab for a Bot."}
]},
{"path": ["gmail"], "sentence": "Gmail for Bots: whether Google is connected, what waits for your approval, and what Bots did.", "rows": [
{"name": "Connect Google", "form": "CODEBOT_GOOGLE_CLIENT_ID and CODEBOT_GOOGLE_CLIENT_SECRET in service.env", "what": "Lets Bots use Gmail; each person brings their own Google app unless the account service relays."},
{"name": "Approvals", "form": "screen gmail/approvals", "what": "Email actions waiting for your yes or no."},
{"name": "Activity", "form": "screen gmail/activity", "what": "The log of Gmail actions Bots took."},
{"name": "Daily summary", "form": "card on this screen (GmailDaily.tsx)", "what": "Today's Gmail summary."},
{"name": "Gmail reference", "form": "docs/automation/gmail.md", "what": "Guide for supervising Bots' Gmail use."}
]},
{"path": ["gmail", "approvals"], "sentence": "Gmail actions a Bot asked to take, waiting for a decision.", "rows": [
{"name": "Approve or decline", "form": "approval card on this screen", "what": "Decides one action; the Bot continues or stops."},
{"name": "Open the Bot that asked", "form": "screen bots/<bot>", "what": "See the conversation behind the request."}
]},
{"path": ["gmail", "activity"], "sentence": "A log of the Gmail actions Bots took.", "rows": [
{"name": "Open the Bot", "form": "screen bots/<bot>", "what": "See the conversation behind an action."}
]},
{"path": ["notifications"], "sentence": "Whether this device gets alerts from Bots, and whether they reach it.", "rows": [
{"name": "Enable this device", "form": "a Bot's settings, then the browser prompt", "what": "Subscribes this device to alerts."},
{"name": "Send test", "form": "a Bot's settings", "what": "Sends a test to the chosen device."},
{"name": "Notifications diagnostics", "form": "/api/notifications/diagnostics (signed-in owner)", "what": "Queue, timer, and active sends."},
{"name": "Recovery hold", "form": "CODEBOT_RECOVERY_HOLD=1 in service.env", "what": "Pauses automatic alerts and test sends."},
{"name": "iPhone and iPad", "form": "the installed Home Screen app", "what": "Alerts work only from the installed app there."}
]},
{"path": ["account"], "sentence": "How you sign in, how the phone app is installed, and how each person is onboarded.", "rows": [
{"name": "Sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Where people sign in and are sent to their own host."},
{"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Key for new devices; read it locally and never paste it."},
{"name": "Install the phone app", "form": "browser Add to Home Screen", "what": "Installs CodeBot as an app on the phone."},
{"name": "Onboarding", "form": "screen account/onboarding", "what": "Replay or reset a person's first-use tour."},
{"name": "Account service", "form": "Supabase project wbgrjvqbupgdclaztuou", "what": "Central sign-in, redirect list, and progress rows."},
{"name": "Operator setup", "form": "npm run setup-account", "what": "Sets up the account for this server."}
]},
{"path": ["account", "onboarding"], "sentence": "Ways to show someone onboarding again. Each one changes data, and the last one deletes it.", "rows": [
{"name": "Replay the first-use tour", "form": "SQL on public.codebot_account_progress, then restart the host", "what": "Only when the person's host has no Bots."},
{"name": "Restart onboarding with a fresh CodeBot", "form": "wipe the host data except identity files, then the SQL", "what": "Their Bots go; the account and folders stay."},
{"name": "Full reset", "form": "delete the user in Supabase, then the host data folder", "what": "Everything goes, including conversations and recordings."}
]},
{"path": ["host"], "sentence": "This computer's CodeBot service: whether it runs, what it did, and how to back it up or move it.", "rows": [
{"name": "Service status", "form": "systemctl --user status codebot.service --no-pager", "what": "Running or stopped."},
{"name": "Recent logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "The last 80 log lines."},
{"name": "Host diagnostics", "form": "/api/diagnostics/host (signed-in app)", "what": "Counters, migrations, queued turns, recovery hold."},
{"name": "Restart", "form": "systemctl --user restart codebot.service", "what": "Only after active turns and recordings finish."},
{"name": "Emergency stop", "form": "systemctl --user stop --no-block codebot.service, then kill the service group", "what": "Interrupts Bot turns; uncommitted media may be lost."},
{"name": "Data folder", "form": "~/.local/share/codebot", "what": "Application data, separate from the checkout."},
{"name": "Back up", "form": "screen host/backup", "what": "A checked copy of the whole stopped installation."},
{"name": "Restore", "form": "screen host/restore", "what": "Restore beside the live copy and test it first."},
{"name": "Change address", "form": "screen host/address", "what": "Steps when the machine's Tailscale name changes."}
]},
{"path": ["host", "backup"], "sentence": "A copy of the whole stopped installation, with checksums. It holds secrets, so keep it private.", "rows": [
{"name": "Make a backup", "form": "stop the service, tar state and source, then start it, into ~/.local/share/codebot-backups/<UTC time>/", "what": "A consistent copy of data, source, and config."},
{"name": "Verify", "form": "sha256sum -c SHA256SUMS inside the backup folder", "what": "Confirms the copy is intact."},
{"name": "Keep it private", "form": "mode 0700, outside project roots", "what": "The copy includes owner sessions, the entrance key, and provider profiles."}
]},
{"path": ["host", "restore"], "sentence": "Restore a backup beside the live copy, check it, run it on a spare port, then promote it.", "rows": [
{"name": "Check checksums", "form": "sha256sum -c SHA256SUMS", "what": "Confirms the backup before extracting."},
{"name": "Extract to a new folder", "form": "~/.local/share/codebot-restore-staging", "what": "Keeps the original installation intact."},
{"name": "Check the database", "form": "integrity check in ops/OPERATIONS.md", "what": "Confirms the restored database is sound."},
{"name": "Inspect on a spare port", "form": "http://127.0.0.1:3508 with CODEBOT_RECOVERY_HOLD=1", "what": "Look without automatic work starting."},
{"name": "Promote", "form": "stop the original, point CODEBOT_DATA_DIR at the restore, start in hold", "what": "Never run two hosts from copies of the same queued state."}
]},
{"path": ["host", "address"], "sentence": "CodeBot's address is the machine's Tailscale name. Renaming it breaks sign-in until every place below is updated.", "rows": [
{"name": "Current name", "form": "tailscale status --json (Self.DNSName)", "what": "The new name, to compare with the old one."},
{"name": "Sign-in allow list", "form": "Supabase URL configuration", "what": "Add the new /onboarding first; keep the old one until the end."},
{"name": "Owner config", "form": "service.env CODEBOT_ACCOUNT_ENTRY_URL and apps/web/.env.local, then npm run build and restart", "what": "Points the owner's host at the new name."},
{"name": "Guest config", "form": "/home/codebot-guest/.config/codebot/service.env, then ops/guest-update.sh", "what": "Points the guest host at the new name."},
{"name": "Account addresses", "form": "SQL update on public.codebot_account_progress", "what": "Sends each person to the new address at sign-in."},
{"name": "Phone apps", "form": "reinstall from the new address", "what": "An installed app belongs to the address it came from."},
{"name": "Domain forward", "form": "codebot.lielbenor.com redirect at the registrar", "what": "Sends people who start at the fixed address."}
]},
{"path": ["people"], "sentence": "Other people's CodeBots on this machine: family on the home Wi-Fi, and the guest account.", "rows": [
{"name": "Family CodeBots", "form": "screen people/family", "what": "One CodeBot per family Google account, at most six."},
{"name": "Guest account", "form": "screen people/guest", "what": "A second CodeBot under its own Linux user."}
]},
{"path": ["people", "family"], "sentence": "Family members each get a CodeBot of their own, signed in with their Google account.", "rows": [
{"name": "Family address", "form": "https://family.codebot.lielbenor.com:10100+N", "what": "Works at home directly; away from home, for invited people with the route approved."},
{"name": "Add a family CodeBot", "form": "sudo codebot-family add N", "what": "Creates CodeBot number N for a new Google account."},
{"name": "Remove one", "form": "sudo codebot-family remove N", "what": "Deletes that CodeBot and frees its number; the Google account stays linked."},
{"name": "Status", "form": "sudo codebot-family status", "what": "Whether each one runs and whether Gmail can connect."},
{"name": "Stop or start all", "form": "sudo codebot-family stop-all, or start-all", "what": "Pauses or resumes every family CodeBot."},
{"name": "Install once", "form": "sudo ops/family-install.sh", "what": "Sets up the front door, helper, services, and nginx."},
{"name": "Update", "form": "ops/family-update.sh", "what": "Rebuilds and restarts all family CodeBots; no password needed."},
{"name": "Service logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Logs for the front door and each family CodeBot."}
]},
{"path": ["people", "guest"], "sentence": "A second CodeBot on this machine under its own Linux user, reached at port 10000.", "rows": [
{"name": "Invite link", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "One-use Google link, valid ten minutes."},
{"name": "Guest address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "The guest's CodeBot on this machine."},
{"name": "Install once", "form": "sudo ops/guest-install.sh", "what": "Creates the user, service, settings, and sudo rules."},
{"name": "Update", "form": "ops/guest-update.sh", "what": "Builds, replaces the program, and restarts; no password needed."},
{"name": "Status and logs", "form": "systemctl status codebot-guest; journalctl -u codebot-guest", "what": "Whether it runs and what it logged."},
{"name": "Disk use", "form": "sudo du -sh /home/codebot-guest", "what": "How much space the guest uses."},
{"name": "Remove", "form": "sudo systemctl disable --now codebot-guest, then userdel -r codebot-guest", "what": "Deletes the guest's data and account."}
]},
{"path": ["update"], "sentence": "Publish code and frontend changes to the running service.", "rows": [
{"name": "Build", "form": "npm run build", "what": "Typechecks and builds a new release; the served one stays if this fails."},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Commits, pushes, waits for Bots, restarts, and verifies; refuses while a Bot works."},
{"name": "Restart by hand", "form": "systemctl --user restart codebot.service", "what": "Only after active turns and recordings finish."},
{"name": "Verify", "form": "curl http://127.0.0.1:3505/api/session, and a new ExecMainStartTimestamp", "what": "Confirms the new process is serving."},
{"name": "Tell the owner", "form": "apps/web/src/whatsNew.ts", "what": "The note shown once after an update."}
]},
{"path": ["check"], "sentence": "Developer checks: typecheck, tests, reviews, and the component playground.", "rows": [
{"name": "Install", "form": "npm ci", "what": "Installs the pinned dependencies."},
{"name": "Run locally", "form": "npm run dev", "what": "Runs the service with reload on port 3505."},
{"name": "Typecheck", "form": "npm run typecheck", "what": "Compiles without emitting; says little about Bot behaviour."},
{"name": "Tests", "form": "npm test", "what": "Gmail automation tests against a fake Google."},
{"name": "Typecheck and tests", "form": "npm run check", "what": "Both at once."},
{"name": "Integration build", "form": "npm run build:integration", "what": "Builds the QA instance on port 3506."},
{"name": "Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md."},
{"name": "Gmail review", "form": "npm run review:gmail", "what": "Checks the Gmail flow in a real browser."},
{"name": "Schedules review", "form": "npm run review:schedules", "what": "Checks the schedules flow."},
{"name": "Component playground", "form": "npm run playground", "what": "Side-by-side screen variants at 127.0.0.1."},
{"name": "Sync agent notes", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."}
]},
{"path": ["experiments"], "sentence": "Three experimental apps in their own repos, each on its own port. They reuse CodeBot's server.", "rows": [
{"name": "V2 Terminal chat", "form": "http://127.0.0.1:3512 from ~/projects/codebot-v2-terminal-chat", "what": "CodeBot's look; a Bot's chat is the Claude Code terminal."},
{"name": "V3 Claude Code mod", "form": "http://127.0.0.1:3513 from ~/projects/codebot-v3-claude-mod", "what": "Claude Code first; a mod draws the Bot list above the prompt."},
{"name": "V4 Launcher menu", "form": "http://127.0.0.1:3514 from ~/projects/codebot-v4-launcher-menu", "what": "A simple menu whose buttons start Claude Code sessions."},
{"name": "Start one", "form": "sh ops/app-run.sh dev, in that folder, in its own terminal", "what": "Runs one app with its own broker."},
{"name": "Stop one", "form": "ss -ltnp | grep :3513, then stop that process id", "what": "Stops only that app; never stop by name pattern."}
]}
],
"questions": [
"Two help trees or one? Recommendation: one owner tree (bots, terminal, gmail, notifications, account) and a separate ops tree (host, people, update, check, experiments), since the owner's path should not need operator work.",
"Should destructive operations appear in help: the full reset, restart onboarding, emergency stop, and removing a family or guest CodeBot? Recommendation: leave them out of top-level help and reach them only through the ops tree, each behind an explicit confirmation step.",
"Include the V2, V3, V4 experiments? They live in private repos outside CodeBot. Recommendation: keep them out of the main help and show the experiments screen only when those folders exist.",
"In-app screen names: the dump gives no web routes beyond /onboarding and the API paths. Recommendation: confirm the real route list from the web app's router before the help text links to it; until then the screens stay named by path.",
"Where do schedules live? docs/objectives/schedules.md exists, but no screen file in the dump is clearly schedules. I placed them under Bot settings as a guess. Please confirm.",
"Terminal when the broker is not installed: show the screen as off with the enable command, or hide it? Recommendation: show it as off with the command, so the owner can see why it is missing.",
"Should the CLI print the entrance key? Recommendation: no; show only its path, since it is a secret.",
"Confirm these referenced files exist: ops/deploy.sh, ops/app-run.sh, ops/guest-install.sh, ops/guest-update.sh, ops/family-install.sh, ops/family-update.sh, ops/setup-account.ts, ops/terminal-broker.ts. The ops listing in the dump is truncated, so I could not verify them. Also, README.md mentions cli/codebot.py, which is not in the file list; confirm whether it exists and what it should cover."
]}
```

Today's skills · run 1 exit=0 seconds=107 · prompt

P1 Recall: 0.513P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 9P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.442
As terminal help
The command line for CodeBot on this machine: the owner's CodeBot, the guest and family copies, and where their files, docs and accounts live.
Owner's CodeBotcodebot runPrints the owner's CodeBot screen: starting, stopping and checking the host on port 3505.
Deploycodebot deployPrints the deploy screen: building, restarting and verifying a new version of the owner's CodeBot.
Checkscodebot checkPrints the check screen: type checks, tests and review scripts.
Datacodebot dataPrints the data screen: where the owner's data lives, and the steps to back it up, restore it or reset someone's onboarding.
Guest CodeBotcodebot guestPrints the guest screen: the second CodeBot on this machine for another person.
Family CodeBotscodebot familyPrints the family screen: the sign-in front door and one CodeBot for each family member.
Account servicecodebot accountPrints the account screen: the shared sign-in service and its deploy steps.
Experimentscodebot experimentsPrints the experiments screen: three experimental apps that reuse CodeBot's server.
Docscodebot docsPrints the docs screen: the guides, plans and behaviour records, each opened from its file.
run
The owner's CodeBot on this machine: its state, its log, and the addresses it answers on.
Start the owner's CodeBotsystemctl --user start codebot.serviceStarts the owner's host on port 3505, the one you sign in to.
Stop the owner's CodeBotsystemctl --user stop codebot.serviceStops the host cleanly, ending running turns and closing browser work.
Owner's CodeBot statussystemctl --user status codebot.service --no-pagerPrints whether the host is running and when it last started.
Owner's CodeBot logjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the host.
Host answers checkcurl --fail --silent http://127.0.0.1:3505/api/sessionChecks that the host on port 3505 answers, and prints its session state.
Owner's CodeBot in the browserhttps://liel.tail18e69e.ts.net/Opens the owner's CodeBot at its private address.
Host diagnosticshttps://liel.tail18e69e.ts.net/api/diagnostics/hostOpens the host's counters and lifecycle state; sign-in is required.
Private address mappingtailscale serve status --jsonPrints which private address reaches the host through Tailscale.
Start the QA copysystemctl --user start codebot-integration.serviceStarts the disposable QA copy on port 3506, for trying changes before they reach the owner.
Development servernpm run devRuns the host from this checkout and restarts it on every code change.
Terminal broker statussystemctl --user status codebot-terminal-broker.servicePrints whether the per-user terminal broker is running.
deploy
Putting a change into the owner's CodeBot: the steps from code to a running host.
Deploy the checkoutsh ops/deploy.shDeploys the current code: builds, commits, pushes, restarts the host and verifies it, waiting while a Bot works.
Build a releasenpm run buildBuilds a new release and swaps it in only when the build succeeds.
Install dependenciesnpm ciInstalls the exact locked dependencies before a build.
Restart the owner's CodeBotsystemctl --user restart codebot.serviceRestarts the host to load a new build, after active turns and recordings finish.
Kept releasesdist/releases/Opens the kept releases: the current one and the two before it.
Deploy guardops/deploy-guard.shBlocks finishing a turn while code is unpushed, newer than the running service, or newer than the served build.
Install and update stepsops/OPERATIONS.md (section: Install or update the host)Opens the install and update steps.
Service unitops/codebot.serviceOpens the systemd unit that runs the host.
check
The checks and review scripts for this project, run from the checkout.
Typechecknpm run typecheckCompiles the code with the TypeScript checker, writing no files.
Testsnpm testRuns the Gmail automation tests against a fake Google server.
Typecheck and testsnpm run checkRuns the typecheck, then the service tests.
Build the QA copynpm run build:integrationTypechecks, then builds the bundle for the QA copy.
Review Gmailnpm run review:gmailRuns the Gmail review script.
Review schedulesnpm run review:schedulesRuns the schedules review script.
Regenerate Gmail referencenpm run docs:gmailRegenerates the Gmail reference document from the code.
Sync agent instructionsnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
Design playgroundnpm run playgroundStarts the design playground on 127.0.0.1 and opens the Gmail sample.
Behaviour test steps.bdd/steps/Opens the behaviour test steps; no runner script is listed in package.json yet.
data
The owner's data on this machine: where it lives, and the steps to back it up, restore it or reset someone's onboarding.
Data folder~/.local/share/codebotOpens the data folder: the database, sessions and media.
Database~/.local/share/codebot/codebot.sqliteOpens the owner's database file.
Entrance key~/.local/share/codebot/owner-keyOpens the key a new device needs to connect; its value is never printed.
Settings file~/.config/codebot/service.envOpens the private settings file; its values are never printed.
Project folders~/projectsOpens the folders Bots may reach, set by CODEBOT_PROJECT_ROOTS.
Backups folder~/.local/share/codebot-backupsOpens the folder of backups.
Make a backupops/OPERATIONS.md (section: Back up a consistent installation)Opens the steps that stop the host and copy its data.
Restore a backupops/OPERATIONS.md (section: Restore into a separate directory first)Opens the steps that restore into a separate folder first.
Emergency stop and rollbackops/OPERATIONS.md (section: Emergency stop and rollback)Opens the steps for stopping the host at once or rolling back.
Reset someone's onboardingops/OPERATIONS.md (section: Reset someone's onboarding)Opens the steps for showing one person the onboarding again.
guest
The guest CodeBot: a second CodeBot on this machine for another person, run as its own Linux user.
Guest statussystemctl status codebot-guestPrints whether the guest's CodeBot is running.
Guest logjournalctl -u codebot-guestPrints the guest's CodeBot log.
Guest disk usesudo du -sh /home/codebot-guestPrints how much disk the guest's CodeBot uses.
Guest CodeBot in the browserhttps://liel.tail18e69e.ts.net:10000Opens the guest's CodeBot at its private address.
Packaged guest copy/opt/codebot-guestOpens the packaged copy the guest service runs.
Update the guestops/guest-update.shBuilds the current version, replaces the guest copy and restarts it; needs no password.
Invite someonesudo -u codebot-guest /opt/codebot-guest/inviteMakes a one-use Google invite link, valid for ten minutes.
Install the guest (once)sudo ops/guest-install.shSets up the guest user, service, settings, sudo rules and Tailscale port 10000.
Remove the guestops/OPERATIONS.md (section: Host a guest on this machine)Opens the removal steps; they are not run from here.
family
The family CodeBots: the sign-in front door and one CodeBot for each family member, on the home Wi-Fi.
Family statussudo codebot-family statusPrints which family CodeBots are running, and whether each can connect Gmail.
Family logjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the front door's and the family CodeBots' log.
Family sign-in pagehttps://family.codebot.lielbenor.comOpens the family sign-in page.
Add a family CodeBotsudo codebot-family add NCreates a CodeBot for family member N, up to six.
Remove a family CodeBotsudo codebot-family remove NDeletes that CodeBot and frees its number; the Google account stays linked for good.
Stop all family CodeBotssudo codebot-family stop-allStops every family CodeBot.
Start all family CodeBotssudo codebot-family start-allStarts every family CodeBot.
Update the familyops/family-update.shBuilds, replaces the family copy and restarts all of them; needs no password.
Install the family (once)sudo ops/family-install.shSets up the front door, helper, services, sudo rules and nginx.
Root helper/usr/local/sbin/codebot-familyOpens the root helper script that adds, removes and reports on family CodeBots.
Family settings/etc/codebot-family.confOpens the settings file the helper reads.
Family runbookops/OPERATIONS.md (section: Home Wi-Fi address)Opens the family setup, address and removal steps.
account
The shared account service that handles sign-in and the host handshake, and the steps that depend on this machine's address.
Account service dashboardhttps://supabase.com/dashboard/project/wbgrjvqbupgdclaztuouOpens the account service project in Supabase.
Command-line token~/.config/supabase-codebot-tokenOpens the token file the Supabase command line uses; its value is never printed.
Deploy host-accessSUPABASE_ACCESS_TOKEN="$(cat ~/.config/supabase-codebot-token)" npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function; redeploy whenever a contract it parses changes.
Account service functionssupabase/functions/Opens the gmail-relay and host-access functions.
Database migrationssupabase/migrations/Opens the database migrations in order.
Change this machine's addressops/OPERATIONS.md (section: Change this machine's address)Opens the checklist of every place that holds the address, and the order to change them.
experiments
Three experimental apps that reuse CodeBot's server. Each is in its own private repo and runs on this computer only.
V2 Terminal chatcodebot experiments v2Prints the V2 screen: CodeBot's look, where a Bot's chat is the Claude Code terminal, on port 3512.
V3 Claude Code modcodebot experiments v3Prints the V3 screen: Claude Code first, with a mod drawing the Bot list above the prompt, on port 3513.
V4 Launcher menucodebot experiments v4Prints the V4 screen: a simple main menu whose buttons set up Claude Code sessions, on port 3514.
experiments › v2
The V2 Terminal chat app: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.
Start V2cd ~/projects/codebot-v2-terminal-chat && sh ops/app-run.sh devStarts V2 on port 3512; run it in its own terminal.
V2 in Chromehttp://127.0.0.1:3512Opens V2 in the browser.
V2 folder~/projects/codebot-v2-terminal-chatOpens the V2 project folder.
Process holding port 3512ss -ltnp | grep :3512Prints the process that holds the port, which is the one to stop.
V2 notes~/projects/codebot-v2-terminal-chat/docs/experiment/Opens the owner's vision, decision log and report for V2.
experiments › v3
The V3 Claude Code mod app: Claude Code first, with a mod drawing the Bot list above the prompt.
Start V3cd ~/projects/codebot-v3-claude-mod && sh ops/app-run.sh devStarts V3 on port 3513; run it in its own terminal.
V3 in Chromehttp://127.0.0.1:3513Opens V3 in the browser.
V3 folder~/projects/codebot-v3-claude-modOpens the V3 project folder.
Process holding port 3513ss -ltnp | grep :3513Prints the process that holds the port, which is the one to stop.
List background sessionsclaude agentsPrints the ids of V3's background Claude Code sessions.
Stop an old test Botclaude stop <id>Stops one background Claude Code session by its id.
V3 notes~/projects/codebot-v3-claude-mod/docs/experiment/Opens the owner's vision, decision log and report for V3.
experiments › v4
The V4 Launcher menu app: a simple main menu whose buttons set up the Claude Code sessions.
Start V4cd ~/projects/codebot-v4-launcher-menu && sh ops/app-run.sh devStarts V4 on port 3514; run it in its own terminal.
V4 in Chromehttp://127.0.0.1:3514Opens V4 in the browser.
V4 folder~/projects/codebot-v4-launcher-menuOpens the V4 project folder.
Process holding port 3514ss -ltnp | grep :3514Prints the process that holds the port, which is the one to stop.
V4 notes~/projects/codebot-v4-launcher-menu/docs/experiment/Opens the owner's vision, decision log and report for V4.
docs
The guides, records and plans for this project, each opened from its file.
OverviewREADME.mdOpens the README: what CodeBot is, how it runs and how it is verified.
Behaviour contractPRODUCT-SPEC.mdOpens the behaviour contract.
ArchitectureARCHITECTURE.mdOpens how CodeBot is built and where its boundaries lie.
Open workDEFERRED-WORK.mdOpens the remaining checklist and the safe restart state.
Implementation statusIMPLEMENTATION-STATUS.mdOpens what has been built so far.
Standing rulesCLAUDE.mdOpens the fundamentals every task assumes; AGENTS.md is generated from it.
Operations runbookops/OPERATIONS.mdOpens the runbook for running, backing up and recovering the host.
Gmail for Botsdocs/automation/gmail.mdOpens the Gmail setup and supervisor guide.
Gmail referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference.
Design methoddocs/design-method.mdOpens the method for designing screens.
Design rulingsdocs/design-taste.mdOpens the owner's design rulings and rejections.
Plansdocs/plans/Opens the plan documents, one per piece of work.
Objectivesdocs/objectives/README.mdOpens the product objectives.
Verification recordsdocs/verification/Opens the recorded evidence that work was checked.
Module intents.idd/modules/Opens the intent record of each module: its constraints and tests.
Behaviour features.bdd/features/Opens the Given, When, Then behaviour features.
QA findings and resolutions.bdd/qa/Opens the QA findings and how each was resolved.
Housekeeping skillskills/codebot-housekeeping/SKILL.mdOpens the housekeeping skill.
Questions
  • Name and alias. Recommend the top command is 'codebot' with 'cb' as the short alias, if whence and type show no clash. The README mentions a cli/codebot.py that is not in the file list; if it is planned, its commands should be folded into this map.
  • Run or print? Recommend that the CLI runs only safe, reversible commands (status, logs, build, checks) and prints the rest (stop, restart, deploy, sudo commands, anything touching the guest or family copies) for the owner to run. Deploy commits and pushes, so it should not run unasked.
  • npm run dev binds the default port 3505, the same port as the systemd host, so the two cannot run together. Recommend keeping the row with that warning, or dropping it from the CLI.
  • Experiments V2 to V4 live in other private repos. Recommend keeping them as one group under this CLI because the README launches them from here. The alternative is a separate CLI for them.
  • The Supabase dashboard link is derived from the project ref in the runbook. Confirm it opens. The runbook also names gmail-relay as a function but gives no deploy command for it; confirm whether to list one.
  • The docs screen has 18 rows. Recommend one screen for now, and a split into 'docs' and 'docs, design' (design method, design rulings, playground) once it passes about 15 rows. Say yes to split now, or keep it.
  • The behaviour test steps in .bdd/steps have no npm script. Which command runs them? Until one is named, the row points at the folder.
As phone screens

Home

The command line for CodeBot on this machine: the owner's CodeBot, the guest and family copies, and where their files, docs and accounts live.

Owner's CodeBotPrints the owner's CodeBot screen: starting, stopping and checking the host on port 3505.
›
DeployPrints the deploy screen: building, restarting and verifying a new version of the owner's CodeBot.
›
ChecksPrints the check screen: type checks, tests and review scripts.
›
DataPrints the data screen: where the owner's data lives, and the steps to back it up, restore it or reset someone's onboarding.
›
Guest CodeBotPrints the guest screen: the second CodeBot on this machine for another person.
›
Family CodeBotsPrints the family screen: the sign-in front door and one CodeBot for each family member.
›
Account servicePrints the account screen: the shared sign-in service and its deploy steps.
›
ExperimentsPrints the experiments screen: three experimental apps that reuse CodeBot's server.
›
DocsPrints the docs screen: the guides, plans and behaviour records, each opened from its file.
›
‹ Home

run

The owner's CodeBot on this machine: its state, its log, and the addresses it answers on.

Start the owner's CodeBotStarts the owner's host on port 3505, the one you sign in to.
›
Stop the owner's CodeBotStops the host cleanly, ending running turns and closing browser work.
›
Owner's CodeBot statusPrints whether the host is running and when it last started.
›
Owner's CodeBot logPrints the last 80 log lines of the host.
›
Host answers checkChecks that the host on port 3505 answers, and prints its session state.
›
Owner's CodeBot in the browserOpens the owner's CodeBot at its private address.
›
Host diagnosticsOpens the host's counters and lifecycle state; sign-in is required.
›
Private address mappingPrints which private address reaches the host through Tailscale.
›
Start the QA copyStarts the disposable QA copy on port 3506, for trying changes before they reach the owner.
›
Development serverRuns the host from this checkout and restarts it on every code change.
›
Terminal broker statusPrints whether the per-user terminal broker is running.
›
‹ Home

deploy

Putting a change into the owner's CodeBot: the steps from code to a running host.

Deploy the checkoutDeploys the current code: builds, commits, pushes, restarts the host and verifies it, waiting while a Bot works.
›
Build a releaseBuilds a new release and swaps it in only when the build succeeds.
›
Install dependenciesInstalls the exact locked dependencies before a build.
›
Restart the owner's CodeBotRestarts the host to load a new build, after active turns and recordings finish.
›
Kept releasesOpens the kept releases: the current one and the two before it.
›
Deploy guardBlocks finishing a turn while code is unpushed, newer than the running service, or newer than the served build.
›
Install and update stepsOpens the install and update steps.
›
Service unitOpens the systemd unit that runs the host.
›
‹ Home

check

The checks and review scripts for this project, run from the checkout.

TypecheckCompiles the code with the TypeScript checker, writing no files.
›
TestsRuns the Gmail automation tests against a fake Google server.
›
Typecheck and testsRuns the typecheck, then the service tests.
›
Build the QA copyTypechecks, then builds the bundle for the QA copy.
›
Review GmailRuns the Gmail review script.
›
Review schedulesRuns the schedules review script.
›
Regenerate Gmail referenceRegenerates the Gmail reference document from the code.
›
Sync agent instructionsRegenerates AGENTS.md from CLAUDE.md.
›
Design playgroundStarts the design playground on 127.0.0.1 and opens the Gmail sample.
›
Behaviour test stepsOpens the behaviour test steps; no runner script is listed in package.json yet.
›
‹ Home

data

The owner's data on this machine: where it lives, and the steps to back it up, restore it or reset someone's onboarding.

Data folderOpens the data folder: the database, sessions and media.
›
DatabaseOpens the owner's database file.
›
Entrance keyOpens the key a new device needs to connect; its value is never printed.
›
Settings fileOpens the private settings file; its values are never printed.
›
Project foldersOpens the folders Bots may reach, set by CODEBOT_PROJECT_ROOTS.
›
Backups folderOpens the folder of backups.
›
Make a backupOpens the steps that stop the host and copy its data.
›
Restore a backupOpens the steps that restore into a separate folder first.
›
Emergency stop and rollbackOpens the steps for stopping the host at once or rolling back.
›
Reset someone's onboardingOpens the steps for showing one person the onboarding again.
›
‹ Home

guest

The guest CodeBot: a second CodeBot on this machine for another person, run as its own Linux user.

Guest statusPrints whether the guest's CodeBot is running.
›
Guest logPrints the guest's CodeBot log.
›
Guest disk usePrints how much disk the guest's CodeBot uses.
›
Guest CodeBot in the browserOpens the guest's CodeBot at its private address.
›
Packaged guest copyOpens the packaged copy the guest service runs.
›
Update the guestBuilds the current version, replaces the guest copy and restarts it; needs no password.
›
Invite someoneMakes a one-use Google invite link, valid for ten minutes.
›
Install the guest (once)Sets up the guest user, service, settings, sudo rules and Tailscale port 10000.
›
Remove the guestOpens the removal steps; they are not run from here.
›
‹ Home

family

The family CodeBots: the sign-in front door and one CodeBot for each family member, on the home Wi-Fi.

Family statusPrints which family CodeBots are running, and whether each can connect Gmail.
›
Family logPrints the front door's and the family CodeBots' log.
›
Family sign-in pageOpens the family sign-in page.
›
Add a family CodeBotCreates a CodeBot for family member N, up to six.
›
Remove a family CodeBotDeletes that CodeBot and frees its number; the Google account stays linked for good.
›
Stop all family CodeBotsStops every family CodeBot.
›
Start all family CodeBotsStarts every family CodeBot.
›
Update the familyBuilds, replaces the family copy and restarts all of them; needs no password.
›
Install the family (once)Sets up the front door, helper, services, sudo rules and nginx.
›
Root helperOpens the root helper script that adds, removes and reports on family CodeBots.
›
Family settingsOpens the settings file the helper reads.
›
Family runbookOpens the family setup, address and removal steps.
›
‹ Home

account

The shared account service that handles sign-in and the host handshake, and the steps that depend on this machine's address.

Account service dashboardOpens the account service project in Supabase.
›
Command-line tokenOpens the token file the Supabase command line uses; its value is never printed.
›
Deploy host-accessDeploys the host-access function; redeploy whenever a contract it parses changes.
›
Account service functionsOpens the gmail-relay and host-access functions.
›
Database migrationsOpens the database migrations in order.
›
Change this machine's addressOpens the checklist of every place that holds the address, and the order to change them.
›
‹ Home

experiments

Three experimental apps that reuse CodeBot's server. Each is in its own private repo and runs on this computer only.

V2 Terminal chatPrints the V2 screen: CodeBot's look, where a Bot's chat is the Claude Code terminal, on port 3512.
›
V3 Claude Code modPrints the V3 screen: Claude Code first, with a mod drawing the Bot list above the prompt, on port 3513.
›
V4 Launcher menuPrints the V4 screen: a simple main menu whose buttons set up Claude Code sessions, on port 3514.
›
‹ experiments

v2

The V2 Terminal chat app: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.

Start V2Starts V2 on port 3512; run it in its own terminal.
›
V2 in ChromeOpens V2 in the browser.
›
V2 folderOpens the V2 project folder.
›
Process holding port 3512Prints the process that holds the port, which is the one to stop.
›
V2 notesOpens the owner's vision, decision log and report for V2.
›
‹ experiments

v3

The V3 Claude Code mod app: Claude Code first, with a mod drawing the Bot list above the prompt.

Start V3Starts V3 on port 3513; run it in its own terminal.
›
V3 in ChromeOpens V3 in the browser.
›
V3 folderOpens the V3 project folder.
›
Process holding port 3513Prints the process that holds the port, which is the one to stop.
›
List background sessionsPrints the ids of V3's background Claude Code sessions.
›
Stop an old test BotStops one background Claude Code session by its id.
›
V3 notesOpens the owner's vision, decision log and report for V3.
›
‹ experiments

v4

The V4 Launcher menu app: a simple main menu whose buttons set up the Claude Code sessions.

Start V4Starts V4 on port 3514; run it in its own terminal.
›
V4 in ChromeOpens V4 in the browser.
›
V4 folderOpens the V4 project folder.
›
Process holding port 3514Prints the process that holds the port, which is the one to stop.
›
V4 notesOpens the owner's vision, decision log and report for V4.
›
‹ Home

docs

The guides, records and plans for this project, each opened from its file.

OverviewOpens the README: what CodeBot is, how it runs and how it is verified.
›
Behaviour contractOpens the behaviour contract.
›
ArchitectureOpens how CodeBot is built and where its boundaries lie.
›
Open workOpens the remaining checklist and the safe restart state.
›
Implementation statusOpens what has been built so far.
›
Standing rulesOpens the fundamentals every task assumes; AGENTS.md is generated from it.
›
Operations runbookOpens the runbook for running, backing up and recovering the host.
›
Gmail for BotsOpens the Gmail setup and supervisor guide.
›
Gmail referenceOpens the generated Gmail reference.
›
Design methodOpens the method for designing screens.
›
Design rulingsOpens the owner's design rulings and rejections.
›
PlansOpens the plan documents, one per piece of work.
›
ObjectivesOpens the product objectives.
›
Verification recordsOpens the recorded evidence that work was checked.
›
Module intentsOpens the intent record of each module: its constraints and tests.
›
Behaviour featuresOpens the Given, When, Then behaviour features.
›
QA findings and resolutionsOpens the QA findings and how each was resolved.
›
Housekeeping skillOpens the housekeeping skill.
›
Raw answer
## Scenario (reasoning from experience)

The owner runs this machine's CodeBot from a desktop terminal, usually after a change, to see whether the host is up, read its log, or back up before something risky. Less often they invite a guest, add a family member, or rotate the address. The CLI should answer "where is it, what does it do, and what's the one command I need" without the runbook open.

## Judgment calls

- **Top level has nine groups**, each named in the owner's words (`run`, `deploy`, `data`, `guest`, `family`, `account`, `experiments`, `docs`, `check`). That keeps the first screen short.
- **Experiments V2 to V4 each get a screen.** Each has its own port, folder and stop procedure.
- **Destructive or high-stakes steps are runbook links, not commands**: restore, full reset, forced kill, removing a guest, changing the address. The map points to the section in `ops/OPERATIONS.md`.
- **Secrets are opened, never printed.** `service.env` and `owner-key` appear as "opens the file" rows only.
- **Three columns are enough.** A fourth "needs sudo" column would add noise, so sudo is written into the command.
- **Some files are named in the README but are not in the dump** (`PRODUCT-SPEC.md`, `IMPLEMENTATION-STATUS.md`, `DEFERRED-WORK.md`). They are mapped on the assumption they exist at the repo root. Verify before building.
- **The Supabase dashboard URL is derived** from the project ref in the runbook, not copied from a link in the dump.

The open decisions are in `questions` at the end of the JSON. The two that block building are the command name and whether commands run or only print.

```json
{"screens": [
{"path": [], "sentence": "The command line for CodeBot on this machine: the owner's CodeBot, the guest and family copies, and where their files, docs and accounts live.", "rows": [
{"name": "Owner's CodeBot", "form": "codebot run", "what": "Prints the owner's CodeBot screen: starting, stopping and checking the host on port 3505."},
{"name": "Deploy", "form": "codebot deploy", "what": "Prints the deploy screen: building, restarting and verifying a new version of the owner's CodeBot."},
{"name": "Checks", "form": "codebot check", "what": "Prints the check screen: type checks, tests and review scripts."},
{"name": "Data", "form": "codebot data", "what": "Prints the data screen: where the owner's data lives, and the steps to back it up, restore it or reset someone's onboarding."},
{"name": "Guest CodeBot", "form": "codebot guest", "what": "Prints the guest screen: the second CodeBot on this machine for another person."},
{"name": "Family CodeBots", "form": "codebot family", "what": "Prints the family screen: the sign-in front door and one CodeBot for each family member."},
{"name": "Account service", "form": "codebot account", "what": "Prints the account screen: the shared sign-in service and its deploy steps."},
{"name": "Experiments", "form": "codebot experiments", "what": "Prints the experiments screen: three experimental apps that reuse CodeBot's server."},
{"name": "Docs", "form": "codebot docs", "what": "Prints the docs screen: the guides, plans and behaviour records, each opened from its file."}
]},
{"path": ["run"], "sentence": "The owner's CodeBot on this machine: its state, its log, and the addresses it answers on.", "rows": [
{"name": "Start the owner's CodeBot", "form": "systemctl --user start codebot.service", "what": "Starts the owner's host on port 3505, the one you sign in to."},
{"name": "Stop the owner's CodeBot", "form": "systemctl --user stop codebot.service", "what": "Stops the host cleanly, ending running turns and closing browser work."},
{"name": "Owner's CodeBot status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether the host is running and when it last started."},
{"name": "Owner's CodeBot log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the host."},
{"name": "Host answers check", "form": "curl --fail --silent http://127.0.0.1:3505/api/session", "what": "Checks that the host on port 3505 answers, and prints its session state."},
{"name": "Owner's CodeBot in the browser", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the owner's CodeBot at its private address."},
{"name": "Host diagnostics", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/host", "what": "Opens the host's counters and lifecycle state; sign-in is required."},
{"name": "Private address mapping", "form": "tailscale serve status --json", "what": "Prints which private address reaches the host through Tailscale."},
{"name": "Start the QA copy", "form": "systemctl --user start codebot-integration.service", "what": "Starts the disposable QA copy on port 3506, for trying changes before they reach the owner."},
{"name": "Development server", "form": "npm run dev", "what": "Runs the host from this checkout and restarts it on every code change."},
{"name": "Terminal broker status", "form": "systemctl --user status codebot-terminal-broker.service", "what": "Prints whether the per-user terminal broker is running."}
]},
{"path": ["deploy"], "sentence": "Putting a change into the owner's CodeBot: the steps from code to a running host.", "rows": [
{"name": "Deploy the checkout", "form": "sh ops/deploy.sh", "what": "Deploys the current code: builds, commits, pushes, restarts the host and verifies it, waiting while a Bot works."},
{"name": "Build a release", "form": "npm run build", "what": "Builds a new release and swaps it in only when the build succeeds."},
{"name": "Install dependencies", "form": "npm ci", "what": "Installs the exact locked dependencies before a build."},
{"name": "Restart the owner's CodeBot", "form": "systemctl --user restart codebot.service", "what": "Restarts the host to load a new build, after active turns and recordings finish."},
{"name": "Kept releases", "form": "dist/releases/", "what": "Opens the kept releases: the current one and the two before it."},
{"name": "Deploy guard", "form": "ops/deploy-guard.sh", "what": "Blocks finishing a turn while code is unpushed, newer than the running service, or newer than the served build."},
{"name": "Install and update steps", "form": "ops/OPERATIONS.md (section: Install or update the host)", "what": "Opens the install and update steps."},
{"name": "Service unit", "form": "ops/codebot.service", "what": "Opens the systemd unit that runs the host."}
]},
{"path": ["check"], "sentence": "The checks and review scripts for this project, run from the checkout.", "rows": [
{"name": "Typecheck", "form": "npm run typecheck", "what": "Compiles the code with the TypeScript checker, writing no files."},
{"name": "Tests", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
{"name": "Typecheck and tests", "form": "npm run check", "what": "Runs the typecheck, then the service tests."},
{"name": "Build the QA copy", "form": "npm run build:integration", "what": "Typechecks, then builds the bundle for the QA copy."},
{"name": "Review Gmail", "form": "npm run review:gmail", "what": "Runs the Gmail review script."},
{"name": "Review schedules", "form": "npm run review:schedules", "what": "Runs the schedules review script."},
{"name": "Regenerate Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates the Gmail reference document from the code."},
{"name": "Sync agent instructions", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."},
{"name": "Design playground", "form": "npm run playground", "what": "Starts the design playground on 127.0.0.1 and opens the Gmail sample."},
{"name": "Behaviour test steps", "form": ".bdd/steps/", "what": "Opens the behaviour test steps; no runner script is listed in package.json yet."}
]},
{"path": ["data"], "sentence": "The owner's data on this machine: where it lives, and the steps to back it up, restore it or reset someone's onboarding.", "rows": [
{"name": "Data folder", "form": "~/.local/share/codebot", "what": "Opens the data folder: the database, sessions and media."},
{"name": "Database", "form": "~/.local/share/codebot/codebot.sqlite", "what": "Opens the owner's database file."},
{"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Opens the key a new device needs to connect; its value is never printed."},
{"name": "Settings file", "form": "~/.config/codebot/service.env", "what": "Opens the private settings file; its values are never printed."},
{"name": "Project folders", "form": "~/projects", "what": "Opens the folders Bots may reach, set by CODEBOT_PROJECT_ROOTS."},
{"name": "Backups folder", "form": "~/.local/share/codebot-backups", "what": "Opens the folder of backups."},
{"name": "Make a backup", "form": "ops/OPERATIONS.md (section: Back up a consistent installation)", "what": "Opens the steps that stop the host and copy its data."},
{"name": "Restore a backup", "form": "ops/OPERATIONS.md (section: Restore into a separate directory first)", "what": "Opens the steps that restore into a separate folder first."},
{"name": "Emergency stop and rollback", "form": "ops/OPERATIONS.md (section: Emergency stop and rollback)", "what": "Opens the steps for stopping the host at once or rolling back."},
{"name": "Reset someone's onboarding", "form": "ops/OPERATIONS.md (section: Reset someone's onboarding)", "what": "Opens the steps for showing one person the onboarding again."}
]},
{"path": ["guest"], "sentence": "The guest CodeBot: a second CodeBot on this machine for another person, run as its own Linux user.", "rows": [
{"name": "Guest status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest's CodeBot is running."},
{"name": "Guest log", "form": "journalctl -u codebot-guest", "what": "Prints the guest's CodeBot log."},
{"name": "Guest disk use", "form": "sudo du -sh /home/codebot-guest", "what": "Prints how much disk the guest's CodeBot uses."},
{"name": "Guest CodeBot in the browser", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's CodeBot at its private address."},
{"name": "Packaged guest copy", "form": "/opt/codebot-guest", "what": "Opens the packaged copy the guest service runs."},
{"name": "Update the guest", "form": "ops/guest-update.sh", "what": "Builds the current version, replaces the guest copy and restarts it; needs no password."},
{"name": "Invite someone", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Makes a one-use Google invite link, valid for ten minutes."},
{"name": "Install the guest (once)", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, service, settings, sudo rules and Tailscale port 10000."},
{"name": "Remove the guest", "form": "ops/OPERATIONS.md (section: Host a guest on this machine)", "what": "Opens the removal steps; they are not run from here."}
]},
{"path": ["family"], "sentence": "The family CodeBots: the sign-in front door and one CodeBot for each family member, on the home Wi-Fi.", "rows": [
{"name": "Family status", "form": "sudo codebot-family status", "what": "Prints which family CodeBots are running, and whether each can connect Gmail."},
{"name": "Family log", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the front door's and the family CodeBots' log."},
{"name": "Family sign-in page", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in page."},
{"name": "Add a family CodeBot", "form": "sudo codebot-family add N", "what": "Creates a CodeBot for family member N, up to six."},
{"name": "Remove a family CodeBot", "form": "sudo codebot-family remove N", "what": "Deletes that CodeBot and frees its number; the Google account stays linked for good."},
{"name": "Stop all family CodeBots", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
{"name": "Start all family CodeBots", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot."},
{"name": "Update the family", "form": "ops/family-update.sh", "what": "Builds, replaces the family copy and restarts all of them; needs no password."},
{"name": "Install the family (once)", "form": "sudo ops/family-install.sh", "what": "Sets up the front door, helper, services, sudo rules and nginx."},
{"name": "Root helper", "form": "/usr/local/sbin/codebot-family", "what": "Opens the root helper script that adds, removes and reports on family CodeBots."},
{"name": "Family settings", "form": "/etc/codebot-family.conf", "what": "Opens the settings file the helper reads."},
{"name": "Family runbook", "form": "ops/OPERATIONS.md (section: Home Wi-Fi address)", "what": "Opens the family setup, address and removal steps."}
]},
{"path": ["account"], "sentence": "The shared account service that handles sign-in and the host handshake, and the steps that depend on this machine's address.", "rows": [
{"name": "Account service dashboard", "form": "https://supabase.com/dashboard/project/wbgrjvqbupgdclaztuou", "what": "Opens the account service project in Supabase."},
{"name": "Command-line token", "form": "~/.config/supabase-codebot-token", "what": "Opens the token file the Supabase command line uses; its value is never printed."},
{"name": "Deploy host-access", "form": "SUPABASE_ACCESS_TOKEN=\"$(cat ~/.config/supabase-codebot-token)\" npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function; redeploy whenever a contract it parses changes."},
{"name": "Account service functions", "form": "supabase/functions/", "what": "Opens the gmail-relay and host-access functions."},
{"name": "Database migrations", "form": "supabase/migrations/", "what": "Opens the database migrations in order."},
{"name": "Change this machine's address", "form": "ops/OPERATIONS.md (section: Change this machine's address)", "what": "Opens the checklist of every place that holds the address, and the order to change them."}
]},
{"path": ["experiments"], "sentence": "Three experimental apps that reuse CodeBot's server. Each is in its own private repo and runs on this computer only.", "rows": [
{"name": "V2 Terminal chat", "form": "codebot experiments v2", "what": "Prints the V2 screen: CodeBot's look, where a Bot's chat is the Claude Code terminal, on port 3512."},
{"name": "V3 Claude Code mod", "form": "codebot experiments v3", "what": "Prints the V3 screen: Claude Code first, with a mod drawing the Bot list above the prompt, on port 3513."},
{"name": "V4 Launcher menu", "form": "codebot experiments v4", "what": "Prints the V4 screen: a simple main menu whose buttons set up Claude Code sessions, on port 3514."}
]},
{"path": ["experiments", "v2"], "sentence": "The V2 Terminal chat app: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.", "rows": [
{"name": "Start V2", "form": "cd ~/projects/codebot-v2-terminal-chat && sh ops/app-run.sh dev", "what": "Starts V2 on port 3512; run it in its own terminal."},
{"name": "V2 in Chrome", "form": "http://127.0.0.1:3512", "what": "Opens V2 in the browser."},
{"name": "V2 folder", "form": "~/projects/codebot-v2-terminal-chat", "what": "Opens the V2 project folder."},
{"name": "Process holding port 3512", "form": "ss -ltnp | grep :3512", "what": "Prints the process that holds the port, which is the one to stop."},
{"name": "V2 notes", "form": "~/projects/codebot-v2-terminal-chat/docs/experiment/", "what": "Opens the owner's vision, decision log and report for V2."}
]},
{"path": ["experiments", "v3"], "sentence": "The V3 Claude Code mod app: Claude Code first, with a mod drawing the Bot list above the prompt.", "rows": [
{"name": "Start V3", "form": "cd ~/projects/codebot-v3-claude-mod && sh ops/app-run.sh dev", "what": "Starts V3 on port 3513; run it in its own terminal."},
{"name": "V3 in Chrome", "form": "http://127.0.0.1:3513", "what": "Opens V3 in the browser."},
{"name": "V3 folder", "form": "~/projects/codebot-v3-claude-mod", "what": "Opens the V3 project folder."},
{"name": "Process holding port 3513", "form": "ss -ltnp | grep :3513", "what": "Prints the process that holds the port, which is the one to stop."},
{"name": "List background sessions", "form": "claude agents", "what": "Prints the ids of V3's background Claude Code sessions."},
{"name": "Stop an old test Bot", "form": "claude stop <id>", "what": "Stops one background Claude Code session by its id."},
{"name": "V3 notes", "form": "~/projects/codebot-v3-claude-mod/docs/experiment/", "what": "Opens the owner's vision, decision log and report for V3."}
]},
{"path": ["experiments", "v4"], "sentence": "The V4 Launcher menu app: a simple main menu whose buttons set up the Claude Code sessions.", "rows": [
{"name": "Start V4", "form": "cd ~/projects/codebot-v4-launcher-menu && sh ops/app-run.sh dev", "what": "Starts V4 on port 3514; run it in its own terminal."},
{"name": "V4 in Chrome", "form": "http://127.0.0.1:3514", "what": "Opens V4 in the browser."},
{"name": "V4 folder", "form": "~/projects/codebot-v4-launcher-menu", "what": "Opens the V4 project folder."},
{"name": "Process holding port 3514", "form": "ss -ltnp | grep :3514", "what": "Prints the process that holds the port, which is the one to stop."},
{"name": "V4 notes", "form": "~/projects/codebot-v4-launcher-menu/docs/experiment/", "what": "Opens the owner's vision, decision log and report for V4."}
]},
{"path": ["docs"], "sentence": "The guides, records and plans for this project, each opened from its file.", "rows": [
{"name": "Overview", "form": "README.md", "what": "Opens the README: what CodeBot is, how it runs and how it is verified."},
{"name": "Behaviour contract", "form": "PRODUCT-SPEC.md", "what": "Opens the behaviour contract."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how CodeBot is built and where its boundaries lie."},
{"name": "Open work", "form": "DEFERRED-WORK.md", "what": "Opens the remaining checklist and the safe restart state."},
{"name": "Implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what has been built so far."},
{"name": "Standing rules", "form": "CLAUDE.md", "what": "Opens the fundamentals every task assumes; AGENTS.md is generated from it."},
{"name": "Operations runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for running, backing up and recovering the host."},
{"name": "Gmail for Bots", "form": "docs/automation/gmail.md", "what": "Opens the Gmail setup and supervisor guide."},
{"name": "Gmail reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference."},
{"name": "Design method", "form": "docs/design-method.md", "what": "Opens the method for designing screens."},
{"name": "Design rulings", "form": "docs/design-taste.md", "what": "Opens the owner's design rulings and rejections."},
{"name": "Plans", "form": "docs/plans/", "what": "Opens the plan documents, one per piece of work."},
{"name": "Objectives", "form": "docs/objectives/README.md", "what": "Opens the product objectives."},
{"name": "Verification records", "form": "docs/verification/", "what": "Opens the recorded evidence that work was checked."},
{"name": "Module intents", "form": ".idd/modules/", "what": "Opens the intent record of each module: its constraints and tests."},
{"name": "Behaviour features", "form": ".bdd/features/", "what": "Opens the Given, When, Then behaviour features."},
{"name": "QA findings and resolutions", "form": ".bdd/qa/", "what": "Opens the QA findings and how each was resolved."},
{"name": "Housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the housekeeping skill."}
]}
],
"questions": [
"Name and alias. Recommend the top command is 'codebot' with 'cb' as the short alias, if whence and type show no clash. The README mentions a cli/codebot.py that is not in the file list; if it is planned, its commands should be folded into this map.",
"Run or print? Recommend that the CLI runs only safe, reversible commands (status, logs, build, checks) and prints the rest (stop, restart, deploy, sudo commands, anything touching the guest or family copies) for the owner to run. Deploy commits and pushes, so it should not run unasked.",
"npm run dev binds the default port 3505, the same port as the systemd host, so the two cannot run together. Recommend keeping the row with that warning, or dropping it from the CLI.",
"Experiments V2 to V4 live in other private repos. Recommend keeping them as one group under this CLI because the README launches them from here. The alternative is a separate CLI for them.",
"The Supabase dashboard link is derived from the project ref in the runbook. Confirm it opens. The runbook also names gmail-relay as a function but gives no deploy command for it; confirm whether to list one.",
"The docs screen has 18 rows. Recommend one screen for now, and a split into 'docs' and 'docs, design' (design method, design rulings, playground) once it passes about 15 rows. Say yes to split now, or keep it.",
"The behaviour test steps in .bdd/steps have no npm script. Which command runs them? Until one is named, the row points at the folder."
]}
```

screen-decomposition, first draft · run 1 exit=0 seconds=101 · prompt

P1 Recall: 0.436P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.947P5 Short top: 5P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.433
As terminal help
The top of CodeBot: the Bots you steer, this CodeBot's settings, and the operator's places for the running host, the scripts and the docs.
Botsscreen: bots (apps/web/src/App.tsx)Opens the list of Bots, each with what it is doing and whether it needs you.
Settingsscreen: settings (apps/web/src/ui/Settings.tsx)Opens this CodeBot's notification, Gmail and update settings.
Hostscreen: host (ops/OPERATIONS.md)Opens the operator's places for the running service, its data, guests, family and address.
Scriptsscreen: scripts (package.json)Opens the npm scripts that run, check, build and review the checkout.
Docsscreen: docs (README.md, docs/)Opens the written docs: layout, architecture, runbook, open work and recorded evidence.
bots
The Bots you have, each with what it is doing and whether it needs you.
A Botscreen: bots > Bot (apps/web/src/workspace/)Opens one Bot's conversation, files, widgets and settings.
New Botapps/web/src/workspace/BotForm.tsxCreates a Bot from a name, a role, a provider and a home folder.
First-use tourapps/web/src/onboarding/Onboarding.tsxShows the tour that creates a first Bot for a new account.
bots › Bot
The conversation with one Bot, with its files, widgets and settings.
Chatscreen: bots > Bot > chatShows the conversation and the queue of messages waiting for this Bot.
Terminalapps/web/src/TerminalTab.tsxOpens this Bot's terminal, the shell it works in on this host.
Pinned filesapps/web/src/resources/PinnedFiles.tsxLists the files pinned to this Bot and opens each one.
Attach a fileapps/web/src/resources/AttachmentPicker.tsxAttaches a file to the next message.
Recordingsapps/web/src/resources/RecordingPlayer.tsxPlays a recording of this Bot's browser work.
Visionscreen: bots > Bot > visionShows the live Chromium page this Bot is using.
Screenshotsscreen: bots > Bot > screenshotsShows the screenshots this Bot has captured, newest first.
Feature contractapps/web/src/contracts/ContractCatalog.tsxOpens this Bot's feature contract: its catalog, files, history and conflicts.
Gitscreen: bots > Bot > gitShows the repository's status and its quick git actions.
Gmail widgetapps/web/src/widgets/GmailWidget.tsxShows the Gmail items this Bot needs approved or has handled.
Widgetsapps/web/src/widgets/WidgetBrowser.tsxAdds, removes or rearranges the widgets on this Bot's surface.
Avatarapps/web/src/workspace/AvatarStudio.tsxDesigns this Bot's avatar.
Schedulesscreen: bots > Bot > schedules (docs/objectives/schedules.md)Lists the wakeups scheduled for this Bot.
Bot settingsapps/web/src/workspace/BotForm.tsxEdits this Bot's name, role, provider, model, folder and notifications.
settings
This CodeBot's own settings: notifications on this device, Gmail, and updates.
Notificationsapps/web/src/pwa/DeviceNotifications.tsxEnables notifications on this device, sends it a test, and removes old devices.
Gmail accessapps/web/src/gmail/GmailAccess.tsxConnects the Google account the Bots use for Gmail.
Gmail activityapps/web/src/gmail/GmailActivity.tsxShows what Bots did with Gmail and the day's summary.
Update noticeapps/web/src/pwa/UpdateNotice.tsxShows what changed after an update, from apps/web/src/whatsNew.ts.
Install on phonedocs/OPERATIONS.md (Private access and PWA installation)Adds CodeBot to the phone's Home Screen from the private HTTPS address.
host
The operator's place for the service running on this machine: its status, logs, deployment and sub-areas.
Service statussystemctl --user status codebot.service --no-pagerPrints whether codebot.service runs and its last state.
Service logjournalctl --user -u codebot.service -n 80 --no-pagerPrints the service's last 80 log lines.
Restartsystemctl --user restart codebot.serviceRestarts the service once active turns and recordings finish.
Deploysh ops/deploy.shBuilds, pushes, waits its turn, restarts the service and verifies it.
Buildnpm run buildType-checks and builds a new web release, keeping the served one if the build fails.
Host diagnostics/api/diagnostics/host (from an authenticated browser)Shows the host's migration, queued turns and recovery hold.
Owner key~/.local/share/codebot/owner-keyPrints the entrance key used to connect a new device; keep it private.
Datascreen: host > dataOpens backup, restore, onboarding reset and emergency stop.
Terminal brokerscreen: host > terminalOpens the per-user terminal broker, the unit that holds the shell.
Devicesscreen: host > devicesOpens how a phone or desktop reaches CodeBot over the private address.
Guestscreen: host > guestOpens the second account on this machine for another person.
Familyscreen: host > familyOpens the family CodeBots on the home Wi-Fi address and their helper.
Addressscreen: host > addressOpens the steps to move CodeBot to a new Tailscale name.
Account servicescreen: host > accountOpens the Supabase account service: sign-in, the host handshake and the Gmail relay.
host › data
Backing up, restoring and resetting this host's data.
Back upops/OPERATIONS.md (Back up a consistent installation)Stops the service and copies its data and settings into a private folder.
Verify a restoreops/OPERATIONS.md (Restore into a separate directory first)Restores a backup into a new folder and checks it before promotion.
Replay the tourops/OPERATIONS.md (Replay only the first-use tour)Starts a person's first-use tour again, on a host with no Bots.
Fresh CodeBotops/OPERATIONS.md (Restart onboarding with a fresh CodeBot)Wipes a guest's Bots and conversations and keeps the account.
Full resetops/OPERATIONS.md (Full reset: the person starts as new)Deletes a person's account, Bots and data so they start as new.
Emergency stopops/OPERATIONS.md (Emergency stop and rollback)Stops the service at once and kills it if a normal stop is not enough.
host › guest
The second account on this machine for another person, using the owner's subscriptions.
Installsudo ops/guest-install.shCreates the guest user, its service, settings and sudo rules, once.
Updateops/guest-update.shBuilds the guest's program and restarts its service, with no password.
Invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google invite link, valid for ten minutes.
Statussystemctl status codebot-guestPrints whether the guest service runs.
Removeops/OPERATIONS.md (Host a guest on this machine)Removes the guest's service, user, program and sharing.
host › family
The family CodeBots on the home Wi-Fi address, one per Google account, and their helper.
Installsudo ops/family-install.shSets up the front door, helper, services, sudo rules and nginx, once.
Updateops/family-update.shBuilds the family program and restarts every family CodeBot.
Statussudo codebot-family statusPrints whether each family CodeBot runs and whether its Gmail can connect.
Add a personsudo codebot-family add NCreates family CodeBot N for a new Google account.
Remove a personsudo codebot-family remove NDeletes family CodeBot N and frees its number.
Stop or start allsudo codebot-family stop-all | start-allStops every family CodeBot, or starts them all again.
host › address
The steps to move CodeBot to a new Tailscale name, in order.
Places to changeops/OPERATIONS.md (Change this machine's address)Lists the places that hold the address and why each must change.
Stepsops/OPERATIONS.md (Change this machine's address, steps 1 to 7)Walks the change in order, from Supabase to the domain forward.
Current nametailscale status --jsonPrints this machine's Tailscale name, which becomes the new address.
host › devices
How a phone or desktop reaches CodeBot over the private Tailscale address.
Serve statustailscale serve status --jsonPrints the current private HTTPS mapping, to check before changing it.
Serve maptailscale serve --bg http://127.0.0.1:3505Maps the private HTTPS address to the service on a new machine.
Connect a deviceops/OPERATIONS.md (Connect a device)Adds CodeBot to a phone's Home Screen from the private HTTPS address.
Device notificationsops/OPERATIONS.md (Background notifications)Turns on notifications for one device and sends it a test.
host › terminal
The per-user terminal broker: a separate unit that holds the shell the terminal uses.
Enablesystemctl --user enable --now codebot-terminal-broker.serviceStarts the terminal broker and keeps it running across web-service restarts.
Broker statussystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the broker runs and its listener state.
Lingeringloginctl show-user "$USER" -p LingerPrints whether the user service runs without a desktop login.
host › account
The Supabase account service: sign-in, the host handshake and the Gmail relay.
Deploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouRedeploys the host-access function after a contract it parses changes.
Access token~/.config/supabase-codebot-tokenSupplies the access token that the deploy command reads.
Gmail relaysupabase/functions/gmail-relay/index.tsForwards Google's sign-in return to the user's own server.
Migrationssupabase/migrations/Creates the account tables and rules, applied through Supabase.
scripts
The npm scripts that run, check, build and review the checkout.
devnpm run devStarts the service with reload on each change, for development.
startnpm run startStarts the service in production mode.
typechecknpm run typecheckType-checks the code without building it.
buildnpm run buildType-checks, then builds the web app into a new release.
testnpm run testRuns the Gmail tests against a fake Google server.
checknpm run checkType-checks, then runs the tests.
setup-accountnpm run setup-accountRuns ops/setup-account.ts, the account setup.
docs:gmailnpm run docs:gmailRegenerates docs/automation/gmail-reference.md.
review:gmailnpm run review:gmailRuns the Gmail review in ops/review/gmail-review.mjs.
review:schedulesnpm run review:schedulesRuns the schedules review in ops/review/schedules-review.mjs.
playgroundnpm run playgroundStarts Vite and opens the Gmail playground to compare design variants.
sync:agentsnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
build:integrationnpm run build:integrationType-checks, then builds the integration bundle with ops/build-integration.mjs.
docs
The written docs: how CodeBot is built and run, and what was verified.
READMEREADME.mdOpens the layout, how to run it and the commands.
ArchitectureARCHITECTURE.mdOpens how the pieces are built and what each boundary owns.
Working rulesCLAUDE.mdOpens the rules for working with the owner and designing screens.
Runbookops/OPERATIONS.mdOpens the runbook for installing, running, backing up and recovering.
Open workDEFERRED-WORK.mdOpens the open work and the safe restart state.
Design tastedocs/design-taste.mdOpens the owner's rulings on design.
Design methoddocs/design-method.mdOpens the method for designing and checking screens.
Gmail guidedocs/automation/gmail.mdOpens the guide to how Bots use Gmail.
Plansdocs/plans/Opens the dated plans for past and current work.
Verificationdocs/verification/Opens the recorded test evidence.
Questions
  • Split the Bot screen? It has 14 rows. Recommend moving Vision, Screenshots, Feature contract, Git and Gmail widget behind a widgets screen under Bot, since WidgetBrowser already groups them.
  • Should the operator screens (host, scripts) appear in the app, or only in the terminal help? Recommend terminal only; the owner works from a phone.
  • Is there a cli/codebot.py, and do PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md and MASTER-PLAN.md exist? They are cited in the docs but are not in the dump, so I left them out. If they exist, I will add their rows.
  • Should the owner-key row show only the path, not offer a command that prints the key? Recommend the path only, since the runbook says not to print it.
As phone screens

Home

The top of CodeBot: the Bots you steer, this CodeBot's settings, and the operator's places for the running host, the scripts and the docs.

BotsOpens the list of Bots, each with what it is doing and whether it needs you.
›
SettingsOpens this CodeBot's notification, Gmail and update settings.
›
HostOpens the operator's places for the running service, its data, guests, family and address.
›
ScriptsOpens the npm scripts that run, check, build and review the checkout.
›
DocsOpens the written docs: layout, architecture, runbook, open work and recorded evidence.
›
‹ Home

bots

The Bots you have, each with what it is doing and whether it needs you.

A BotOpens one Bot's conversation, files, widgets and settings.
›
New BotCreates a Bot from a name, a role, a provider and a home folder.
›
First-use tourShows the tour that creates a first Bot for a new account.
›
‹ bots

Bot

The conversation with one Bot, with its files, widgets and settings.

ChatShows the conversation and the queue of messages waiting for this Bot.
›
TerminalOpens this Bot's terminal, the shell it works in on this host.
›
Pinned filesLists the files pinned to this Bot and opens each one.
›
Attach a fileAttaches a file to the next message.
›
RecordingsPlays a recording of this Bot's browser work.
›
VisionShows the live Chromium page this Bot is using.
›
ScreenshotsShows the screenshots this Bot has captured, newest first.
›
Feature contractOpens this Bot's feature contract: its catalog, files, history and conflicts.
›
GitShows the repository's status and its quick git actions.
›
Gmail widgetShows the Gmail items this Bot needs approved or has handled.
›
WidgetsAdds, removes or rearranges the widgets on this Bot's surface.
›
AvatarDesigns this Bot's avatar.
›
SchedulesLists the wakeups scheduled for this Bot.
›
Bot settingsEdits this Bot's name, role, provider, model, folder and notifications.
›
‹ Home

settings

This CodeBot's own settings: notifications on this device, Gmail, and updates.

NotificationsEnables notifications on this device, sends it a test, and removes old devices.
›
Gmail accessConnects the Google account the Bots use for Gmail.
›
Gmail activityShows what Bots did with Gmail and the day's summary.
›
Update noticeShows what changed after an update, from apps/web/src/whatsNew.ts.
›
Install on phoneAdds CodeBot to the phone's Home Screen from the private HTTPS address.
›
‹ Home

host

The operator's place for the service running on this machine: its status, logs, deployment and sub-areas.

Service statusPrints whether codebot.service runs and its last state.
›
Service logPrints the service's last 80 log lines.
›
RestartRestarts the service once active turns and recordings finish.
›
DeployBuilds, pushes, waits its turn, restarts the service and verifies it.
›
BuildType-checks and builds a new web release, keeping the served one if the build fails.
›
Host diagnosticsShows the host's migration, queued turns and recovery hold.
›
Owner keyPrints the entrance key used to connect a new device; keep it private.
›
DataOpens backup, restore, onboarding reset and emergency stop.
›
Terminal brokerOpens the per-user terminal broker, the unit that holds the shell.
›
DevicesOpens how a phone or desktop reaches CodeBot over the private address.
›
GuestOpens the second account on this machine for another person.
›
FamilyOpens the family CodeBots on the home Wi-Fi address and their helper.
›
AddressOpens the steps to move CodeBot to a new Tailscale name.
›
Account serviceOpens the Supabase account service: sign-in, the host handshake and the Gmail relay.
›
‹ host

data

Backing up, restoring and resetting this host's data.

Back upStops the service and copies its data and settings into a private folder.
›
Verify a restoreRestores a backup into a new folder and checks it before promotion.
›
Replay the tourStarts a person's first-use tour again, on a host with no Bots.
›
Fresh CodeBotWipes a guest's Bots and conversations and keeps the account.
›
Full resetDeletes a person's account, Bots and data so they start as new.
›
Emergency stopStops the service at once and kills it if a normal stop is not enough.
›
‹ host

guest

The second account on this machine for another person, using the owner's subscriptions.

InstallCreates the guest user, its service, settings and sudo rules, once.
›
UpdateBuilds the guest's program and restarts its service, with no password.
›
InvitePrints a one-use Google invite link, valid for ten minutes.
›
StatusPrints whether the guest service runs.
›
RemoveRemoves the guest's service, user, program and sharing.
›
‹ host

family

The family CodeBots on the home Wi-Fi address, one per Google account, and their helper.

InstallSets up the front door, helper, services, sudo rules and nginx, once.
›
UpdateBuilds the family program and restarts every family CodeBot.
›
StatusPrints whether each family CodeBot runs and whether its Gmail can connect.
›
Add a personCreates family CodeBot N for a new Google account.
›
Remove a personDeletes family CodeBot N and frees its number.
›
Stop or start allStops every family CodeBot, or starts them all again.
›
‹ host

address

The steps to move CodeBot to a new Tailscale name, in order.

Places to changeLists the places that hold the address and why each must change.
›
StepsWalks the change in order, from Supabase to the domain forward.
›
Current namePrints this machine's Tailscale name, which becomes the new address.
›
‹ host

devices

How a phone or desktop reaches CodeBot over the private Tailscale address.

Serve statusPrints the current private HTTPS mapping, to check before changing it.
›
Serve mapMaps the private HTTPS address to the service on a new machine.
›
Connect a deviceAdds CodeBot to a phone's Home Screen from the private HTTPS address.
›
Device notificationsTurns on notifications for one device and sends it a test.
›
‹ host

terminal

The per-user terminal broker: a separate unit that holds the shell the terminal uses.

EnableStarts the terminal broker and keeps it running across web-service restarts.
›
Broker statusPrints whether the broker runs and its listener state.
›
LingeringPrints whether the user service runs without a desktop login.
›
‹ host

account

The Supabase account service: sign-in, the host handshake and the Gmail relay.

Deploy host-accessRedeploys the host-access function after a contract it parses changes.
›
Access tokenSupplies the access token that the deploy command reads.
›
Gmail relayForwards Google's sign-in return to the user's own server.
›
MigrationsCreates the account tables and rules, applied through Supabase.
›
‹ Home

scripts

The npm scripts that run, check, build and review the checkout.

devStarts the service with reload on each change, for development.
›
startStarts the service in production mode.
›
typecheckType-checks the code without building it.
›
buildType-checks, then builds the web app into a new release.
›
testRuns the Gmail tests against a fake Google server.
›
checkType-checks, then runs the tests.
›
setup-accountRuns ops/setup-account.ts, the account setup.
›
docs:gmailRegenerates docs/automation/gmail-reference.md.
›
review:gmailRuns the Gmail review in ops/review/gmail-review.mjs.
›
review:schedulesRuns the schedules review in ops/review/schedules-review.mjs.
›
playgroundStarts Vite and opens the Gmail playground to compare design variants.
›
sync:agentsRegenerates AGENTS.md from CLAUDE.md.
›
build:integrationType-checks, then builds the integration bundle with ops/build-integration.mjs.
›
‹ Home

docs

The written docs: how CodeBot is built and run, and what was verified.

READMEOpens the layout, how to run it and the commands.
›
ArchitectureOpens how the pieces are built and what each boundary owns.
›
Working rulesOpens the rules for working with the owner and designing screens.
›
RunbookOpens the runbook for installing, running, backing up and recovering.
›
Open workOpens the open work and the safe restart state.
›
Design tasteOpens the owner's rulings on design.
›
Design methodOpens the method for designing and checking screens.
›
Gmail guideOpens the guide to how Bots use Gmail.
›
PlansOpens the dated plans for past and current work.
›
VerificationOpens the recorded test evidence.
›
Raw answer
**Scenario** (from `CLAUDE.md`, `ops/OPERATIONS.md`, reasoning from experience): the owner opens CodeBot on a phone to see which Bot needs them, read its chat, and steer it. The operator, at the workstation, checks the service, deploys, backs up, and recovers when something breaks.

**Inventory:** every item on the screens below. Its form is a file, command, URL, or the screen itself. I read only the dump, so I could not run anything or confirm files outside it. `OPERATIONS.md` was cut at 32,000 characters and `ARCHITECTURE.md` at 14,000, so some runbook detail may be missing.

**Judgment calls**
- Owner screens come first, since the owner is phone-first. Operator screens sit under `host` and `scripts`.
- Where the component file for a screen was not in the dump (chat, Vision, screenshots, Git, schedules), its form is the screen path, not a guessed file.
- Runbook steps stay in `OPERATIONS.md`, and the map links to their section instead of retyping them (one source).
- `owner-key` is listed by path only. The runbook says not to print it, so its row says it prints the key.
- `deploy.sh` and `npm run build` are both listed, since deploy runs the build.

**Questions for you**
1. **Split the Bot screen?** It has 14 rows. *Recommendation:* yes. Move Vision, Screenshots, Contract, Git, and the Gmail widget behind a `widgets` screen under Bot. The app's `WidgetBrowser` already groups them that way.
2. **Should the operator screens (`host`, `scripts`) appear in the app, or only in the terminal help?** *Recommendation:* terminal only. The owner never needs them from a phone.
3. **Is there a `cli/codebot.py`?** The README refers to it, but it is not in the tree. `PRODUCT-SPEC.md`, `IMPLEMENTATION-STATUS.md`, and `MASTER-PLAN.md` are also cited but not in the dump, so I left them out. *Recommendation:* tell me if they exist and I'll add their rows.

```json
{"screens": [
{"path": [], "sentence": "The top of CodeBot: the Bots you steer, this CodeBot's settings, and the operator's places for the running host, the scripts and the docs.", "rows": [
{"name": "Bots", "form": "screen: bots (apps/web/src/App.tsx)", "what": "Opens the list of Bots, each with what it is doing and whether it needs you."},
{"name": "Settings", "form": "screen: settings (apps/web/src/ui/Settings.tsx)", "what": "Opens this CodeBot's notification, Gmail and update settings."},
{"name": "Host", "form": "screen: host (ops/OPERATIONS.md)", "what": "Opens the operator's places for the running service, its data, guests, family and address."},
{"name": "Scripts", "form": "screen: scripts (package.json)", "what": "Opens the npm scripts that run, check, build and review the checkout."},
{"name": "Docs", "form": "screen: docs (README.md, docs/)", "what": "Opens the written docs: layout, architecture, runbook, open work and recorded evidence."}
]},
{"path": ["bots"], "sentence": "The Bots you have, each with what it is doing and whether it needs you.", "rows": [
{"name": "A Bot", "form": "screen: bots > Bot (apps/web/src/workspace/)", "what": "Opens one Bot's conversation, files, widgets and settings."},
{"name": "New Bot", "form": "apps/web/src/workspace/BotForm.tsx", "what": "Creates a Bot from a name, a role, a provider and a home folder."},
{"name": "First-use tour", "form": "apps/web/src/onboarding/Onboarding.tsx", "what": "Shows the tour that creates a first Bot for a new account."}
]},
{"path": ["bots", "Bot"], "sentence": "The conversation with one Bot, with its files, widgets and settings.", "rows": [
{"name": "Chat", "form": "screen: bots > Bot > chat", "what": "Shows the conversation and the queue of messages waiting for this Bot."},
{"name": "Terminal", "form": "apps/web/src/TerminalTab.tsx", "what": "Opens this Bot's terminal, the shell it works in on this host."},
{"name": "Pinned files", "form": "apps/web/src/resources/PinnedFiles.tsx", "what": "Lists the files pinned to this Bot and opens each one."},
{"name": "Attach a file", "form": "apps/web/src/resources/AttachmentPicker.tsx", "what": "Attaches a file to the next message."},
{"name": "Recordings", "form": "apps/web/src/resources/RecordingPlayer.tsx", "what": "Plays a recording of this Bot's browser work."},
{"name": "Vision", "form": "screen: bots > Bot > vision", "what": "Shows the live Chromium page this Bot is using."},
{"name": "Screenshots", "form": "screen: bots > Bot > screenshots", "what": "Shows the screenshots this Bot has captured, newest first."},
{"name": "Feature contract", "form": "apps/web/src/contracts/ContractCatalog.tsx", "what": "Opens this Bot's feature contract: its catalog, files, history and conflicts."},
{"name": "Git", "form": "screen: bots > Bot > git", "what": "Shows the repository's status and its quick git actions."},
{"name": "Gmail widget", "form": "apps/web/src/widgets/GmailWidget.tsx", "what": "Shows the Gmail items this Bot needs approved or has handled."},
{"name": "Widgets", "form": "apps/web/src/widgets/WidgetBrowser.tsx", "what": "Adds, removes or rearranges the widgets on this Bot's surface."},
{"name": "Avatar", "form": "apps/web/src/workspace/AvatarStudio.tsx", "what": "Designs this Bot's avatar."},
{"name": "Schedules", "form": "screen: bots > Bot > schedules (docs/objectives/schedules.md)", "what": "Lists the wakeups scheduled for this Bot."},
{"name": "Bot settings", "form": "apps/web/src/workspace/BotForm.tsx", "what": "Edits this Bot's name, role, provider, model, folder and notifications."}
]},
{"path": ["settings"], "sentence": "This CodeBot's own settings: notifications on this device, Gmail, and updates.", "rows": [
{"name": "Notifications", "form": "apps/web/src/pwa/DeviceNotifications.tsx", "what": "Enables notifications on this device, sends it a test, and removes old devices."},
{"name": "Gmail access", "form": "apps/web/src/gmail/GmailAccess.tsx", "what": "Connects the Google account the Bots use for Gmail."},
{"name": "Gmail activity", "form": "apps/web/src/gmail/GmailActivity.tsx", "what": "Shows what Bots did with Gmail and the day's summary."},
{"name": "Update notice", "form": "apps/web/src/pwa/UpdateNotice.tsx", "what": "Shows what changed after an update, from apps/web/src/whatsNew.ts."},
{"name": "Install on phone", "form": "docs/OPERATIONS.md (Private access and PWA installation)", "what": "Adds CodeBot to the phone's Home Screen from the private HTTPS address."}
]},
{"path": ["host"], "sentence": "The operator's place for the service running on this machine: its status, logs, deployment and sub-areas.", "rows": [
{"name": "Service status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether codebot.service runs and its last state."},
{"name": "Service log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the service's last 80 log lines."},
{"name": "Restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service once active turns and recordings finish."},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, pushes, waits its turn, restarts the service and verifies it."},
{"name": "Build", "form": "npm run build", "what": "Type-checks and builds a new web release, keeping the served one if the build fails."},
{"name": "Host diagnostics", "form": "/api/diagnostics/host (from an authenticated browser)", "what": "Shows the host's migration, queued turns and recovery hold."},
{"name": "Owner key", "form": "~/.local/share/codebot/owner-key", "what": "Prints the entrance key used to connect a new device; keep it private."},
{"name": "Data", "form": "screen: host > data", "what": "Opens backup, restore, onboarding reset and emergency stop."},
{"name": "Terminal broker", "form": "screen: host > terminal", "what": "Opens the per-user terminal broker, the unit that holds the shell."},
{"name": "Devices", "form": "screen: host > devices", "what": "Opens how a phone or desktop reaches CodeBot over the private address."},
{"name": "Guest", "form": "screen: host > guest", "what": "Opens the second account on this machine for another person."},
{"name": "Family", "form": "screen: host > family", "what": "Opens the family CodeBots on the home Wi-Fi address and their helper."},
{"name": "Address", "form": "screen: host > address", "what": "Opens the steps to move CodeBot to a new Tailscale name."},
{"name": "Account service", "form": "screen: host > account", "what": "Opens the Supabase account service: sign-in, the host handshake and the Gmail relay."}
]},
{"path": ["host", "data"], "sentence": "Backing up, restoring and resetting this host's data.", "rows": [
{"name": "Back up", "form": "ops/OPERATIONS.md (Back up a consistent installation)", "what": "Stops the service and copies its data and settings into a private folder."},
{"name": "Verify a restore", "form": "ops/OPERATIONS.md (Restore into a separate directory first)", "what": "Restores a backup into a new folder and checks it before promotion."},
{"name": "Replay the tour", "form": "ops/OPERATIONS.md (Replay only the first-use tour)", "what": "Starts a person's first-use tour again, on a host with no Bots."},
{"name": "Fresh CodeBot", "form": "ops/OPERATIONS.md (Restart onboarding with a fresh CodeBot)", "what": "Wipes a guest's Bots and conversations and keeps the account."},
{"name": "Full reset", "form": "ops/OPERATIONS.md (Full reset: the person starts as new)", "what": "Deletes a person's account, Bots and data so they start as new."},
{"name": "Emergency stop", "form": "ops/OPERATIONS.md (Emergency stop and rollback)", "what": "Stops the service at once and kills it if a normal stop is not enough."}
]},
{"path": ["host", "guest"], "sentence": "The second account on this machine for another person, using the owner's subscriptions.", "rows": [
{"name": "Install", "form": "sudo ops/guest-install.sh", "what": "Creates the guest user, its service, settings and sudo rules, once."},
{"name": "Update", "form": "ops/guest-update.sh", "what": "Builds the guest's program and restarts its service, with no password."},
{"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google invite link, valid for ten minutes."},
{"name": "Status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest service runs."},
{"name": "Remove", "form": "ops/OPERATIONS.md (Host a guest on this machine)", "what": "Removes the guest's service, user, program and sharing."}
]},
{"path": ["host", "family"], "sentence": "The family CodeBots on the home Wi-Fi address, one per Google account, and their helper.", "rows": [
{"name": "Install", "form": "sudo ops/family-install.sh", "what": "Sets up the front door, helper, services, sudo rules and nginx, once."},
{"name": "Update", "form": "ops/family-update.sh", "what": "Builds the family program and restarts every family CodeBot."},
{"name": "Status", "form": "sudo codebot-family status", "what": "Prints whether each family CodeBot runs and whether its Gmail can connect."},
{"name": "Add a person", "form": "sudo codebot-family add N", "what": "Creates family CodeBot N for a new Google account."},
{"name": "Remove a person", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number."},
{"name": "Stop or start all", "form": "sudo codebot-family stop-all | start-all", "what": "Stops every family CodeBot, or starts them all again."}
]},
{"path": ["host", "address"], "sentence": "The steps to move CodeBot to a new Tailscale name, in order.", "rows": [
{"name": "Places to change", "form": "ops/OPERATIONS.md (Change this machine's address)", "what": "Lists the places that hold the address and why each must change."},
{"name": "Steps", "form": "ops/OPERATIONS.md (Change this machine's address, steps 1 to 7)", "what": "Walks the change in order, from Supabase to the domain forward."},
{"name": "Current name", "form": "tailscale status --json", "what": "Prints this machine's Tailscale name, which becomes the new address."}
]},
{"path": ["host", "devices"], "sentence": "How a phone or desktop reaches CodeBot over the private Tailscale address.", "rows": [
{"name": "Serve status", "form": "tailscale serve status --json", "what": "Prints the current private HTTPS mapping, to check before changing it."},
{"name": "Serve map", "form": "tailscale serve --bg http://127.0.0.1:3505", "what": "Maps the private HTTPS address to the service on a new machine."},
{"name": "Connect a device", "form": "ops/OPERATIONS.md (Connect a device)", "what": "Adds CodeBot to a phone's Home Screen from the private HTTPS address."},
{"name": "Device notifications", "form": "ops/OPERATIONS.md (Background notifications)", "what": "Turns on notifications for one device and sends it a test."}
]},
{"path": ["host", "terminal"], "sentence": "The per-user terminal broker: a separate unit that holds the shell the terminal uses.", "rows": [
{"name": "Enable", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "Starts the terminal broker and keeps it running across web-service restarts."},
{"name": "Broker status", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the broker runs and its listener state."},
{"name": "Lingering", "form": "loginctl show-user \"$USER\" -p Linger", "what": "Prints whether the user service runs without a desktop login."}
]},
{"path": ["host", "account"], "sentence": "The Supabase account service: sign-in, the host handshake and the Gmail relay.", "rows": [
{"name": "Deploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Redeploys the host-access function after a contract it parses changes."},
{"name": "Access token", "form": "~/.config/supabase-codebot-token", "what": "Supplies the access token that the deploy command reads."},
{"name": "Gmail relay", "form": "supabase/functions/gmail-relay/index.ts", "what": "Forwards Google's sign-in return to the user's own server."},
{"name": "Migrations", "form": "supabase/migrations/", "what": "Creates the account tables and rules, applied through Supabase."}
]},
{"path": ["scripts"], "sentence": "The npm scripts that run, check, build and review the checkout.", "rows": [
{"name": "dev", "form": "npm run dev", "what": "Starts the service with reload on each change, for development."},
{"name": "start", "form": "npm run start", "what": "Starts the service in production mode."},
{"name": "typecheck", "form": "npm run typecheck", "what": "Type-checks the code without building it."},
{"name": "build", "form": "npm run build", "what": "Type-checks, then builds the web app into a new release."},
{"name": "test", "form": "npm run test", "what": "Runs the Gmail tests against a fake Google server."},
{"name": "check", "form": "npm run check", "what": "Type-checks, then runs the tests."},
{"name": "setup-account", "form": "npm run setup-account", "what": "Runs ops/setup-account.ts, the account setup."},
{"name": "docs:gmail", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md."},
{"name": "review:gmail", "form": "npm run review:gmail", "what": "Runs the Gmail review in ops/review/gmail-review.mjs."},
{"name": "review:schedules", "form": "npm run review:schedules", "what": "Runs the schedules review in ops/review/schedules-review.mjs."},
{"name": "playground", "form": "npm run playground", "what": "Starts Vite and opens the Gmail playground to compare design variants."},
{"name": "sync:agents", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."},
{"name": "build:integration", "form": "npm run build:integration", "what": "Type-checks, then builds the integration bundle with ops/build-integration.mjs."}
]},
{"path": ["docs"], "sentence": "The written docs: how CodeBot is built and run, and what was verified.", "rows": [
{"name": "README", "form": "README.md", "what": "Opens the layout, how to run it and the commands."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how the pieces are built and what each boundary owns."},
{"name": "Working rules", "form": "CLAUDE.md", "what": "Opens the rules for working with the owner and designing screens."},
{"name": "Runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for installing, running, backing up and recovering."},
{"name": "Open work", "form": "DEFERRED-WORK.md", "what": "Opens the open work and the safe restart state."},
{"name": "Design taste", "form": "docs/design-taste.md", "what": "Opens the owner's rulings on design."},
{"name": "Design method", "form": "docs/design-method.md", "what": "Opens the method for designing and checking screens."},
{"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "Opens the guide to how Bots use Gmail."},
{"name": "Plans", "form": "docs/plans/", "what": "Opens the dated plans for past and current work."},
{"name": "Verification", "form": "docs/verification/", "what": "Opens the recorded test evidence."}
]}
],
"questions": [
"Split the Bot screen? It has 14 rows. Recommend moving Vision, Screenshots, Feature contract, Git and Gmail widget behind a widgets screen under Bot, since WidgetBrowser already groups them.",
"Should the operator screens (host, scripts) appear in the app, or only in the terminal help? Recommend terminal only; the owner works from a phone.",
"Is there a cli/codebot.py, and do PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md and MASTER-PLAN.md exist? They are cited in the docs but are not in the dump, so I left them out. If they exist, I will add their rows.",
"Should the owner-key row show only the path, not offer a command that prints the key? Recommend the path only, since the runbook says not to print it."
]}
```

screen-decomposition, final · run 1 exit=0 seconds=130 · prompt

P1 Recall: 0.551P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 6P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.55
As terminal help
Everything CodeBot has: the app, the service that runs it, access, backups, family hosts and the docs.
appcodebot appOpens the app's screens: Bots, Contracts, Gmail, Terminal, Widgets, Onboarding, Settings.
servicecodebot serviceOpens the service's screens: running it, and the commands that build, test and review it.
accesscodebot accessOpens the sign-in and device screens, and the account service screen.
backupscodebot backupsOpens the backup and restore steps, and the folder that holds every backup.
familycodebot familyOpens the guest host and the family CodeBots that run on this computer for other people.
docscodebot docsOpens the written references: the runbook, the README, the architecture, and the records.
app
The app's screens, where you read and steer Bots from a phone, tablet or desktop.
Private addresshttps://liel.tail18e69e.ts.netOpens the app at its private Tailscale address; on a phone, choose Install app or Add to Home Screen to install it.
Botsapps/web/src/workspace/Opens the Bot list, the Bot form and the avatar studio, where each Bot's conversation is read and steered.
Contractsapps/web/src/contracts/Opens a Bot's FeatureContract: catalog, files, history, diffs and conflicts.
Gmailapps/web/src/gmail/Opens Gmail for Bots: access, approvals, activity, cards and the daily summary.
Terminalapps/web/src/TerminalPage.tsxOpens the terminal tabs on this computer, when the terminal is turned on.
Widgetsapps/web/src/widgets/Opens the widgets a Bot shows, arranged by the owner.
Onboardingapps/web/src/onboarding/Opens the first-use steps: device arrival, connection, family setup and the first Bot.
Settingsapps/web/src/ui/Settings.tsxOpens Settings, which each widget's cog button leads to.
Update noticeapps/web/src/pwa/UpdateNotice.tsxShows what changed since the last update, from apps/web/src/whatsNew.ts.
Design playgroundnpm run playgroundStarts the playground that compares Gmail design variants on the dev server.
service
The service on this computer, and the commands that run, build and test it.
runcodebot service runOpens the running screens: start and stop, status and logs, settings, data and deploy.
devcodebot service devOpens the commands that build, typecheck, test and review the code.
Loopback addresshttp://127.0.0.1:3505Opens the service on this computer only, on port 3505.
service › run
The service's running state, its private settings and its data.
Startsystemctl --user start codebot.serviceStarts the service on 127.0.0.1:3505.
Stopsystemctl --user stop codebot.serviceStops the service, interrupting Bot turns and finalizing recordings.
Restartsystemctl --user restart codebot.serviceRestarts the service after active turns and recordings finish; run it after an update.
Statussystemctl --user status codebot.service --no-pagerPrints whether the service is running and its recent state.
Logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 lines of the service's log.
Health checkcurl --fail http://127.0.0.1:3505/api/sessionPrints the session answer; an unsigned answer still proves the service is ready.
Terminal brokersystemctl --user start codebot-terminal-broker.serviceStarts the per-user terminal broker, a separate unit the terminal needs.
Deploysh ops/deploy.shBuilds, commits, pushes, waits for active work, restarts and verifies the service.
Emergency stopsystemctl --user kill --kill-whom=all --signal=SIGKILL codebot.serviceKills every service process at once, losing unsaved media; use only when a normal stop fails (ops/OPERATIONS.md).
Settings file~/.config/codebot/service.envOpens the private settings: port, data folder, project roots, provider credentials. Mode 0600; never print it.
Data folder~/.local/share/codebotOpens the data folder: the database, transcripts, artifacts and recordings.
Project foldersCODEBOT_PROJECT_ROOTS (/home/liel/projects)Opens the project folders Bots may reach; widening them grants real file access.
service › dev
The commands that build, typecheck, test and review CodeBot's code.
Dev servicenpm run devStarts the service in watch mode from the source, for development.
Buildnpm run buildTypechecks, then builds the app into a new release under dist/releases.
Build integrationnpm run build:integrationBuilds the copy that the QA instance on port 3506 runs.
Typechecknpm run typecheckChecks the code compiles and prints any type errors.
Testnpm testRuns the Gmail automation tests against a fake Google server.
Checknpm run checkTypechecks, then runs the tests.
Gmail reviewnpm run review:gmailRuns ops/review/gmail-review.mjs against the real service and browser.
Schedules reviewnpm run review:schedulesRuns ops/review/schedules-review.mjs.
Sync agentsnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, not AGENTS.md.
Gmail referencenpm run docs:gmailRegenerates docs/automation/gmail-reference.md.
access
How people sign in to this computer's CodeBot, and the account service behind sign-in.
devicecodebot access deviceOpens the device screen: connecting a phone, tablet or desktop.
accountcodebot access accountOpens the account screen: the central sign-in service and each person's onboarding.
access › device
The devices that reach this computer's CodeBot, and how each one is connected.
Sign-in entryhttps://liel.tail18e69e.ts.net/onboardingOpens the owner's sign-in entry, where a person signs in and is sent to their own host.
Entrance key~/.local/share/codebot/owner-keyOpens the file holding the key a new device signs in with; read it only at this computer and never paste it.
Serve mappingtailscale serve status --jsonPrints the private HTTPS mapping that exposes the service; the root handler should be 127.0.0.1:3505 on port 443.
Map a new machinetailscale serve --bg http://127.0.0.1:3505Maps the service to private HTTPS on a machine with no root mapping; never reset an existing mapping.
Device notificationsapps/web/src/pwa/DeviceNotifications.tsxOpens the notification setup for this device: enable, reconnect, other devices and send test.
access › account
The central account service, the sign-in records behind it, and the steps when an address or onboarding changes.
Account servicehttps://supabase.com/dashboard/project/wbgrjvqbupgdclaztuouOpens the central account service's dashboard, in the mobile-coder login rather than the Lebnor login.
Account token~/.config/supabase-codebot-tokenOpens the token file used for CLI deploys (mode 600); read it, never print it.
Account setupnpm run setup-accountRuns ops/setup-account.ts to set up the account service.
Deploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function; run it again whenever a contract it parses changes.
Gmail relaysupabase/functions/gmail-relay/index.tsForwards Google sign-in back to the person's own server.
Account recordpublic.codebot_account_progress (Supabase)Opens the onboarding record for each account: draft, first Bot and server address.
Change addressops/OPERATIONS.md, 'Change this machine's address'Reads the seven steps and the nine places that hold this machine's address.
Reset onboardingops/OPERATIONS.md, 'Reset someone's onboarding'Reads how to replay the first-use tour or restart onboarding for a person; these steps delete data.
backups
Whole-data backups of this computer's CodeBot, and how to restore one into a separate folder first.
Back upops/OPERATIONS.md, 'Back up a consistent installation'Stops the service, copies its whole data folder, service.env and unit to a new backup folder, then restarts it.
Backup folder~/.local/share/codebot-backups/Opens the folder holding every backup, each with state.tar, source.tar, service.env and SHA256SUMS.
Verify backupsha256sum -c SHA256SUMS (inside a backup folder)Checks a backup's files against their checksums before any restore.
Restoreops/OPERATIONS.md, 'Restore into a separate directory first'Extracts a backup into an empty staging folder, never over the running copy, and gives the steps to promote it.
Check restored databaseops/OPERATIONS.md (PRAGMA integrity_check script)Checks the restored database's integrity and references, read-only.
Inspect restored copyhttp://127.0.0.1:3508Opens the restored copy on port 3508 with recovery hold on, so nothing runs automatically.
family
Guest and family CodeBots that run on this computer for other people, each under its own Linux user.
guestcodebot family guestOpens the guest host: one person, its own Linux user, port 10000.
memberscodebot family membersOpens the family front door and the family CodeBots, up to six, on the home Wi-Fi address.
family › guest
The guest host on this computer: its install, update, invite and status.
Install guestsudo ops/guest-install.shSets up the guest user, service, settings, sudo rules and Tailscale on port 10000; run once.
Update guestops/guest-update.shBuilds, replaces /opt/codebot-guest and restarts the guest host; needs no password.
Invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google invite link, valid for ten minutes.
Statussystemctl status codebot-guestPrints whether the guest host is running.
Logsjournalctl -u codebot-guestPrints the guest host's log.
Guest home/home/codebot-guestOpens the guest's home folder, where its data and projects are kept.
Remove guestops/OPERATIONS.md, 'Host a guest on this machine'Reads the steps that remove the guest host; they delete its user and data, so they stay as steps, not a command.
family › members
The family front door and the family CodeBots on the home Wi-Fi address, one per Google account.
Family addresshttps://family.codebot.lielbenor.comOpens the front door on the home Wi-Fi address, where a family member signs in with Google.
Install familysudo ops/family-install.shSets up the front door user, the helper, services, sudo rules and nginx; run once.
Update familyops/family-update.shBuilds, replaces /opt/codebot-family and restarts every family CodeBot; needs no password.
Statussudo codebot-family statusPrints each family CodeBot: whether it runs, and whether Gmail can connect.
Add membersudo codebot-family add NAdds family CodeBot N for a new Google account; the front door runs this itself on a new sign-in.
Remove membersudo codebot-family remove NDeletes family CodeBot N and frees its number; the same Google account cannot be linked again without editing the account database.
Stop allsudo codebot-family stop-allStops every family CodeBot.
Start allsudo codebot-family start-allStarts every family CodeBot.
Family logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the front door's and the family CodeBots' logs.
Family settings/etc/codebot-family.confOpens the settings every family CodeBot receives, including the Google app secret; keep it private.
docs
The written references: how to run CodeBot, what it is, and what is still open.
Runbookops/OPERATIONS.mdOpens the runbook: running, connecting, backing up, restoring, resetting and recovering CodeBot.
Bot model selectionops/OPERATIONS.md, 'Bot model selection'Reads which model a Bot uses for ordinary messages and for /goal.
READMEREADME.mdOpens the overview: what CodeBot is, how its pieces fit and which checks it runs.
ArchitectureARCHITECTURE.mdOpens the technical boundaries, invariants and persistence design.
Product specPRODUCT-SPEC.md (named by the README; not in the file list)Opens the behavior contract.
Status and open workIMPLEMENTATION-STATUS.md and DEFERRED-WORK.md (named by the README; not in the file list)Opens what was built and the remaining checklist.
Agent rulesCLAUDE.mdOpens the rules every agent follows; AGENTS.md is generated from it.
Gmail guidedocs/automation/gmail.mdOpens the supervisor guide for Gmail automation.
Designdocs/design-method.md and docs/design-taste.mdOpens the design method and the owner's design rulings.
Objectivesdocs/objectives/Lists the objectives: chat current session, Gmail widget, schedules and terminal tabs.
Recordscodebot docs recordsOpens the plans, verification evidence, task reports, intents and QA records.
docs › records
The records of past work: plans, verification evidence, task reports, intents, feature tests and QA findings.
Plansdocs/plans/ and .plans/Lists the plan documents for past and planned work.
Verificationdocs/verification/Opens the recorded verification evidence, including the onboarding proof.
Tasksdocs/tasks/ and docs/superpowers/plans/Lists the task reports and dated work plans.
Intents.idd/modules/Lists each module's INTENT.md: its constraints and its Given / When / Then table.
Feature tests.bdd/features/ and .bdd/steps/Lists the feature files and the step files that run them.
QA findings.bdd/qa/findings/ and .bdd/qa/resolutions/Lists the QA findings and how each one was resolved.
Design critiques.impeccable/critique/Lists the design critiques of app screens.
Questions
  • Facade name: should the command be `codebot` (so `codebot help` is the map)? Recommendation: yes, with no short alias yet; add `cb` only after `whence -a cb` shows no clash.
  • Top group name: 'service' or 'host'? The docs use both. Recommendation: 'service', because the unit is codebot.service and the README calls it the local service.
  • Destructive or sudo steps (remove guest, remove member, emergency stop, reset onboarding, delete a person): should the CLI run them, or only print the steps? Recommendation: only print the steps, so nothing irreversible runs from a single typed command.
  • Should the app screens (Bots, Contracts, Gmail, Terminal and so on) appear in the CLI, or should the CLI only open the private address? Recommendation: list them, with source folders as forms; the CLI does not drive the UI.
  • Should the family and guest hosting stay on the owner's CLI, or be operator-only docs? Recommendation: keep them under 'family', with destructive steps as read-only steps.
  • Three referenced files (PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md, DEFERRED-WORK.md) and cli/codebot.py are not in the file list. Do they exist in the repo? Recommendation: confirm before the CLI links to them.
As phone screens

Home

Everything CodeBot has: the app, the service that runs it, access, backups, family hosts and the docs.

appOpens the app's screens: Bots, Contracts, Gmail, Terminal, Widgets, Onboarding, Settings.
›
serviceOpens the service's screens: running it, and the commands that build, test and review it.
›
accessOpens the sign-in and device screens, and the account service screen.
›
backupsOpens the backup and restore steps, and the folder that holds every backup.
›
familyOpens the guest host and the family CodeBots that run on this computer for other people.
›
docsOpens the written references: the runbook, the README, the architecture, and the records.
›
‹ Home

app

The app's screens, where you read and steer Bots from a phone, tablet or desktop.

Private addressOpens the app at its private Tailscale address; on a phone, choose Install app or Add to Home Screen to install it.
›
BotsOpens the Bot list, the Bot form and the avatar studio, where each Bot's conversation is read and steered.
›
ContractsOpens a Bot's FeatureContract: catalog, files, history, diffs and conflicts.
›
GmailOpens Gmail for Bots: access, approvals, activity, cards and the daily summary.
›
TerminalOpens the terminal tabs on this computer, when the terminal is turned on.
›
WidgetsOpens the widgets a Bot shows, arranged by the owner.
›
OnboardingOpens the first-use steps: device arrival, connection, family setup and the first Bot.
›
SettingsOpens Settings, which each widget's cog button leads to.
›
Update noticeShows what changed since the last update, from apps/web/src/whatsNew.ts.
›
Design playgroundStarts the playground that compares Gmail design variants on the dev server.
›
‹ Home

service

The service on this computer, and the commands that run, build and test it.

runOpens the running screens: start and stop, status and logs, settings, data and deploy.
›
devOpens the commands that build, typecheck, test and review the code.
›
Loopback addressOpens the service on this computer only, on port 3505.
›
‹ service

run

The service's running state, its private settings and its data.

StartStarts the service on 127.0.0.1:3505.
›
StopStops the service, interrupting Bot turns and finalizing recordings.
›
RestartRestarts the service after active turns and recordings finish; run it after an update.
›
StatusPrints whether the service is running and its recent state.
›
LogsPrints the last 80 lines of the service's log.
›
Health checkPrints the session answer; an unsigned answer still proves the service is ready.
›
Terminal brokerStarts the per-user terminal broker, a separate unit the terminal needs.
›
DeployBuilds, commits, pushes, waits for active work, restarts and verifies the service.
›
Emergency stopKills every service process at once, losing unsaved media; use only when a normal stop fails (ops/OPERATIONS.md).
›
Settings fileOpens the private settings: port, data folder, project roots, provider credentials. Mode 0600; never print it.
›
Data folderOpens the data folder: the database, transcripts, artifacts and recordings.
›
Project foldersOpens the project folders Bots may reach; widening them grants real file access.
›
‹ service

dev

The commands that build, typecheck, test and review CodeBot's code.

Dev serviceStarts the service in watch mode from the source, for development.
›
BuildTypechecks, then builds the app into a new release under dist/releases.
›
Build integrationBuilds the copy that the QA instance on port 3506 runs.
›
TypecheckChecks the code compiles and prints any type errors.
›
TestRuns the Gmail automation tests against a fake Google server.
›
CheckTypechecks, then runs the tests.
›
Gmail reviewRuns ops/review/gmail-review.mjs against the real service and browser.
›
Schedules reviewRuns ops/review/schedules-review.mjs.
›
Sync agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, not AGENTS.md.
›
Gmail referenceRegenerates docs/automation/gmail-reference.md.
›
‹ Home

access

How people sign in to this computer's CodeBot, and the account service behind sign-in.

deviceOpens the device screen: connecting a phone, tablet or desktop.
›
accountOpens the account screen: the central sign-in service and each person's onboarding.
›
‹ access

device

The devices that reach this computer's CodeBot, and how each one is connected.

Sign-in entryOpens the owner's sign-in entry, where a person signs in and is sent to their own host.
›
Entrance keyOpens the file holding the key a new device signs in with; read it only at this computer and never paste it.
›
Serve mappingPrints the private HTTPS mapping that exposes the service; the root handler should be 127.0.0.1:3505 on port 443.
›
Map a new machineMaps the service to private HTTPS on a machine with no root mapping; never reset an existing mapping.
›
Device notificationsOpens the notification setup for this device: enable, reconnect, other devices and send test.
›
‹ access

account

The central account service, the sign-in records behind it, and the steps when an address or onboarding changes.

Account serviceOpens the central account service's dashboard, in the mobile-coder login rather than the Lebnor login.
›
Account tokenOpens the token file used for CLI deploys (mode 600); read it, never print it.
›
Account setupRuns ops/setup-account.ts to set up the account service.
›
Deploy host-accessDeploys the host-access function; run it again whenever a contract it parses changes.
›
Gmail relayForwards Google sign-in back to the person's own server.
›
Account recordOpens the onboarding record for each account: draft, first Bot and server address.
›
Change addressReads the seven steps and the nine places that hold this machine's address.
›
Reset onboardingReads how to replay the first-use tour or restart onboarding for a person; these steps delete data.
›
‹ Home

backups

Whole-data backups of this computer's CodeBot, and how to restore one into a separate folder first.

Back upStops the service, copies its whole data folder, service.env and unit to a new backup folder, then restarts it.
›
Backup folderOpens the folder holding every backup, each with state.tar, source.tar, service.env and SHA256SUMS.
›
Verify backupChecks a backup's files against their checksums before any restore.
›
RestoreExtracts a backup into an empty staging folder, never over the running copy, and gives the steps to promote it.
›
Check restored databaseChecks the restored database's integrity and references, read-only.
›
Inspect restored copyOpens the restored copy on port 3508 with recovery hold on, so nothing runs automatically.
›
‹ Home

family

Guest and family CodeBots that run on this computer for other people, each under its own Linux user.

guestOpens the guest host: one person, its own Linux user, port 10000.
›
membersOpens the family front door and the family CodeBots, up to six, on the home Wi-Fi address.
›
‹ family

guest

The guest host on this computer: its install, update, invite and status.

Install guestSets up the guest user, service, settings, sudo rules and Tailscale on port 10000; run once.
›
Update guestBuilds, replaces /opt/codebot-guest and restarts the guest host; needs no password.
›
InvitePrints a one-use Google invite link, valid for ten minutes.
›
StatusPrints whether the guest host is running.
›
LogsPrints the guest host's log.
›
Guest homeOpens the guest's home folder, where its data and projects are kept.
›
Remove guestReads the steps that remove the guest host; they delete its user and data, so they stay as steps, not a command.
›
‹ family

members

The family front door and the family CodeBots on the home Wi-Fi address, one per Google account.

Family addressOpens the front door on the home Wi-Fi address, where a family member signs in with Google.
›
Install familySets up the front door user, the helper, services, sudo rules and nginx; run once.
›
Update familyBuilds, replaces /opt/codebot-family and restarts every family CodeBot; needs no password.
›
StatusPrints each family CodeBot: whether it runs, and whether Gmail can connect.
›
Add memberAdds family CodeBot N for a new Google account; the front door runs this itself on a new sign-in.
›
Remove memberDeletes family CodeBot N and frees its number; the same Google account cannot be linked again without editing the account database.
›
Stop allStops every family CodeBot.
›
Start allStarts every family CodeBot.
›
Family logsPrints the front door's and the family CodeBots' logs.
›
Family settingsOpens the settings every family CodeBot receives, including the Google app secret; keep it private.
›
‹ Home

docs

The written references: how to run CodeBot, what it is, and what is still open.

RunbookOpens the runbook: running, connecting, backing up, restoring, resetting and recovering CodeBot.
›
Bot model selectionReads which model a Bot uses for ordinary messages and for /goal.
›
READMEOpens the overview: what CodeBot is, how its pieces fit and which checks it runs.
›
ArchitectureOpens the technical boundaries, invariants and persistence design.
›
Product specOpens the behavior contract.
›
Status and open workOpens what was built and the remaining checklist.
›
Agent rulesOpens the rules every agent follows; AGENTS.md is generated from it.
›
Gmail guideOpens the supervisor guide for Gmail automation.
›
DesignOpens the design method and the owner's design rulings.
›
ObjectivesLists the objectives: chat current session, Gmail widget, schedules and terminal tabs.
›
RecordsOpens the plans, verification evidence, task reports, intents and QA records.
›
‹ docs

records

The records of past work: plans, verification evidence, task reports, intents, feature tests and QA findings.

PlansLists the plan documents for past and planned work.
›
VerificationOpens the recorded verification evidence, including the onboarding proof.
›
TasksLists the task reports and dated work plans.
›
IntentsLists each module's INTENT.md: its constraints and its Given / When / Then table.
›
Feature testsLists the feature files and the step files that run them.
›
QA findingsLists the QA findings and how each one was resolved.
›
Design critiquesLists the design critiques of app screens.
›
Raw answer
**Scenario (reasoned from the README and `ops/OPERATIONS.md`, not observed):** the owner, usually from a phone, wants to reach their CodeBot. Sometimes they sit at the workstation. They ask things like "where do I restart the host?", "how do I back it up?", "how do I connect a new phone?", and "how do I add a family member?"

**Judgment calls:**
- **Left off the map:** the V2/V3/V4 experiments, which the README says live in separate private repos and are "not part of CodeBot." Also `codebot-preview.service`, which `OPERATIONS.md` says was transient and has been replaced.
- **Not mapped:** the README mentions `cli/codebot.py`, but it is not in the file list, so I could not confirm it exists. The `apps/service/src` internals and the truncated `workspace` components are not user-reached, so I did not map them.
- **Unverified references:** `PRODUCT-SPEC.md`, `IMPLEMENTATION-STATUS.md` and `DEFERRED-WORK.md` are named by the README but are not in the dump. They are kept, marked as unconfirmed.
- **Forms:** the app's real URL routes are unknown, so app rows point at their source folders.
- **Destructive steps** (remove a guest or family member, force-kill, reset onboarding, delete a person) are shown as readable steps, not runnable commands.
- **Splits:** `service` is split into `run` and `dev`, `access` into `device` and `account`, `family` into `guest` and `members`, and `docs` into `records`. The top screen keeps six groups.

```json
{"screens": [
 {"path": [], "sentence": "Everything CodeBot has: the app, the service that runs it, access, backups, family hosts and the docs.", "rows": [
  {"name": "app", "form": "codebot app", "what": "Opens the app's screens: Bots, Contracts, Gmail, Terminal, Widgets, Onboarding, Settings."},
  {"name": "service", "form": "codebot service", "what": "Opens the service's screens: running it, and the commands that build, test and review it."},
  {"name": "access", "form": "codebot access", "what": "Opens the sign-in and device screens, and the account service screen."},
  {"name": "backups", "form": "codebot backups", "what": "Opens the backup and restore steps, and the folder that holds every backup."},
  {"name": "family", "form": "codebot family", "what": "Opens the guest host and the family CodeBots that run on this computer for other people."},
  {"name": "docs", "form": "codebot docs", "what": "Opens the written references: the runbook, the README, the architecture, and the records."}
 ]},
 {"path": ["app"], "sentence": "The app's screens, where you read and steer Bots from a phone, tablet or desktop.", "rows": [
  {"name": "Private address", "form": "https://liel.tail18e69e.ts.net", "what": "Opens the app at its private Tailscale address; on a phone, choose Install app or Add to Home Screen to install it."},
  {"name": "Bots", "form": "apps/web/src/workspace/", "what": "Opens the Bot list, the Bot form and the avatar studio, where each Bot's conversation is read and steered."},
  {"name": "Contracts", "form": "apps/web/src/contracts/", "what": "Opens a Bot's FeatureContract: catalog, files, history, diffs and conflicts."},
  {"name": "Gmail", "form": "apps/web/src/gmail/", "what": "Opens Gmail for Bots: access, approvals, activity, cards and the daily summary."},
  {"name": "Terminal", "form": "apps/web/src/TerminalPage.tsx", "what": "Opens the terminal tabs on this computer, when the terminal is turned on."},
  {"name": "Widgets", "form": "apps/web/src/widgets/", "what": "Opens the widgets a Bot shows, arranged by the owner."},
  {"name": "Onboarding", "form": "apps/web/src/onboarding/", "what": "Opens the first-use steps: device arrival, connection, family setup and the first Bot."},
  {"name": "Settings", "form": "apps/web/src/ui/Settings.tsx", "what": "Opens Settings, which each widget's cog button leads to."},
  {"name": "Update notice", "form": "apps/web/src/pwa/UpdateNotice.tsx", "what": "Shows what changed since the last update, from apps/web/src/whatsNew.ts."},
  {"name": "Design playground", "form": "npm run playground", "what": "Starts the playground that compares Gmail design variants on the dev server."}
 ]},
 {"path": ["service"], "sentence": "The service on this computer, and the commands that run, build and test it.", "rows": [
  {"name": "run", "form": "codebot service run", "what": "Opens the running screens: start and stop, status and logs, settings, data and deploy."},
  {"name": "dev", "form": "codebot service dev", "what": "Opens the commands that build, typecheck, test and review the code."},
  {"name": "Loopback address", "form": "http://127.0.0.1:3505", "what": "Opens the service on this computer only, on port 3505."}
 ]},
 {"path": ["service", "run"], "sentence": "The service's running state, its private settings and its data.", "rows": [
  {"name": "Start", "form": "systemctl --user start codebot.service", "what": "Starts the service on 127.0.0.1:3505."},
  {"name": "Stop", "form": "systemctl --user stop codebot.service", "what": "Stops the service, interrupting Bot turns and finalizing recordings."},
  {"name": "Restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service after active turns and recordings finish; run it after an update."},
  {"name": "Status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether the service is running and its recent state."},
  {"name": "Logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 lines of the service's log."},
  {"name": "Health check", "form": "curl --fail http://127.0.0.1:3505/api/session", "what": "Prints the session answer; an unsigned answer still proves the service is ready."},
  {"name": "Terminal broker", "form": "systemctl --user start codebot-terminal-broker.service", "what": "Starts the per-user terminal broker, a separate unit the terminal needs."},
  {"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, commits, pushes, waits for active work, restarts and verifies the service."},
  {"name": "Emergency stop", "form": "systemctl --user kill --kill-whom=all --signal=SIGKILL codebot.service", "what": "Kills every service process at once, losing unsaved media; use only when a normal stop fails (ops/OPERATIONS.md)."},
  {"name": "Settings file", "form": "~/.config/codebot/service.env", "what": "Opens the private settings: port, data folder, project roots, provider credentials. Mode 0600; never print it."},
  {"name": "Data folder", "form": "~/.local/share/codebot", "what": "Opens the data folder: the database, transcripts, artifacts and recordings."},
  {"name": "Project folders", "form": "CODEBOT_PROJECT_ROOTS (/home/liel/projects)", "what": "Opens the project folders Bots may reach; widening them grants real file access."}
 ]},
 {"path": ["service", "dev"], "sentence": "The commands that build, typecheck, test and review CodeBot's code.", "rows": [
  {"name": "Dev service", "form": "npm run dev", "what": "Starts the service in watch mode from the source, for development."},
  {"name": "Build", "form": "npm run build", "what": "Typechecks, then builds the app into a new release under dist/releases."},
  {"name": "Build integration", "form": "npm run build:integration", "what": "Builds the copy that the QA instance on port 3506 runs."},
  {"name": "Typecheck", "form": "npm run typecheck", "what": "Checks the code compiles and prints any type errors."},
  {"name": "Test", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
  {"name": "Check", "form": "npm run check", "what": "Typechecks, then runs the tests."},
  {"name": "Gmail review", "form": "npm run review:gmail", "what": "Runs ops/review/gmail-review.mjs against the real service and browser."},
  {"name": "Schedules review", "form": "npm run review:schedules", "what": "Runs ops/review/schedules-review.mjs."},
  {"name": "Sync agents", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, not AGENTS.md."},
  {"name": "Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md."}
 ]},
 {"path": ["access"], "sentence": "How people sign in to this computer's CodeBot, and the account service behind sign-in.", "rows": [
  {"name": "device", "form": "codebot access device", "what": "Opens the device screen: connecting a phone, tablet or desktop."},
  {"name": "account", "form": "codebot access account", "what": "Opens the account screen: the central sign-in service and each person's onboarding."}
 ]},
 {"path": ["access", "device"], "sentence": "The devices that reach this computer's CodeBot, and how each one is connected.", "rows": [
  {"name": "Sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Opens the owner's sign-in entry, where a person signs in and is sent to their own host."},
  {"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Opens the file holding the key a new device signs in with; read it only at this computer and never paste it."},
  {"name": "Serve mapping", "form": "tailscale serve status --json", "what": "Prints the private HTTPS mapping that exposes the service; the root handler should be 127.0.0.1:3505 on port 443."},
  {"name": "Map a new machine", "form": "tailscale serve --bg http://127.0.0.1:3505", "what": "Maps the service to private HTTPS on a machine with no root mapping; never reset an existing mapping."},
  {"name": "Device notifications", "form": "apps/web/src/pwa/DeviceNotifications.tsx", "what": "Opens the notification setup for this device: enable, reconnect, other devices and send test."}
 ]},
 {"path": ["access", "account"], "sentence": "The central account service, the sign-in records behind it, and the steps when an address or onboarding changes.", "rows": [
  {"name": "Account service", "form": "https://supabase.com/dashboard/project/wbgrjvqbupgdclaztuou", "what": "Opens the central account service's dashboard, in the mobile-coder login rather than the Lebnor login."},
  {"name": "Account token", "form": "~/.config/supabase-codebot-token", "what": "Opens the token file used for CLI deploys (mode 600); read it, never print it."},
  {"name": "Account setup", "form": "npm run setup-account", "what": "Runs ops/setup-account.ts to set up the account service."},
  {"name": "Deploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function; run it again whenever a contract it parses changes."},
  {"name": "Gmail relay", "form": "supabase/functions/gmail-relay/index.ts", "what": "Forwards Google sign-in back to the person's own server."},
  {"name": "Account record", "form": "public.codebot_account_progress (Supabase)", "what": "Opens the onboarding record for each account: draft, first Bot and server address."},
  {"name": "Change address", "form": "ops/OPERATIONS.md, 'Change this machine's address'", "what": "Reads the seven steps and the nine places that hold this machine's address."},
  {"name": "Reset onboarding", "form": "ops/OPERATIONS.md, 'Reset someone's onboarding'", "what": "Reads how to replay the first-use tour or restart onboarding for a person; these steps delete data."}
 ]},
 {"path": ["backups"], "sentence": "Whole-data backups of this computer's CodeBot, and how to restore one into a separate folder first.", "rows": [
  {"name": "Back up", "form": "ops/OPERATIONS.md, 'Back up a consistent installation'", "what": "Stops the service, copies its whole data folder, service.env and unit to a new backup folder, then restarts it."},
  {"name": "Backup folder", "form": "~/.local/share/codebot-backups/", "what": "Opens the folder holding every backup, each with state.tar, source.tar, service.env and SHA256SUMS."},
  {"name": "Verify backup", "form": "sha256sum -c SHA256SUMS (inside a backup folder)", "what": "Checks a backup's files against their checksums before any restore."},
  {"name": "Restore", "form": "ops/OPERATIONS.md, 'Restore into a separate directory first'", "what": "Extracts a backup into an empty staging folder, never over the running copy, and gives the steps to promote it."},
  {"name": "Check restored database", "form": "ops/OPERATIONS.md (PRAGMA integrity_check script)", "what": "Checks the restored database's integrity and references, read-only."},
  {"name": "Inspect restored copy", "form": "http://127.0.0.1:3508", "what": "Opens the restored copy on port 3508 with recovery hold on, so nothing runs automatically."}
 ]},
 {"path": ["family"], "sentence": "Guest and family CodeBots that run on this computer for other people, each under its own Linux user.", "rows": [
  {"name": "guest", "form": "codebot family guest", "what": "Opens the guest host: one person, its own Linux user, port 10000."},
  {"name": "members", "form": "codebot family members", "what": "Opens the family front door and the family CodeBots, up to six, on the home Wi-Fi address."}
 ]},
 {"path": ["family", "guest"], "sentence": "The guest host on this computer: its install, update, invite and status.", "rows": [
  {"name": "Install guest", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, service, settings, sudo rules and Tailscale on port 10000; run once."},
  {"name": "Update guest", "form": "ops/guest-update.sh", "what": "Builds, replaces /opt/codebot-guest and restarts the guest host; needs no password."},
  {"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google invite link, valid for ten minutes."},
  {"name": "Status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest host is running."},
  {"name": "Logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest host's log."},
  {"name": "Guest home", "form": "/home/codebot-guest", "what": "Opens the guest's home folder, where its data and projects are kept."},
  {"name": "Remove guest", "form": "ops/OPERATIONS.md, 'Host a guest on this machine'", "what": "Reads the steps that remove the guest host; they delete its user and data, so they stay as steps, not a command."}
 ]},
 {"path": ["family", "members"], "sentence": "The family front door and the family CodeBots on the home Wi-Fi address, one per Google account.", "rows": [
  {"name": "Family address", "form": "https://family.codebot.lielbenor.com", "what": "Opens the front door on the home Wi-Fi address, where a family member signs in with Google."},
  {"name": "Install family", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, the helper, services, sudo rules and nginx; run once."},
  {"name": "Update family", "form": "ops/family-update.sh", "what": "Builds, replaces /opt/codebot-family and restarts every family CodeBot; needs no password."},
  {"name": "Status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot: whether it runs, and whether Gmail can connect."},
  {"name": "Add member", "form": "sudo codebot-family add N", "what": "Adds family CodeBot N for a new Google account; the front door runs this itself on a new sign-in."},
  {"name": "Remove member", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number; the same Google account cannot be linked again without editing the account database."},
  {"name": "Stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
  {"name": "Start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot."},
  {"name": "Family logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the front door's and the family CodeBots' logs."},
  {"name": "Family settings", "form": "/etc/codebot-family.conf", "what": "Opens the settings every family CodeBot receives, including the Google app secret; keep it private."}
 ]},
 {"path": ["docs"], "sentence": "The written references: how to run CodeBot, what it is, and what is still open.", "rows": [
  {"name": "Runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook: running, connecting, backing up, restoring, resetting and recovering CodeBot."},
  {"name": "Bot model selection", "form": "ops/OPERATIONS.md, 'Bot model selection'", "what": "Reads which model a Bot uses for ordinary messages and for /goal."},
  {"name": "README", "form": "README.md", "what": "Opens the overview: what CodeBot is, how its pieces fit and which checks it runs."},
  {"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens the technical boundaries, invariants and persistence design."},
  {"name": "Product spec", "form": "PRODUCT-SPEC.md (named by the README; not in the file list)", "what": "Opens the behavior contract."},
  {"name": "Status and open work", "form": "IMPLEMENTATION-STATUS.md and DEFERRED-WORK.md (named by the README; not in the file list)", "what": "Opens what was built and the remaining checklist."},
  {"name": "Agent rules", "form": "CLAUDE.md", "what": "Opens the rules every agent follows; AGENTS.md is generated from it."},
  {"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "Opens the supervisor guide for Gmail automation."},
  {"name": "Design", "form": "docs/design-method.md and docs/design-taste.md", "what": "Opens the design method and the owner's design rulings."},
  {"name": "Objectives", "form": "docs/objectives/", "what": "Lists the objectives: chat current session, Gmail widget, schedules and terminal tabs."},
  {"name": "Records", "form": "codebot docs records", "what": "Opens the plans, verification evidence, task reports, intents and QA records."}
 ]},
 {"path": ["docs", "records"], "sentence": "The records of past work: plans, verification evidence, task reports, intents, feature tests and QA findings.", "rows": [
  {"name": "Plans", "form": "docs/plans/ and .plans/", "what": "Lists the plan documents for past and planned work."},
  {"name": "Verification", "form": "docs/verification/", "what": "Opens the recorded verification evidence, including the onboarding proof."},
  {"name": "Tasks", "form": "docs/tasks/ and docs/superpowers/plans/", "what": "Lists the task reports and dated work plans."},
  {"name": "Intents", "form": ".idd/modules/", "what": "Lists each module's INTENT.md: its constraints and its Given / When / Then table."},
  {"name": "Feature tests", "form": ".bdd/features/ and .bdd/steps/", "what": "Lists the feature files and the step files that run them."},
  {"name": "QA findings", "form": ".bdd/qa/findings/ and .bdd/qa/resolutions/", "what": "Lists the QA findings and how each one was resolved."},
  {"name": "Design critiques", "form": ".impeccable/critique/", "what": "Lists the design critiques of app screens."}
 ]}
],
"questions": [
 "Facade name: should the command be `codebot` (so `codebot help` is the map)? Recommendation: yes, with no short alias yet; add `cb` only after `whence -a cb` shows no clash.",
 "Top group name: 'service' or 'host'? The docs use both. Recommendation: 'service', because the unit is codebot.service and the README calls it the local service.",
 "Destructive or sudo steps (remove guest, remove member, emergency stop, reset onboarding, delete a person): should the CLI run them, or only print the steps? Recommendation: only print the steps, so nothing irreversible runs from a single typed command.",
 "Should the app screens (Bots, Contracts, Gmail, Terminal and so on) appear in the CLI, or should the CLI only open the private address? Recommendation: list them, with source folders as forms; the CLI does not drive the UI.",
 "Should the family and guest hosting stay on the owner's CLI, or be operator-only docs? Recommendation: keep them under 'family', with destructive steps as read-only steps.",
 "Three referenced files (PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md, DEFERRED-WORK.md) and cli/codebot.py are not in the file list. Do they exist in the repo? Recommendation: confirm before the CLI links to them."
]}
```

No skill · run 2 exit=0 seconds=120 · prompt

P1 Recall: 0.192P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.4P5 Short top: 11P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.177
As terminal help
Your Bots, each with its current state and whether it needs you, plus the entry points to everything else.
Open a Botthe Bot screen, chosen from the listReach one Bot's conversation and tools.
Create a Botnew-bot screenStart a new Bot with a name, role, provider and folder.
Gmailgmail screenSee Gmail activity, approvals and access for your Bots.
Avataravatar screenPick or design a Bot's avatar.
Terminalterminal screenShells and Claude sessions on this computer.
Settingssettings screen (cog, top right)This device's theme, notifications, computer and install.
What's newwhats-new screenRead the changes since your last update.
Onboardingonboarding screen (/onboarding)First-time setup until the first Bot exists.
Experimentsexperiments screenLocal experimental apps on ports 3512 to 3514.
Operationsops screenOperator tasks for the computer's CodeBot.
Developmentdev screenProject commands for building, testing and reviewing.
bot
One Bot's conversation: what it is doing now, the messages waiting for it, and what it needs from you.
Send a messagecomposer at the bottom of the Bot screenSend, queue behind a running reply, or send now. Attach files here too.
Queued messagesqueue bar above the composerSee, edit, take back or send now the messages waiting for the Bot.
StopStop button beside the composer (Esc)Interrupt the current turn; the queue is kept.
Transcriptthe conversation itself, divided by chat markersRead every message as it was sent.
Chatsbot/chats screenBrowse this Bot's topics.
Questions and approvalsbot/questions screenAnswer what the Bot asked and approve or deny its requests.
Filesbot/files screenPinned files, resources and attachments.
Browser and screenshotsbot/vision screenWatch or take over the Bot's browser.
Contractbot/contract screenThe Bot's feature contract.
Gitbot/git screenRepository status and quick git actions.
Schedulesbot/schedules screenTimed wakeups for this Bot.
Widgetsbot/widgets screenChoose and arrange the widgets on this Bot's screen.
Bot settingsbot/settings screen (cog)Identity, provider, folder, notifications and skills.
bot › chats
The topics this Bot has had, each with its label and kind of work, newest first.
Open a chatchat divider in the transcriptRead one topic's turns; the original messages stay unchanged.
Earlier workchats/ folder in the Bot's homeThe saved transcript the Bot reads when you refer to earlier work.
bot › questions
Questions the Bot is waiting on, and requests that need a yes or no.
Answer a questionquestion cardReply so the Bot can continue.
Approve or deny a file linkapproval card (ApproveFileLink)Let the Bot share or open a file, or refuse.
bot › files
Files this Bot has pinned, produced or been given.
Pinned filespinned files panelKeep the files you return to.
Open a resourceresource viewerPreview a file, image, markdown or recording.
Attach a fileattachment picker (+ on the composer)Give the Bot a file in your next message.
bot › vision
The Bot's browser: what the page shows now, past recordings and the screenshot gallery.
Live browservision viewWatch the Bot's Chromium page.
Take controlcontrol handoff buttonPause the Bot's automation and drive the browser yourself.
Recordingsrecording playerReplay a finished recording.
Screenshotsscreenshot galleryBrowse the Bot's captured screenshots in order.
bot › contract
The Bot's feature contract: the items it covers, their files, and how they have changed.
Catalogcontract catalog viewThe contract's items and their status.
Filescontract files viewFiles the contract covers.
Historycontract history view (opens diffs)Each revision, and what changed in it.
Conflictscontract conflict viewPlaces where the contract disagrees and needs a decision.
Relationshipscomponent relationships viewHow the contract's components depend on each other.
bot › git
The repository this Bot works in: its status and the actions you can take on it.
Repository statusgit status panelCurrent branch, changes and revision.
Quick actionsgit quick-action buttonsTyped git actions; each shows its outcome.
bot › schedules
Timed wakeups that start this Bot's work without a message from you.
Add or change a wakeupschedule editorSet when the Bot wakes and what it should do.
Pause a wakeupschedule row controlsStop a wakeup from firing.
bot › widgets
The widgets on this Bot's screen and the ones you can add.
Widget browserwidget browserAdd a widget to this Bot's screen.
Arrangewidget arrangementChange the order of the widgets.
bot › settings
This Bot's identity and behaviour, and how this device gets its notifications.
Name and roleform field on Bot settingsRename the Bot or change its role.
Provider and modelform field on Bot settingsClaude, Codex or OpenCode; an empty model uses the automatic policy.
Primary folderform field on Bot settingsThe folder the Bot works in; must sit inside an allowed project root.
Avataravatar screenChange the Bot's picture.
Automatic actions and skillspolicy options and skills fieldsWhat the Bot may do without asking, and which skills it has.
Notifications for this Botswitch on Bot settingsSend replies, approval requests and failures to your devices.
Enable this devicebrowser notification promptTurn on alerts on this device.
Reconnect this devicebutton on Bot settingsRepair an expired or rejected notification subscription.
Other devicesdevice listRemove old devices; up to 16 are kept.
Send testbutton on Bot settingsCheck the selected device; a sent test does not prove it displayed.
new-bot
Create a new Bot.
Name, role, provider, folderform on new-botSet up the Bot before its first message.
Createbutton; opens the Bot screenMake the Bot and go to it.
gmail
Gmail for your Bots: whether it is connected, what Bots did lately, and what waits for a decision.
Connect GmailGoogle sign-in via the account service's gmail-relayLink a Google account. Self-hosted needs its own Google client ID and secret.
Approvalsgmail/approvals screenGmail actions waiting for your yes or no.
Activitygmail/activity screenWhat Bots did in Gmail, as cards, with the daily summary.
Accessgmail/access screenWhich Bots may read or send, and disconnecting.
gmail › approvals
Gmail actions a Bot has asked to take, waiting for your decision.
Approveapproval card buttonLet the action go ahead.
Denyapproval card buttonStop the action.
gmail › activity
What Bots have done in Gmail, newest first, and the daily summary.
Open a cardGmail cardSee one message or action in detail.
Daily summarydaily summary panelToday's Gmail work in one view.
gmail › access
Which Bots may use Gmail, and the connected Google account.
Bot accessaccess toggle per BotAllow or stop a Bot reading or sending mail.
Disconnect Gmailbutton, asks to confirmRemove the link to the Google account; linking again needs sign-in.
avatar
Pick or design a Bot's avatar.
Pick an avataravatar pickerChoose a ready-made avatar.
Design with partsavatar studioBuild a face from body, eyes, accessories and colours.
settings
This device's settings and the computer it connects to.
Themetheme controlLight or dark.
Notifications on this devicesettings/notifications screenEnable, reconnect and test alerts for this device.
Accountcentral sign-in at /onboardingSign in through the central account service; it returns you to this computer.
This computerread-only panel (address and server ID from /api/onboarding/identity)Which computer this app is served by.
Diagnosticssettings/diagnostics screenHost, scheduler, vision and notification counters.
Terminal accessstatus line in this panelWhether the terminal is turned on for this computer.
Install the appbrowser Install app / Add to Home Screen commandInstall CodeBot on a phone or desktop.
settings › notifications
Alerts for this device, and the devices that receive them.
Enable this devicebrowser notification promptAllow alerts here.
Reconnect this devicebuttonRepair an expired subscription.
Other devicesdevice listRemove old devices.
Send testbuttonCheck this device; a sent test is not proof it showed the alert.
Notification queue/api/notifications/diagnosticsPending alerts and the send timer, for diagnosis.
settings › diagnostics
Counters and state for the host, the scheduler, vision and notifications. No provider credentials appear here.
Host/api/diagnostics/hostMigration, queued and running turns, recovery hold.
Scheduler/api/diagnostics/schedulerTimers and wakeup state.
Vision/api/diagnostics/visionBrowser capture state.
Session/api/sessionWhether the app is signed in to this computer.
whats-new
What changed in CodeBot, in plain words, with where to find it.
Latest changesentries from apps/web/src/whatsNew.tsShown once after each update.
onboarding
First-time setup: connect this device, meet your Bots and create the first one.
Connect a deviceDeviceConnection screenSign this device in to the computer.
Meet your BotsFirstBotIntroduction screenLearn what a Bot is for.
Create your first BotFirstBotCreation screenMake the first Bot.
terminal
Shell and Claude Code sessions on this computer, one per tab.
New tabterminal new-tab controlOpen a shell in an allowed project folder.
Tabterminal tabAttach to a session that keeps running if the web service restarts.
Claude sessionsClaude session listFind background Claude Code sessions to attach to.
experiments
Experimental apps that run next to CodeBot on this computer. Each has its own folder, port and data; they are not part of CodeBot.
V2 Terminal chathttp://127.0.0.1:3512 (run from ~/projects/codebot-v2-terminal-chat)CodeBot's look; a Bot's chat is the Claude Code terminal.
V3 Claude Code modhttp://127.0.0.1:3513 (run from ~/projects/codebot-v3-claude-mod)Claude Code first; a mod draws the Bot list above the prompt.
V4 Launcher menuhttp://127.0.0.1:3514 (run from ~/projects/codebot-v4-launcher-menu)A main menu whose buttons set up Claude Code sessions.
ops
Operator work on the computer that runs CodeBot. It is not part of the owner's path.
Deploy an updatesh ops/deploy.shBuild, push and restart; refuses while a Bot is working.
Buildnpm run buildTypecheck and publish a new release.
Restart the hostsystemctl --user restart codebot.serviceRestart after active turns finish, then check /api/session.
Stop the hostsystemctl --user stop codebot.serviceNormal stop; interrupts Bot turns and stops scheduling.
Status and logssystemctl --user status codebot.service; journalctl --user -u codebot.service -n 80Find out why the host is down.
Terminal brokersystemctl --user enable --now codebot-terminal-broker.serviceTurn on terminal access for this computer.
Backup and restoreops/backup screenStop, copy and verify the whole data folder.
Hosted peopleops/hosting screenThe guest and family CodeBots on this machine.
Change the addressops/address screenMove sign-in when the computer's Tailscale name changes.
Reset onboardingops/reset-onboarding screenShow someone the first-use setup again.
Account serviceSupabase project wbgrjvqbupgdclaztuouCentral sign-in data and functions.
ops › backup
Take a consistent copy of the data folder, or restore one into a separate folder first.
Back upstop the service, tar ~/.local/share/codebot, verify SHA256SUMS, startA copy that includes owner sessions and keys; keep it private.
Restore into stagingextract into an empty private folder; run on port 3508 with CODEBOT_RECOVERY_HOLD=1Check the copy before it replaces anything.
Promote a restorepoint CODEBOT_DATA_DIR at the verified copy in service.envMake the restored copy live; keep the old data as rollback.
ops › hosting
Other people's CodeBots on this machine: the guest account and the family CodeBots.
Guest hostsudo ops/guest-install.sh; ops/guest-update.sh; sudo -u codebot-guest /opt/codebot-guest/inviteA second account for one person, with its own Google sign-in.
Family CodeBotssudo ops/family-install.sh; ops/family-update.sh; sudo codebot-family add NOne CodeBot per family member, up to six, behind the family address.
Statussystemctl status codebot-guest; systemctl status 'codebot-family@*'Check whether each is running.
ops › address
The places that must change when this computer's Tailscale name changes.
Full listOPERATIONS.md, section Change this machine's addressNine places, from the domain forward to the installed phone apps.
Checksign in as each accountConfirm each account lands on its own host.
ops › reset-onboarding
Show a person the first-use setup again: replay only the tour, or start with a fresh CodeBot.
Replay the tourSupabase statement and a first_use_receipts deleteOnly works when the host has no Bots.
Fresh CodeBot, same accountwipe data except server-id, server-signing-key and owner-key; then the Supabase statementTheir Bots and conversations go; their Google account and folders stay.
Full resetdelete the data folder and the auth user, then re-inviteDestroys the account, its Bots, conversations and attachments.
dev
Project commands for development and checking.
Run the servicenpm run devStart the local service with reload.
Typecheck and testnpm run checkTypecheck and run the service tests.
Gmail referencenpm run docs:gmailRegenerate the Gmail reference.
Gmail reviewnpm run review:gmailCheck the Gmail flow in the real app.
Schedule reviewnpm run review:schedulesCheck schedules in the real app.
Playgroundnpm run playgroundCompare screen variants in apps/web/playground.
Host account setupnpm run setup-accountSet up the host's account binding.
Questions
  • Should operator and developer commands (ops, dev, experiments) share one help tree with the owner's screens, or be a separate command set? Recommendation: a separate set, because CLAUDE.md keeps operator work out of the owner's path.
  • Is there a command-line tool? The README line about cli/codebot.py is garbled, and no cli/ folder is in the file list. Recommendation: confirm before writing help for a codebot command. Until then, the ops and dev rows show only npm and systemctl commands.
  • Should the map include a delete-Bot row? OPERATIONS.md says CodeBot has no delete-Bot feature. Recommendation: leave it out until the feature exists.
  • Bot config export and import have plans in docs/plans but appear nowhere in the map. Recommendation: add them to Bot settings only when they ship.
  • Should Terminal stay in the owner's tree while the terminal broker is off? Recommendation: keep it, with a status line that says it is disabled, so the owner knows why it is empty.
  • Are the forms for app screens (for example gmail/approvals, bot/vision) real URLs or in-app views? The dump lists component files, not routes. Recommendation: confirm the router before the forms are final.
  • Should Connect Gmail appear for cloud users, given that cloud can offer Gmail only to a small early group? Recommendation: show it with a status line that says who it is available to.
  • Are the guest and family flows for the owner or for family members? Recommendation: keep hosting under ops only; family members see their own app, not this map.
As phone screens

Home

Your Bots, each with its current state and whether it needs you, plus the entry points to everything else.

Open a BotReach one Bot's conversation and tools.
›
Create a BotStart a new Bot with a name, role, provider and folder.
›
GmailSee Gmail activity, approvals and access for your Bots.
›
AvatarPick or design a Bot's avatar.
›
TerminalShells and Claude sessions on this computer.
›
SettingsThis device's theme, notifications, computer and install.
›
What's newRead the changes since your last update.
›
OnboardingFirst-time setup until the first Bot exists.
›
ExperimentsLocal experimental apps on ports 3512 to 3514.
›
OperationsOperator tasks for the computer's CodeBot.
›
DevelopmentProject commands for building, testing and reviewing.
›
‹ Home

bot

One Bot's conversation: what it is doing now, the messages waiting for it, and what it needs from you.

Send a messageSend, queue behind a running reply, or send now. Attach files here too.
›
Queued messagesSee, edit, take back or send now the messages waiting for the Bot.
›
StopInterrupt the current turn; the queue is kept.
›
TranscriptRead every message as it was sent.
›
ChatsBrowse this Bot's topics.
›
Questions and approvalsAnswer what the Bot asked and approve or deny its requests.
›
FilesPinned files, resources and attachments.
›
Browser and screenshotsWatch or take over the Bot's browser.
›
ContractThe Bot's feature contract.
›
GitRepository status and quick git actions.
›
SchedulesTimed wakeups for this Bot.
›
WidgetsChoose and arrange the widgets on this Bot's screen.
›
Bot settingsIdentity, provider, folder, notifications and skills.
›
‹ bot

chats

The topics this Bot has had, each with its label and kind of work, newest first.

Open a chatRead one topic's turns; the original messages stay unchanged.
›
Earlier workThe saved transcript the Bot reads when you refer to earlier work.
›
‹ bot

questions

Questions the Bot is waiting on, and requests that need a yes or no.

Answer a questionReply so the Bot can continue.
›
Approve or deny a file linkLet the Bot share or open a file, or refuse.
›
‹ bot

files

Files this Bot has pinned, produced or been given.

Pinned filesKeep the files you return to.
›
Open a resourcePreview a file, image, markdown or recording.
›
Attach a fileGive the Bot a file in your next message.
›
‹ bot

vision

The Bot's browser: what the page shows now, past recordings and the screenshot gallery.

Live browserWatch the Bot's Chromium page.
›
Take controlPause the Bot's automation and drive the browser yourself.
›
RecordingsReplay a finished recording.
›
ScreenshotsBrowse the Bot's captured screenshots in order.
›
‹ bot

contract

The Bot's feature contract: the items it covers, their files, and how they have changed.

CatalogThe contract's items and their status.
›
FilesFiles the contract covers.
›
HistoryEach revision, and what changed in it.
›
ConflictsPlaces where the contract disagrees and needs a decision.
›
RelationshipsHow the contract's components depend on each other.
›
‹ bot

git

The repository this Bot works in: its status and the actions you can take on it.

Repository statusCurrent branch, changes and revision.
›
Quick actionsTyped git actions; each shows its outcome.
›
‹ bot

schedules

Timed wakeups that start this Bot's work without a message from you.

Add or change a wakeupSet when the Bot wakes and what it should do.
›
Pause a wakeupStop a wakeup from firing.
›
‹ bot

widgets

The widgets on this Bot's screen and the ones you can add.

Widget browserAdd a widget to this Bot's screen.
›
ArrangeChange the order of the widgets.
›
‹ bot

settings

This Bot's identity and behaviour, and how this device gets its notifications.

Name and roleRename the Bot or change its role.
›
Provider and modelClaude, Codex or OpenCode; an empty model uses the automatic policy.
›
Primary folderThe folder the Bot works in; must sit inside an allowed project root.
›
AvatarChange the Bot's picture.
›
Automatic actions and skillsWhat the Bot may do without asking, and which skills it has.
›
Notifications for this BotSend replies, approval requests and failures to your devices.
›
Enable this deviceTurn on alerts on this device.
›
Reconnect this deviceRepair an expired or rejected notification subscription.
›
Other devicesRemove old devices; up to 16 are kept.
›
Send testCheck the selected device; a sent test does not prove it displayed.
›
‹ Home

new-bot

Create a new Bot.

Name, role, provider, folderSet up the Bot before its first message.
›
CreateMake the Bot and go to it.
›
‹ Home

gmail

Gmail for your Bots: whether it is connected, what Bots did lately, and what waits for a decision.

Connect GmailLink a Google account. Self-hosted needs its own Google client ID and secret.
›
ApprovalsGmail actions waiting for your yes or no.
›
ActivityWhat Bots did in Gmail, as cards, with the daily summary.
›
AccessWhich Bots may read or send, and disconnecting.
›
‹ gmail

approvals

Gmail actions a Bot has asked to take, waiting for your decision.

ApproveLet the action go ahead.
›
DenyStop the action.
›
‹ gmail

activity

What Bots have done in Gmail, newest first, and the daily summary.

Open a cardSee one message or action in detail.
›
Daily summaryToday's Gmail work in one view.
›
‹ gmail

access

Which Bots may use Gmail, and the connected Google account.

Bot accessAllow or stop a Bot reading or sending mail.
›
Disconnect GmailRemove the link to the Google account; linking again needs sign-in.
›
‹ Home

avatar

Pick or design a Bot's avatar.

Pick an avatarChoose a ready-made avatar.
›
Design with partsBuild a face from body, eyes, accessories and colours.
›
‹ Home

settings

This device's settings and the computer it connects to.

ThemeLight or dark.
›
Notifications on this deviceEnable, reconnect and test alerts for this device.
›
AccountSign in through the central account service; it returns you to this computer.
›
This computerWhich computer this app is served by.
›
DiagnosticsHost, scheduler, vision and notification counters.
›
Terminal accessWhether the terminal is turned on for this computer.
›
Install the appInstall CodeBot on a phone or desktop.
›
‹ settings

notifications

Alerts for this device, and the devices that receive them.

Enable this deviceAllow alerts here.
›
Reconnect this deviceRepair an expired subscription.
›
Other devicesRemove old devices.
›
Send testCheck this device; a sent test is not proof it showed the alert.
›
Notification queuePending alerts and the send timer, for diagnosis.
›
‹ settings

diagnostics

Counters and state for the host, the scheduler, vision and notifications. No provider credentials appear here.

HostMigration, queued and running turns, recovery hold.
›
SchedulerTimers and wakeup state.
›
VisionBrowser capture state.
›
SessionWhether the app is signed in to this computer.
›
‹ Home

whats-new

What changed in CodeBot, in plain words, with where to find it.

Latest changesShown once after each update.
›
‹ Home

onboarding

First-time setup: connect this device, meet your Bots and create the first one.

Connect a deviceSign this device in to the computer.
›
Meet your BotsLearn what a Bot is for.
›
Create your first BotMake the first Bot.
›
‹ Home

terminal

Shell and Claude Code sessions on this computer, one per tab.

New tabOpen a shell in an allowed project folder.
›
TabAttach to a session that keeps running if the web service restarts.
›
Claude sessionsFind background Claude Code sessions to attach to.
›
‹ Home

experiments

Experimental apps that run next to CodeBot on this computer. Each has its own folder, port and data; they are not part of CodeBot.

V2 Terminal chatCodeBot's look; a Bot's chat is the Claude Code terminal.
›
V3 Claude Code modClaude Code first; a mod draws the Bot list above the prompt.
›
V4 Launcher menuA main menu whose buttons set up Claude Code sessions.
›
‹ Home

ops

Operator work on the computer that runs CodeBot. It is not part of the owner's path.

Deploy an updateBuild, push and restart; refuses while a Bot is working.
›
BuildTypecheck and publish a new release.
›
Restart the hostRestart after active turns finish, then check /api/session.
›
Stop the hostNormal stop; interrupts Bot turns and stops scheduling.
›
Status and logsFind out why the host is down.
›
Terminal brokerTurn on terminal access for this computer.
›
Backup and restoreStop, copy and verify the whole data folder.
›
Hosted peopleThe guest and family CodeBots on this machine.
›
Change the addressMove sign-in when the computer's Tailscale name changes.
›
Reset onboardingShow someone the first-use setup again.
›
Account serviceCentral sign-in data and functions.
›
‹ ops

backup

Take a consistent copy of the data folder, or restore one into a separate folder first.

Back upA copy that includes owner sessions and keys; keep it private.
›
Restore into stagingCheck the copy before it replaces anything.
›
Promote a restoreMake the restored copy live; keep the old data as rollback.
›
‹ ops

hosting

Other people's CodeBots on this machine: the guest account and the family CodeBots.

Guest hostA second account for one person, with its own Google sign-in.
›
Family CodeBotsOne CodeBot per family member, up to six, behind the family address.
›
StatusCheck whether each is running.
›
‹ ops

address

The places that must change when this computer's Tailscale name changes.

Full listNine places, from the domain forward to the installed phone apps.
›
CheckConfirm each account lands on its own host.
›
‹ ops

reset-onboarding

Show a person the first-use setup again: replay only the tour, or start with a fresh CodeBot.

Replay the tourOnly works when the host has no Bots.
›
Fresh CodeBot, same accountTheir Bots and conversations go; their Google account and folders stay.
›
Full resetDestroys the account, its Bots, conversations and attachments.
›
‹ Home

dev

Project commands for development and checking.

Run the serviceStart the local service with reload.
›
Typecheck and testTypecheck and run the service tests.
›
Gmail referenceRegenerate the Gmail reference.
›
Gmail reviewCheck the Gmail flow in the real app.
›
Schedule reviewCheck schedules in the real app.
›
PlaygroundCompare screen variants in apps/web/playground.
›
Host account setupSet up the host's account binding.
›
Raw answer
I planned the map from the dump. Most screens come from file names in `apps/web/src` and the docs, so the forms are inferred rather than checked against the router. The dump also cuts off partway through `OPERATIONS.md` and `ARCHITECTURE.md`, so anything after those cuts is missing. The owner's screens sit at the top level. Operator, developer and experimental commands sit under their own nouns. Features that don't exist yet are left out and raised as questions.

```json
{"screens": [
{"path": [], "sentence": "Your Bots, each with its current state and whether it needs you, plus the entry points to everything else.", "rows": [
{"name": "Open a Bot", "form": "the Bot screen, chosen from the list", "what": "Reach one Bot's conversation and tools."},
{"name": "Create a Bot", "form": "new-bot screen", "what": "Start a new Bot with a name, role, provider and folder."},
{"name": "Gmail", "form": "gmail screen", "what": "See Gmail activity, approvals and access for your Bots."},
{"name": "Avatar", "form": "avatar screen", "what": "Pick or design a Bot's avatar."},
{"name": "Terminal", "form": "terminal screen", "what": "Shells and Claude sessions on this computer."},
{"name": "Settings", "form": "settings screen (cog, top right)", "what": "This device's theme, notifications, computer and install."},
{"name": "What's new", "form": "whats-new screen", "what": "Read the changes since your last update."},
{"name": "Onboarding", "form": "onboarding screen (/onboarding)", "what": "First-time setup until the first Bot exists."},
{"name": "Experiments", "form": "experiments screen", "what": "Local experimental apps on ports 3512 to 3514."},
{"name": "Operations", "form": "ops screen", "what": "Operator tasks for the computer's CodeBot."},
{"name": "Development", "form": "dev screen", "what": "Project commands for building, testing and reviewing."}
]},
{"path": ["bot"], "sentence": "One Bot's conversation: what it is doing now, the messages waiting for it, and what it needs from you.", "rows": [
{"name": "Send a message", "form": "composer at the bottom of the Bot screen", "what": "Send, queue behind a running reply, or send now. Attach files here too."},
{"name": "Queued messages", "form": "queue bar above the composer", "what": "See, edit, take back or send now the messages waiting for the Bot."},
{"name": "Stop", "form": "Stop button beside the composer (Esc)", "what": "Interrupt the current turn; the queue is kept."},
{"name": "Transcript", "form": "the conversation itself, divided by chat markers", "what": "Read every message as it was sent."},
{"name": "Chats", "form": "bot/chats screen", "what": "Browse this Bot's topics."},
{"name": "Questions and approvals", "form": "bot/questions screen", "what": "Answer what the Bot asked and approve or deny its requests."},
{"name": "Files", "form": "bot/files screen", "what": "Pinned files, resources and attachments."},
{"name": "Browser and screenshots", "form": "bot/vision screen", "what": "Watch or take over the Bot's browser."},
{"name": "Contract", "form": "bot/contract screen", "what": "The Bot's feature contract."},
{"name": "Git", "form": "bot/git screen", "what": "Repository status and quick git actions."},
{"name": "Schedules", "form": "bot/schedules screen", "what": "Timed wakeups for this Bot."},
{"name": "Widgets", "form": "bot/widgets screen", "what": "Choose and arrange the widgets on this Bot's screen."},
{"name": "Bot settings", "form": "bot/settings screen (cog)", "what": "Identity, provider, folder, notifications and skills."}
]},
{"path": ["bot", "chats"], "sentence": "The topics this Bot has had, each with its label and kind of work, newest first.", "rows": [
{"name": "Open a chat", "form": "chat divider in the transcript", "what": "Read one topic's turns; the original messages stay unchanged."},
{"name": "Earlier work", "form": "chats/ folder in the Bot's home", "what": "The saved transcript the Bot reads when you refer to earlier work."}
]},
{"path": ["bot", "questions"], "sentence": "Questions the Bot is waiting on, and requests that need a yes or no.", "rows": [
{"name": "Answer a question", "form": "question card", "what": "Reply so the Bot can continue."},
{"name": "Approve or deny a file link", "form": "approval card (ApproveFileLink)", "what": "Let the Bot share or open a file, or refuse."}
]},
{"path": ["bot", "files"], "sentence": "Files this Bot has pinned, produced or been given.", "rows": [
{"name": "Pinned files", "form": "pinned files panel", "what": "Keep the files you return to."},
{"name": "Open a resource", "form": "resource viewer", "what": "Preview a file, image, markdown or recording."},
{"name": "Attach a file", "form": "attachment picker (+ on the composer)", "what": "Give the Bot a file in your next message."}
]},
{"path": ["bot", "vision"], "sentence": "The Bot's browser: what the page shows now, past recordings and the screenshot gallery.", "rows": [
{"name": "Live browser", "form": "vision view", "what": "Watch the Bot's Chromium page."},
{"name": "Take control", "form": "control handoff button", "what": "Pause the Bot's automation and drive the browser yourself."},
{"name": "Recordings", "form": "recording player", "what": "Replay a finished recording."},
{"name": "Screenshots", "form": "screenshot gallery", "what": "Browse the Bot's captured screenshots in order."}
]},
{"path": ["bot", "contract"], "sentence": "The Bot's feature contract: the items it covers, their files, and how they have changed.", "rows": [
{"name": "Catalog", "form": "contract catalog view", "what": "The contract's items and their status."},
{"name": "Files", "form": "contract files view", "what": "Files the contract covers."},
{"name": "History", "form": "contract history view (opens diffs)", "what": "Each revision, and what changed in it."},
{"name": "Conflicts", "form": "contract conflict view", "what": "Places where the contract disagrees and needs a decision."},
{"name": "Relationships", "form": "component relationships view", "what": "How the contract's components depend on each other."}
]},
{"path": ["bot", "git"], "sentence": "The repository this Bot works in: its status and the actions you can take on it.", "rows": [
{"name": "Repository status", "form": "git status panel", "what": "Current branch, changes and revision."},
{"name": "Quick actions", "form": "git quick-action buttons", "what": "Typed git actions; each shows its outcome."}
]},
{"path": ["bot", "schedules"], "sentence": "Timed wakeups that start this Bot's work without a message from you.", "rows": [
{"name": "Add or change a wakeup", "form": "schedule editor", "what": "Set when the Bot wakes and what it should do."},
{"name": "Pause a wakeup", "form": "schedule row controls", "what": "Stop a wakeup from firing."}
]},
{"path": ["bot", "widgets"], "sentence": "The widgets on this Bot's screen and the ones you can add.", "rows": [
{"name": "Widget browser", "form": "widget browser", "what": "Add a widget to this Bot's screen."},
{"name": "Arrange", "form": "widget arrangement", "what": "Change the order of the widgets."}
]},
{"path": ["bot", "settings"], "sentence": "This Bot's identity and behaviour, and how this device gets its notifications.", "rows": [
{"name": "Name and role", "form": "form field on Bot settings", "what": "Rename the Bot or change its role."},
{"name": "Provider and model", "form": "form field on Bot settings", "what": "Claude, Codex or OpenCode; an empty model uses the automatic policy."},
{"name": "Primary folder", "form": "form field on Bot settings", "what": "The folder the Bot works in; must sit inside an allowed project root."},
{"name": "Avatar", "form": "avatar screen", "what": "Change the Bot's picture."},
{"name": "Automatic actions and skills", "form": "policy options and skills fields", "what": "What the Bot may do without asking, and which skills it has."},
{"name": "Notifications for this Bot", "form": "switch on Bot settings", "what": "Send replies, approval requests and failures to your devices."},
{"name": "Enable this device", "form": "browser notification prompt", "what": "Turn on alerts on this device."},
{"name": "Reconnect this device", "form": "button on Bot settings", "what": "Repair an expired or rejected notification subscription."},
{"name": "Other devices", "form": "device list", "what": "Remove old devices; up to 16 are kept."},
{"name": "Send test", "form": "button on Bot settings", "what": "Check the selected device; a sent test does not prove it displayed."}
]},
{"path": ["new-bot"], "sentence": "Create a new Bot.", "rows": [
{"name": "Name, role, provider, folder", "form": "form on new-bot", "what": "Set up the Bot before its first message."},
{"name": "Create", "form": "button; opens the Bot screen", "what": "Make the Bot and go to it."}
]},
{"path": ["gmail"], "sentence": "Gmail for your Bots: whether it is connected, what Bots did lately, and what waits for a decision.", "rows": [
{"name": "Connect Gmail", "form": "Google sign-in via the account service's gmail-relay", "what": "Link a Google account. Self-hosted needs its own Google client ID and secret."},
{"name": "Approvals", "form": "gmail/approvals screen", "what": "Gmail actions waiting for your yes or no."},
{"name": "Activity", "form": "gmail/activity screen", "what": "What Bots did in Gmail, as cards, with the daily summary."},
{"name": "Access", "form": "gmail/access screen", "what": "Which Bots may read or send, and disconnecting."}
]},
{"path": ["gmail", "approvals"], "sentence": "Gmail actions a Bot has asked to take, waiting for your decision.", "rows": [
{"name": "Approve", "form": "approval card button", "what": "Let the action go ahead."},
{"name": "Deny", "form": "approval card button", "what": "Stop the action."}
]},
{"path": ["gmail", "activity"], "sentence": "What Bots have done in Gmail, newest first, and the daily summary.", "rows": [
{"name": "Open a card", "form": "Gmail card", "what": "See one message or action in detail."},
{"name": "Daily summary", "form": "daily summary panel", "what": "Today's Gmail work in one view."}
]},
{"path": ["gmail", "access"], "sentence": "Which Bots may use Gmail, and the connected Google account.", "rows": [
{"name": "Bot access", "form": "access toggle per Bot", "what": "Allow or stop a Bot reading or sending mail."},
{"name": "Disconnect Gmail", "form": "button, asks to confirm", "what": "Remove the link to the Google account; linking again needs sign-in."}
]},
{"path": ["avatar"], "sentence": "Pick or design a Bot's avatar.", "rows": [
{"name": "Pick an avatar", "form": "avatar picker", "what": "Choose a ready-made avatar."},
{"name": "Design with parts", "form": "avatar studio", "what": "Build a face from body, eyes, accessories and colours."}
]},
{"path": ["settings"], "sentence": "This device's settings and the computer it connects to.", "rows": [
{"name": "Theme", "form": "theme control", "what": "Light or dark."},
{"name": "Notifications on this device", "form": "settings/notifications screen", "what": "Enable, reconnect and test alerts for this device."},
{"name": "Account", "form": "central sign-in at /onboarding", "what": "Sign in through the central account service; it returns you to this computer."},
{"name": "This computer", "form": "read-only panel (address and server ID from /api/onboarding/identity)", "what": "Which computer this app is served by."},
{"name": "Diagnostics", "form": "settings/diagnostics screen", "what": "Host, scheduler, vision and notification counters."},
{"name": "Terminal access", "form": "status line in this panel", "what": "Whether the terminal is turned on for this computer."},
{"name": "Install the app", "form": "browser Install app / Add to Home Screen command", "what": "Install CodeBot on a phone or desktop."}
]},
{"path": ["settings", "notifications"], "sentence": "Alerts for this device, and the devices that receive them.", "rows": [
{"name": "Enable this device", "form": "browser notification prompt", "what": "Allow alerts here."},
{"name": "Reconnect this device", "form": "button", "what": "Repair an expired subscription."},
{"name": "Other devices", "form": "device list", "what": "Remove old devices."},
{"name": "Send test", "form": "button", "what": "Check this device; a sent test is not proof it showed the alert."},
{"name": "Notification queue", "form": "/api/notifications/diagnostics", "what": "Pending alerts and the send timer, for diagnosis."}
]},
{"path": ["settings", "diagnostics"], "sentence": "Counters and state for the host, the scheduler, vision and notifications. No provider credentials appear here.", "rows": [
{"name": "Host", "form": "/api/diagnostics/host", "what": "Migration, queued and running turns, recovery hold."},
{"name": "Scheduler", "form": "/api/diagnostics/scheduler", "what": "Timers and wakeup state."},
{"name": "Vision", "form": "/api/diagnostics/vision", "what": "Browser capture state."},
{"name": "Session", "form": "/api/session", "what": "Whether the app is signed in to this computer."}
]},
{"path": ["whats-new"], "sentence": "What changed in CodeBot, in plain words, with where to find it.", "rows": [
{"name": "Latest changes", "form": "entries from apps/web/src/whatsNew.ts", "what": "Shown once after each update."}
]},
{"path": ["onboarding"], "sentence": "First-time setup: connect this device, meet your Bots and create the first one.", "rows": [
{"name": "Connect a device", "form": "DeviceConnection screen", "what": "Sign this device in to the computer."},
{"name": "Meet your Bots", "form": "FirstBotIntroduction screen", "what": "Learn what a Bot is for."},
{"name": "Create your first Bot", "form": "FirstBotCreation screen", "what": "Make the first Bot."}
]},
{"path": ["terminal"], "sentence": "Shell and Claude Code sessions on this computer, one per tab.", "rows": [
{"name": "New tab", "form": "terminal new-tab control", "what": "Open a shell in an allowed project folder."},
{"name": "Tab", "form": "terminal tab", "what": "Attach to a session that keeps running if the web service restarts."},
{"name": "Claude sessions", "form": "Claude session list", "what": "Find background Claude Code sessions to attach to."}
]},
{"path": ["experiments"], "sentence": "Experimental apps that run next to CodeBot on this computer. Each has its own folder, port and data; they are not part of CodeBot.", "rows": [
{"name": "V2 Terminal chat", "form": "http://127.0.0.1:3512 (run from ~/projects/codebot-v2-terminal-chat)", "what": "CodeBot's look; a Bot's chat is the Claude Code terminal."},
{"name": "V3 Claude Code mod", "form": "http://127.0.0.1:3513 (run from ~/projects/codebot-v3-claude-mod)", "what": "Claude Code first; a mod draws the Bot list above the prompt."},
{"name": "V4 Launcher menu", "form": "http://127.0.0.1:3514 (run from ~/projects/codebot-v4-launcher-menu)", "what": "A main menu whose buttons set up Claude Code sessions."}
]},
{"path": ["ops"], "sentence": "Operator work on the computer that runs CodeBot. It is not part of the owner's path.", "rows": [
{"name": "Deploy an update", "form": "sh ops/deploy.sh", "what": "Build, push and restart; refuses while a Bot is working."},
{"name": "Build", "form": "npm run build", "what": "Typecheck and publish a new release."},
{"name": "Restart the host", "form": "systemctl --user restart codebot.service", "what": "Restart after active turns finish, then check /api/session."},
{"name": "Stop the host", "form": "systemctl --user stop codebot.service", "what": "Normal stop; interrupts Bot turns and stops scheduling."},
{"name": "Status and logs", "form": "systemctl --user status codebot.service; journalctl --user -u codebot.service -n 80", "what": "Find out why the host is down."},
{"name": "Terminal broker", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "Turn on terminal access for this computer."},
{"name": "Backup and restore", "form": "ops/backup screen", "what": "Stop, copy and verify the whole data folder."},
{"name": "Hosted people", "form": "ops/hosting screen", "what": "The guest and family CodeBots on this machine."},
{"name": "Change the address", "form": "ops/address screen", "what": "Move sign-in when the computer's Tailscale name changes."},
{"name": "Reset onboarding", "form": "ops/reset-onboarding screen", "what": "Show someone the first-use setup again."},
{"name": "Account service", "form": "Supabase project wbgrjvqbupgdclaztuou", "what": "Central sign-in data and functions."}
]},
{"path": ["ops", "backup"], "sentence": "Take a consistent copy of the data folder, or restore one into a separate folder first.", "rows": [
{"name": "Back up", "form": "stop the service, tar ~/.local/share/codebot, verify SHA256SUMS, start", "what": "A copy that includes owner sessions and keys; keep it private."},
{"name": "Restore into staging", "form": "extract into an empty private folder; run on port 3508 with CODEBOT_RECOVERY_HOLD=1", "what": "Check the copy before it replaces anything."},
{"name": "Promote a restore", "form": "point CODEBOT_DATA_DIR at the verified copy in service.env", "what": "Make the restored copy live; keep the old data as rollback."}
]},
{"path": ["ops", "hosting"], "sentence": "Other people's CodeBots on this machine: the guest account and the family CodeBots.", "rows": [
{"name": "Guest host", "form": "sudo ops/guest-install.sh; ops/guest-update.sh; sudo -u codebot-guest /opt/codebot-guest/invite", "what": "A second account for one person, with its own Google sign-in."},
{"name": "Family CodeBots", "form": "sudo ops/family-install.sh; ops/family-update.sh; sudo codebot-family add N", "what": "One CodeBot per family member, up to six, behind the family address."},
{"name": "Status", "form": "systemctl status codebot-guest; systemctl status 'codebot-family@*'", "what": "Check whether each is running."}
]},
{"path": ["ops", "address"], "sentence": "The places that must change when this computer's Tailscale name changes.", "rows": [
{"name": "Full list", "form": "OPERATIONS.md, section Change this machine's address", "what": "Nine places, from the domain forward to the installed phone apps."},
{"name": "Check", "form": "sign in as each account", "what": "Confirm each account lands on its own host."}
]},
{"path": ["ops", "reset-onboarding"], "sentence": "Show a person the first-use setup again: replay only the tour, or start with a fresh CodeBot.", "rows": [
{"name": "Replay the tour", "form": "Supabase statement and a first_use_receipts delete", "what": "Only works when the host has no Bots."},
{"name": "Fresh CodeBot, same account", "form": "wipe data except server-id, server-signing-key and owner-key; then the Supabase statement", "what": "Their Bots and conversations go; their Google account and folders stay."},
{"name": "Full reset", "form": "delete the data folder and the auth user, then re-invite", "what": "Destroys the account, its Bots, conversations and attachments."}
]},
{"path": ["dev"], "sentence": "Project commands for development and checking.", "rows": [
{"name": "Run the service", "form": "npm run dev", "what": "Start the local service with reload."},
{"name": "Typecheck and test", "form": "npm run check", "what": "Typecheck and run the service tests."},
{"name": "Gmail reference", "form": "npm run docs:gmail", "what": "Regenerate the Gmail reference."},
{"name": "Gmail review", "form": "npm run review:gmail", "what": "Check the Gmail flow in the real app."},
{"name": "Schedule review", "form": "npm run review:schedules", "what": "Check schedules in the real app."},
{"name": "Playground", "form": "npm run playground", "what": "Compare screen variants in apps/web/playground."},
{"name": "Host account setup", "form": "npm run setup-account", "what": "Set up the host's account binding."}
]}
],
"questions": [
"Should operator and developer commands (ops, dev, experiments) share one help tree with the owner's screens, or be a separate command set? Recommendation: a separate set, because CLAUDE.md keeps operator work out of the owner's path.",
"Is there a command-line tool? The README line about cli/codebot.py is garbled, and no cli/ folder is in the file list. Recommendation: confirm before writing help for a codebot command. Until then, the ops and dev rows show only npm and systemctl commands.",
"Should the map include a delete-Bot row? OPERATIONS.md says CodeBot has no delete-Bot feature. Recommendation: leave it out until the feature exists.",
"Bot config export and import have plans in docs/plans but appear nowhere in the map. Recommendation: add them to Bot settings only when they ship.",
"Should Terminal stay in the owner's tree while the terminal broker is off? Recommendation: keep it, with a status line that says it is disabled, so the owner knows why it is empty.",
"Are the forms for app screens (for example gmail/approvals, bot/vision) real URLs or in-app views? The dump lists component files, not routes. Recommendation: confirm the router before the forms are final.",
"Should Connect Gmail appear for cloud users, given that cloud can offer Gmail only to a small early group? Recommendation: show it with a status line that says who it is available to.",
"Are the guest and family flows for the owner or for family members? Recommendation: keep hosting under ops only; family members see their own app, not this map."
]}
```

Today's skills · run 2 exit=0 seconds=134 · prompt

P1 Recall: 0.513P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.473
As terminal help
The CodeBot project's command line: this machine's own CodeBot and the other CodeBots on it, backups, the account service, Gmail, development, and the documents.
Hostcodebot hostPrints the host screen: this machine's own CodeBot, its service, its address and its data.
Guestcodebot guestPrints the guest screen: a second CodeBot on this machine for another person, run as its own Linux user.
Familycodebot familyPrints the family screen: the home-Wi-Fi front door and one CodeBot per family member.
Backupcodebot backupPrints the backup screen: making a backup of the stopped data and restoring one into a separate folder.
Accountcodebot accountPrints the account screen: the Supabase account service that handles sign-in and pairs people with their computers.
Gmailcodebot gmailPrints the Gmail screen: the Gmail guide, its generated reference, and the Gmail review.
Developmentcodebot devPrints the development screen: running, checking and building the code, and the design playground.
Documentscodebot docsPrints the documents screen: the runbook, the architecture, the rules for agents, and the plans.
host
This machine's own CodeBot: its service on port 3505, its private address, its data, and how to deploy it.
Servicecodebot host servicePrints the service screen: starting, stopping, restarting and reading the owner's service.
Deploysh ops/deploy.shDeploys the current code: builds it, commits and pushes it, restarts codebot.service and checks that it answers. Refuses while a Bot is working or the server code has someone else's uncommitted edits.
Private addresshttps://liel.tail18e69e.ts.netOpens the owner's CodeBot in the browser, over Tailscale.
Address maptailscale serve status --jsonShows how the private address maps to port 3505 on this machine.
Host diagnosticshttp://127.0.0.1:3505/api/diagnostics/hostOpens the host counters in the browser; sign in to the app first.
Data folder~/.local/share/codebotOpens the data folder: the database, the owner sessions and the entrance key.
Private settings~/.config/codebot/service.envOpens the private settings file; the CLI never prints its values.
Entrance key~/.local/share/codebot/owner-keyOpens the file that holds the entrance key; the CLI never prints its contents.
Connect a phoneops/OPERATIONS.md, section Connect a deviceOpens the steps to connect a phone: Tailscale, the private address, and Add to Home Screen.
Change addressops/OPERATIONS.md, section Change this machine's addressOpens the checklist of the nine places to update when this machine's address changes.
host › service
The owner's codebot.service and the optional terminal broker, as this user's systemd sees them.
Statussystemctl --user status codebot.service --no-pagerShows whether the service is running, and since when.
Startsystemctl --user start codebot.serviceStarts the service.
Stopsystemctl --user stop codebot.serviceStops the service; this interrupts Bot turns and finalizes recordings.
Restartsystemctl --user restart codebot.serviceRestarts the service; run it only after active turns and recordings finish.
Logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the service.
Port ownerss -ltnp 'sport = :3505'Lists which process holds port 3505.
Answer checkcurl --fail --silent --show-error http://127.0.0.1:3505/api/sessionChecks that the service answers on port 3505.
Terminal brokersystemctl --user status codebot-terminal-broker.service --no-pagerShows whether the optional terminal broker is running.
Stay runningloginctl show-user <your user> -p LingerShows whether the service stays up without a desktop login.
guest
The guest CodeBot: a second CodeBot on this machine, run by the Linux user codebot-guest, on port 10000.
Statussystemctl status codebot-guest --no-pagerShows whether the guest CodeBot is running.
Logsjournalctl -u codebot-guest -n 80 --no-pagerPrints the last 80 log lines of the guest CodeBot.
Guest addresshttps://liel.tail18e69e.ts.net:10000Opens the guest's CodeBot in the browser.
Disk usesudo du -sh /home/codebot-guestShows how much disk the guest CodeBot uses.
Projects folder/home/codebot-guest/projectsOpens the guest's project folders.
Invitesudo -u codebot-guest /opt/codebot-guest/inviteCreates a one-use Google sign-in link, valid for ten minutes.
Updateops/guest-update.shBuilds the current version, replaces the guest program and restarts it; needs no password.
Set up oncesudo ops/guest-install.shSets up the guest user, its service, the sudo rules and Tailscale port 10000; run once.
Remove or resetops/OPERATIONS.md, sections Host a guest on this machine and Restart onboarding with a fresh CodeBotOpens the steps to remove the guest or restart its onboarding; both delete data.
family
The family CodeBots: the home-Wi-Fi front door and one CodeBot per family member, each as its own Linux user.
Statuscodebot-family statusShows whether the front door and each family CodeBot are running, and whether Gmail can connect.
Logsjournalctl -u codebot-family-lobby -u 'codebot-family@*' -n 80 --no-pagerPrints the last 80 log lines of the front door and the family CodeBots.
Family sign-in addresshttps://family.codebot.lielbenor.comOpens the family sign-in page, from home Wi-Fi or over the owner's tailnet.
Add membersudo codebot-family add NCreates family CodeBot N with its own user, port 3540 plus N, and its address.
Remove membersudo codebot-family remove NDeletes family CodeBot N and frees its number; its Google account stays linked to it for good.
Stop allsudo codebot-family stop-allStops every family CodeBot.
Start allsudo codebot-family start-allStarts every family CodeBot again.
Updateops/family-update.shBuilds and replaces the family program and restarts all family CodeBots; needs no password.
Set up oncesudo ops/family-install.shSets up the front door user, the helper, the services, the sudo rules and nginx; run once.
Family settings/etc/codebot-family.confOpens the family settings file; reading it needs sudo.
backup
Backups of the owner's CodeBot: a consistent copy taken while the service is stopped, and a restore checked in a separate folder.
Make a backupops/OPERATIONS.md, section Back up a consistent installationMakes a backup: stops the service, copies its data, settings and unit file, then starts it again. No script exists yet.
Restoreops/OPERATIONS.md, section Restore into a separate directory firstRestores a backup into a new folder and checks it there; never restores over the running install.
Check checksumssha256sum -c SHA256SUMS (run inside the backup folder)Checks a backup's files against its recorded checksums.
Backup folder~/.local/share/codebot-backupsOpens the folder that holds every backup, one dated folder each.
account
The Supabase account service: the sign-in database, its functions and its migrations.
Dashboardhttps://supabase.com/dashboard/project/wbgrjvqbupgdclaztuouOpens the account service in the Supabase dashboard, under the mobile-coder login.
Deploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou (token from ~/.config/supabase-codebot-token)Deploys the host-access function to the cloud; redeploy it whenever a contract it parses changes.
Deploy gmail-relaynpx supabase functions deploy gmail-relay --project-ref wbgrjvqbupgdclaztuou (same token)Deploys the gmail-relay function to the cloud.
Token file~/.config/supabase-codebot-tokenOpens the CLI token file; the CLI never prints its value.
Functions foldersupabase/functions/Opens the two functions, gmail-relay and host-access.
Migrations foldersupabase/migrations/Opens the six database migrations, in order.
Reset onboardingops/OPERATIONS.md, section Reset someone's onboardingOpens the steps to reset one person's onboarding; both databases are changed by hand.
gmail
Gmail for Bots: the guide, the generated reference, the review, and the relay function that carries Google sign-in.
Guidedocs/automation/gmail.mdOpens the Gmail guide for supervisors.
Referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference.
Regenerate referencenpm run docs:gmailRegenerates the Gmail reference from the code.
Reviewnpm run review:gmailRuns the Gmail review script (ops/review/gmail-review.mjs).
Relay functionsupabase/functions/gmail-relay/index.tsOpens the Google sign-in relay function's source.
dev
Development: installing, running, checking and building the code, the design playground, and the scripts that keep files in step.
Installnpm ciInstalls the exact dependencies from the lockfile.
Run in watch modenpm run devStarts the service in watch mode, restarting on each code change; stop codebot.service first if they share a port.
Run in production modenpm run startStarts the service in production mode, in the foreground.
Typechecknpm run typecheckChecks the TypeScript types without building.
Testnpm testRuns the Gmail automation tests against a fake Google server.
Checknpm run checkRuns the typecheck and the tests together.
Buildnpm run buildTypechecks, then builds the web app into a new release folder and switches to it.
Build for QAnpm run build:integrationTypechecks, then builds for the disposable QA instance on port 3506.
Design playgroundnpm run playgroundStarts the design playground's Gmail page in the browser.
Sync agents filenpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
Schedules reviewnpm run review:schedulesRuns the schedules review script (ops/review/schedules-review.mjs).
Account setupnpm run setup-accountRuns the account setup script (ops/setup-account.ts).
Development settings.envOpens the development settings, copied from .env.example; never prints its values.
docs
The project's documents: the runbook, the architecture, the rules for agents, the design records, and the plans.
Runbookops/OPERATIONS.mdOpens the runbook: install, back up, restore, change the address and reset onboarding.
ArchitectureARCHITECTURE.mdOpens the technical boundaries and how CodeBot is built.
OverviewREADME.mdOpens the project overview and how to run the service.
Rules for agentsCLAUDE.mdOpens the fundamentals every task assumes, and the design rules.
Plansdocs/plans/Opens the folder of plans, one file each.
Design methoddocs/design-method.mdOpens the method used for designing screens.
Design rulingsdocs/design-taste.mdOpens the owner's design rulings and what they rejected.
Objectivesdocs/objectives/Opens the objectives, one file each.
Module intents.idd/modules/Opens each module's intent, with its constraints and tests.
Behaviour specs.bdd/features/Opens the Given-When-Then feature specs.
Verification recordsdocs/verification/Opens the recorded verification evidence.
Housekeeping skillskills/codebot-housekeeping/SKILL.mdOpens the housekeeping skill for the Bots.
Implementation statusIMPLEMENTATION-STATUS.mdOpens what was built and where the first beta stopped.
Deferred workDEFERRED-WORK.mdOpens the open work and the safe restart state.
Questions
  • Eight top-level nouns (host, guest, family, backup, account, gmail, dev, docs). Keep all eight, or fold guest and family into host? Recommend keeping eight: each is a different job with different rules, and guest and family setup need sudo.
  • Facade name and alias. Recommend `codebot`, with `cb` as the alias only if the clash check at build time finds it free. I could not run that check from here.
  • Port 3505 clash: `dev` (npm run dev) and the owner's service may both want that port. Recommend that `codebot dev run` refuses with exit 1 and names codebot.service while it is active, and never stops it on its own.
  • Force-kill (SIGKILL) of the service: include it as a command, or keep it in the runbook only? Recommend the runbook only. It can lose uncommitted recordings, so it should not be one keystroke.
  • Secret files: the entrance key, service.env, the Supabase token and .env appear as rows that open them. Recommend that the CLI opens the path and never prints contents, and that the editor's display is left to you.
  • Restart and stop: should `host service restart` and `stop` refuse while a Bot is working, as ops/deploy.sh does? Recommend yes, by calling the same guard rather than copying its logic.
  • Destructive and outward actions: family remove, guest setup, the Supabase deploys (which publish to the cloud) and deploy (which pushes to the remote). Should the CLI run them, or only print the command for you to run? Recommend print-first. Remove gets a typed confirmation. Cloud deploys and push stay print-only.
  • Backup and restore have no script yet; the runbook has bash blocks. Recommend a worker task to write ops/backup.sh and ops/restore.sh from those blocks, after which the rows point at them. Do you want that task?
  • Unverified commands: `codebot-family status` and the sudo needs of the family and guest rows follow the runbook, but I did not check the helper's source. The gmail-relay deploy command is not written in the runbook; I used the host-access pattern. Confirm both before the build.
  • Scripts I did not map: ops/review/redirect-google.mjs, seed-gmail.ts, schedule-drill.mjs and terminal-tabs-stack.sh, whose purposes are not in the dump. Recommend mapping only the npm scripts now and reading these before adding rows.
  • Experimental apps V2, V3 and V4 (ports 3512 to 3514) live in their own repos and the README says they are not part of CodeBot. Leave them out of this map? Recommend yes.
  • Files named in the README but not visible in the dump's file list: DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md, PRODUCT-SPEC.md and MASTER-PLAN.md. I kept rows for the first two in docs. Confirm they exist before the build, and say whether PRODUCT-SPEC and MASTER-PLAN should get rows too.
As phone screens

Home

The CodeBot project's command line: this machine's own CodeBot and the other CodeBots on it, backups, the account service, Gmail, development, and the documents.

HostPrints the host screen: this machine's own CodeBot, its service, its address and its data.
›
GuestPrints the guest screen: a second CodeBot on this machine for another person, run as its own Linux user.
›
FamilyPrints the family screen: the home-Wi-Fi front door and one CodeBot per family member.
›
BackupPrints the backup screen: making a backup of the stopped data and restoring one into a separate folder.
›
AccountPrints the account screen: the Supabase account service that handles sign-in and pairs people with their computers.
›
GmailPrints the Gmail screen: the Gmail guide, its generated reference, and the Gmail review.
›
DevelopmentPrints the development screen: running, checking and building the code, and the design playground.
›
DocumentsPrints the documents screen: the runbook, the architecture, the rules for agents, and the plans.
›
‹ Home

host

This machine's own CodeBot: its service on port 3505, its private address, its data, and how to deploy it.

ServicePrints the service screen: starting, stopping, restarting and reading the owner's service.
›
DeployDeploys the current code: builds it, commits and pushes it, restarts codebot.service and checks that it answers. Refuses while a Bot is working or the server code has someone else's uncommitted edits.
›
Private addressOpens the owner's CodeBot in the browser, over Tailscale.
›
Address mapShows how the private address maps to port 3505 on this machine.
›
Host diagnosticsOpens the host counters in the browser; sign in to the app first.
›
Data folderOpens the data folder: the database, the owner sessions and the entrance key.
›
Private settingsOpens the private settings file; the CLI never prints its values.
›
Entrance keyOpens the file that holds the entrance key; the CLI never prints its contents.
›
Connect a phoneOpens the steps to connect a phone: Tailscale, the private address, and Add to Home Screen.
›
Change addressOpens the checklist of the nine places to update when this machine's address changes.
›
‹ host

service

The owner's codebot.service and the optional terminal broker, as this user's systemd sees them.

StatusShows whether the service is running, and since when.
›
StartStarts the service.
›
StopStops the service; this interrupts Bot turns and finalizes recordings.
›
RestartRestarts the service; run it only after active turns and recordings finish.
›
LogsPrints the last 80 log lines of the service.
›
Port ownerLists which process holds port 3505.
›
Answer checkChecks that the service answers on port 3505.
›
Terminal brokerShows whether the optional terminal broker is running.
›
Stay runningShows whether the service stays up without a desktop login.
›
‹ Home

guest

The guest CodeBot: a second CodeBot on this machine, run by the Linux user codebot-guest, on port 10000.

StatusShows whether the guest CodeBot is running.
›
LogsPrints the last 80 log lines of the guest CodeBot.
›
Guest addressOpens the guest's CodeBot in the browser.
›
Disk useShows how much disk the guest CodeBot uses.
›
Projects folderOpens the guest's project folders.
›
InviteCreates a one-use Google sign-in link, valid for ten minutes.
›
UpdateBuilds the current version, replaces the guest program and restarts it; needs no password.
›
Set up onceSets up the guest user, its service, the sudo rules and Tailscale port 10000; run once.
›
Remove or resetOpens the steps to remove the guest or restart its onboarding; both delete data.
›
‹ Home

family

The family CodeBots: the home-Wi-Fi front door and one CodeBot per family member, each as its own Linux user.

StatusShows whether the front door and each family CodeBot are running, and whether Gmail can connect.
›
LogsPrints the last 80 log lines of the front door and the family CodeBots.
›
Family sign-in addressOpens the family sign-in page, from home Wi-Fi or over the owner's tailnet.
›
Add memberCreates family CodeBot N with its own user, port 3540 plus N, and its address.
›
Remove memberDeletes family CodeBot N and frees its number; its Google account stays linked to it for good.
›
Stop allStops every family CodeBot.
›
Start allStarts every family CodeBot again.
›
UpdateBuilds and replaces the family program and restarts all family CodeBots; needs no password.
›
Set up onceSets up the front door user, the helper, the services, the sudo rules and nginx; run once.
›
Family settingsOpens the family settings file; reading it needs sudo.
›
‹ Home

backup

Backups of the owner's CodeBot: a consistent copy taken while the service is stopped, and a restore checked in a separate folder.

Make a backupMakes a backup: stops the service, copies its data, settings and unit file, then starts it again. No script exists yet.
›
RestoreRestores a backup into a new folder and checks it there; never restores over the running install.
›
Check checksumsChecks a backup's files against its recorded checksums.
›
Backup folderOpens the folder that holds every backup, one dated folder each.
›
‹ Home

account

The Supabase account service: the sign-in database, its functions and its migrations.

DashboardOpens the account service in the Supabase dashboard, under the mobile-coder login.
›
Deploy host-accessDeploys the host-access function to the cloud; redeploy it whenever a contract it parses changes.
›
Deploy gmail-relayDeploys the gmail-relay function to the cloud.
›
Token fileOpens the CLI token file; the CLI never prints its value.
›
Functions folderOpens the two functions, gmail-relay and host-access.
›
Migrations folderOpens the six database migrations, in order.
›
Reset onboardingOpens the steps to reset one person's onboarding; both databases are changed by hand.
›
‹ Home

gmail

Gmail for Bots: the guide, the generated reference, the review, and the relay function that carries Google sign-in.

GuideOpens the Gmail guide for supervisors.
›
ReferenceOpens the generated Gmail reference.
›
Regenerate referenceRegenerates the Gmail reference from the code.
›
ReviewRuns the Gmail review script (ops/review/gmail-review.mjs).
›
Relay functionOpens the Google sign-in relay function's source.
›
‹ Home

dev

Development: installing, running, checking and building the code, the design playground, and the scripts that keep files in step.

InstallInstalls the exact dependencies from the lockfile.
›
Run in watch modeStarts the service in watch mode, restarting on each code change; stop codebot.service first if they share a port.
›
Run in production modeStarts the service in production mode, in the foreground.
›
TypecheckChecks the TypeScript types without building.
›
TestRuns the Gmail automation tests against a fake Google server.
›
CheckRuns the typecheck and the tests together.
›
BuildTypechecks, then builds the web app into a new release folder and switches to it.
›
Build for QATypechecks, then builds for the disposable QA instance on port 3506.
›
Design playgroundStarts the design playground's Gmail page in the browser.
›
Sync agents fileRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
›
Schedules reviewRuns the schedules review script (ops/review/schedules-review.mjs).
›
Account setupRuns the account setup script (ops/setup-account.ts).
›
Development settingsOpens the development settings, copied from .env.example; never prints its values.
›
‹ Home

docs

The project's documents: the runbook, the architecture, the rules for agents, the design records, and the plans.

RunbookOpens the runbook: install, back up, restore, change the address and reset onboarding.
›
ArchitectureOpens the technical boundaries and how CodeBot is built.
›
OverviewOpens the project overview and how to run the service.
›
Rules for agentsOpens the fundamentals every task assumes, and the design rules.
›
PlansOpens the folder of plans, one file each.
›
Design methodOpens the method used for designing screens.
›
Design rulingsOpens the owner's design rulings and what they rejected.
›
ObjectivesOpens the objectives, one file each.
›
Module intentsOpens each module's intent, with its constraints and tests.
›
Behaviour specsOpens the Given-When-Then feature specs.
›
Verification recordsOpens the recorded verification evidence.
›
Housekeeping skillOpens the housekeeping skill for the Bots.
›
Implementation statusOpens what was built and where the first beta stopped.
›
Deferred workOpens the open work and the safe restart state.
›
Raw answer
This is a plan only. I built nothing and ran no commands. I worked from the file dump alone, so I could not read `opencode help` or `workstation help` (the bar for this CLI), run `whence` for name clashes, or check the files the README names but the dump doesn't show. The map is below, with questions for you at the end.

The top level has eight nouns, each a separate job with its own rules. `host`, `guest` and `family` are split because they need different sudo rules. Every "what" starts with the verb of its command, and each group row's "what" says what its bare noun prints.

```json
{"screens": [
{"path": [], "sentence": "The CodeBot project's command line: this machine's own CodeBot and the other CodeBots on it, backups, the account service, Gmail, development, and the documents.", "rows": [
{"name": "Host", "form": "codebot host", "what": "Prints the host screen: this machine's own CodeBot, its service, its address and its data."},
{"name": "Guest", "form": "codebot guest", "what": "Prints the guest screen: a second CodeBot on this machine for another person, run as its own Linux user."},
{"name": "Family", "form": "codebot family", "what": "Prints the family screen: the home-Wi-Fi front door and one CodeBot per family member."},
{"name": "Backup", "form": "codebot backup", "what": "Prints the backup screen: making a backup of the stopped data and restoring one into a separate folder."},
{"name": "Account", "form": "codebot account", "what": "Prints the account screen: the Supabase account service that handles sign-in and pairs people with their computers."},
{"name": "Gmail", "form": "codebot gmail", "what": "Prints the Gmail screen: the Gmail guide, its generated reference, and the Gmail review."},
{"name": "Development", "form": "codebot dev", "what": "Prints the development screen: running, checking and building the code, and the design playground."},
{"name": "Documents", "form": "codebot docs", "what": "Prints the documents screen: the runbook, the architecture, the rules for agents, and the plans."}
]},
{"path": ["host"], "sentence": "This machine's own CodeBot: its service on port 3505, its private address, its data, and how to deploy it.", "rows": [
{"name": "Service", "form": "codebot host service", "what": "Prints the service screen: starting, stopping, restarting and reading the owner's service."},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Deploys the current code: builds it, commits and pushes it, restarts codebot.service and checks that it answers. Refuses while a Bot is working or the server code has someone else's uncommitted edits."},
{"name": "Private address", "form": "https://liel.tail18e69e.ts.net", "what": "Opens the owner's CodeBot in the browser, over Tailscale."},
{"name": "Address map", "form": "tailscale serve status --json", "what": "Shows how the private address maps to port 3505 on this machine."},
{"name": "Host diagnostics", "form": "http://127.0.0.1:3505/api/diagnostics/host", "what": "Opens the host counters in the browser; sign in to the app first."},
{"name": "Data folder", "form": "~/.local/share/codebot", "what": "Opens the data folder: the database, the owner sessions and the entrance key."},
{"name": "Private settings", "form": "~/.config/codebot/service.env", "what": "Opens the private settings file; the CLI never prints its values."},
{"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Opens the file that holds the entrance key; the CLI never prints its contents."},
{"name": "Connect a phone", "form": "ops/OPERATIONS.md, section Connect a device", "what": "Opens the steps to connect a phone: Tailscale, the private address, and Add to Home Screen."},
{"name": "Change address", "form": "ops/OPERATIONS.md, section Change this machine's address", "what": "Opens the checklist of the nine places to update when this machine's address changes."}
]},
{"path": ["host", "service"], "sentence": "The owner's codebot.service and the optional terminal broker, as this user's systemd sees them.", "rows": [
{"name": "Status", "form": "systemctl --user status codebot.service --no-pager", "what": "Shows whether the service is running, and since when."},
{"name": "Start", "form": "systemctl --user start codebot.service", "what": "Starts the service."},
{"name": "Stop", "form": "systemctl --user stop codebot.service", "what": "Stops the service; this interrupts Bot turns and finalizes recordings."},
{"name": "Restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service; run it only after active turns and recordings finish."},
{"name": "Logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the service."},
{"name": "Port owner", "form": "ss -ltnp 'sport = :3505'", "what": "Lists which process holds port 3505."},
{"name": "Answer check", "form": "curl --fail --silent --show-error http://127.0.0.1:3505/api/session", "what": "Checks that the service answers on port 3505."},
{"name": "Terminal broker", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Shows whether the optional terminal broker is running."},
{"name": "Stay running", "form": "loginctl show-user <your user> -p Linger", "what": "Shows whether the service stays up without a desktop login."}
]},
{"path": ["guest"], "sentence": "The guest CodeBot: a second CodeBot on this machine, run by the Linux user codebot-guest, on port 10000.", "rows": [
{"name": "Status", "form": "systemctl status codebot-guest --no-pager", "what": "Shows whether the guest CodeBot is running."},
{"name": "Logs", "form": "journalctl -u codebot-guest -n 80 --no-pager", "what": "Prints the last 80 log lines of the guest CodeBot."},
{"name": "Guest address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's CodeBot in the browser."},
{"name": "Disk use", "form": "sudo du -sh /home/codebot-guest", "what": "Shows how much disk the guest CodeBot uses."},
{"name": "Projects folder", "form": "/home/codebot-guest/projects", "what": "Opens the guest's project folders."},
{"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Creates a one-use Google sign-in link, valid for ten minutes."},
{"name": "Update", "form": "ops/guest-update.sh", "what": "Builds the current version, replaces the guest program and restarts it; needs no password."},
{"name": "Set up once", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, its service, the sudo rules and Tailscale port 10000; run once."},
{"name": "Remove or reset", "form": "ops/OPERATIONS.md, sections Host a guest on this machine and Restart onboarding with a fresh CodeBot", "what": "Opens the steps to remove the guest or restart its onboarding; both delete data."}
]},
{"path": ["family"], "sentence": "The family CodeBots: the home-Wi-Fi front door and one CodeBot per family member, each as its own Linux user.", "rows": [
{"name": "Status", "form": "codebot-family status", "what": "Shows whether the front door and each family CodeBot are running, and whether Gmail can connect."},
{"name": "Logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*' -n 80 --no-pager", "what": "Prints the last 80 log lines of the front door and the family CodeBots."},
{"name": "Family sign-in address", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in page, from home Wi-Fi or over the owner's tailnet."},
{"name": "Add member", "form": "sudo codebot-family add N", "what": "Creates family CodeBot N with its own user, port 3540 plus N, and its address."},
{"name": "Remove member", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number; its Google account stays linked to it for good."},
{"name": "Stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
{"name": "Start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot again."},
{"name": "Update", "form": "ops/family-update.sh", "what": "Builds and replaces the family program and restarts all family CodeBots; needs no password."},
{"name": "Set up once", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, the helper, the services, the sudo rules and nginx; run once."},
{"name": "Family settings", "form": "/etc/codebot-family.conf", "what": "Opens the family settings file; reading it needs sudo."}
]},
{"path": ["backup"], "sentence": "Backups of the owner's CodeBot: a consistent copy taken while the service is stopped, and a restore checked in a separate folder.", "rows": [
{"name": "Make a backup", "form": "ops/OPERATIONS.md, section Back up a consistent installation", "what": "Makes a backup: stops the service, copies its data, settings and unit file, then starts it again. No script exists yet."},
{"name": "Restore", "form": "ops/OPERATIONS.md, section Restore into a separate directory first", "what": "Restores a backup into a new folder and checks it there; never restores over the running install."},
{"name": "Check checksums", "form": "sha256sum -c SHA256SUMS (run inside the backup folder)", "what": "Checks a backup's files against its recorded checksums."},
{"name": "Backup folder", "form": "~/.local/share/codebot-backups", "what": "Opens the folder that holds every backup, one dated folder each."}
]},
{"path": ["account"], "sentence": "The Supabase account service: the sign-in database, its functions and its migrations.", "rows": [
{"name": "Dashboard", "form": "https://supabase.com/dashboard/project/wbgrjvqbupgdclaztuou", "what": "Opens the account service in the Supabase dashboard, under the mobile-coder login."},
{"name": "Deploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou (token from ~/.config/supabase-codebot-token)", "what": "Deploys the host-access function to the cloud; redeploy it whenever a contract it parses changes."},
{"name": "Deploy gmail-relay", "form": "npx supabase functions deploy gmail-relay --project-ref wbgrjvqbupgdclaztuou (same token)", "what": "Deploys the gmail-relay function to the cloud."},
{"name": "Token file", "form": "~/.config/supabase-codebot-token", "what": "Opens the CLI token file; the CLI never prints its value."},
{"name": "Functions folder", "form": "supabase/functions/", "what": "Opens the two functions, gmail-relay and host-access."},
{"name": "Migrations folder", "form": "supabase/migrations/", "what": "Opens the six database migrations, in order."},
{"name": "Reset onboarding", "form": "ops/OPERATIONS.md, section Reset someone's onboarding", "what": "Opens the steps to reset one person's onboarding; both databases are changed by hand."}
]},
{"path": ["gmail"], "sentence": "Gmail for Bots: the guide, the generated reference, the review, and the relay function that carries Google sign-in.", "rows": [
{"name": "Guide", "form": "docs/automation/gmail.md", "what": "Opens the Gmail guide for supervisors."},
{"name": "Reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference."},
{"name": "Regenerate reference", "form": "npm run docs:gmail", "what": "Regenerates the Gmail reference from the code."},
{"name": "Review", "form": "npm run review:gmail", "what": "Runs the Gmail review script (ops/review/gmail-review.mjs)."},
{"name": "Relay function", "form": "supabase/functions/gmail-relay/index.ts", "what": "Opens the Google sign-in relay function's source."}
]},
{"path": ["dev"], "sentence": "Development: installing, running, checking and building the code, the design playground, and the scripts that keep files in step.", "rows": [
{"name": "Install", "form": "npm ci", "what": "Installs the exact dependencies from the lockfile."},
{"name": "Run in watch mode", "form": "npm run dev", "what": "Starts the service in watch mode, restarting on each code change; stop codebot.service first if they share a port."},
{"name": "Run in production mode", "form": "npm run start", "what": "Starts the service in production mode, in the foreground."},
{"name": "Typecheck", "form": "npm run typecheck", "what": "Checks the TypeScript types without building."},
{"name": "Test", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
{"name": "Check", "form": "npm run check", "what": "Runs the typecheck and the tests together."},
{"name": "Build", "form": "npm run build", "what": "Typechecks, then builds the web app into a new release folder and switches to it."},
{"name": "Build for QA", "form": "npm run build:integration", "what": "Typechecks, then builds for the disposable QA instance on port 3506."},
{"name": "Design playground", "form": "npm run playground", "what": "Starts the design playground's Gmail page in the browser."},
{"name": "Sync agents file", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md."},
{"name": "Schedules review", "form": "npm run review:schedules", "what": "Runs the schedules review script (ops/review/schedules-review.mjs)."},
{"name": "Account setup", "form": "npm run setup-account", "what": "Runs the account setup script (ops/setup-account.ts)."},
{"name": "Development settings", "form": ".env", "what": "Opens the development settings, copied from .env.example; never prints its values."}
]},
{"path": ["docs"], "sentence": "The project's documents: the runbook, the architecture, the rules for agents, the design records, and the plans.", "rows": [
{"name": "Runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook: install, back up, restore, change the address and reset onboarding."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens the technical boundaries and how CodeBot is built."},
{"name": "Overview", "form": "README.md", "what": "Opens the project overview and how to run the service."},
{"name": "Rules for agents", "form": "CLAUDE.md", "what": "Opens the fundamentals every task assumes, and the design rules."},
{"name": "Plans", "form": "docs/plans/", "what": "Opens the folder of plans, one file each."},
{"name": "Design method", "form": "docs/design-method.md", "what": "Opens the method used for designing screens."},
{"name": "Design rulings", "form": "docs/design-taste.md", "what": "Opens the owner's design rulings and what they rejected."},
{"name": "Objectives", "form": "docs/objectives/", "what": "Opens the objectives, one file each."},
{"name": "Module intents", "form": ".idd/modules/", "what": "Opens each module's intent, with its constraints and tests."},
{"name": "Behaviour specs", "form": ".bdd/features/", "what": "Opens the Given-When-Then feature specs."},
{"name": "Verification records", "form": "docs/verification/", "what": "Opens the recorded verification evidence."},
{"name": "Housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the housekeeping skill for the Bots."},
{"name": "Implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what was built and where the first beta stopped."},
{"name": "Deferred work", "form": "DEFERRED-WORK.md", "what": "Opens the open work and the safe restart state."}
]}
],
"questions": [
"Eight top-level nouns (host, guest, family, backup, account, gmail, dev, docs). Keep all eight, or fold guest and family into host? Recommend keeping eight: each is a different job with different rules, and guest and family setup need sudo.",
"Facade name and alias. Recommend `codebot`, with `cb` as the alias only if the clash check at build time finds it free. I could not run that check from here.",
"Port 3505 clash: `dev` (npm run dev) and the owner's service may both want that port. Recommend that `codebot dev run` refuses with exit 1 and names codebot.service while it is active, and never stops it on its own.",
"Force-kill (SIGKILL) of the service: include it as a command, or keep it in the runbook only? Recommend the runbook only. It can lose uncommitted recordings, so it should not be one keystroke.",
"Secret files: the entrance key, service.env, the Supabase token and .env appear as rows that open them. Recommend that the CLI opens the path and never prints contents, and that the editor's display is left to you.",
"Restart and stop: should `host service restart` and `stop` refuse while a Bot is working, as ops/deploy.sh does? Recommend yes, by calling the same guard rather than copying its logic.",
"Destructive and outward actions: family remove, guest setup, the Supabase deploys (which publish to the cloud) and deploy (which pushes to the remote). Should the CLI run them, or only print the command for you to run? Recommend print-first. Remove gets a typed confirmation. Cloud deploys and push stay print-only.",
"Backup and restore have no script yet; the runbook has bash blocks. Recommend a worker task to write ops/backup.sh and ops/restore.sh from those blocks, after which the rows point at them. Do you want that task?",
"Unverified commands: `codebot-family status` and the sudo needs of the family and guest rows follow the runbook, but I did not check the helper's source. The gmail-relay deploy command is not written in the runbook; I used the host-access pattern. Confirm both before the build.",
"Scripts I did not map: ops/review/redirect-google.mjs, seed-gmail.ts, schedule-drill.mjs and terminal-tabs-stack.sh, whose purposes are not in the dump. Recommend mapping only the npm scripts now and reading these before adding rows.",
"Experimental apps V2, V3 and V4 (ports 3512 to 3514) live in their own repos and the README says they are not part of CodeBot. Leave them out of this map? Recommend yes.",
"Files named in the README but not visible in the dump's file list: DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md, PRODUCT-SPEC.md and MASTER-PLAN.md. I kept rows for the first two in docs. Confirm they exist before the build, and say whether PRODUCT-SPEC and MASTER-PLAN should get rows too."
]}
```

screen-decomposition, first draft · run 2 exit=0 seconds=151 · prompt

P1 Recall: 0.474P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.991P5 Short top: 6P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.251
As terminal help
The top of CodeBot: everything you can reach, grouped by what you are trying to do.
Botsscreen: botsOpens your Bots: pick one to chat with, or create one.
Automationscreen: automationOpens what Bots do on their own: Gmail and schedules.
Devicesscreen: devicesOpens the phones and browsers that reach this host, and which of them get notifications.
Hostscreen: hostOpens this computer's CodeBot: running state, updates, backups, account, and terminal.
Family and guestscreen: familyOpens the people who share this computer: family CodeBots and the guest.
Docsscreen: docsOpens the project's documents, runbooks and records.
bots
Your Bots on this host, each with its own chat.
Create new botBot form (apps/web/src/workspace/BotForm.tsx)Opens the form that creates a Bot with its provider, folder and model.
<Bot name>screen: bots <bot>Opens that Bot's chat: its messages, queue and what it is doing.
bots › <bot>
The chat with this Bot: its messages, its queue, and what it is working on.
QueuePOST /bots/:id/queue/take and /queue/send-now (queue bar above the composer)Takes queued messages back to the composer, or sends them to the Bot now.
AttachmentsAttachmentPicker.tsx, useAttachments.tsAttaches files to the next message this Bot receives.
Pinned filesPinnedFiles.tsx, PinnedResources.tsxOpens the files pinned to this Bot's chat.
ResourcesResourceViewer.tsx, FilePreview.tsxOpens a file or resource this Bot produced, in a safe viewer.
RecordingsRecordingPlayer.tsxPlays a recording of this Bot's browser work.
VisionStreamable vision, owned by this BotOpens the live view of the browser this Bot uses.
ScreenshotsStreamable screenshot_gallery, owned by this BotOpens the screenshots this Bot captured, in capture order.
ContractStreamable feature_contract (ContractCatalog.tsx, ContractHistory.tsx)Opens this Bot's FeatureContract: its revisions, files and history.
GitStreamable git_quick_info, owned by this BotShows this Bot's repository status and its quick git actions.
WidgetsWidgetBrowser.tsx, WidgetArrangement.tsxAdds, removes and arranges the widgets on this screen.
Settingsscreen: bots <bot> settings (cog button)Opens this Bot's settings: model, folder, notifications, skills and avatar.
bots › <bot> › settings
The settings of this Bot.
ModelBot model field (empty uses the automatic policy, ops/OPERATIONS.md)Chooses the model; empty uses the automatic policy for each message.
FolderPrimary Folder, inside CODEBOT_PROJECT_ROOTSSets the folder this Bot works in; it must lie inside an allowed project root.
NotificationsNotifications switchTurns on alerts for this Bot's replies, approvals and failures.
Enable this deviceEnable this device buttonAsks the browser for notification permission and subscribes this device.
Send testSend test buttonSends a test notification to the selected device, whatever this Bot's switch says.
AvatarAvatarPicker.tsx, AvatarStudio.tsxChanges this Bot's avatar.
Skillsattached skills (ARCHITECTURE.md, Bot domain)Attaches the skills this Bot can use.
automation
What Bots do on their own: Gmail and scheduled wake-ups.
Gmailscreen: automation gmailOpens Gmail for Bots: the connected account, approvals and activity.
Schedulesscreen: schedules (objective in docs/objectives/schedules.md)Lists the schedules that wake Bots, and when each next runs.
automation › gmail
Gmail for Bots: the connected Google account, what Bots asked to do in it, and what they did.
AccessGmailAccess.tsx (sign-in returns through gmail-relay)Connects or disconnects the Google account Bots use.
ApprovalsGmailApprovals.tsxApproves or refuses what a Bot asked to do in Gmail.
ActivityGmailActivity.tsxLists what Bots did in Gmail.
DailyGmailDaily.tsxShows the Gmail picture for the day.
GlanceGmailGlance.tsxShows a short Gmail status at a glance.
CardsGmailCards.tsxShows Gmail items as cards.
devices
The phones, tablets and browsers that reach this host, and which of them get notifications.
Connect a devicehttps://liel.tail18e69e.ts.net/ over TailscaleOpens CodeBot from a new device, through its private Tailscale address.
Entrance key~/.local/share/codebot/owner-keyShows the entrance key a new device signs in with; keep it private.
Install appbrowser's Install app / Add to Home ScreenInstalls CodeBot on a phone's Home Screen, at the address it was installed from.
Other devicesOther devices (Bot settings)Lists the devices with notifications and removes old ones; up to 16 are kept.
Reconnect this deviceReconnect this device buttonRenews an expired or rejected notification subscription on this device.
Check a deviceSend test (Bot settings)Checks that a chosen device shows alerts; a queued test is not proof.
host
This computer's CodeBot: whether it runs, its updates and data, its account, and its terminal.
Runningscreen: host runningOpens whether CodeBot runs here, its logs and its emergency controls.
Updatescreen: host updateOpens building, checking and restarting CodeBot so a change goes live.
Datascreen: host dataOpens the backups of CodeBot's data and how to restore them.
Accountscreen: host accountOpens sign-in, onboarding and the account service.
Terminalscreen: host terminalOpens the terminal on this computer, through its per-user broker.
host › running
Whether CodeBot runs on this computer, and what it reports about itself.
Statussystemctl --user status codebot.service --no-pagerPrints whether CodeBot runs and when it last started.
Logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints CodeBot's last 80 log lines.
Listenerss -ltnp 'sport = :3505'Prints which process holds CodeBot's port 3505.
Diagnostics/api/diagnostics/host, /scheduler, /vision (signed-in browser)Shows counters and lifecycle state for the host, scheduler and vision, without credentials.
Recovery holdCODEBOT_RECOVERY_HOLD=1 in service.envPauses automatic sends and schedules; explicit Send and Retry still work.
Emergency stopsystemctl --user stop --no-block codebot.service, then systemctl --user kill --signal=SIGKILLStops CodeBot at once when a normal stop cannot finish; may lose uncommitted media.
Settings file~/.config/codebot/service.env (mode 0600)Edits CodeBot's private settings; restart CodeBot to apply them.
host › update
Building, checking and restarting CodeBot so a change goes live.
Deploysh ops/deploy.shBuilds, pushes and restarts CodeBot, waiting while a Bot is working and refusing uncommitted server edits.
Buildnpm run buildBuilds a new web release; a failed build leaves the served release intact.
Checknpm run check (also .github/workflows/check.yml)Type-checks and runs the service tests; it proves the code compiles, not Bot behaviour.
Reviewnpm run review:gmail; npm run review:schedulesRuns the Gmail and schedule reviews against the real service and browser.
Playgroundnpm run playgroundOpens the design variants side by side in the browser.
Installops/OPERATIONS.md, Install or update the hostInstalls dependencies, the build and the service unit on a new machine, once.
Sync agent rulesnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md instead.
Integration QAcodebot-integration.service, port 3506; npm run build:integrationRuns a disposable CodeBot on port 3506 to try a change first.
host › data
Backups of CodeBot's data, source and settings, and how to restore them.
Back upops/OPERATIONS.md, Back up a consistent installationStops CodeBot, copies its data, source and settings into a backup folder, then starts it again.
Restoreops/OPERATIONS.md, Restore into a separate directory firstRestores a backup into a separate folder and checks it before anything is promoted.
Roll backops/OPERATIONS.md, Emergency stop and rollbackPoints CodeBot back at the retained data copy after a failed promotion.
host › account
Signing in to CodeBot, the account service it uses, and the first-use tour.
Sign-in entryCODEBOT_ACCOUNT_ENTRY_URL (https://liel.tail18e69e.ts.net/onboarding)Opens the common sign-in entry, which sends each account to its own host.
First-use tour/onboarding (account service), apps/web/src/onboarding/Walks a new account through setup and creates its first Bot.
Replay first-use tourops/OPERATIONS.md, Replay only the first-use tourShows the first-use tour again from the start, for a host with no Bots.
Restart onboardingops/OPERATIONS.md, Restart onboarding with a fresh CodeBotWipes a host's Bots and conversations, keeping the account and its folders.
Full resetops/OPERATIONS.md, Full resetDeletes an account and everything it holds, so the person starts as new.
Change addressops/OPERATIONS.md, Change this machine's addressLists the places that hold this machine's address, to update when it changes.
Account serviceSupabase project wbgrjvqbupgdclaztuouOpens the Supabase project that holds accounts and host bindings.
Redeploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouRedeploys the host-access function after a contract it parses changes.
Keep-alive.github/workflows/supabase-keepalive.ymlKeeps the account service awake on a schedule.
host › terminal
The terminal on this computer and the broker that keeps it running.
TerminalTerminalPage.tsx, TerminalTab.tsxOpens a terminal tab on this computer.
Brokercodebot-terminal-broker.service (user unit)Runs the per-user broker that holds the terminal's tmux session across web restarts.
Enable brokersystemctl --user enable --now codebot-terminal-broker.serviceTurns the terminal on; without it no shell opens.
Broker statussystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the broker runs and answers.
family
The people who share this computer: family CodeBots, and the guest.
Family CodeBotsscreen: family codebotsOpens the family CodeBots on this computer, one per Google account.
Guestscreen: family guestOpens the guest's CodeBot: its service, invite and updates.
family › codebots
Family CodeBots on this computer, and the helper that adds, removes and restarts them.
Statuscodebot-family statusPrints each family CodeBot and whether its Gmail can be connected.
Addsudo codebot-family add N (run by the front door for a new Google account)Creates a family CodeBot at the next free number.
Removesudo codebot-family remove NDeletes a family CodeBot and frees its number; its Google account stays linked.
Stop allsudo codebot-family stop-allStops every family CodeBot.
Start allsudo codebot-family start-allStarts every family CodeBot again.
Updateops/family-update.shBuilds the family program and restarts every family CodeBot.
Set upsudo ops/family-install.shSets up the front door, helper, services, sudo rules and nginx, once.
Logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the front door's and the family CodeBots' logs.
family › guest
The guest's CodeBot: whether it runs, its invite, and its updates.
Statussystemctl status codebot-guestPrints whether the guest's CodeBot runs.
Logsjournalctl -u codebot-guestPrints the guest's log.
Usagesudo du -sh /home/codebot-guestPrints how much space the guest's data takes.
Invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google link that is valid for ten minutes.
Updateops/guest-update.shBuilds the guest's program, replaces it and restarts the guest's CodeBot.
Set upsudo ops/guest-install.shCreates the guest's user, service, settings, sudo rules and Tailscale port, once.
Removeops/OPERATIONS.md, To remove itDeletes the guest's service, user, data and program.
docs
The project's documents, from what CodeBot is to how to run and change it.
READMEREADME.mdExplains what CodeBot is, how to run it and what its checks prove.
Product specPRODUCT-SPEC.md (not in the dump)Sets out how CodeBot must behave, as its behaviour contract.
ArchitectureARCHITECTURE.mdExplains how CodeBot is built and where its boundaries lie.
Operations runbookops/OPERATIONS.mdExplains how to run, recover and change CodeBot.
Agent rules and skillsCLAUDE.md; skills/codebot-housekeeping/SKILL.mdSets the rules and skills every agent follows on this project.
Design method and tastedocs/design-method.md, docs/design-taste.mdExplains how screens are designed and records the owner's rulings.
Gmail for Botsdocs/automation/gmail.md, docs/automation/gmail-reference.mdExplains Gmail for Bots, for the supervisor and as a generated reference.
Objectivesdocs/objectives/README.mdLists the objectives: chat current session, Gmail widget, schedules and terminal tabs.
What's newapps/web/src/whatsNew.tsShows what changed in the latest update, once.
Recordsscreen: docs recordsOpens the intents, scenarios, plans and verification records.
docs › records
Intents, scenarios, plans and verification records, kept per module.
Intents.idd/modules/<module>/INTENT.mdDescribes a module's intent: its constraints and tests.
Scenarios.bdd/features/<feature>/*.feature, .bdd/steps/Describes a feature's behaviour as Given, When, Then scenarios.
QA findings and resolutions.bdd/qa/findings/, .bdd/qa/resolutions/Records what QA found and how each finding was resolved.
Plansdocs/plans/, .plans/, docs/superpowers/plans/Holds plan documents for earlier and current work.
Verificationdocs/verification/, docs/onboarding-recorded-proof-2026-09-14.mdRecords the evidence that a change was tested.
Tasksdocs/tasks/Records tasks and their audits.
Design critiques.impeccable/critique/Records a design critique of a screen.
Questions
  • Does cli/codebot.py exist? The README mentions it, but it is not in the file list. Recommendation: if not, build the operator rows as a codebot command with cli-engineer.
  • Keep the six top groups, with Host as the name for this computer? Recommendation: yes; Host matches the app and diagnostics.
  • Are widgets per Bot or one dashboard? Recommendation: one dashboard screen, once known.
  • Should the owner browse earlier chats in the UI, or only through the chat divider? Recommendation: add a Chats row on the Bot screen if they should browse.
  • Are Gmail Daily, Cards and Glance screens or widgets, and does a schedules screen exist? Recommendation: confirm before building those rows.
  • Leave the V2 to V4 preview apps (other repos, ports 3512 to 3514) off this map? Recommendation: yes.
As phone screens

Home

The top of CodeBot: everything you can reach, grouped by what you are trying to do.

BotsOpens your Bots: pick one to chat with, or create one.
›
AutomationOpens what Bots do on their own: Gmail and schedules.
›
DevicesOpens the phones and browsers that reach this host, and which of them get notifications.
›
HostOpens this computer's CodeBot: running state, updates, backups, account, and terminal.
›
Family and guestOpens the people who share this computer: family CodeBots and the guest.
›
DocsOpens the project's documents, runbooks and records.
›
‹ Home

bots

Your Bots on this host, each with its own chat.

Create new botOpens the form that creates a Bot with its provider, folder and model.
›
<Bot name>Opens that Bot's chat: its messages, queue and what it is doing.
›
‹ bots

<bot>

The chat with this Bot: its messages, its queue, and what it is working on.

QueueTakes queued messages back to the composer, or sends them to the Bot now.
›
AttachmentsAttaches files to the next message this Bot receives.
›
Pinned filesOpens the files pinned to this Bot's chat.
›
ResourcesOpens a file or resource this Bot produced, in a safe viewer.
›
RecordingsPlays a recording of this Bot's browser work.
›
VisionOpens the live view of the browser this Bot uses.
›
ScreenshotsOpens the screenshots this Bot captured, in capture order.
›
ContractOpens this Bot's FeatureContract: its revisions, files and history.
›
GitShows this Bot's repository status and its quick git actions.
›
WidgetsAdds, removes and arranges the widgets on this screen.
›
SettingsOpens this Bot's settings: model, folder, notifications, skills and avatar.
›
‹ <bot>

settings

The settings of this Bot.

ModelChooses the model; empty uses the automatic policy for each message.
›
FolderSets the folder this Bot works in; it must lie inside an allowed project root.
›
NotificationsTurns on alerts for this Bot's replies, approvals and failures.
›
Enable this deviceAsks the browser for notification permission and subscribes this device.
›
Send testSends a test notification to the selected device, whatever this Bot's switch says.
›
AvatarChanges this Bot's avatar.
›
SkillsAttaches the skills this Bot can use.
›
‹ Home

automation

What Bots do on their own: Gmail and scheduled wake-ups.

GmailOpens Gmail for Bots: the connected account, approvals and activity.
›
SchedulesLists the schedules that wake Bots, and when each next runs.
›
‹ automation

gmail

Gmail for Bots: the connected Google account, what Bots asked to do in it, and what they did.

AccessConnects or disconnects the Google account Bots use.
›
ApprovalsApproves or refuses what a Bot asked to do in Gmail.
›
ActivityLists what Bots did in Gmail.
›
DailyShows the Gmail picture for the day.
›
GlanceShows a short Gmail status at a glance.
›
CardsShows Gmail items as cards.
›
‹ Home

devices

The phones, tablets and browsers that reach this host, and which of them get notifications.

Connect a deviceOpens CodeBot from a new device, through its private Tailscale address.
›
Entrance keyShows the entrance key a new device signs in with; keep it private.
›
Install appInstalls CodeBot on a phone's Home Screen, at the address it was installed from.
›
Other devicesLists the devices with notifications and removes old ones; up to 16 are kept.
›
Reconnect this deviceRenews an expired or rejected notification subscription on this device.
›
Check a deviceChecks that a chosen device shows alerts; a queued test is not proof.
›
‹ Home

host

This computer's CodeBot: whether it runs, its updates and data, its account, and its terminal.

RunningOpens whether CodeBot runs here, its logs and its emergency controls.
›
UpdateOpens building, checking and restarting CodeBot so a change goes live.
›
DataOpens the backups of CodeBot's data and how to restore them.
›
AccountOpens sign-in, onboarding and the account service.
›
TerminalOpens the terminal on this computer, through its per-user broker.
›
‹ host

running

Whether CodeBot runs on this computer, and what it reports about itself.

StatusPrints whether CodeBot runs and when it last started.
›
LogsPrints CodeBot's last 80 log lines.
›
ListenerPrints which process holds CodeBot's port 3505.
›
DiagnosticsShows counters and lifecycle state for the host, scheduler and vision, without credentials.
›
Recovery holdPauses automatic sends and schedules; explicit Send and Retry still work.
›
Emergency stopStops CodeBot at once when a normal stop cannot finish; may lose uncommitted media.
›
Settings fileEdits CodeBot's private settings; restart CodeBot to apply them.
›
‹ host

update

Building, checking and restarting CodeBot so a change goes live.

DeployBuilds, pushes and restarts CodeBot, waiting while a Bot is working and refusing uncommitted server edits.
›
BuildBuilds a new web release; a failed build leaves the served release intact.
›
CheckType-checks and runs the service tests; it proves the code compiles, not Bot behaviour.
›
ReviewRuns the Gmail and schedule reviews against the real service and browser.
›
PlaygroundOpens the design variants side by side in the browser.
›
InstallInstalls dependencies, the build and the service unit on a new machine, once.
›
Sync agent rulesRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md instead.
›
Integration QARuns a disposable CodeBot on port 3506 to try a change first.
›
‹ host

data

Backups of CodeBot's data, source and settings, and how to restore them.

Back upStops CodeBot, copies its data, source and settings into a backup folder, then starts it again.
›
RestoreRestores a backup into a separate folder and checks it before anything is promoted.
›
Roll backPoints CodeBot back at the retained data copy after a failed promotion.
›
‹ host

account

Signing in to CodeBot, the account service it uses, and the first-use tour.

Sign-in entryOpens the common sign-in entry, which sends each account to its own host.
›
First-use tourWalks a new account through setup and creates its first Bot.
›
Replay first-use tourShows the first-use tour again from the start, for a host with no Bots.
›
Restart onboardingWipes a host's Bots and conversations, keeping the account and its folders.
›
Full resetDeletes an account and everything it holds, so the person starts as new.
›
Change addressLists the places that hold this machine's address, to update when it changes.
›
Account serviceOpens the Supabase project that holds accounts and host bindings.
›
Redeploy host-accessRedeploys the host-access function after a contract it parses changes.
›
Keep-aliveKeeps the account service awake on a schedule.
›
‹ host

terminal

The terminal on this computer and the broker that keeps it running.

TerminalOpens a terminal tab on this computer.
›
BrokerRuns the per-user broker that holds the terminal's tmux session across web restarts.
›
Enable brokerTurns the terminal on; without it no shell opens.
›
Broker statusPrints whether the broker runs and answers.
›
‹ Home

family

The people who share this computer: family CodeBots, and the guest.

Family CodeBotsOpens the family CodeBots on this computer, one per Google account.
›
GuestOpens the guest's CodeBot: its service, invite and updates.
›
‹ family

codebots

Family CodeBots on this computer, and the helper that adds, removes and restarts them.

StatusPrints each family CodeBot and whether its Gmail can be connected.
›
AddCreates a family CodeBot at the next free number.
›
RemoveDeletes a family CodeBot and frees its number; its Google account stays linked.
›
Stop allStops every family CodeBot.
›
Start allStarts every family CodeBot again.
›
UpdateBuilds the family program and restarts every family CodeBot.
›
Set upSets up the front door, helper, services, sudo rules and nginx, once.
›
LogsPrints the front door's and the family CodeBots' logs.
›
‹ family

guest

The guest's CodeBot: whether it runs, its invite, and its updates.

StatusPrints whether the guest's CodeBot runs.
›
LogsPrints the guest's log.
›
UsagePrints how much space the guest's data takes.
›
InvitePrints a one-use Google link that is valid for ten minutes.
›
UpdateBuilds the guest's program, replaces it and restarts the guest's CodeBot.
›
Set upCreates the guest's user, service, settings, sudo rules and Tailscale port, once.
›
RemoveDeletes the guest's service, user, data and program.
›
‹ Home

docs

The project's documents, from what CodeBot is to how to run and change it.

READMEExplains what CodeBot is, how to run it and what its checks prove.
›
Product specSets out how CodeBot must behave, as its behaviour contract.
›
ArchitectureExplains how CodeBot is built and where its boundaries lie.
›
Operations runbookExplains how to run, recover and change CodeBot.
›
Agent rules and skillsSets the rules and skills every agent follows on this project.
›
Design method and tasteExplains how screens are designed and records the owner's rulings.
›
Gmail for BotsExplains Gmail for Bots, for the supervisor and as a generated reference.
›
ObjectivesLists the objectives: chat current session, Gmail widget, schedules and terminal tabs.
›
What's newShows what changed in the latest update, once.
›
RecordsOpens the intents, scenarios, plans and verification records.
›
‹ docs

records

Intents, scenarios, plans and verification records, kept per module.

IntentsDescribes a module's intent: its constraints and tests.
›
ScenariosDescribes a feature's behaviour as Given, When, Then scenarios.
›
QA findings and resolutionsRecords what QA found and how each finding was resolved.
›
PlansHolds plan documents for earlier and current work.
›
VerificationRecords the evidence that a change was tested.
›
TasksRecords tasks and their audits.
›
Design critiquesRecords a design critique of a screen.
›
Raw answer
# CodeBot map: planning only

**Scenario** (reasoning from the project's own docs, not observed use). The owner opens CodeBot on a phone to see whether a Bot needs them, answers an approval or a question, and checks what it produced. At a desktop, the operator checks whether the host runs, backs up before an update, deploys, or sets up a family member or guest. Every screen below serves one of these moments.

**Inventory** (each thing's technical form is in the JSON rows; the sources are below):
- **Web app** (`apps/web/src/`): Bots and chats, Bot settings, widgets, Gmail, contracts, terminal tabs, onboarding, notifications, avatars, what's new.
- **Service** (`apps/service/src/`, port 3505, Tailscale HTTPS): `/api/*` routes, diagnostics, provider adapters, terminal broker.
- **Operations** (`ops/`, `ops/OPERATIONS.md`): deploy, build, backup, restore, emergency stop, guest and family hosts, address change, onboarding resets, account service.
- **npm scripts** (`package.json`): dev, build, check, test, playground, review:gmail, review:schedules, sync:agents, build:integration, docs:gmail.
- **Documents** (`README.md`, `ARCHITECTURE.md`, `CLAUDE.md`, `docs/`, `.idd/`, `.bdd/`, `.impeccable/`, `skills/`).

**Questions for the user** (recommendations are in the JSON):
1. Does `cli/codebot.py` exist? The README mentions it, but it is not in the file list. If it doesn't, I recommend a `codebot` command built with `cli-engineer` for the operator rows.
2. The top screen has six groups. Recommend keeping them, with **Host** as the name (the app and diagnostics say "host"; the README says "computer").
3. Widgets: per Bot, or one dashboard? Recommend one dashboard screen once known.
4. Should the owner browse earlier chats in the UI, or only through the divider? Recommend a "Chats" row on the Bot screen if yes.
5. Are the Gmail Cards, Daily and Glance components screens or widgets, and does a schedules screen exist? Recommend confirming before building.
6. The V2 to V4 preview apps live in other repos. Recommend leaving them off this map.

**Judgment calls:**
- Operator commands are shown as their exact command forms, not as a drawn CLI, until question 1 is answered.
- Several directory listings are truncated in the dump (`apps/web/src/workspace`, `apps/service/src`, `ops/`, `providers`). Items in those folders are not inventoried.
- Some named docs are not in the dump: `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md`, `MASTER-PLAN.md`. The tree has `MASER_PLAN.md`. I did not link them.
- The `ops/review` scripts not named in npm (`schedule-drill.mjs`, `redirect-google.mjs`, `seed-gmail.ts`, `terminal-tabs-stack.sh`) are unmapped until their purpose is confirmed.
- Gmail Daily, Cards and Glance, and the "attached skills" row, are inferred from file names and `ARCHITECTURE.md`. Their sentences need checking.
- The Bot screen's Streamables (Vision, Screenshots, Contract, Git) appear as rows, not as nested screens. Each owns one Bot.

```json
{"screens": [
{"path": [], "sentence": "The top of CodeBot: everything you can reach, grouped by what you are trying to do.", "rows": [
 {"name": "Bots", "form": "screen: bots", "what": "Opens your Bots: pick one to chat with, or create one."},
 {"name": "Automation", "form": "screen: automation", "what": "Opens what Bots do on their own: Gmail and schedules."},
 {"name": "Devices", "form": "screen: devices", "what": "Opens the phones and browsers that reach this host, and which of them get notifications."},
 {"name": "Host", "form": "screen: host", "what": "Opens this computer's CodeBot: running state, updates, backups, account, and terminal."},
 {"name": "Family and guest", "form": "screen: family", "what": "Opens the people who share this computer: family CodeBots and the guest."},
 {"name": "Docs", "form": "screen: docs", "what": "Opens the project's documents, runbooks and records."}
]},
{"path": ["bots"], "sentence": "Your Bots on this host, each with its own chat.", "rows": [
 {"name": "Create new bot", "form": "Bot form (apps/web/src/workspace/BotForm.tsx)", "what": "Opens the form that creates a Bot with its provider, folder and model."},
 {"name": "<Bot name>", "form": "screen: bots <bot>", "what": "Opens that Bot's chat: its messages, queue and what it is doing."}
]},
{"path": ["bots", "<bot>"], "sentence": "The chat with this Bot: its messages, its queue, and what it is working on.", "rows": [
 {"name": "Queue", "form": "POST /bots/:id/queue/take and /queue/send-now (queue bar above the composer)", "what": "Takes queued messages back to the composer, or sends them to the Bot now."},
 {"name": "Attachments", "form": "AttachmentPicker.tsx, useAttachments.ts", "what": "Attaches files to the next message this Bot receives."},
 {"name": "Pinned files", "form": "PinnedFiles.tsx, PinnedResources.tsx", "what": "Opens the files pinned to this Bot's chat."},
 {"name": "Resources", "form": "ResourceViewer.tsx, FilePreview.tsx", "what": "Opens a file or resource this Bot produced, in a safe viewer."},
 {"name": "Recordings", "form": "RecordingPlayer.tsx", "what": "Plays a recording of this Bot's browser work."},
 {"name": "Vision", "form": "Streamable vision, owned by this Bot", "what": "Opens the live view of the browser this Bot uses."},
 {"name": "Screenshots", "form": "Streamable screenshot_gallery, owned by this Bot", "what": "Opens the screenshots this Bot captured, in capture order."},
 {"name": "Contract", "form": "Streamable feature_contract (ContractCatalog.tsx, ContractHistory.tsx)", "what": "Opens this Bot's FeatureContract: its revisions, files and history."},
 {"name": "Git", "form": "Streamable git_quick_info, owned by this Bot", "what": "Shows this Bot's repository status and its quick git actions."},
 {"name": "Widgets", "form": "WidgetBrowser.tsx, WidgetArrangement.tsx", "what": "Adds, removes and arranges the widgets on this screen."},
 {"name": "Settings", "form": "screen: bots <bot> settings (cog button)", "what": "Opens this Bot's settings: model, folder, notifications, skills and avatar."}
]},
{"path": ["bots", "<bot>", "settings"], "sentence": "The settings of this Bot.", "rows": [
 {"name": "Model", "form": "Bot model field (empty uses the automatic policy, ops/OPERATIONS.md)", "what": "Chooses the model; empty uses the automatic policy for each message."},
 {"name": "Folder", "form": "Primary Folder, inside CODEBOT_PROJECT_ROOTS", "what": "Sets the folder this Bot works in; it must lie inside an allowed project root."},
 {"name": "Notifications", "form": "Notifications switch", "what": "Turns on alerts for this Bot's replies, approvals and failures."},
 {"name": "Enable this device", "form": "Enable this device button", "what": "Asks the browser for notification permission and subscribes this device."},
 {"name": "Send test", "form": "Send test button", "what": "Sends a test notification to the selected device, whatever this Bot's switch says."},
 {"name": "Avatar", "form": "AvatarPicker.tsx, AvatarStudio.tsx", "what": "Changes this Bot's avatar."},
 {"name": "Skills", "form": "attached skills (ARCHITECTURE.md, Bot domain)", "what": "Attaches the skills this Bot can use."}
]},
{"path": ["automation"], "sentence": "What Bots do on their own: Gmail and scheduled wake-ups.", "rows": [
 {"name": "Gmail", "form": "screen: automation gmail", "what": "Opens Gmail for Bots: the connected account, approvals and activity."},
 {"name": "Schedules", "form": "screen: schedules (objective in docs/objectives/schedules.md)", "what": "Lists the schedules that wake Bots, and when each next runs."}
]},
{"path": ["automation", "gmail"], "sentence": "Gmail for Bots: the connected Google account, what Bots asked to do in it, and what they did.", "rows": [
 {"name": "Access", "form": "GmailAccess.tsx (sign-in returns through gmail-relay)", "what": "Connects or disconnects the Google account Bots use."},
 {"name": "Approvals", "form": "GmailApprovals.tsx", "what": "Approves or refuses what a Bot asked to do in Gmail."},
 {"name": "Activity", "form": "GmailActivity.tsx", "what": "Lists what Bots did in Gmail."},
 {"name": "Daily", "form": "GmailDaily.tsx", "what": "Shows the Gmail picture for the day."},
 {"name": "Glance", "form": "GmailGlance.tsx", "what": "Shows a short Gmail status at a glance."},
 {"name": "Cards", "form": "GmailCards.tsx", "what": "Shows Gmail items as cards."}
]},
{"path": ["devices"], "sentence": "The phones, tablets and browsers that reach this host, and which of them get notifications.", "rows": [
 {"name": "Connect a device", "form": "https://liel.tail18e69e.ts.net/ over Tailscale", "what": "Opens CodeBot from a new device, through its private Tailscale address."},
 {"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Shows the entrance key a new device signs in with; keep it private."},
 {"name": "Install app", "form": "browser's Install app / Add to Home Screen", "what": "Installs CodeBot on a phone's Home Screen, at the address it was installed from."},
 {"name": "Other devices", "form": "Other devices (Bot settings)", "what": "Lists the devices with notifications and removes old ones; up to 16 are kept."},
 {"name": "Reconnect this device", "form": "Reconnect this device button", "what": "Renews an expired or rejected notification subscription on this device."},
 {"name": "Check a device", "form": "Send test (Bot settings)", "what": "Checks that a chosen device shows alerts; a queued test is not proof."}
]},
{"path": ["host"], "sentence": "This computer's CodeBot: whether it runs, its updates and data, its account, and its terminal.", "rows": [
 {"name": "Running", "form": "screen: host running", "what": "Opens whether CodeBot runs here, its logs and its emergency controls."},
 {"name": "Update", "form": "screen: host update", "what": "Opens building, checking and restarting CodeBot so a change goes live."},
 {"name": "Data", "form": "screen: host data", "what": "Opens the backups of CodeBot's data and how to restore them."},
 {"name": "Account", "form": "screen: host account", "what": "Opens sign-in, onboarding and the account service."},
 {"name": "Terminal", "form": "screen: host terminal", "what": "Opens the terminal on this computer, through its per-user broker."}
]},
{"path": ["host", "running"], "sentence": "Whether CodeBot runs on this computer, and what it reports about itself.", "rows": [
 {"name": "Status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether CodeBot runs and when it last started."},
 {"name": "Logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints CodeBot's last 80 log lines."},
 {"name": "Listener", "form": "ss -ltnp 'sport = :3505'", "what": "Prints which process holds CodeBot's port 3505."},
 {"name": "Diagnostics", "form": "/api/diagnostics/host, /scheduler, /vision (signed-in browser)", "what": "Shows counters and lifecycle state for the host, scheduler and vision, without credentials."},
 {"name": "Recovery hold", "form": "CODEBOT_RECOVERY_HOLD=1 in service.env", "what": "Pauses automatic sends and schedules; explicit Send and Retry still work."},
 {"name": "Emergency stop", "form": "systemctl --user stop --no-block codebot.service, then systemctl --user kill --signal=SIGKILL", "what": "Stops CodeBot at once when a normal stop cannot finish; may lose uncommitted media."},
 {"name": "Settings file", "form": "~/.config/codebot/service.env (mode 0600)", "what": "Edits CodeBot's private settings; restart CodeBot to apply them."}
]},
{"path": ["host", "update"], "sentence": "Building, checking and restarting CodeBot so a change goes live.", "rows": [
 {"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, pushes and restarts CodeBot, waiting while a Bot is working and refusing uncommitted server edits."},
 {"name": "Build", "form": "npm run build", "what": "Builds a new web release; a failed build leaves the served release intact."},
 {"name": "Check", "form": "npm run check (also .github/workflows/check.yml)", "what": "Type-checks and runs the service tests; it proves the code compiles, not Bot behaviour."},
 {"name": "Review", "form": "npm run review:gmail; npm run review:schedules", "what": "Runs the Gmail and schedule reviews against the real service and browser."},
 {"name": "Playground", "form": "npm run playground", "what": "Opens the design variants side by side in the browser."},
 {"name": "Install", "form": "ops/OPERATIONS.md, Install or update the host", "what": "Installs dependencies, the build and the service unit on a new machine, once."},
 {"name": "Sync agent rules", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md instead."},
 {"name": "Integration QA", "form": "codebot-integration.service, port 3506; npm run build:integration", "what": "Runs a disposable CodeBot on port 3506 to try a change first."}
]},
{"path": ["host", "data"], "sentence": "Backups of CodeBot's data, source and settings, and how to restore them.", "rows": [
 {"name": "Back up", "form": "ops/OPERATIONS.md, Back up a consistent installation", "what": "Stops CodeBot, copies its data, source and settings into a backup folder, then starts it again."},
 {"name": "Restore", "form": "ops/OPERATIONS.md, Restore into a separate directory first", "what": "Restores a backup into a separate folder and checks it before anything is promoted."},
 {"name": "Roll back", "form": "ops/OPERATIONS.md, Emergency stop and rollback", "what": "Points CodeBot back at the retained data copy after a failed promotion."}
]},
{"path": ["host", "account"], "sentence": "Signing in to CodeBot, the account service it uses, and the first-use tour.", "rows": [
 {"name": "Sign-in entry", "form": "CODEBOT_ACCOUNT_ENTRY_URL (https://liel.tail18e69e.ts.net/onboarding)", "what": "Opens the common sign-in entry, which sends each account to its own host."},
 {"name": "First-use tour", "form": "/onboarding (account service), apps/web/src/onboarding/", "what": "Walks a new account through setup and creates its first Bot."},
 {"name": "Replay first-use tour", "form": "ops/OPERATIONS.md, Replay only the first-use tour", "what": "Shows the first-use tour again from the start, for a host with no Bots."},
 {"name": "Restart onboarding", "form": "ops/OPERATIONS.md, Restart onboarding with a fresh CodeBot", "what": "Wipes a host's Bots and conversations, keeping the account and its folders."},
 {"name": "Full reset", "form": "ops/OPERATIONS.md, Full reset", "what": "Deletes an account and everything it holds, so the person starts as new."},
 {"name": "Change address", "form": "ops/OPERATIONS.md, Change this machine's address", "what": "Lists the places that hold this machine's address, to update when it changes."},
 {"name": "Account service", "form": "Supabase project wbgrjvqbupgdclaztuou", "what": "Opens the Supabase project that holds accounts and host bindings."},
 {"name": "Redeploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Redeploys the host-access function after a contract it parses changes."},
 {"name": "Keep-alive", "form": ".github/workflows/supabase-keepalive.yml", "what": "Keeps the account service awake on a schedule."}
]},
{"path": ["host", "terminal"], "sentence": "The terminal on this computer and the broker that keeps it running.", "rows": [
 {"name": "Terminal", "form": "TerminalPage.tsx, TerminalTab.tsx", "what": "Opens a terminal tab on this computer."},
 {"name": "Broker", "form": "codebot-terminal-broker.service (user unit)", "what": "Runs the per-user broker that holds the terminal's tmux session across web restarts."},
 {"name": "Enable broker", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "Turns the terminal on; without it no shell opens."},
 {"name": "Broker status", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the broker runs and answers."}
]},
{"path": ["family"], "sentence": "The people who share this computer: family CodeBots, and the guest.", "rows": [
 {"name": "Family CodeBots", "form": "screen: family codebots", "what": "Opens the family CodeBots on this computer, one per Google account."},
 {"name": "Guest", "form": "screen: family guest", "what": "Opens the guest's CodeBot: its service, invite and updates."}
]},
{"path": ["family", "codebots"], "sentence": "Family CodeBots on this computer, and the helper that adds, removes and restarts them.", "rows": [
 {"name": "Status", "form": "codebot-family status", "what": "Prints each family CodeBot and whether its Gmail can be connected."},
 {"name": "Add", "form": "sudo codebot-family add N (run by the front door for a new Google account)", "what": "Creates a family CodeBot at the next free number."},
 {"name": "Remove", "form": "sudo codebot-family remove N", "what": "Deletes a family CodeBot and frees its number; its Google account stays linked."},
 {"name": "Stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
 {"name": "Start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot again."},
 {"name": "Update", "form": "ops/family-update.sh", "what": "Builds the family program and restarts every family CodeBot."},
 {"name": "Set up", "form": "sudo ops/family-install.sh", "what": "Sets up the front door, helper, services, sudo rules and nginx, once."},
 {"name": "Logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the front door's and the family CodeBots' logs."}
]},
{"path": ["family", "guest"], "sentence": "The guest's CodeBot: whether it runs, its invite, and its updates.", "rows": [
 {"name": "Status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest's CodeBot runs."},
 {"name": "Logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest's log."},
 {"name": "Usage", "form": "sudo du -sh /home/codebot-guest", "what": "Prints how much space the guest's data takes."},
 {"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google link that is valid for ten minutes."},
 {"name": "Update", "form": "ops/guest-update.sh", "what": "Builds the guest's program, replaces it and restarts the guest's CodeBot."},
 {"name": "Set up", "form": "sudo ops/guest-install.sh", "what": "Creates the guest's user, service, settings, sudo rules and Tailscale port, once."},
 {"name": "Remove", "form": "ops/OPERATIONS.md, To remove it", "what": "Deletes the guest's service, user, data and program."}
]},
{"path": ["docs"], "sentence": "The project's documents, from what CodeBot is to how to run and change it.", "rows": [
 {"name": "README", "form": "README.md", "what": "Explains what CodeBot is, how to run it and what its checks prove."},
 {"name": "Product spec", "form": "PRODUCT-SPEC.md (not in the dump)", "what": "Sets out how CodeBot must behave, as its behaviour contract."},
 {"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Explains how CodeBot is built and where its boundaries lie."},
 {"name": "Operations runbook", "form": "ops/OPERATIONS.md", "what": "Explains how to run, recover and change CodeBot."},
 {"name": "Agent rules and skills", "form": "CLAUDE.md; skills/codebot-housekeeping/SKILL.md", "what": "Sets the rules and skills every agent follows on this project."},
 {"name": "Design method and taste", "form": "docs/design-method.md, docs/design-taste.md", "what": "Explains how screens are designed and records the owner's rulings."},
 {"name": "Gmail for Bots", "form": "docs/automation/gmail.md, docs/automation/gmail-reference.md", "what": "Explains Gmail for Bots, for the supervisor and as a generated reference."},
 {"name": "Objectives", "form": "docs/objectives/README.md", "what": "Lists the objectives: chat current session, Gmail widget, schedules and terminal tabs."},
 {"name": "What's new", "form": "apps/web/src/whatsNew.ts", "what": "Shows what changed in the latest update, once."},
 {"name": "Records", "form": "screen: docs records", "what": "Opens the intents, scenarios, plans and verification records."}
]},
{"path": ["docs", "records"], "sentence": "Intents, scenarios, plans and verification records, kept per module.", "rows": [
 {"name": "Intents", "form": ".idd/modules/<module>/INTENT.md", "what": "Describes a module's intent: its constraints and tests."},
 {"name": "Scenarios", "form": ".bdd/features/<feature>/*.feature, .bdd/steps/", "what": "Describes a feature's behaviour as Given, When, Then scenarios."},
 {"name": "QA findings and resolutions", "form": ".bdd/qa/findings/, .bdd/qa/resolutions/", "what": "Records what QA found and how each finding was resolved."},
 {"name": "Plans", "form": "docs/plans/, .plans/, docs/superpowers/plans/", "what": "Holds plan documents for earlier and current work."},
 {"name": "Verification", "form": "docs/verification/, docs/onboarding-recorded-proof-2026-09-14.md", "what": "Records the evidence that a change was tested."},
 {"name": "Tasks", "form": "docs/tasks/", "what": "Records tasks and their audits."},
 {"name": "Design critiques", "form": ".impeccable/critique/", "what": "Records a design critique of a screen."}
]}
],
"questions": [
"Does cli/codebot.py exist? The README mentions it, but it is not in the file list. Recommendation: if not, build the operator rows as a codebot command with cli-engineer.",
"Keep the six top groups, with Host as the name for this computer? Recommendation: yes; Host matches the app and diagnostics.",
"Are widgets per Bot or one dashboard? Recommendation: one dashboard screen, once known.",
"Should the owner browse earlier chats in the UI, or only through the chat divider? Recommendation: add a Chats row on the Bot screen if they should browse.",
"Are Gmail Daily, Cards and Glance screens or widgets, and does a schedules screen exist? Recommendation: confirm before building those rows.",
"Leave the V2 to V4 preview apps (other repos, ports 3512 to 3514) off this map? Recommendation: yes."
]}
```

screen-decomposition, final · run 2 exit=0 seconds=231 · prompt

P1 Recall: 0.462P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 5P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.257
As terminal help
The top of CodeBot: your Bots, Gmail, the terminal, this computer, and the docs.
Botsscreen: botsOpens the Bots list: each Bot's chat, and a way to make a new Bot.
Gmailscreen: gmailOpens the Gmail screen: the Google account Bots use, what they did, and what waits for approval.
Terminalscreen: terminalOpens the terminal: the owner's shell on this computer, in tabs.
Computerscreen: computerOpens this computer: devices, services, family and guest accounts, backups, diagnostics and commands.
Docsscreen: docsOpens the written guides, plans and records of the project.
bots
The Bots on this computer.
<bot name>screen: bots > <bot>Opens this Bot's chat.
New Botapps/web/src/workspace/BotForm.tsxCreates a Bot with a name, a provider (Codex, Claude or OpenCode) and a Primary Folder.
bots › <bot>
The chat with this Bot: its messages, what it is doing now, and what waits for you.
Queued messagesqueue bar above the composerShows the messages waiting behind a reply; edit them, send them now, or take them back.
StopStop button beside the composer (Esc)Interrupts the reply; the queued messages are kept.
Bot questionsquestion card in the chatAnswers a question this Bot is waiting on.
Approval requestsapproval card in the chatAnswers an approval request from this Bot.
Streamablesscreen: bots > <bot> > streamablesOpens this Bot's live views: Vision, Screenshots, Contract and Git.
Filesscreen: bots > <bot> > filesOpens this Bot's pinned files, the folder of its past chats, and its Primary Folder.
Settingsscreen: bots > <bot> > settingsOpens this Bot's settings, behind the cog button at the top right.
bots › <bot> › streamables
The live views this Bot owns: its browser, its screenshots, its feature contract and its Git status.
Visionscreen: bots > <bot> > streamables > visionOpens the live view of the browser this Bot uses, and its recordings.
Screenshotsstreamable kind screenshot_galleryShows the screenshots this Bot captured, in a gallery.
Contractscreen: bots > <bot> > streamables > contractOpens this Bot's feature contract and its revisions.
Gitstreamable kind git_quick_infoShows the status of this Bot's repository, with quick Git actions.
bots › <bot> › streamables › vision
The browser this Bot uses, and the recordings of it.
Recordingsapps/web/src/resources/RecordingPlayer.tsxPlays a recording of the browser view.
bots › <bot> › streamables › contract
This Bot's feature contract: its revisions, changes and conflicts.
Historyapps/web/src/contracts/ContractHistory.tsxLists the revisions of the contract, in order.
Diffapps/web/src/contracts/ContractDiff.tsxShows what changed between two revisions.
Conflictapps/web/src/contracts/ContractConflict.tsxShows a conflict between revisions that needs settling.
Contract filesapps/web/src/contracts/ContractFiles.tsxLists the files the contract covers.
Component relationshipsapps/web/src/contracts/ComponentRelationships.tsxShows how the contract's components relate to each other.
Contract catalogapps/web/src/contracts/ContractCatalog.tsxLists the contracts in the catalog.
bots › <bot> › files
The files this Bot works with: pinned ones, its past chats and its Primary Folder.
Pinned filesapps/web/src/resources/PinnedFiles.tsxOpens a pinned file in the file viewer.
Pinned resourcesapps/web/src/resources/PinnedResources.tsxOpens a pinned resource in the resource viewer.
Chats folder<bot home>/chats/Opens the transcripts of this Bot's ended chats.
Primary Folderthe Bot's Primary Folder, a path under CODEBOT_PROJECT_ROOTSOpens the project folder this Bot works in.
bots › <bot> › settings
This Bot's settings, behind the cog button.
Detailsapps/web/src/workspace/BotForm.tsxChanges the name, provider, model and Primary Folder of this Bot.
Avatarapps/web/src/workspace/AvatarPicker.tsxChanges this Bot's avatar, from the avatar parts.
NotificationsNotifications switch and Enable this device, in this screenTurns on notifications for this Bot's replies, approval requests and failures.
Automatic actionsautomatic-action policy, in this screenSets which actions this Bot takes without asking.
Skillsskills/codebot-housekeeping/SKILL.mdAttaches the skills this Bot can use, such as codebot-housekeeping.
Widgetsapps/web/src/widgets/WidgetBrowser.tsxOpens the widget browser to add widgets, then arranges them.
gmail
Gmail for your Bots: the connected account, what Bots did, and what waits for approval.
Accessapps/web/src/gmail/GmailAccess.tsxShows the Google account Bots use for mail, and sets it.
Activityapps/web/src/gmail/GmailActivity.tsxShows what Bots did with Gmail.
Approvalsapps/web/src/gmail/GmailApprovals.tsxShows Gmail actions waiting for your approval.
Dailyapps/web/src/gmail/GmailDaily.tsxShows the day's Gmail activity from Bots.
terminal
The owner's shell on this computer, in tabs.
Shell tabsapps/web/src/TerminalTab.tsx and apps/web/src/TerminalPage.tsxOpens a shell in a tab on this computer; needs the terminal broker running (Computer > Services).
computer
This computer: its devices, services, family and guest accounts, backups, diagnostics and commands.
Devicesscreen: computer > devicesOpens the devices: the entrance key, the private address and the devices that get notifications.
Family and guestscreen: computer > familyOpens the family CodeBots and the guest CodeBot on this computer.
Onboardingscreen: computer > onboardingOpens how a person starts on this computer, and how to start them again.
Servicesscreen: computer > servicesOpens the services that run CodeBot here, and the account service.
Experimentsscreen: computer > experimentsOpens the experimental apps V2, V3 and V4, which run beside CodeBot.
Backupscreen: computer > backupOpens how to back up, restore and stop CodeBot safely.
Diagnosticsscreen: computer > diagnosticsOpens the checks that show whether CodeBot is up and what it is doing.
Commandsscreen: computer > commandsOpens the commands that run, build, check, deploy and review CodeBot.
App settingsapps/web/src/ui/Settings.tsxOpens the settings of the app.
computer › devices
The keys, addresses and notification devices that connect your phones and computers to this CodeBot.
Entrance key~/.local/share/codebot/owner-keyShows the key a new device needs to open CodeBot.
Private addresstailscale serve status --jsonShows the private address this CodeBot is published at.
Install on a phoneops/OPERATIONS.md, section Connect a deviceShows the steps to install CodeBot on a phone from its private address.
Change the addressops/OPERATIONS.md, section Change this machine's addressShows the places to update when the address changes; sign-in breaks until they match.
Notification devicesOther devices, in any Bot's settingsOpens the devices that get notifications, to remove old ones.
computer › family
The family CodeBots and the guest CodeBot on this computer.
Family statussudo codebot-family statusPrints each family CodeBot, whether it runs, and whether its Gmail can be connected.
Add a family membersudo codebot-family add NCreates family CodeBot N for a new Google account; at most 6.
Remove a family membersudo codebot-family remove NDeletes family CodeBot N and frees its number; its Google account stays linked.
Guest statussystemctl status codebot-guestShows whether the guest CodeBot runs, and its recent log lines.
Invite a guestsudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google invite link, valid for ten minutes.
Remove the guestops/OPERATIONS.md, section Host a guest on this machineShows the steps that remove the guest's service, user and program; this is destructive.
computer › onboarding
How a person starts on this computer, and how to start them again.
Sign-inCODEBOT_ACCOUNT_ENTRY_URL, path /onboardingOpens the sign-in page, where a person signs in with Google.
First-use tourapps/web/src/onboarding/Starts at sign-in and creates the first Bot.
Replay the tourops/OPERATIONS.md, section Replay only the first-use tourShows the steps to replay the first-use tour for a person whose host has no Bots.
Restart with a fresh CodeBotops/OPERATIONS.md, section Restart onboarding with a fresh CodeBotShows the steps that wipe the host's Bots and conversations and keep the account; this is destructive.
Full resetops/OPERATIONS.md, section Full resetShows the steps that delete a person's account, data and Bots so they start as new; this is destructive.
computer › services
The services that run CodeBot on this computer, and the account service.
CodeBot hostsystemctl --user restart codebot.serviceRuns the host; restart it after an update.
Terminal brokerops/codebot-terminal-broker.serviceRuns the per-user broker that opens terminal shells; it stays off until installed.
Family front doorops/codebot-family-lobby.serviceRuns the sign-in for family members at the home Wi-Fi address.
Family CodeBotsops/codebot-family@.serviceRuns one CodeBot per family member, each as its own user.
Guest CodeBotops/codebot-guest.serviceRuns the guest's own CodeBot on this computer.
Account serviceSupabase project wbgrjvqbupgdclaztuou, dashboardOpens the account service: sign-in redirects, users and the SQL editor.
computer › experiments
The experimental apps V2, V3 and V4, which run beside CodeBot in their own repos.
V2 Terminal chathttp://127.0.0.1:3512 (folder ~/projects/codebot-v2-terminal-chat)Opens V2 in Chrome; start it first with sh ops/app-run.sh dev in its folder.
V3 Claude Code modhttp://127.0.0.1:3513 (folder ~/projects/codebot-v3-claude-mod)Opens V3 in Chrome; start it first with sh ops/app-run.sh dev in its folder.
V4 Launcher menuhttp://127.0.0.1:3514 (folder ~/projects/codebot-v4-launcher-menu)Opens V4 in Chrome; start it first with sh ops/app-run.sh dev in its folder.
computer › backup
How to back up, restore and stop CodeBot safely.
Back upops/OPERATIONS.md, section Back up a consistent installationShows the steps to stop the host, copy its data into a private archive, and start it again.
Restoreops/OPERATIONS.md, section Restore into a separate directory firstShows the steps to check an archive and start a restored copy on port 3508, leaving the original alone.
Emergency stopops/OPERATIONS.md, section Emergency stop and rollbackShows the steps to stop the host normally, or kill it when it must stop now.
computer › diagnostics
The checks that show whether CodeBot is up and what it is doing.
Session/api/session on the host's own addressReturns whether the host is up; this is the check after a restart.
Host diagnostics/api/diagnostics/host on the host's own addressShows the migration, queued and running turns, and the recovery hold.
Scheduler diagnostics/api/diagnostics/scheduler on the host's own addressShows the scheduler's counters and lifecycle state.
Vision diagnostics/api/diagnostics/vision on the host's own addressShows the Vision counters and lifecycle state.
Notification diagnostics/api/notifications/diagnostics on the host's own addressShows the notification queue, its timer and the sends in progress.
Host statussystemctl --user status codebot.service --no-pagerShows whether the host is active.
Host logjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the host.
Port holderss -ltnp 'sport = :3505'Shows which process holds the host's port, 3505.
computer › commands
The commands that run, build, check, deploy and review CodeBot.
Run the service (dev)npm run devStarts the local service and restarts it when files change.
Run the servicenpm startStarts the service in production mode.
Buildnpm run buildChecks the types, then builds the web app into a new release.
Type checknpm run typecheckChecks the types, without building.
Testnpm testRuns the Gmail automation tests against a fake Google server.
Checknpm run checkChecks the types, then runs the tests.
Build the QA instancenpm run build:integrationBuilds the integration build used by the QA instance on port 3506.
Set up the accountnpm run setup-accountRuns the account setup script for this computer.
Regenerate the Gmail referencenpm run docs:gmailRegenerates docs/automation/gmail-reference.md.
Sync the agent instructionsnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
Gmail reviewnpm run review:gmailRuns the Gmail review script.
Schedules reviewnpm run review:schedulesRuns the schedules review script.
Playgroundnpm run playgroundOpens the Gmail playground in the browser, for design variants.
Deploysh ops/deploy.shBuilds, pushes and restarts the host, and waits while a Bot is working.
Guest installsudo ops/guest-install.shSets up the guest's user, service and sudo rules, once.
Guest updateops/guest-update.shRebuilds and restarts the guest CodeBot.
Family installsudo ops/family-install.shSets up the family front door, its helper and sudo rules, once.
Family updateops/family-update.shRebuilds and restarts every family CodeBot.
Schedule drillops/review/schedule-drill.mjsRuns the schedule drill script.
Google redirectops/review/redirect-google.mjsRuns the Google redirect script.
Seed Gmailops/review/seed-gmail.tsRuns the Gmail seed script.
Terminal tabs stackops/review/terminal-tabs-stack.shRuns the terminal tabs stack script.
Check workflow.github/workflows/check.ymlRuns the check workflow on GitHub Actions.
Keepalive workflow.github/workflows/supabase-keepalive.ymlRuns the Supabase keepalive workflow on GitHub Actions.
docs
The project's written guides, plans and records.
READMEREADME.mdOpens the README: what CodeBot is, and how to run and test it.
ArchitectureARCHITECTURE.mdOpens how CodeBot is built: its boundaries, transcript and providers.
Operations runbookops/OPERATIONS.mdOpens the runbook for running, backing up, restoring and recovering CodeBot.
Gmail guidedocs/automation/gmail.mdOpens how Bots use Gmail, with the supervisor guide.
Design methoddocs/design-method.mdOpens the method for designing and checking screens.
Design tastedocs/design-taste.mdOpens the owner's design rulings, and what they rejected.
Objectivesdocs/objectives/README.mdOpens the goals: chat, the Gmail widget, schedules and terminal tabs.
Plansdocs/plans/Opens the plans and designs, one file per change.
Verificationdocs/verification/Opens the recorded evidence that features were checked.
Tasksdocs/tasks/Opens the written tasks and their reports.
Design referencesdesign/Opens the design references and annotated screenshots.
What's newapps/web/src/whatsNew.tsOpens the list of changes shown once after an update.
Questions
  • Split Computer into Computer (devices, services, experiments, backup, diagnostics, commands, app settings) and Hosting (family and guest, onboarding)? Recommendation: yes. Computer has nine rows, and Hosting holds the setup work a family or guest needs, not everyday use.
  • Split Commands (24 rows) by job: run, build and check, deploy, review, setup? Recommendation: yes, after the first split. A list this long is hard to scan.
  • Are schedules per Bot (wakeups a Bot takes on its own) or one list for the whole app? Recommendation: per Bot, as a row in Bot settings. No schedules screen is drawn until you answer.
  • Keep process records (.idd/, .bdd/, .plans/, .impeccable/) and agent files (AGENTS.md, CLAUDE.md) off the map? Recommendation: off, since they are for agents rather than the owner. Say if you want any on Docs.
As phone screens

Home

The top of CodeBot: your Bots, Gmail, the terminal, this computer, and the docs.

BotsOpens the Bots list: each Bot's chat, and a way to make a new Bot.
›
GmailOpens the Gmail screen: the Google account Bots use, what they did, and what waits for approval.
›
TerminalOpens the terminal: the owner's shell on this computer, in tabs.
›
ComputerOpens this computer: devices, services, family and guest accounts, backups, diagnostics and commands.
›
DocsOpens the written guides, plans and records of the project.
›
‹ Home

bots

The Bots on this computer.

<bot name>Opens this Bot's chat.
›
New BotCreates a Bot with a name, a provider (Codex, Claude or OpenCode) and a Primary Folder.
›
‹ bots

<bot>

The chat with this Bot: its messages, what it is doing now, and what waits for you.

Queued messagesShows the messages waiting behind a reply; edit them, send them now, or take them back.
›
StopInterrupts the reply; the queued messages are kept.
›
Bot questionsAnswers a question this Bot is waiting on.
›
Approval requestsAnswers an approval request from this Bot.
›
StreamablesOpens this Bot's live views: Vision, Screenshots, Contract and Git.
›
FilesOpens this Bot's pinned files, the folder of its past chats, and its Primary Folder.
›
SettingsOpens this Bot's settings, behind the cog button at the top right.
›
‹ <bot>

streamables

The live views this Bot owns: its browser, its screenshots, its feature contract and its Git status.

VisionOpens the live view of the browser this Bot uses, and its recordings.
›
ScreenshotsShows the screenshots this Bot captured, in a gallery.
›
ContractOpens this Bot's feature contract and its revisions.
›
GitShows the status of this Bot's repository, with quick Git actions.
›
‹ streamables

vision

The browser this Bot uses, and the recordings of it.

RecordingsPlays a recording of the browser view.
›
‹ streamables

contract

This Bot's feature contract: its revisions, changes and conflicts.

HistoryLists the revisions of the contract, in order.
›
DiffShows what changed between two revisions.
›
ConflictShows a conflict between revisions that needs settling.
›
Contract filesLists the files the contract covers.
›
Component relationshipsShows how the contract's components relate to each other.
›
Contract catalogLists the contracts in the catalog.
›
‹ <bot>

files

The files this Bot works with: pinned ones, its past chats and its Primary Folder.

Pinned filesOpens a pinned file in the file viewer.
›
Pinned resourcesOpens a pinned resource in the resource viewer.
›
Chats folderOpens the transcripts of this Bot's ended chats.
›
Primary FolderOpens the project folder this Bot works in.
›
‹ <bot>

settings

This Bot's settings, behind the cog button.

DetailsChanges the name, provider, model and Primary Folder of this Bot.
›
AvatarChanges this Bot's avatar, from the avatar parts.
›
NotificationsTurns on notifications for this Bot's replies, approval requests and failures.
›
Automatic actionsSets which actions this Bot takes without asking.
›
SkillsAttaches the skills this Bot can use, such as codebot-housekeeping.
›
WidgetsOpens the widget browser to add widgets, then arranges them.
›
‹ Home

gmail

Gmail for your Bots: the connected account, what Bots did, and what waits for approval.

AccessShows the Google account Bots use for mail, and sets it.
›
ActivityShows what Bots did with Gmail.
›
ApprovalsShows Gmail actions waiting for your approval.
›
DailyShows the day's Gmail activity from Bots.
›
‹ Home

terminal

The owner's shell on this computer, in tabs.

Shell tabsOpens a shell in a tab on this computer; needs the terminal broker running (Computer > Services).
›
‹ Home

computer

This computer: its devices, services, family and guest accounts, backups, diagnostics and commands.

DevicesOpens the devices: the entrance key, the private address and the devices that get notifications.
›
Family and guestOpens the family CodeBots and the guest CodeBot on this computer.
›
OnboardingOpens how a person starts on this computer, and how to start them again.
›
ServicesOpens the services that run CodeBot here, and the account service.
›
ExperimentsOpens the experimental apps V2, V3 and V4, which run beside CodeBot.
›
BackupOpens how to back up, restore and stop CodeBot safely.
›
DiagnosticsOpens the checks that show whether CodeBot is up and what it is doing.
›
CommandsOpens the commands that run, build, check, deploy and review CodeBot.
›
App settingsOpens the settings of the app.
›
‹ computer

devices

The keys, addresses and notification devices that connect your phones and computers to this CodeBot.

Entrance keyShows the key a new device needs to open CodeBot.
›
Private addressShows the private address this CodeBot is published at.
›
Install on a phoneShows the steps to install CodeBot on a phone from its private address.
›
Change the addressShows the places to update when the address changes; sign-in breaks until they match.
›
Notification devicesOpens the devices that get notifications, to remove old ones.
›
‹ computer

family

The family CodeBots and the guest CodeBot on this computer.

Family statusPrints each family CodeBot, whether it runs, and whether its Gmail can be connected.
›
Add a family memberCreates family CodeBot N for a new Google account; at most 6.
›
Remove a family memberDeletes family CodeBot N and frees its number; its Google account stays linked.
›
Guest statusShows whether the guest CodeBot runs, and its recent log lines.
›
Invite a guestPrints a one-use Google invite link, valid for ten minutes.
›
Remove the guestShows the steps that remove the guest's service, user and program; this is destructive.
›
‹ computer

onboarding

How a person starts on this computer, and how to start them again.

Sign-inOpens the sign-in page, where a person signs in with Google.
›
First-use tourStarts at sign-in and creates the first Bot.
›
Replay the tourShows the steps to replay the first-use tour for a person whose host has no Bots.
›
Restart with a fresh CodeBotShows the steps that wipe the host's Bots and conversations and keep the account; this is destructive.
›
Full resetShows the steps that delete a person's account, data and Bots so they start as new; this is destructive.
›
‹ computer

services

The services that run CodeBot on this computer, and the account service.

CodeBot hostRuns the host; restart it after an update.
›
Terminal brokerRuns the per-user broker that opens terminal shells; it stays off until installed.
›
Family front doorRuns the sign-in for family members at the home Wi-Fi address.
›
Family CodeBotsRuns one CodeBot per family member, each as its own user.
›
Guest CodeBotRuns the guest's own CodeBot on this computer.
›
Account serviceOpens the account service: sign-in redirects, users and the SQL editor.
›
‹ computer

experiments

The experimental apps V2, V3 and V4, which run beside CodeBot in their own repos.

V2 Terminal chatOpens V2 in Chrome; start it first with sh ops/app-run.sh dev in its folder.
›
V3 Claude Code modOpens V3 in Chrome; start it first with sh ops/app-run.sh dev in its folder.
›
V4 Launcher menuOpens V4 in Chrome; start it first with sh ops/app-run.sh dev in its folder.
›
‹ computer

backup

How to back up, restore and stop CodeBot safely.

Back upShows the steps to stop the host, copy its data into a private archive, and start it again.
›
RestoreShows the steps to check an archive and start a restored copy on port 3508, leaving the original alone.
›
Emergency stopShows the steps to stop the host normally, or kill it when it must stop now.
›
‹ computer

diagnostics

The checks that show whether CodeBot is up and what it is doing.

SessionReturns whether the host is up; this is the check after a restart.
›
Host diagnosticsShows the migration, queued and running turns, and the recovery hold.
›
Scheduler diagnosticsShows the scheduler's counters and lifecycle state.
›
Vision diagnosticsShows the Vision counters and lifecycle state.
›
Notification diagnosticsShows the notification queue, its timer and the sends in progress.
›
Host statusShows whether the host is active.
›
Host logPrints the last 80 log lines of the host.
›
Port holderShows which process holds the host's port, 3505.
›
‹ computer

commands

The commands that run, build, check, deploy and review CodeBot.

Run the service (dev)Starts the local service and restarts it when files change.
›
Run the serviceStarts the service in production mode.
›
BuildChecks the types, then builds the web app into a new release.
›
Type checkChecks the types, without building.
›
TestRuns the Gmail automation tests against a fake Google server.
›
CheckChecks the types, then runs the tests.
›
Build the QA instanceBuilds the integration build used by the QA instance on port 3506.
›
Set up the accountRuns the account setup script for this computer.
›
Regenerate the Gmail referenceRegenerates docs/automation/gmail-reference.md.
›
Sync the agent instructionsRegenerates AGENTS.md from CLAUDE.md.
›
Gmail reviewRuns the Gmail review script.
›
Schedules reviewRuns the schedules review script.
›
PlaygroundOpens the Gmail playground in the browser, for design variants.
›
DeployBuilds, pushes and restarts the host, and waits while a Bot is working.
›
Guest installSets up the guest's user, service and sudo rules, once.
›
Guest updateRebuilds and restarts the guest CodeBot.
›
Family installSets up the family front door, its helper and sudo rules, once.
›
Family updateRebuilds and restarts every family CodeBot.
›
Schedule drillRuns the schedule drill script.
›
Google redirectRuns the Google redirect script.
›
Seed GmailRuns the Gmail seed script.
›
Terminal tabs stackRuns the terminal tabs stack script.
›
Check workflowRuns the check workflow on GitHub Actions.
›
Keepalive workflowRuns the Supabase keepalive workflow on GitHub Actions.
›
‹ Home

docs

The project's written guides, plans and records.

READMEOpens the README: what CodeBot is, and how to run and test it.
›
ArchitectureOpens how CodeBot is built: its boundaries, transcript and providers.
›
Operations runbookOpens the runbook for running, backing up, restoring and recovering CodeBot.
›
Gmail guideOpens how Bots use Gmail, with the supervisor guide.
›
Design methodOpens the method for designing and checking screens.
›
Design tasteOpens the owner's design rulings, and what they rejected.
›
ObjectivesOpens the goals: chat, the Gmail widget, schedules and terminal tabs.
›
PlansOpens the plans and designs, one file per change.
›
VerificationOpens the recorded evidence that features were checked.
›
TasksOpens the written tasks and their reports.
›
Design referencesOpens the design references and annotated screenshots.
›
What's newOpens the list of changes shown once after an update.
›
Raw answer
## Scenario

Reasoning from the README, `ops/OPERATIONS.md` and `CLAUDE.md`, not confirmed by the owner: the owner runs CodeBot on one computer and mostly uses it from a phone. On the phone they check which Bot needs them, read what it is doing, and answer or steer it. Now and then they sit at the computer to check services, pair a device, back up, add a family member, or run a command.

## The map

The top screen has five groups: **Bots**, **Gmail**, **Terminal**, **Computer** and **Docs**. Bots go three levels deep (Bot, then Streamables or Files or Settings, then one view). Computer has eight sub-screens.

## Questions for the owner

1. **Split Computer?** It has nine rows. I recommend splitting it into **Computer** (devices, services, experiments, backup, diagnostics, commands, app settings) and **Hosting** (family and guest, onboarding). Hosting is occasional setup work, not everyday use.
2. **Split Commands?** It has 24 rows. I recommend grouping them by job (run, build and check, deploy, review, setup), after question 1 is settled.
3. **Are schedules per Bot or app-wide?** I recommend per Bot, as a row in Bot settings. The objective is in Docs, but no screen is drawn for it until you answer.
4. **Keep process records and agent files off the map?** That means `.idd/`, `.bdd/`, `.plans/`, `.impeccable/`, `AGENTS.md` and `CLAUDE.md`. I recommend keeping them off, since they are for agents rather than the owner.

## Judgment calls

- **Left off, not reached by the owner:** `apps/control/` and the Supabase functions (server code), `packages/`, migrations, avatar and icon asset folders (the picker's contents, not places), `ops/agent-start.sh`, `ops/global/CLAUDE.md`.
- **Named in the docs but not in the file list:** `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md`, `MASTER-PLAN.md`, `cli/codebot.py`. Not mapped. The README's `cli/codebot.py` mention sits in a broken fragment.
- **Contents not read:** the `ops/review/` scripts, both workflow files, `apps/web/src/ui/Settings.tsx`, and the Gmail daily and summary components. Their "what" lines come from file names. Read them before building the CLI.
- **Chats** are dividers in the Bot chat. Their transcripts sit in the Bot's `chats/` folder, which is a row under Files. No separate screen.
- **Queue, Stop, Bot questions and approval requests** are controls in the chat, so they are rows on the chat screen.
- **Gmail Glance** is a widget, reached through Widgets in Bot settings. **Gmail Cards** is a component and gets no row.
- **Streamables** is the project's own word for Vision, Screenshots, Contract and Git. I kept it as a screen name, though it is a developer term. If the owner wants different names, the four rows change.
- **Experimental apps V2, V3 and V4** come from the README and live in their own repos. They are listed under Computer › Experiments with their ports.
- **Forms** use the host's own address, not a fixed domain, because addresses vary (`CLAUDE.md`).
- **Notifications** appear on two screens with different lines: Bot settings (turn on for a Bot) and Devices (remove old devices).
- **Files** appears twice with different lines: the Bot's Files, and Contract files.

```json
{"screens": [
{"path": [], "sentence": "The top of CodeBot: your Bots, Gmail, the terminal, this computer, and the docs.", "rows": [
{"name": "Bots", "form": "screen: bots", "what": "Opens the Bots list: each Bot's chat, and a way to make a new Bot."},
{"name": "Gmail", "form": "screen: gmail", "what": "Opens the Gmail screen: the Google account Bots use, what they did, and what waits for approval."},
{"name": "Terminal", "form": "screen: terminal", "what": "Opens the terminal: the owner's shell on this computer, in tabs."},
{"name": "Computer", "form": "screen: computer", "what": "Opens this computer: devices, services, family and guest accounts, backups, diagnostics and commands."},
{"name": "Docs", "form": "screen: docs", "what": "Opens the written guides, plans and records of the project."}
]},
{"path": ["bots"], "sentence": "The Bots on this computer.", "rows": [
{"name": "<bot name>", "form": "screen: bots > <bot>", "what": "Opens this Bot's chat."},
{"name": "New Bot", "form": "apps/web/src/workspace/BotForm.tsx", "what": "Creates a Bot with a name, a provider (Codex, Claude or OpenCode) and a Primary Folder."}
]},
{"path": ["bots", "<bot>"], "sentence": "The chat with this Bot: its messages, what it is doing now, and what waits for you.", "rows": [
{"name": "Queued messages", "form": "queue bar above the composer", "what": "Shows the messages waiting behind a reply; edit them, send them now, or take them back."},
{"name": "Stop", "form": "Stop button beside the composer (Esc)", "what": "Interrupts the reply; the queued messages are kept."},
{"name": "Bot questions", "form": "question card in the chat", "what": "Answers a question this Bot is waiting on."},
{"name": "Approval requests", "form": "approval card in the chat", "what": "Answers an approval request from this Bot."},
{"name": "Streamables", "form": "screen: bots > <bot> > streamables", "what": "Opens this Bot's live views: Vision, Screenshots, Contract and Git."},
{"name": "Files", "form": "screen: bots > <bot> > files", "what": "Opens this Bot's pinned files, the folder of its past chats, and its Primary Folder."},
{"name": "Settings", "form": "screen: bots > <bot> > settings", "what": "Opens this Bot's settings, behind the cog button at the top right."}
]},
{"path": ["bots", "<bot>", "streamables"], "sentence": "The live views this Bot owns: its browser, its screenshots, its feature contract and its Git status.", "rows": [
{"name": "Vision", "form": "screen: bots > <bot> > streamables > vision", "what": "Opens the live view of the browser this Bot uses, and its recordings."},
{"name": "Screenshots", "form": "streamable kind screenshot_gallery", "what": "Shows the screenshots this Bot captured, in a gallery."},
{"name": "Contract", "form": "screen: bots > <bot> > streamables > contract", "what": "Opens this Bot's feature contract and its revisions."},
{"name": "Git", "form": "streamable kind git_quick_info", "what": "Shows the status of this Bot's repository, with quick Git actions."}
]},
{"path": ["bots", "<bot>", "streamables", "vision"], "sentence": "The browser this Bot uses, and the recordings of it.", "rows": [
{"name": "Recordings", "form": "apps/web/src/resources/RecordingPlayer.tsx", "what": "Plays a recording of the browser view."}
]},
{"path": ["bots", "<bot>", "streamables", "contract"], "sentence": "This Bot's feature contract: its revisions, changes and conflicts.", "rows": [
{"name": "History", "form": "apps/web/src/contracts/ContractHistory.tsx", "what": "Lists the revisions of the contract, in order."},
{"name": "Diff", "form": "apps/web/src/contracts/ContractDiff.tsx", "what": "Shows what changed between two revisions."},
{"name": "Conflict", "form": "apps/web/src/contracts/ContractConflict.tsx", "what": "Shows a conflict between revisions that needs settling."},
{"name": "Contract files", "form": "apps/web/src/contracts/ContractFiles.tsx", "what": "Lists the files the contract covers."},
{"name": "Component relationships", "form": "apps/web/src/contracts/ComponentRelationships.tsx", "what": "Shows how the contract's components relate to each other."},
{"name": "Contract catalog", "form": "apps/web/src/contracts/ContractCatalog.tsx", "what": "Lists the contracts in the catalog."}
]},
{"path": ["bots", "<bot>", "files"], "sentence": "The files this Bot works with: pinned ones, its past chats and its Primary Folder.", "rows": [
{"name": "Pinned files", "form": "apps/web/src/resources/PinnedFiles.tsx", "what": "Opens a pinned file in the file viewer."},
{"name": "Pinned resources", "form": "apps/web/src/resources/PinnedResources.tsx", "what": "Opens a pinned resource in the resource viewer."},
{"name": "Chats folder", "form": "<bot home>/chats/", "what": "Opens the transcripts of this Bot's ended chats."},
{"name": "Primary Folder", "form": "the Bot's Primary Folder, a path under CODEBOT_PROJECT_ROOTS", "what": "Opens the project folder this Bot works in."}
]},
{"path": ["bots", "<bot>", "settings"], "sentence": "This Bot's settings, behind the cog button.", "rows": [
{"name": "Details", "form": "apps/web/src/workspace/BotForm.tsx", "what": "Changes the name, provider, model and Primary Folder of this Bot."},
{"name": "Avatar", "form": "apps/web/src/workspace/AvatarPicker.tsx", "what": "Changes this Bot's avatar, from the avatar parts."},
{"name": "Notifications", "form": "Notifications switch and Enable this device, in this screen", "what": "Turns on notifications for this Bot's replies, approval requests and failures."},
{"name": "Automatic actions", "form": "automatic-action policy, in this screen", "what": "Sets which actions this Bot takes without asking."},
{"name": "Skills", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Attaches the skills this Bot can use, such as codebot-housekeeping."},
{"name": "Widgets", "form": "apps/web/src/widgets/WidgetBrowser.tsx", "what": "Opens the widget browser to add widgets, then arranges them."}
]},
{"path": ["gmail"], "sentence": "Gmail for your Bots: the connected account, what Bots did, and what waits for approval.", "rows": [
{"name": "Access", "form": "apps/web/src/gmail/GmailAccess.tsx", "what": "Shows the Google account Bots use for mail, and sets it."},
{"name": "Activity", "form": "apps/web/src/gmail/GmailActivity.tsx", "what": "Shows what Bots did with Gmail."},
{"name": "Approvals", "form": "apps/web/src/gmail/GmailApprovals.tsx", "what": "Shows Gmail actions waiting for your approval."},
{"name": "Daily", "form": "apps/web/src/gmail/GmailDaily.tsx", "what": "Shows the day's Gmail activity from Bots."}
]},
{"path": ["terminal"], "sentence": "The owner's shell on this computer, in tabs.", "rows": [
{"name": "Shell tabs", "form": "apps/web/src/TerminalTab.tsx and apps/web/src/TerminalPage.tsx", "what": "Opens a shell in a tab on this computer; needs the terminal broker running (Computer > Services)."}
]},
{"path": ["computer"], "sentence": "This computer: its devices, services, family and guest accounts, backups, diagnostics and commands.", "rows": [
{"name": "Devices", "form": "screen: computer > devices", "what": "Opens the devices: the entrance key, the private address and the devices that get notifications."},
{"name": "Family and guest", "form": "screen: computer > family", "what": "Opens the family CodeBots and the guest CodeBot on this computer."},
{"name": "Onboarding", "form": "screen: computer > onboarding", "what": "Opens how a person starts on this computer, and how to start them again."},
{"name": "Services", "form": "screen: computer > services", "what": "Opens the services that run CodeBot here, and the account service."},
{"name": "Experiments", "form": "screen: computer > experiments", "what": "Opens the experimental apps V2, V3 and V4, which run beside CodeBot."},
{"name": "Backup", "form": "screen: computer > backup", "what": "Opens how to back up, restore and stop CodeBot safely."},
{"name": "Diagnostics", "form": "screen: computer > diagnostics", "what": "Opens the checks that show whether CodeBot is up and what it is doing."},
{"name": "Commands", "form": "screen: computer > commands", "what": "Opens the commands that run, build, check, deploy and review CodeBot."},
{"name": "App settings", "form": "apps/web/src/ui/Settings.tsx", "what": "Opens the settings of the app."}
]},
{"path": ["computer", "devices"], "sentence": "The keys, addresses and notification devices that connect your phones and computers to this CodeBot.", "rows": [
{"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Shows the key a new device needs to open CodeBot."},
{"name": "Private address", "form": "tailscale serve status --json", "what": "Shows the private address this CodeBot is published at."},
{"name": "Install on a phone", "form": "ops/OPERATIONS.md, section Connect a device", "what": "Shows the steps to install CodeBot on a phone from its private address."},
{"name": "Change the address", "form": "ops/OPERATIONS.md, section Change this machine's address", "what": "Shows the places to update when the address changes; sign-in breaks until they match."},
{"name": "Notification devices", "form": "Other devices, in any Bot's settings", "what": "Opens the devices that get notifications, to remove old ones."}
]},
{"path": ["computer", "family"], "sentence": "The family CodeBots and the guest CodeBot on this computer.", "rows": [
{"name": "Family status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot, whether it runs, and whether its Gmail can be connected."},
{"name": "Add a family member", "form": "sudo codebot-family add N", "what": "Creates family CodeBot N for a new Google account; at most 6."},
{"name": "Remove a family member", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number; its Google account stays linked."},
{"name": "Guest status", "form": "systemctl status codebot-guest", "what": "Shows whether the guest CodeBot runs, and its recent log lines."},
{"name": "Invite a guest", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google invite link, valid for ten minutes."},
{"name": "Remove the guest", "form": "ops/OPERATIONS.md, section Host a guest on this machine", "what": "Shows the steps that remove the guest's service, user and program; this is destructive."}
]},
{"path": ["computer", "onboarding"], "sentence": "How a person starts on this computer, and how to start them again.", "rows": [
{"name": "Sign-in", "form": "CODEBOT_ACCOUNT_ENTRY_URL, path /onboarding", "what": "Opens the sign-in page, where a person signs in with Google."},
{"name": "First-use tour", "form": "apps/web/src/onboarding/", "what": "Starts at sign-in and creates the first Bot."},
{"name": "Replay the tour", "form": "ops/OPERATIONS.md, section Replay only the first-use tour", "what": "Shows the steps to replay the first-use tour for a person whose host has no Bots."},
{"name": "Restart with a fresh CodeBot", "form": "ops/OPERATIONS.md, section Restart onboarding with a fresh CodeBot", "what": "Shows the steps that wipe the host's Bots and conversations and keep the account; this is destructive."},
{"name": "Full reset", "form": "ops/OPERATIONS.md, section Full reset", "what": "Shows the steps that delete a person's account, data and Bots so they start as new; this is destructive."}
]},
{"path": ["computer", "services"], "sentence": "The services that run CodeBot on this computer, and the account service.", "rows": [
{"name": "CodeBot host", "form": "systemctl --user restart codebot.service", "what": "Runs the host; restart it after an update."},
{"name": "Terminal broker", "form": "ops/codebot-terminal-broker.service", "what": "Runs the per-user broker that opens terminal shells; it stays off until installed."},
{"name": "Family front door", "form": "ops/codebot-family-lobby.service", "what": "Runs the sign-in for family members at the home Wi-Fi address."},
{"name": "Family CodeBots", "form": "ops/codebot-family@.service", "what": "Runs one CodeBot per family member, each as its own user."},
{"name": "Guest CodeBot", "form": "ops/codebot-guest.service", "what": "Runs the guest's own CodeBot on this computer."},
{"name": "Account service", "form": "Supabase project wbgrjvqbupgdclaztuou, dashboard", "what": "Opens the account service: sign-in redirects, users and the SQL editor."}
]},
{"path": ["computer", "experiments"], "sentence": "The experimental apps V2, V3 and V4, which run beside CodeBot in their own repos.", "rows": [
{"name": "V2 Terminal chat", "form": "http://127.0.0.1:3512 (folder ~/projects/codebot-v2-terminal-chat)", "what": "Opens V2 in Chrome; start it first with sh ops/app-run.sh dev in its folder."},
{"name": "V3 Claude Code mod", "form": "http://127.0.0.1:3513 (folder ~/projects/codebot-v3-claude-mod)", "what": "Opens V3 in Chrome; start it first with sh ops/app-run.sh dev in its folder."},
{"name": "V4 Launcher menu", "form": "http://127.0.0.1:3514 (folder ~/projects/codebot-v4-launcher-menu)", "what": "Opens V4 in Chrome; start it first with sh ops/app-run.sh dev in its folder."}
]},
{"path": ["computer", "backup"], "sentence": "How to back up, restore and stop CodeBot safely.", "rows": [
{"name": "Back up", "form": "ops/OPERATIONS.md, section Back up a consistent installation", "what": "Shows the steps to stop the host, copy its data into a private archive, and start it again."},
{"name": "Restore", "form": "ops/OPERATIONS.md, section Restore into a separate directory first", "what": "Shows the steps to check an archive and start a restored copy on port 3508, leaving the original alone."},
{"name": "Emergency stop", "form": "ops/OPERATIONS.md, section Emergency stop and rollback", "what": "Shows the steps to stop the host normally, or kill it when it must stop now."}
]},
{"path": ["computer", "diagnostics"], "sentence": "The checks that show whether CodeBot is up and what it is doing.", "rows": [
{"name": "Session", "form": "/api/session on the host's own address", "what": "Returns whether the host is up; this is the check after a restart."},
{"name": "Host diagnostics", "form": "/api/diagnostics/host on the host's own address", "what": "Shows the migration, queued and running turns, and the recovery hold."},
{"name": "Scheduler diagnostics", "form": "/api/diagnostics/scheduler on the host's own address", "what": "Shows the scheduler's counters and lifecycle state."},
{"name": "Vision diagnostics", "form": "/api/diagnostics/vision on the host's own address", "what": "Shows the Vision counters and lifecycle state."},
{"name": "Notification diagnostics", "form": "/api/notifications/diagnostics on the host's own address", "what": "Shows the notification queue, its timer and the sends in progress."},
{"name": "Host status", "form": "systemctl --user status codebot.service --no-pager", "what": "Shows whether the host is active."},
{"name": "Host log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the host."},
{"name": "Port holder", "form": "ss -ltnp 'sport = :3505'", "what": "Shows which process holds the host's port, 3505."}
]},
{"path": ["computer", "commands"], "sentence": "The commands that run, build, check, deploy and review CodeBot.", "rows": [
{"name": "Run the service (dev)", "form": "npm run dev", "what": "Starts the local service and restarts it when files change."},
{"name": "Run the service", "form": "npm start", "what": "Starts the service in production mode."},
{"name": "Build", "form": "npm run build", "what": "Checks the types, then builds the web app into a new release."},
{"name": "Type check", "form": "npm run typecheck", "what": "Checks the types, without building."},
{"name": "Test", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
{"name": "Check", "form": "npm run check", "what": "Checks the types, then runs the tests."},
{"name": "Build the QA instance", "form": "npm run build:integration", "what": "Builds the integration build used by the QA instance on port 3506."},
{"name": "Set up the account", "form": "npm run setup-account", "what": "Runs the account setup script for this computer."},
{"name": "Regenerate the Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md."},
{"name": "Sync the agent instructions", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."},
{"name": "Gmail review", "form": "npm run review:gmail", "what": "Runs the Gmail review script."},
{"name": "Schedules review", "form": "npm run review:schedules", "what": "Runs the schedules review script."},
{"name": "Playground", "form": "npm run playground", "what": "Opens the Gmail playground in the browser, for design variants."},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, pushes and restarts the host, and waits while a Bot is working."},
{"name": "Guest install", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest's user, service and sudo rules, once."},
{"name": "Guest update", "form": "ops/guest-update.sh", "what": "Rebuilds and restarts the guest CodeBot."},
{"name": "Family install", "form": "sudo ops/family-install.sh", "what": "Sets up the family front door, its helper and sudo rules, once."},
{"name": "Family update", "form": "ops/family-update.sh", "what": "Rebuilds and restarts every family CodeBot."},
{"name": "Schedule drill", "form": "ops/review/schedule-drill.mjs", "what": "Runs the schedule drill script."},
{"name": "Google redirect", "form": "ops/review/redirect-google.mjs", "what": "Runs the Google redirect script."},
{"name": "Seed Gmail", "form": "ops/review/seed-gmail.ts", "what": "Runs the Gmail seed script."},
{"name": "Terminal tabs stack", "form": "ops/review/terminal-tabs-stack.sh", "what": "Runs the terminal tabs stack script."},
{"name": "Check workflow", "form": ".github/workflows/check.yml", "what": "Runs the check workflow on GitHub Actions."},
{"name": "Keepalive workflow", "form": ".github/workflows/supabase-keepalive.yml", "what": "Runs the Supabase keepalive workflow on GitHub Actions."}
]},
{"path": ["docs"], "sentence": "The project's written guides, plans and records.", "rows": [
{"name": "README", "form": "README.md", "what": "Opens the README: what CodeBot is, and how to run and test it."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how CodeBot is built: its boundaries, transcript and providers."},
{"name": "Operations runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for running, backing up, restoring and recovering CodeBot."},
{"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "Opens how Bots use Gmail, with the supervisor guide."},
{"name": "Design method", "form": "docs/design-method.md", "what": "Opens the method for designing and checking screens."},
{"name": "Design taste", "form": "docs/design-taste.md", "what": "Opens the owner's design rulings, and what they rejected."},
{"name": "Objectives", "form": "docs/objectives/README.md", "what": "Opens the goals: chat, the Gmail widget, schedules and terminal tabs."},
{"name": "Plans", "form": "docs/plans/", "what": "Opens the plans and designs, one file per change."},
{"name": "Verification", "form": "docs/verification/", "what": "Opens the recorded evidence that features were checked."},
{"name": "Tasks", "form": "docs/tasks/", "what": "Opens the written tasks and their reports."},
{"name": "Design references", "form": "design/", "what": "Opens the design references and annotated screenshots."},
{"name": "What's new", "form": "apps/web/src/whatsNew.ts", "what": "Opens the list of changes shown once after an update."}
]}
],
"questions": [
"Split Computer into Computer (devices, services, experiments, backup, diagnostics, commands, app settings) and Hosting (family and guest, onboarding)? Recommendation: yes. Computer has nine rows, and Hosting holds the setup work a family or guest needs, not everyday use.",
"Split Commands (24 rows) by job: run, build and check, deploy, review, setup? Recommendation: yes, after the first split. A list this long is hard to scan.",
"Are schedules per Bot (wakeups a Bot takes on its own) or one list for the whole app? Recommendation: per Bot, as a row in Bot settings. No schedules screen is drawn until you answer.",
"Keep process records (.idd/, .bdd/, .plans/, .impeccable/) and agent files (AGENTS.md, CLAUDE.md) off the map? Recommendation: off, since they are for agents rather than the owner. Say if you want any on Docs."
]}
```

No skill · run 3 exit=0 seconds=75 · prompt

P1 Recall: 0.205P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.4P5 Short top: 13P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.104
As terminal help
The start screen: your Bots and which one needs you, with links to everything else.
Open CodeBot (private address)https://liel.tail18e69e.ts.net/Opens the app from a phone, tablet or desktop on your tailnet.
Open CodeBot on this computerhttp://127.0.0.1:3505Opens the running host locally.
Botsthe Bots screenAll your Bots, their state, and which one is waiting for you.
Gmailthe Gmail screenGmail connection, approvals and activity for Bots.
Terminalthe Terminal screenShell tabs on this computer, when the terminal is turned on.
Schedulesthe Schedules screenTimed wakeups for Bots.
Devices and notificationsthe Devices screenAlerts for this device and the phone app.
Widgetsthe widget arrangement on the start screenChoose and order the widgets shown here.
Settingsthe Settings screenTheme, account, avatars and what's new.
Account and onboardingthe Account screenSign-in, the first-use tour and connecting a computer.
Diagnosticsthe Diagnostics screenCounters and lifecycle state for a signed-in owner.
Experimentsthe Experiments screenThe local V2 to V4 experiments, which live in separate repos.
Operationsthe Operations screenOperator-only: check, deploy, back up and host others.
bots
Every Bot on this host, with its provider, what it is doing now, and which one is waiting for you.
A Botthe Bot screen for that BotOpen one Bot's conversation and controls.
New Botthe New Bot formCreate a Bot with a name, provider and home folder.
Questions from Botsthe Questions listAnswer what a Bot asked you.
bots › <bot>
One Bot's conversation: its messages, what it is doing now, the queued messages, and its tools.
Message queuePOST /bots/<bot>/queue/take or /bots/<bot>/queue/send-nowTake queued messages back to edit, or send them now.
Chatsthe Chats screen for this BotThis Bot's chats, each one a topic.
Bot settingsthe Bot settings screen (cog)Provider, model, folder and notifications.
Attachments and recordingsthe Attachments screenFiles, previews, pinned files and recordings.
Vision and screenshotsthe Vision screenLive browser view and the screenshot gallery for this Bot.
Feature contractthe Contract screenThis Bot's contract, its history, diffs and conflicts.
Git quick infothe Git screenRepository status and quick git actions.
Avatarthe Avatar studioPick this Bot's avatar.
bots › <bot> › chats
This Bot's chats in order. A new chat starts when the topic changes, and each has a label and a kind of work.
A chatthe transcript of that chatRead the messages of one chat.
Chat filesthe chats/ folder in the Bot's homeText copies of finished chats, which the Bot reads for earlier work.
bots › <bot> › settings
This Bot's settings, behind one cog: which provider and model it uses, its folder, and its notifications.
Providerfield: codex, claude or opencodeWhich AI provider runs this Bot.
Modelfield: empty means automatic policyPin a model, or leave it empty for a per-message automatic choice.
Primary foldera path under CODEBOT_PROJECT_ROOTSWhere this Bot works.
Notifications switchtoggleTurns on replies, approvals and failure alerts for this Bot.
Enable this devicebutton, then the browser permission promptAllows alerts on this device.
Send testbuttonChecks that the selected device can receive alerts.
gmail
Whether Gmail is connected for Bots, what is waiting for your approval, and what Bots did in Gmail.
Connect Google accountGoogle sign-in via the account service gmail-relay or /api/gmail/oauth/callbackLinks the Google account this host uses.
Approvalsthe Approvals listGmail actions Bots want to take that wait for you.
Activitythe Activity listWhat Bots did in Gmail.
Daily summarythe Daily screenGmail items for the day.
Accessthe Access screenWhat Bots may read or send.
terminal
Shell tabs on this computer. When the per-user terminal broker is not running, it says the terminal is off.
A terminal tabthe Terminal tab screenA shell on this computer.
Claude sessionsthe Claude sessions listClaude Code sessions the terminal can attach to.
devices
Which devices get alerts and sign-in, and how to add the phone app.
Enable this devicebutton in a Bot's settingsSubscribes this browser to alerts.
Reconnect this devicebuttonFixes an expired or rejected subscription.
Other devicesthe Other devices listRemoves old subscriptions; up to 16 are kept.
Install the phone appAdd to Home Screen in the browserInstalls CodeBot on a phone.
Notification diagnostics/api/notifications/diagnostics (signed-in owner)Alert queue, timer and active-send counts.
schedules
Timed wakeups that start Bot work, and whether the scheduler is running.
Create or edit a schedulethe schedule formSet when a Bot wakes up.
Scheduler diagnostics/api/diagnostics/scheduler (signed-in owner)Timers and lifecycle counters.
settings
Host-wide settings: look, your account, avatars, and the list of changes since your last update.
Themetheme settingLight or dark look.
Avatarsthe Avatar studioBuild avatar parts for Bots.
Account profilethe Account screenWho you are on this host.
What's newthe What's new entryThe changes in the latest update, shown once.
account
Who is signed in, how this computer is connected, and the first-use tour.
Sign inhttps://liel.tail18e69e.ts.net/onboardingThe shared sign-in entry; it sends you to your own host.
Connect a new devicethe Device connection screenPairs a phone or another computer with this host.
Entrance keyfile ~/.local/share/codebot/owner-keyKey for connecting a new device. Read it locally and never paste it anywhere.
First-use tourthe First bot screen in onboardingThe guided first Bot.
diagnostics
Counters and state for a signed-in owner. No credentials are shown.
Sessionhttp://127.0.0.1:3505/api/sessionReadiness check; an unsigned response still counts as ready.
Host/api/diagnostics/hostMigration, event cursor, queued and running turns, recovery hold.
Scheduler/api/diagnostics/schedulerTimers and lifecycle state.
Vision/api/diagnostics/visionBrowser capture state.
Notifications/api/notifications/diagnosticsAlert queue and sends.
Recent service logjournalctl --user -u codebot.service -n 80 --no-pagerLast lines of the service log.
experiments
Three local experiments, each in its own private repo and not part of CodeBot. Start one per terminal with sh ops/app-run.sh dev.
V2 Terminal chathttp://127.0.0.1:3512 (folder ~/projects/codebot-v2-terminal-chat)CodeBot's look; a Bot's chat is the Claude Code terminal.
V3 Claude Code modhttp://127.0.0.1:3513 (folder ~/projects/codebot-v3-claude-mod)Claude Code first; a mod draws the Bot list above the prompt.
V4 Launcher menuhttp://127.0.0.1:3514 (folder ~/projects/codebot-v4-launcher-menu)A simple main menu that sets up Claude Code sessions.
operations
Operator-only tasks: check, build, deploy, restart, back up and host other people. Not part of the owner's path.
Check and buildnpm run check; npm run buildType check, tests, then build.
Deploysh ops/deploy.shCommit, push, restart and verify the live service. Waits while a Bot is working.
Service statussystemctl --user status codebot.service --no-pagerWhether the host is running.
Terminal brokersystemctl --user enable --now codebot-terminal-broker.serviceTurns on terminal access for this installation.
Gmail reviewnpm run review:gmailReal-service check of Gmail.
Backup and restorethe Backup screenCopy and verify the whole data directory.
Change this machine's addressthe Address screenThe nine places to update when the machine's name changes.
Reset someone's onboardingthe Onboarding reset screenWays to show onboarding again.
Family CodeBotsthe Family screenOne CodeBot per family member on the home address.
Guest CodeBotthe Guest screenA second CodeBot for one guest, in its own Linux user.
operations › backup
Copy the stopped data directory and config into a private backup, then prove the copy restores before using it.
Make a backupstop codebot.service, tar ~/.local/share/codebot into ~/.local/share/codebot-backups/<UTC time>A consistent copy of state, source and config.
Check and restore to stagingsha256sum -c SHA256SUMS, then extract into a new private staging directoryConfirms the copy is intact before promoting it.
Inspect the restored copyhttp://127.0.0.1:3508 with CODEBOT_RECOVERY_HOLD=1Review it with automatic work held.
Promote the restored copyCODEBOT_DATA_DIR in service.env, then restartMakes the verified copy live. Keep the old data as rollback.
operations › address
The checklist for changing the machine's Tailscale name. It touches nine places and only some are automatic.
Supabase redirect list and Site URLSupabase Authentication, URL ConfigurationGoogle sign-in only returns to allowed addresses.
Owner service settingsCODEBOT_ACCOUNT_ENTRY_URL in ~/.config/codebot/service.env, then rebuild and restartThe host accepts arrivals only from this origin.
Guest service settingsservice.env for codebot-guest, then ops/guest-update.shSame arrival check and the invite link.
Account progress addressesSQL update on public.codebot_account_progress.server_urlSends each person to their own host.
Tailscale serve and guest sharetailscale serve status --jsonOnly changes on a new machine.
Domain forward and phone appsregistrar forward; reinstall the phone app from the new addressPeople start at the forward; installed apps belong to one address.
operations › onboarding-reset
Three ways to show someone onboarding again. Each is manual, and the last deletes their data.
Replay only the first-use tourSQL on codebot_account_progress and delete the first_use_receipts row, with the host stoppedWorks only when the host has no Bots.
Fresh CodeBot, keep the accountwipe the data folder except server-id, server-signing-key and owner-key, then the SQL resetBots and conversations go; the Google link and project folders stay.
Full resetdelete the data folder and the Supabase userAccount, Bots, attachments and recordings are gone.
operations › family
Family CodeBots: one per family member at the home address, each in its own Linux user.
Install the front doorsudo ops/family-install.shSets up the sign-in front door, helper, services and nginx.
Update all family CodeBotsops/family-update.shRebuilds and restarts every family CodeBot.
Add or remove a membersudo codebot-family add N; sudo codebot-family remove NCreates or deletes one member's CodeBot.
Status and logssudo codebot-family status; journalctl -u codebot-family-lobby -u 'codebot-family@*'Whether each family CodeBot is running.
operations › guest
A second CodeBot for one guest on this machine, in its own Linux user with its own Google account.
Installsudo ops/guest-install.shCreates the user, service, settings and sharing.
Updateops/guest-update.shRebuilds and restarts the guest CodeBot.
Invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google link valid for ten minutes.
Statussystemctl status codebot-guestWhether the guest CodeBot is running.
Removesudo systemctl disable --now codebot-guest, then the removal steps in ops/OPERATIONS.mdDeletes the guest's setup. Destructive; do it by hand.
Questions
  • Should operator commands (backup, restore, address change, onboarding reset, family, guest) be in the same help tree as owner screens? Recommendation: keep them under a separate operations branch that the owner's default help does not show, because CLAUDE.md keeps operator work out of the owner's path.
  • Should destructive steps (full reset, guest removal, address change, restore promotion) be runnable commands or documented steps only? Recommendation: documented steps only, with the user doing each one by hand, so nothing destructive runs from a single command.
  • Should the experimental V2 to V4 apps appear in this help tree? Recommendation: keep them in a separate experiments branch, since they are separate repos outside CodeBot and their port rules differ.
  • Which name should the help use for a conversation: 'chat' (the owner's word, used in the product) or 'context epoch' (the internal word)? Recommendation: 'Bot' and 'chat' only, and never 'context epoch'.
  • Should the help ever print the entrance key? Recommendation: no. Show only the file path and tell the user to read it locally.
  • Should the Terminal screen appear when the terminal is off or unavailable (Windows, cloud)? Recommendation: show it with a plain 'off' message on every installation, so the owner can see why it is missing.
  • Gmail and Bot config export and import have plans in docs/plans but no confirmed screens. Should they appear now? Recommendation: leave them out until the code exists.
  • README refers to cli/codebot.py, which is not in the dump. Does a command-line tool already exist that these help screens should match? Recommendation: check whether that file exists before fixing command names; I have used the npm scripts and ops scripts as the command forms here.
As phone screens

Home

The start screen: your Bots and which one needs you, with links to everything else.

Open CodeBot (private address)Opens the app from a phone, tablet or desktop on your tailnet.
›
Open CodeBot on this computerOpens the running host locally.
›
BotsAll your Bots, their state, and which one is waiting for you.
›
GmailGmail connection, approvals and activity for Bots.
›
TerminalShell tabs on this computer, when the terminal is turned on.
›
SchedulesTimed wakeups for Bots.
›
Devices and notificationsAlerts for this device and the phone app.
›
WidgetsChoose and order the widgets shown here.
›
SettingsTheme, account, avatars and what's new.
›
Account and onboardingSign-in, the first-use tour and connecting a computer.
›
DiagnosticsCounters and lifecycle state for a signed-in owner.
›
ExperimentsThe local V2 to V4 experiments, which live in separate repos.
›
OperationsOperator-only: check, deploy, back up and host others.
›
‹ Home

bots

Every Bot on this host, with its provider, what it is doing now, and which one is waiting for you.

A BotOpen one Bot's conversation and controls.
›
New BotCreate a Bot with a name, provider and home folder.
›
Questions from BotsAnswer what a Bot asked you.
›
‹ bots

<bot>

One Bot's conversation: its messages, what it is doing now, the queued messages, and its tools.

Message queueTake queued messages back to edit, or send them now.
›
ChatsThis Bot's chats, each one a topic.
›
Bot settingsProvider, model, folder and notifications.
›
Attachments and recordingsFiles, previews, pinned files and recordings.
›
Vision and screenshotsLive browser view and the screenshot gallery for this Bot.
›
Feature contractThis Bot's contract, its history, diffs and conflicts.
›
Git quick infoRepository status and quick git actions.
›
AvatarPick this Bot's avatar.
›
‹ <bot>

chats

This Bot's chats in order. A new chat starts when the topic changes, and each has a label and a kind of work.

A chatRead the messages of one chat.
›
Chat filesText copies of finished chats, which the Bot reads for earlier work.
›
‹ <bot>

settings

This Bot's settings, behind one cog: which provider and model it uses, its folder, and its notifications.

ProviderWhich AI provider runs this Bot.
›
ModelPin a model, or leave it empty for a per-message automatic choice.
›
Primary folderWhere this Bot works.
›
Notifications switchTurns on replies, approvals and failure alerts for this Bot.
›
Enable this deviceAllows alerts on this device.
›
Send testChecks that the selected device can receive alerts.
›
‹ Home

gmail

Whether Gmail is connected for Bots, what is waiting for your approval, and what Bots did in Gmail.

Connect Google accountLinks the Google account this host uses.
›
ApprovalsGmail actions Bots want to take that wait for you.
›
ActivityWhat Bots did in Gmail.
›
Daily summaryGmail items for the day.
›
AccessWhat Bots may read or send.
›
‹ Home

terminal

Shell tabs on this computer. When the per-user terminal broker is not running, it says the terminal is off.

A terminal tabA shell on this computer.
›
Claude sessionsClaude Code sessions the terminal can attach to.
›
‹ Home

devices

Which devices get alerts and sign-in, and how to add the phone app.

Enable this deviceSubscribes this browser to alerts.
›
Reconnect this deviceFixes an expired or rejected subscription.
›
Other devicesRemoves old subscriptions; up to 16 are kept.
›
Install the phone appInstalls CodeBot on a phone.
›
Notification diagnosticsAlert queue, timer and active-send counts.
›
‹ Home

schedules

Timed wakeups that start Bot work, and whether the scheduler is running.

Create or edit a scheduleSet when a Bot wakes up.
›
Scheduler diagnosticsTimers and lifecycle counters.
›
‹ Home

settings

Host-wide settings: look, your account, avatars, and the list of changes since your last update.

ThemeLight or dark look.
›
AvatarsBuild avatar parts for Bots.
›
Account profileWho you are on this host.
›
What's newThe changes in the latest update, shown once.
›
‹ Home

account

Who is signed in, how this computer is connected, and the first-use tour.

Sign inThe shared sign-in entry; it sends you to your own host.
›
Connect a new devicePairs a phone or another computer with this host.
›
Entrance keyKey for connecting a new device. Read it locally and never paste it anywhere.
›
First-use tourThe guided first Bot.
›
‹ Home

diagnostics

Counters and state for a signed-in owner. No credentials are shown.

SessionReadiness check; an unsigned response still counts as ready.
›
HostMigration, event cursor, queued and running turns, recovery hold.
›
SchedulerTimers and lifecycle state.
›
VisionBrowser capture state.
›
NotificationsAlert queue and sends.
›
Recent service logLast lines of the service log.
›
‹ Home

experiments

Three local experiments, each in its own private repo and not part of CodeBot. Start one per terminal with sh ops/app-run.sh dev.

V2 Terminal chatCodeBot's look; a Bot's chat is the Claude Code terminal.
›
V3 Claude Code modClaude Code first; a mod draws the Bot list above the prompt.
›
V4 Launcher menuA simple main menu that sets up Claude Code sessions.
›
‹ Home

operations

Operator-only tasks: check, build, deploy, restart, back up and host other people. Not part of the owner's path.

Check and buildType check, tests, then build.
›
DeployCommit, push, restart and verify the live service. Waits while a Bot is working.
›
Service statusWhether the host is running.
›
Terminal brokerTurns on terminal access for this installation.
›
Gmail reviewReal-service check of Gmail.
›
Backup and restoreCopy and verify the whole data directory.
›
Change this machine's addressThe nine places to update when the machine's name changes.
›
Reset someone's onboardingWays to show onboarding again.
›
Family CodeBotsOne CodeBot per family member on the home address.
›
Guest CodeBotA second CodeBot for one guest, in its own Linux user.
›
‹ operations

backup

Copy the stopped data directory and config into a private backup, then prove the copy restores before using it.

Make a backupA consistent copy of state, source and config.
›
Check and restore to stagingConfirms the copy is intact before promoting it.
›
Inspect the restored copyReview it with automatic work held.
›
Promote the restored copyMakes the verified copy live. Keep the old data as rollback.
›
‹ operations

address

The checklist for changing the machine's Tailscale name. It touches nine places and only some are automatic.

Supabase redirect list and Site URLGoogle sign-in only returns to allowed addresses.
›
Owner service settingsThe host accepts arrivals only from this origin.
›
Guest service settingsSame arrival check and the invite link.
›
Account progress addressesSends each person to their own host.
›
Tailscale serve and guest shareOnly changes on a new machine.
›
Domain forward and phone appsPeople start at the forward; installed apps belong to one address.
›
‹ operations

onboarding-reset

Three ways to show someone onboarding again. Each is manual, and the last deletes their data.

Replay only the first-use tourWorks only when the host has no Bots.
›
Fresh CodeBot, keep the accountBots and conversations go; the Google link and project folders stay.
›
Full resetAccount, Bots, attachments and recordings are gone.
›
‹ operations

family

Family CodeBots: one per family member at the home address, each in its own Linux user.

Install the front doorSets up the sign-in front door, helper, services and nginx.
›
Update all family CodeBotsRebuilds and restarts every family CodeBot.
›
Add or remove a memberCreates or deletes one member's CodeBot.
›
Status and logsWhether each family CodeBot is running.
›
‹ operations

guest

A second CodeBot for one guest on this machine, in its own Linux user with its own Google account.

InstallCreates the user, service, settings and sharing.
›
UpdateRebuilds and restarts the guest CodeBot.
›
InvitePrints a one-use Google link valid for ten minutes.
›
StatusWhether the guest CodeBot is running.
›
RemoveDeletes the guest's setup. Destructive; do it by hand.
›
Raw answer
I mapped the owner's screens first, then the operator branch, which CLAUDE.md keeps out of the owner's path. Some screens are inferred from file names (for example `GmailDaily.tsx` and `Settings.tsx`), and the dump was cut off partway through `OPERATIONS.md` and `ARCHITECTURE.md`, so a few rows may be missing. The README refers to `cli/codebot.py`, which isn't in the dump, so I couldn't confirm whether a CLI already exists.

```json
{"screens": [
 {"path": [], "sentence": "The start screen: your Bots and which one needs you, with links to everything else.", "rows": [
   {"name": "Open CodeBot (private address)", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the app from a phone, tablet or desktop on your tailnet."},
   {"name": "Open CodeBot on this computer", "form": "http://127.0.0.1:3505", "what": "Opens the running host locally."},
   {"name": "Bots", "form": "the Bots screen", "what": "All your Bots, their state, and which one is waiting for you."},
   {"name": "Gmail", "form": "the Gmail screen", "what": "Gmail connection, approvals and activity for Bots."},
   {"name": "Terminal", "form": "the Terminal screen", "what": "Shell tabs on this computer, when the terminal is turned on."},
   {"name": "Schedules", "form": "the Schedules screen", "what": "Timed wakeups for Bots."},
   {"name": "Devices and notifications", "form": "the Devices screen", "what": "Alerts for this device and the phone app."},
   {"name": "Widgets", "form": "the widget arrangement on the start screen", "what": "Choose and order the widgets shown here."},
   {"name": "Settings", "form": "the Settings screen", "what": "Theme, account, avatars and what's new."},
   {"name": "Account and onboarding", "form": "the Account screen", "what": "Sign-in, the first-use tour and connecting a computer."},
   {"name": "Diagnostics", "form": "the Diagnostics screen", "what": "Counters and lifecycle state for a signed-in owner."},
   {"name": "Experiments", "form": "the Experiments screen", "what": "The local V2 to V4 experiments, which live in separate repos."},
   {"name": "Operations", "form": "the Operations screen", "what": "Operator-only: check, deploy, back up and host others."}
 ], "questions": []},
 {"path": ["bots"], "sentence": "Every Bot on this host, with its provider, what it is doing now, and which one is waiting for you.", "rows": [
   {"name": "A Bot", "form": "the Bot screen for that Bot", "what": "Open one Bot's conversation and controls."},
   {"name": "New Bot", "form": "the New Bot form", "what": "Create a Bot with a name, provider and home folder."},
   {"name": "Questions from Bots", "form": "the Questions list", "what": "Answer what a Bot asked you."}
 ]},
 {"path": ["bots", "<bot>"], "sentence": "One Bot's conversation: its messages, what it is doing now, the queued messages, and its tools.", "rows": [
   {"name": "Message queue", "form": "POST /bots/<bot>/queue/take or /bots/<bot>/queue/send-now", "what": "Take queued messages back to edit, or send them now."},
   {"name": "Chats", "form": "the Chats screen for this Bot", "what": "This Bot's chats, each one a topic."},
   {"name": "Bot settings", "form": "the Bot settings screen (cog)", "what": "Provider, model, folder and notifications."},
   {"name": "Attachments and recordings", "form": "the Attachments screen", "what": "Files, previews, pinned files and recordings."},
   {"name": "Vision and screenshots", "form": "the Vision screen", "what": "Live browser view and the screenshot gallery for this Bot."},
   {"name": "Feature contract", "form": "the Contract screen", "what": "This Bot's contract, its history, diffs and conflicts."},
   {"name": "Git quick info", "form": "the Git screen", "what": "Repository status and quick git actions."},
   {"name": "Avatar", "form": "the Avatar studio", "what": "Pick this Bot's avatar."}
 ]},
 {"path": ["bots", "<bot>", "chats"], "sentence": "This Bot's chats in order. A new chat starts when the topic changes, and each has a label and a kind of work.", "rows": [
   {"name": "A chat", "form": "the transcript of that chat", "what": "Read the messages of one chat."},
   {"name": "Chat files", "form": "the chats/ folder in the Bot's home", "what": "Text copies of finished chats, which the Bot reads for earlier work."}
 ]},
 {"path": ["bots", "<bot>", "settings"], "sentence": "This Bot's settings, behind one cog: which provider and model it uses, its folder, and its notifications.", "rows": [
   {"name": "Provider", "form": "field: codex, claude or opencode", "what": "Which AI provider runs this Bot."},
   {"name": "Model", "form": "field: empty means automatic policy", "what": "Pin a model, or leave it empty for a per-message automatic choice."},
   {"name": "Primary folder", "form": "a path under CODEBOT_PROJECT_ROOTS", "what": "Where this Bot works."},
   {"name": "Notifications switch", "form": "toggle", "what": "Turns on replies, approvals and failure alerts for this Bot."},
   {"name": "Enable this device", "form": "button, then the browser permission prompt", "what": "Allows alerts on this device."},
   {"name": "Send test", "form": "button", "what": "Checks that the selected device can receive alerts."}
 ]},
 {"path": ["gmail"], "sentence": "Whether Gmail is connected for Bots, what is waiting for your approval, and what Bots did in Gmail.", "rows": [
   {"name": "Connect Google account", "form": "Google sign-in via the account service gmail-relay or /api/gmail/oauth/callback", "what": "Links the Google account this host uses."},
   {"name": "Approvals", "form": "the Approvals list", "what": "Gmail actions Bots want to take that wait for you."},
   {"name": "Activity", "form": "the Activity list", "what": "What Bots did in Gmail."},
   {"name": "Daily summary", "form": "the Daily screen", "what": "Gmail items for the day."},
   {"name": "Access", "form": "the Access screen", "what": "What Bots may read or send."}
 ]},
 {"path": ["terminal"], "sentence": "Shell tabs on this computer. When the per-user terminal broker is not running, it says the terminal is off.", "rows": [
   {"name": "A terminal tab", "form": "the Terminal tab screen", "what": "A shell on this computer."},
   {"name": "Claude sessions", "form": "the Claude sessions list", "what": "Claude Code sessions the terminal can attach to."}
 ]},
 {"path": ["devices"], "sentence": "Which devices get alerts and sign-in, and how to add the phone app.", "rows": [
   {"name": "Enable this device", "form": "button in a Bot's settings", "what": "Subscribes this browser to alerts."},
   {"name": "Reconnect this device", "form": "button", "what": "Fixes an expired or rejected subscription."},
   {"name": "Other devices", "form": "the Other devices list", "what": "Removes old subscriptions; up to 16 are kept."},
   {"name": "Install the phone app", "form": "Add to Home Screen in the browser", "what": "Installs CodeBot on a phone."},
   {"name": "Notification diagnostics", "form": "/api/notifications/diagnostics (signed-in owner)", "what": "Alert queue, timer and active-send counts."}
 ]},
 {"path": ["schedules"], "sentence": "Timed wakeups that start Bot work, and whether the scheduler is running.", "rows": [
   {"name": "Create or edit a schedule", "form": "the schedule form", "what": "Set when a Bot wakes up."},
   {"name": "Scheduler diagnostics", "form": "/api/diagnostics/scheduler (signed-in owner)", "what": "Timers and lifecycle counters."}
 ]},
 {"path": ["settings"], "sentence": "Host-wide settings: look, your account, avatars, and the list of changes since your last update.", "rows": [
   {"name": "Theme", "form": "theme setting", "what": "Light or dark look."},
   {"name": "Avatars", "form": "the Avatar studio", "what": "Build avatar parts for Bots."},
   {"name": "Account profile", "form": "the Account screen", "what": "Who you are on this host."},
   {"name": "What's new", "form": "the What's new entry", "what": "The changes in the latest update, shown once."}
 ]},
 {"path": ["account"], "sentence": "Who is signed in, how this computer is connected, and the first-use tour.", "rows": [
   {"name": "Sign in", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "The shared sign-in entry; it sends you to your own host."},
   {"name": "Connect a new device", "form": "the Device connection screen", "what": "Pairs a phone or another computer with this host."},
   {"name": "Entrance key", "form": "file ~/.local/share/codebot/owner-key", "what": "Key for connecting a new device. Read it locally and never paste it anywhere."},
   {"name": "First-use tour", "form": "the First bot screen in onboarding", "what": "The guided first Bot."}
 ]},
 {"path": ["diagnostics"], "sentence": "Counters and state for a signed-in owner. No credentials are shown.", "rows": [
   {"name": "Session", "form": "http://127.0.0.1:3505/api/session", "what": "Readiness check; an unsigned response still counts as ready."},
   {"name": "Host", "form": "/api/diagnostics/host", "what": "Migration, event cursor, queued and running turns, recovery hold."},
   {"name": "Scheduler", "form": "/api/diagnostics/scheduler", "what": "Timers and lifecycle state."},
   {"name": "Vision", "form": "/api/diagnostics/vision", "what": "Browser capture state."},
   {"name": "Notifications", "form": "/api/notifications/diagnostics", "what": "Alert queue and sends."},
   {"name": "Recent service log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Last lines of the service log."}
 ]},
 {"path": ["experiments"], "sentence": "Three local experiments, each in its own private repo and not part of CodeBot. Start one per terminal with sh ops/app-run.sh dev.", "rows": [
   {"name": "V2 Terminal chat", "form": "http://127.0.0.1:3512 (folder ~/projects/codebot-v2-terminal-chat)", "what": "CodeBot's look; a Bot's chat is the Claude Code terminal."},
   {"name": "V3 Claude Code mod", "form": "http://127.0.0.1:3513 (folder ~/projects/codebot-v3-claude-mod)", "what": "Claude Code first; a mod draws the Bot list above the prompt."},
   {"name": "V4 Launcher menu", "form": "http://127.0.0.1:3514 (folder ~/projects/codebot-v4-launcher-menu)", "what": "A simple main menu that sets up Claude Code sessions."}
 ]},
 {"path": ["operations"], "sentence": "Operator-only tasks: check, build, deploy, restart, back up and host other people. Not part of the owner's path.", "rows": [
   {"name": "Check and build", "form": "npm run check; npm run build", "what": "Type check, tests, then build."},
   {"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Commit, push, restart and verify the live service. Waits while a Bot is working."},
   {"name": "Service status", "form": "systemctl --user status codebot.service --no-pager", "what": "Whether the host is running."},
   {"name": "Terminal broker", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "Turns on terminal access for this installation."},
   {"name": "Gmail review", "form": "npm run review:gmail", "what": "Real-service check of Gmail."},
   {"name": "Backup and restore", "form": "the Backup screen", "what": "Copy and verify the whole data directory."},
   {"name": "Change this machine's address", "form": "the Address screen", "what": "The nine places to update when the machine's name changes."},
   {"name": "Reset someone's onboarding", "form": "the Onboarding reset screen", "what": "Ways to show onboarding again."},
   {"name": "Family CodeBots", "form": "the Family screen", "what": "One CodeBot per family member on the home address."},
   {"name": "Guest CodeBot", "form": "the Guest screen", "what": "A second CodeBot for one guest, in its own Linux user."}
 ], "questions": []},
 {"path": ["operations", "backup"], "sentence": "Copy the stopped data directory and config into a private backup, then prove the copy restores before using it.", "rows": [
   {"name": "Make a backup", "form": "stop codebot.service, tar ~/.local/share/codebot into ~/.local/share/codebot-backups/<UTC time>", "what": "A consistent copy of state, source and config."},
   {"name": "Check and restore to staging", "form": "sha256sum -c SHA256SUMS, then extract into a new private staging directory", "what": "Confirms the copy is intact before promoting it."},
   {"name": "Inspect the restored copy", "form": "http://127.0.0.1:3508 with CODEBOT_RECOVERY_HOLD=1", "what": "Review it with automatic work held."},
   {"name": "Promote the restored copy", "form": "CODEBOT_DATA_DIR in service.env, then restart", "what": "Makes the verified copy live. Keep the old data as rollback."}
 ]},
 {"path": ["operations", "address"], "sentence": "The checklist for changing the machine's Tailscale name. It touches nine places and only some are automatic.", "rows": [
   {"name": "Supabase redirect list and Site URL", "form": "Supabase Authentication, URL Configuration", "what": "Google sign-in only returns to allowed addresses."},
   {"name": "Owner service settings", "form": "CODEBOT_ACCOUNT_ENTRY_URL in ~/.config/codebot/service.env, then rebuild and restart", "what": "The host accepts arrivals only from this origin."},
   {"name": "Guest service settings", "form": "service.env for codebot-guest, then ops/guest-update.sh", "what": "Same arrival check and the invite link."},
   {"name": "Account progress addresses", "form": "SQL update on public.codebot_account_progress.server_url", "what": "Sends each person to their own host."},
   {"name": "Tailscale serve and guest share", "form": "tailscale serve status --json", "what": "Only changes on a new machine."},
   {"name": "Domain forward and phone apps", "form": "registrar forward; reinstall the phone app from the new address", "what": "People start at the forward; installed apps belong to one address."}
 ]},
 {"path": ["operations", "onboarding-reset"], "sentence": "Three ways to show someone onboarding again. Each is manual, and the last deletes their data.", "rows": [
   {"name": "Replay only the first-use tour", "form": "SQL on codebot_account_progress and delete the first_use_receipts row, with the host stopped", "what": "Works only when the host has no Bots."},
   {"name": "Fresh CodeBot, keep the account", "form": "wipe the data folder except server-id, server-signing-key and owner-key, then the SQL reset", "what": "Bots and conversations go; the Google link and project folders stay."},
   {"name": "Full reset", "form": "delete the data folder and the Supabase user", "what": "Account, Bots, attachments and recordings are gone."}
 ]},
 {"path": ["operations", "family"], "sentence": "Family CodeBots: one per family member at the home address, each in its own Linux user.", "rows": [
   {"name": "Install the front door", "form": "sudo ops/family-install.sh", "what": "Sets up the sign-in front door, helper, services and nginx."},
   {"name": "Update all family CodeBots", "form": "ops/family-update.sh", "what": "Rebuilds and restarts every family CodeBot."},
   {"name": "Add or remove a member", "form": "sudo codebot-family add N; sudo codebot-family remove N", "what": "Creates or deletes one member's CodeBot."},
   {"name": "Status and logs", "form": "sudo codebot-family status; journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Whether each family CodeBot is running."}
 ]},
 {"path": ["operations", "guest"], "sentence": "A second CodeBot for one guest on this machine, in its own Linux user with its own Google account.", "rows": [
   {"name": "Install", "form": "sudo ops/guest-install.sh", "what": "Creates the user, service, settings and sharing."},
   {"name": "Update", "form": "ops/guest-update.sh", "what": "Rebuilds and restarts the guest CodeBot."},
   {"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google link valid for ten minutes."},
   {"name": "Status", "form": "systemctl status codebot-guest", "what": "Whether the guest CodeBot is running."},
   {"name": "Remove", "form": "sudo systemctl disable --now codebot-guest, then the removal steps in ops/OPERATIONS.md", "what": "Deletes the guest's setup. Destructive; do it by hand."}
 ]}
],
"questions": [
 "Should operator commands (backup, restore, address change, onboarding reset, family, guest) be in the same help tree as owner screens? Recommendation: keep them under a separate operations branch that the owner's default help does not show, because CLAUDE.md keeps operator work out of the owner's path.",
 "Should destructive steps (full reset, guest removal, address change, restore promotion) be runnable commands or documented steps only? Recommendation: documented steps only, with the user doing each one by hand, so nothing destructive runs from a single command.",
 "Should the experimental V2 to V4 apps appear in this help tree? Recommendation: keep them in a separate experiments branch, since they are separate repos outside CodeBot and their port rules differ.",
 "Which name should the help use for a conversation: 'chat' (the owner's word, used in the product) or 'context epoch' (the internal word)? Recommendation: 'Bot' and 'chat' only, and never 'context epoch'.",
 "Should the help ever print the entrance key? Recommendation: no. Show only the file path and tell the user to read it locally.",
 "Should the Terminal screen appear when the terminal is off or unavailable (Windows, cloud)? Recommendation: show it with a plain 'off' message on every installation, so the owner can see why it is missing.",
 "Gmail and Bot config export and import have plans in docs/plans but no confirmed screens. Should they appear now? Recommendation: leave them out until the code exists.",
 "README refers to cli/codebot.py, which is not in the dump. Does a command-line tool already exist that these help screens should match? Recommendation: check whether that file exists before fixing command names; I have used the npm scripts and ops scripts as the command forms here."
]}
```

Today's skills · run 3 exit=0 seconds=91 · prompt

P1 Recall: 0.333P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.988P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.576
As terminal help
Everything you can run, check, open or reach for this project, grouped by the job it does.
Run the hostcodebot runPrints the run screen: start, stop, update and read the host.
Check the codecodebot checkPrints the check screen: the type check, build, tests and reviews.
Open thingscodebot openPrints the open screen: the app, the documents, the folders and the settings files.
Back up and restorecodebot backupPrints the backup screen: the copy and restore procedures and where backups are kept.
Other peoplecodebot peoplePrints the people screen: the guest account and the family CodeBots.
Experimental appscodebot appsPrints the apps screen: the three experimental apps, their ports and how to start them.
Account service and addressescodebot accountPrints the account screen: the sign-in service, its deploy, and the steps that depend on this machine's name.
run
The CodeBot host on this machine: start it for development, or manage the installed copy.
Start the host for developmentnpm run devStarts the host in watch mode on port 3505; stop the installed host first, since the port is shared.
Restart the installed hostsystemctl --user restart codebot.serviceRestarts the installed host after a build, once active work has finished.
Stop the installed hostsystemctl --user stop codebot.serviceStops the installed host and interrupts its running Bot turns.
Show the installed host's statussystemctl --user status codebot.service --no-pagerShows whether the installed host is running and when it started.
Read the installed host's logjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the installed host.
Check the host answerscurl --fail --silent http://127.0.0.1:3505/api/sessionChecks that the host answers on its port; an error means it is not running.
Update the hostsh ops/deploy.shBuilds, pushes and restarts the host, and refuses while a Bot is working.
Open the host's diagnosticshttp://127.0.0.1:3505/api/diagnostics/hostOpens the host's counters as JSON; needs a browser already signed in.
Show the terminal brokersystemctl --user status codebot-terminal-broker.service --no-pagerShows whether the terminal broker, which gives a shell to the owner, is running.
check
The checks that show the code still compiles, builds and passes its tests and reviews.
Type checknpm run typecheckRuns the TypeScript check, which compiles the code without building it.
Buildnpm run buildType-checks, then builds the web app and publishes a new release.
Run the testsnpm testRuns the Gmail tests against a fake Google server.
Type check and testsnpm run checkRuns the type check and the tests together.
Regenerate the Gmail referencenpm run docs:gmailRegenerates docs/automation/gmail-reference.md from its source.
Review Gmailnpm run review:gmailRuns the Gmail review script against the running service.
Review schedulesnpm run review:schedulesRuns the schedules review script against the running service.
Regenerate the agents filenpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
open
Where to look: the running app, the documents, the folders and the settings files.
The app on this computerhttp://127.0.0.1:3505Opens CodeBot in a browser on this computer.
The app over Tailscalehttps://liel.tail18e69e.ts.net/Opens CodeBot on a phone or another device over the private address.
The design playgroundnpm run playgroundStarts the Vite playground and opens the Gmail widget variants in a browser.
The documentscodebot open docsPrints the documents screen: where each project document is.
The host data folder~/.local/share/codebotOpens the data folder with the database, attachments and recordings; handle it with care.
The host settings file~/.config/codebot/service.envOpens the private settings file; it holds secrets, so do not paste it anywhere.
The allowed project folders~/projectsOpens the folders Bots may reach; widening them grants real file access.
The settings templateops/environment.exampleOpens the template for the settings file, with each setting explained.
The installed service file~/.config/systemd/user/codebot.serviceOpens the service file that starts the host.
open › docs
The documents that describe this project, from how to run it to how it is built.
Project overviewREADME.mdOpens the overview, how to run it and how the pieces fit.
Runbookops/OPERATIONS.mdOpens the runbook for running, recovering, backing up and moving the host.
ArchitectureARCHITECTURE.mdOpens how the pieces are built and the rules they keep.
Product behaviourPRODUCT-SPEC.mdOpens the behaviour contract the product must meet.
Open workDEFERRED-WORK.mdOpens the remaining checklist and the safe restart state.
Owner rules for agentsCLAUDE.mdOpens the fundamentals every task assumes and the screen design rules.
Gmail for Botsdocs/automation/gmail.mdOpens the guide for connecting Gmail to Bots.
Design tastedocs/design-taste.mdOpens the owner's rulings on screens: what was accepted and what was rejected.
backup
The procedures that copy the host's data somewhere safe and bring it back.
Back up the hostops/OPERATIONS.md (Back up a consistent installation)Opens the backup steps; they stop the host while the copy is made.
Restore a backupops/OPERATIONS.md (Restore into a separate directory first)Opens the restore steps, which restore into a separate folder first.
The backup folder~/.local/share/codebot-backupsOpens the folder where timestamped backups are kept, if any exist yet.
Verify a backupsha256sum -c SHA256SUMSChecks a backup's files against their recorded checksums; run it inside the backup folder.
people
Other people who use CodeBot on this machine: a guest account and the family CodeBots.
Guestcodebot people guestPrints the guest screen: the second CodeBot for one other person.
Familycodebot people familyPrints the family screen: the family CodeBots, their address and Gmail status.
people › guest
The guest CodeBot: its own Linux user and service, reached by an invite over Tailscale.
Guest statussystemctl status codebot-guestShows whether the guest host is running.
Guest logjournalctl -u codebot-guestPrints the guest host's log.
Guest processesps -u codebot-guestLists what the guest's user is running.
Guest disk usesudo du -sh /home/codebot-guestMeasures how much space the guest's data takes.
Invite the guestsudo -u codebot-guest /opt/codebot-guest/inviteCreates a one-use Google sign-in link, valid for ten minutes.
Update the guestops/guest-update.shBuilds, replaces and restarts the guest host; needs no password.
Set up the guestsudo ops/guest-install.shCreates the guest user, service, settings and sudo rules; run once.
The guest's addresshttps://liel.tail18e69e.ts.net:10000Opens the guest's CodeBot in a browser.
Remove the guestops/OPERATIONS.md (Host a guest on this machine)Opens the steps that remove the guest completely; this command does not run them.
Restart the guest's onboardingops/OPERATIONS.md (Restart onboarding with a fresh CodeBot)Opens the steps that give the guest a fresh CodeBot, keeping the account.
people › family
The family CodeBots on the home Wi-Fi address: one per family member, each with its own user and port.
The family addresshttps://family.codebot.lielbenor.comOpens the family sign-in page on the home address.
Family statussudo codebot-family statusLists each family CodeBot, whether it runs, and whether Gmail can connect.
Add a family membersudo codebot-family add NCreates a family CodeBot in slot N; at most six.
Remove a family membersudo codebot-family remove NDeletes family CodeBot N and frees its slot; its Google account cannot be linked again.
Stop all family CodeBotssudo codebot-family stop-allStops every family CodeBot.
Start all family CodeBotssudo codebot-family start-allStarts every family CodeBot.
Family logjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the logs of the front door and every family CodeBot.
Update the familyops/family-update.shBuilds and restarts every family CodeBot; needs no password.
Set up the familysudo ops/family-install.shCreates the front door, helper, services, sudo rules and nginx; run once.
Address, certificate and removalops/OPERATIONS.md (Home Wi-Fi address)Opens the address, certificate and removal steps for the home address.
apps
The three experimental apps on this computer; each has its own folder, port and data, separate from CodeBot.
V2 Terminal chat: startcd ~/projects/codebot-v2-terminal-chat && sh ops/app-run.sh devStarts V2 on port 3512 in this terminal.
V2 Terminal chat: openhttp://127.0.0.1:3512Opens V2 in Chrome.
V3 Claude Code mod: startcd ~/projects/codebot-v3-claude-mod && sh ops/app-run.sh devStarts V3 on port 3513 in this terminal.
V3 Claude Code mod: openhttp://127.0.0.1:3513Opens V3 in Chrome.
V4 Launcher menu: startcd ~/projects/codebot-v4-launcher-menu && sh ops/app-run.sh devStarts V4 on port 3514 in this terminal.
V4 Launcher menu: openhttp://127.0.0.1:3514Opens V4 in Chrome.
Find an app's processss -ltnp 'sport = :3513'Shows the one process that holds an app's port, so only that one is stopped.
List V3's background sessionsclaude agentsLists the V3 background Claude sessions and their ids.
Stop a V3 background sessionclaude stop <id>Stops one V3 background session, using an id from the list.
account
The central account service (Supabase) and what depends on this machine's name.
Account service dashboardhttps://supabase.com/dashboard/project/wbgrjvqbupgdclaztuouOpens the Supabase project for CodeBot's account service.
The account service token~/.config/supabase-codebot-tokenOpens the token file the CLI uses; keep it private and never paste it.
Deploy the host-access functionnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou (reads the token file)Deploys host-access to the account service; needed when a parsed contract changes, and it is outward-facing, so confirm first.
Operator account setupnpm run setup-accountRuns the operator setup script for the account service.
Account database migrationssupabase/migrationsOpens the account database's migration files, in order.
Change this machine's addressops/OPERATIONS.md (Change this machine's address)Opens the checklist of every place that must change for a new machine name.
Reset someone's onboardingops/OPERATIONS.md (Reset someone's onboarding)Opens the procedures to replay or reset a person's onboarding.
Questions
  • Facade name: use codebot, with cb as a short alias? Recommendation: yes, if cb clashes with nothing (check with whence -a).
  • The README mentions cli/codebot.py, which is not in the dump's file list. Does it exist, and does it already cover part of this map? Recommendation: check before building; if it exists, wrap it rather than write a second one.
  • Family removal (sudo codebot-family remove N): wire it as a thin command with a typed-slot confirmation? Recommendation: yes. Keep guest removal as docs only, since it takes several steps.
  • Deploy (sh ops/deploy.sh) and the Supabase host-access deploy are outward-facing. Should each run only after an explicit confirmation? Recommendation: yes for both; deploy already refuses while a Bot is working.
  • Backup: wire it as a codebot backup command later? Recommendation: not yet. It stops the host, so it should be a worker task with the intent recorded first; keep it as a doc row until then.
As phone screens

Home

Everything you can run, check, open or reach for this project, grouped by the job it does.

Run the hostPrints the run screen: start, stop, update and read the host.
›
Check the codePrints the check screen: the type check, build, tests and reviews.
›
Open thingsPrints the open screen: the app, the documents, the folders and the settings files.
›
Back up and restorePrints the backup screen: the copy and restore procedures and where backups are kept.
›
Other peoplePrints the people screen: the guest account and the family CodeBots.
›
Experimental appsPrints the apps screen: the three experimental apps, their ports and how to start them.
›
Account service and addressesPrints the account screen: the sign-in service, its deploy, and the steps that depend on this machine's name.
›
‹ Home

run

The CodeBot host on this machine: start it for development, or manage the installed copy.

Start the host for developmentStarts the host in watch mode on port 3505; stop the installed host first, since the port is shared.
›
Restart the installed hostRestarts the installed host after a build, once active work has finished.
›
Stop the installed hostStops the installed host and interrupts its running Bot turns.
›
Show the installed host's statusShows whether the installed host is running and when it started.
›
Read the installed host's logPrints the last 80 log lines of the installed host.
›
Check the host answersChecks that the host answers on its port; an error means it is not running.
›
Update the hostBuilds, pushes and restarts the host, and refuses while a Bot is working.
›
Open the host's diagnosticsOpens the host's counters as JSON; needs a browser already signed in.
›
Show the terminal brokerShows whether the terminal broker, which gives a shell to the owner, is running.
›
‹ Home

check

The checks that show the code still compiles, builds and passes its tests and reviews.

Type checkRuns the TypeScript check, which compiles the code without building it.
›
BuildType-checks, then builds the web app and publishes a new release.
›
Run the testsRuns the Gmail tests against a fake Google server.
›
Type check and testsRuns the type check and the tests together.
›
Regenerate the Gmail referenceRegenerates docs/automation/gmail-reference.md from its source.
›
Review GmailRuns the Gmail review script against the running service.
›
Review schedulesRuns the schedules review script against the running service.
›
Regenerate the agents fileRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
›
‹ Home

open

Where to look: the running app, the documents, the folders and the settings files.

The app on this computerOpens CodeBot in a browser on this computer.
›
The app over TailscaleOpens CodeBot on a phone or another device over the private address.
›
The design playgroundStarts the Vite playground and opens the Gmail widget variants in a browser.
›
The documentsPrints the documents screen: where each project document is.
›
The host data folderOpens the data folder with the database, attachments and recordings; handle it with care.
›
The host settings fileOpens the private settings file; it holds secrets, so do not paste it anywhere.
›
The allowed project foldersOpens the folders Bots may reach; widening them grants real file access.
›
The settings templateOpens the template for the settings file, with each setting explained.
›
The installed service fileOpens the service file that starts the host.
›
‹ open

docs

The documents that describe this project, from how to run it to how it is built.

Project overviewOpens the overview, how to run it and how the pieces fit.
›
RunbookOpens the runbook for running, recovering, backing up and moving the host.
›
ArchitectureOpens how the pieces are built and the rules they keep.
›
Product behaviourOpens the behaviour contract the product must meet.
›
Open workOpens the remaining checklist and the safe restart state.
›
Owner rules for agentsOpens the fundamentals every task assumes and the screen design rules.
›
Gmail for BotsOpens the guide for connecting Gmail to Bots.
›
Design tasteOpens the owner's rulings on screens: what was accepted and what was rejected.
›
‹ Home

backup

The procedures that copy the host's data somewhere safe and bring it back.

Back up the hostOpens the backup steps; they stop the host while the copy is made.
›
Restore a backupOpens the restore steps, which restore into a separate folder first.
›
The backup folderOpens the folder where timestamped backups are kept, if any exist yet.
›
Verify a backupChecks a backup's files against their recorded checksums; run it inside the backup folder.
›
‹ Home

people

Other people who use CodeBot on this machine: a guest account and the family CodeBots.

GuestPrints the guest screen: the second CodeBot for one other person.
›
FamilyPrints the family screen: the family CodeBots, their address and Gmail status.
›
‹ people

guest

The guest CodeBot: its own Linux user and service, reached by an invite over Tailscale.

Guest statusShows whether the guest host is running.
›
Guest logPrints the guest host's log.
›
Guest processesLists what the guest's user is running.
›
Guest disk useMeasures how much space the guest's data takes.
›
Invite the guestCreates a one-use Google sign-in link, valid for ten minutes.
›
Update the guestBuilds, replaces and restarts the guest host; needs no password.
›
Set up the guestCreates the guest user, service, settings and sudo rules; run once.
›
The guest's addressOpens the guest's CodeBot in a browser.
›
Remove the guestOpens the steps that remove the guest completely; this command does not run them.
›
Restart the guest's onboardingOpens the steps that give the guest a fresh CodeBot, keeping the account.
›
‹ people

family

The family CodeBots on the home Wi-Fi address: one per family member, each with its own user and port.

The family addressOpens the family sign-in page on the home address.
›
Family statusLists each family CodeBot, whether it runs, and whether Gmail can connect.
›
Add a family memberCreates a family CodeBot in slot N; at most six.
›
Remove a family memberDeletes family CodeBot N and frees its slot; its Google account cannot be linked again.
›
Stop all family CodeBotsStops every family CodeBot.
›
Start all family CodeBotsStarts every family CodeBot.
›
Family logPrints the logs of the front door and every family CodeBot.
›
Update the familyBuilds and restarts every family CodeBot; needs no password.
›
Set up the familyCreates the front door, helper, services, sudo rules and nginx; run once.
›
Address, certificate and removalOpens the address, certificate and removal steps for the home address.
›
‹ Home

apps

The three experimental apps on this computer; each has its own folder, port and data, separate from CodeBot.

V2 Terminal chat: startStarts V2 on port 3512 in this terminal.
›
V2 Terminal chat: openOpens V2 in Chrome.
›
V3 Claude Code mod: startStarts V3 on port 3513 in this terminal.
›
V3 Claude Code mod: openOpens V3 in Chrome.
›
V4 Launcher menu: startStarts V4 on port 3514 in this terminal.
›
V4 Launcher menu: openOpens V4 in Chrome.
›
Find an app's processShows the one process that holds an app's port, so only that one is stopped.
›
List V3's background sessionsLists the V3 background Claude sessions and their ids.
›
Stop a V3 background sessionStops one V3 background session, using an id from the list.
›
‹ Home

account

The central account service (Supabase) and what depends on this machine's name.

Account service dashboardOpens the Supabase project for CodeBot's account service.
›
The account service tokenOpens the token file the CLI uses; keep it private and never paste it.
›
Deploy the host-access functionDeploys host-access to the account service; needed when a parsed contract changes, and it is outward-facing, so confirm first.
›
Operator account setupRuns the operator setup script for the account service.
›
Account database migrationsOpens the account database's migration files, in order.
›
Change this machine's addressOpens the checklist of every place that must change for a new machine name.
›
Reset someone's onboardingOpens the procedures to replay or reset a person's onboarding.
›
Raw answer
## Planning notes

**Scenario (reasoning from the docs, not observed use):** The owner works on this machine. After a change they restart the installed host and check that it came up. Later they check on a guest or family CodeBot, or open CodeBot from a phone. They also need the runbook for backups and removals, which stop or delete things and so should be read, not run by accident.

**Judgment calls:**
- **Seven top-level groups, grouped by job:** run, check, open, backup, people, apps, account. Each is a noun the owner would use.
- **Two ways to start the host:** `npm run dev` and the installed systemd service both use port 3505. The map shows both, and the dev row says to stop the installed one first. `npm start` is left out because it would collide with the same port.
- **Procedures that stop or delete things are doc rows**, with the runbook as the form: backup, restore, guest removal, the address change, and onboarding resets. They are not thin commands yet.
- **Force-kill is left out of the map.** The runbook says it can lose unfinished recordings, so it stays there.
- **`sudo` rows** need a password, and the `*-update.sh` rows do not.

**Gaps to check at build time:** The file list in the dump is truncated. These are referenced but not confirmed in the dump: `ops/deploy.sh`, `ops/family-helper.sh`, `ops/terminal-broker.ts`, `ops/setup-account.ts`, `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md`, and `cli/codebot.py`. Every form has to be checked against the real tree before the help is built.

**Decisions for you** (also in the JSON `questions`):
1. Facade name: `codebot`, with `cb` as an alias? I recommend it if `cb` is free.
2. The README mentions `cli/codebot.py`. Does it exist and already do part of this? If so, wrap it rather than duplicate it.
3. Remove commands: wire `family remove N` with a typed-slot confirmation? I recommend yes. Keep guest removal as docs only, since it is multi-step.
4. Deploy and the Supabase function deploy are outward-facing. Should the first run only after a confirmation? I recommend yes for the Supabase deploy.
5. Backup: wire it as `codebot backup` later? I recommend keeping it a doc row for now, since the backup stops the host.

```json
{"screens": [
{"path": [], "sentence": "Everything you can run, check, open or reach for this project, grouped by the job it does.", "rows": [
{"name": "Run the host", "form": "codebot run", "what": "Prints the run screen: start, stop, update and read the host."},
{"name": "Check the code", "form": "codebot check", "what": "Prints the check screen: the type check, build, tests and reviews."},
{"name": "Open things", "form": "codebot open", "what": "Prints the open screen: the app, the documents, the folders and the settings files."},
{"name": "Back up and restore", "form": "codebot backup", "what": "Prints the backup screen: the copy and restore procedures and where backups are kept."},
{"name": "Other people", "form": "codebot people", "what": "Prints the people screen: the guest account and the family CodeBots."},
{"name": "Experimental apps", "form": "codebot apps", "what": "Prints the apps screen: the three experimental apps, their ports and how to start them."},
{"name": "Account service and addresses", "form": "codebot account", "what": "Prints the account screen: the sign-in service, its deploy, and the steps that depend on this machine's name."}
]},
{"path": ["run"], "sentence": "The CodeBot host on this machine: start it for development, or manage the installed copy.", "rows": [
{"name": "Start the host for development", "form": "npm run dev", "what": "Starts the host in watch mode on port 3505; stop the installed host first, since the port is shared."},
{"name": "Restart the installed host", "form": "systemctl --user restart codebot.service", "what": "Restarts the installed host after a build, once active work has finished."},
{"name": "Stop the installed host", "form": "systemctl --user stop codebot.service", "what": "Stops the installed host and interrupts its running Bot turns."},
{"name": "Show the installed host's status", "form": "systemctl --user status codebot.service --no-pager", "what": "Shows whether the installed host is running and when it started."},
{"name": "Read the installed host's log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the installed host."},
{"name": "Check the host answers", "form": "curl --fail --silent http://127.0.0.1:3505/api/session", "what": "Checks that the host answers on its port; an error means it is not running."},
{"name": "Update the host", "form": "sh ops/deploy.sh", "what": "Builds, pushes and restarts the host, and refuses while a Bot is working."},
{"name": "Open the host's diagnostics", "form": "http://127.0.0.1:3505/api/diagnostics/host", "what": "Opens the host's counters as JSON; needs a browser already signed in."},
{"name": "Show the terminal broker", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Shows whether the terminal broker, which gives a shell to the owner, is running."}
]},
{"path": ["check"], "sentence": "The checks that show the code still compiles, builds and passes its tests and reviews.", "rows": [
{"name": "Type check", "form": "npm run typecheck", "what": "Runs the TypeScript check, which compiles the code without building it."},
{"name": "Build", "form": "npm run build", "what": "Type-checks, then builds the web app and publishes a new release."},
{"name": "Run the tests", "form": "npm test", "what": "Runs the Gmail tests against a fake Google server."},
{"name": "Type check and tests", "form": "npm run check", "what": "Runs the type check and the tests together."},
{"name": "Regenerate the Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md from its source."},
{"name": "Review Gmail", "form": "npm run review:gmail", "what": "Runs the Gmail review script against the running service."},
{"name": "Review schedules", "form": "npm run review:schedules", "what": "Runs the schedules review script against the running service."},
{"name": "Regenerate the agents file", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md."}
]},
{"path": ["open"], "sentence": "Where to look: the running app, the documents, the folders and the settings files.", "rows": [
{"name": "The app on this computer", "form": "http://127.0.0.1:3505", "what": "Opens CodeBot in a browser on this computer."},
{"name": "The app over Tailscale", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens CodeBot on a phone or another device over the private address."},
{"name": "The design playground", "form": "npm run playground", "what": "Starts the Vite playground and opens the Gmail widget variants in a browser."},
{"name": "The documents", "form": "codebot open docs", "what": "Prints the documents screen: where each project document is."},
{"name": "The host data folder", "form": "~/.local/share/codebot", "what": "Opens the data folder with the database, attachments and recordings; handle it with care."},
{"name": "The host settings file", "form": "~/.config/codebot/service.env", "what": "Opens the private settings file; it holds secrets, so do not paste it anywhere."},
{"name": "The allowed project folders", "form": "~/projects", "what": "Opens the folders Bots may reach; widening them grants real file access."},
{"name": "The settings template", "form": "ops/environment.example", "what": "Opens the template for the settings file, with each setting explained."},
{"name": "The installed service file", "form": "~/.config/systemd/user/codebot.service", "what": "Opens the service file that starts the host."}
]},
{"path": ["open", "docs"], "sentence": "The documents that describe this project, from how to run it to how it is built.", "rows": [
{"name": "Project overview", "form": "README.md", "what": "Opens the overview, how to run it and how the pieces fit."},
{"name": "Runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for running, recovering, backing up and moving the host."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how the pieces are built and the rules they keep."},
{"name": "Product behaviour", "form": "PRODUCT-SPEC.md", "what": "Opens the behaviour contract the product must meet."},
{"name": "Open work", "form": "DEFERRED-WORK.md", "what": "Opens the remaining checklist and the safe restart state."},
{"name": "Owner rules for agents", "form": "CLAUDE.md", "what": "Opens the fundamentals every task assumes and the screen design rules."},
{"name": "Gmail for Bots", "form": "docs/automation/gmail.md", "what": "Opens the guide for connecting Gmail to Bots."},
{"name": "Design taste", "form": "docs/design-taste.md", "what": "Opens the owner's rulings on screens: what was accepted and what was rejected."}
]},
{"path": ["backup"], "sentence": "The procedures that copy the host's data somewhere safe and bring it back.", "rows": [
{"name": "Back up the host", "form": "ops/OPERATIONS.md (Back up a consistent installation)", "what": "Opens the backup steps; they stop the host while the copy is made."},
{"name": "Restore a backup", "form": "ops/OPERATIONS.md (Restore into a separate directory first)", "what": "Opens the restore steps, which restore into a separate folder first."},
{"name": "The backup folder", "form": "~/.local/share/codebot-backups", "what": "Opens the folder where timestamped backups are kept, if any exist yet."},
{"name": "Verify a backup", "form": "sha256sum -c SHA256SUMS", "what": "Checks a backup's files against their recorded checksums; run it inside the backup folder."}
]},
{"path": ["people"], "sentence": "Other people who use CodeBot on this machine: a guest account and the family CodeBots.", "rows": [
{"name": "Guest", "form": "codebot people guest", "what": "Prints the guest screen: the second CodeBot for one other person."},
{"name": "Family", "form": "codebot people family", "what": "Prints the family screen: the family CodeBots, their address and Gmail status."}
]},
{"path": ["people", "guest"], "sentence": "The guest CodeBot: its own Linux user and service, reached by an invite over Tailscale.", "rows": [
{"name": "Guest status", "form": "systemctl status codebot-guest", "what": "Shows whether the guest host is running."},
{"name": "Guest log", "form": "journalctl -u codebot-guest", "what": "Prints the guest host's log."},
{"name": "Guest processes", "form": "ps -u codebot-guest", "what": "Lists what the guest's user is running."},
{"name": "Guest disk use", "form": "sudo du -sh /home/codebot-guest", "what": "Measures how much space the guest's data takes."},
{"name": "Invite the guest", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Creates a one-use Google sign-in link, valid for ten minutes."},
{"name": "Update the guest", "form": "ops/guest-update.sh", "what": "Builds, replaces and restarts the guest host; needs no password."},
{"name": "Set up the guest", "form": "sudo ops/guest-install.sh", "what": "Creates the guest user, service, settings and sudo rules; run once."},
{"name": "The guest's address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's CodeBot in a browser."},
{"name": "Remove the guest", "form": "ops/OPERATIONS.md (Host a guest on this machine)", "what": "Opens the steps that remove the guest completely; this command does not run them."},
{"name": "Restart the guest's onboarding", "form": "ops/OPERATIONS.md (Restart onboarding with a fresh CodeBot)", "what": "Opens the steps that give the guest a fresh CodeBot, keeping the account."}
]},
{"path": ["people", "family"], "sentence": "The family CodeBots on the home Wi-Fi address: one per family member, each with its own user and port.", "rows": [
{"name": "The family address", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in page on the home address."},
{"name": "Family status", "form": "sudo codebot-family status", "what": "Lists each family CodeBot, whether it runs, and whether Gmail can connect."},
{"name": "Add a family member", "form": "sudo codebot-family add N", "what": "Creates a family CodeBot in slot N; at most six."},
{"name": "Remove a family member", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its slot; its Google account cannot be linked again."},
{"name": "Stop all family CodeBots", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
{"name": "Start all family CodeBots", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot."},
{"name": "Family log", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the logs of the front door and every family CodeBot."},
{"name": "Update the family", "form": "ops/family-update.sh", "what": "Builds and restarts every family CodeBot; needs no password."},
{"name": "Set up the family", "form": "sudo ops/family-install.sh", "what": "Creates the front door, helper, services, sudo rules and nginx; run once."},
{"name": "Address, certificate and removal", "form": "ops/OPERATIONS.md (Home Wi-Fi address)", "what": "Opens the address, certificate and removal steps for the home address."}
]},
{"path": ["apps"], "sentence": "The three experimental apps on this computer; each has its own folder, port and data, separate from CodeBot.", "rows": [
{"name": "V2 Terminal chat: start", "form": "cd ~/projects/codebot-v2-terminal-chat && sh ops/app-run.sh dev", "what": "Starts V2 on port 3512 in this terminal."},
{"name": "V2 Terminal chat: open", "form": "http://127.0.0.1:3512", "what": "Opens V2 in Chrome."},
{"name": "V3 Claude Code mod: start", "form": "cd ~/projects/codebot-v3-claude-mod && sh ops/app-run.sh dev", "what": "Starts V3 on port 3513 in this terminal."},
{"name": "V3 Claude Code mod: open", "form": "http://127.0.0.1:3513", "what": "Opens V3 in Chrome."},
{"name": "V4 Launcher menu: start", "form": "cd ~/projects/codebot-v4-launcher-menu && sh ops/app-run.sh dev", "what": "Starts V4 on port 3514 in this terminal."},
{"name": "V4 Launcher menu: open", "form": "http://127.0.0.1:3514", "what": "Opens V4 in Chrome."},
{"name": "Find an app's process", "form": "ss -ltnp 'sport = :3513'", "what": "Shows the one process that holds an app's port, so only that one is stopped."},
{"name": "List V3's background sessions", "form": "claude agents", "what": "Lists the V3 background Claude sessions and their ids."},
{"name": "Stop a V3 background session", "form": "claude stop <id>", "what": "Stops one V3 background session, using an id from the list."}
]},
{"path": ["account"], "sentence": "The central account service (Supabase) and what depends on this machine's name.", "rows": [
{"name": "Account service dashboard", "form": "https://supabase.com/dashboard/project/wbgrjvqbupgdclaztuou", "what": "Opens the Supabase project for CodeBot's account service."},
{"name": "The account service token", "form": "~/.config/supabase-codebot-token", "what": "Opens the token file the CLI uses; keep it private and never paste it."},
{"name": "Deploy the host-access function", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou (reads the token file)", "what": "Deploys host-access to the account service; needed when a parsed contract changes, and it is outward-facing, so confirm first."},
{"name": "Operator account setup", "form": "npm run setup-account", "what": "Runs the operator setup script for the account service."},
{"name": "Account database migrations", "form": "supabase/migrations", "what": "Opens the account database's migration files, in order."},
{"name": "Change this machine's address", "form": "ops/OPERATIONS.md (Change this machine's address)", "what": "Opens the checklist of every place that must change for a new machine name."},
{"name": "Reset someone's onboarding", "form": "ops/OPERATIONS.md (Reset someone's onboarding)", "what": "Opens the procedures to replay or reset a person's onboarding."}
]}
],
"questions": [
"Facade name: use codebot, with cb as a short alias? Recommendation: yes, if cb clashes with nothing (check with whence -a).",
"The README mentions cli/codebot.py, which is not in the dump's file list. Does it exist, and does it already cover part of this map? Recommendation: check before building; if it exists, wrap it rather than write a second one.",
"Family removal (sudo codebot-family remove N): wire it as a thin command with a typed-slot confirmation? Recommendation: yes. Keep guest removal as docs only, since it takes several steps.",
"Deploy (sh ops/deploy.sh) and the Supabase host-access deploy are outward-facing. Should each run only after an explicit confirmation? Recommendation: yes for both; deploy already refuses while a Bot is working.",
"Backup: wire it as a codebot backup command later? Recommendation: not yet. It stops the host, so it should be a worker task with the intent recorded first; keep it as a doc row until then."
]}
```

screen-decomposition, first draft · run 3 exit=0 seconds=195 · prompt

P1 Recall: 0.628P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.257
As terminal help
Everything this computer's CodeBot reaches, grouped by what you are trying to do.
appcodebot appShows the app screen: the addresses, phone install, notifications and device connection.
servicecodebot serviceShows the service screen: whether CodeBot is running, and how to start, stop, restart and read it.
updatecodebot updateShows the update screen: how a new version is built, deployed and sent to the guest and family copies.
peoplecodebot peopleShows the people screen: the guest, the family CodeBots and onboarding.
datacodebot dataShows the data screen: the database, backups and restores.
accountcodebot accountShows the account screen: the central account service (Supabase) and Gmail.
projectcodebot projectShows the project screen: the docs, design, apps and ops files.
app
Where to open CodeBot from, how to install it on a phone, and how to connect a device.
owner addresshttps://liel.tail18e69e.ts.net/Opens the owner's CodeBot over the private Tailscale address, from a device on the tailnet.
family addresshttps://family.codebot.lielbenor.comOpens the family sign-in on the home Wi-Fi, where each family member gets their own CodeBot.
local addresshttp://127.0.0.1:3505Opens the owner's CodeBot on this computer only.
tailscale mappingtailscale serve status --jsonPrints how Tailscale maps the private HTTPS address to port 3505; the root handler must stay as it is.
install on phoneops/OPERATIONS.md, Private access and PWA installationShows how to install CodeBot on the phone's home screen from the private address.
notificationsops/OPERATIONS.md, Background notificationsShows how to turn on notifications for a device and for each Bot, and how to send a test.
connect a deviceops/OPERATIONS.md, Connect a deviceShows how to connect a new device to the private address with the entrance key.
entrance key~/.local/share/codebot/owner-keyOpens the file holding the entrance key, to type on a new device; codebot never prints the key.
change addressops/OPERATIONS.md, Change this machine's addressShows the nine places to update, in order, when the private address changes.
service
Whether CodeBot's service is running on this computer, and how to start, stop, restart or read it.
statussystemctl --user status codebot.service --no-pagerPrints whether the service is running, with its last log lines.
startsystemctl --user start codebot.serviceStarts the CodeBot service on port 3505.
stopsystemctl --user stop codebot.serviceStops the service: scheduling halts, Bot turns are interrupted and recordings are finalized.
restartsystemctl --user restart codebot.serviceRestarts the service to load a new build; wait for active turns and recordings to finish first.
logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 lines of the service log.
settings file~/.config/codebot/service.envOpens the private service settings, which hold provider credentials; never paste them anywhere.
recovery holdCODEBOT_RECOVERY_HOLD in ~/.config/codebot/service.envPauses automatic sends and schedules when set to 1; explicit Send, Continue and Retry still work.
emergency stopops/OPERATIONS.md, Emergency stop and rollbackShows the forced stop for when a normal stop cannot finish; a forced stop can lose unsaved recording footage.
terminal brokersystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the optional per-user terminal broker is running; it is separate from the service.
diagnosticscodebot service diagnosticsShows the screen of checks on the running service.
service › diagnostics
The checks on the running service: whether it answers, which process holds its port, and its own status.
answerscurl --fail --silent --show-error http://127.0.0.1:3505/api/sessionChecks that the service answers on port 3505; an unauthenticated answer counts as up.
port holderss -ltnp 'sport = :3505'Prints which process listens on port 3505, so only that one process is stopped if needed.
host statushttps://liel.tail18e69e.ts.net/api/diagnostics/hostOpens the host's migration, queued and running turns and recovery hold, for a signed-in owner.
schedulerhttps://liel.tail18e69e.ts.net/api/diagnostics/schedulerOpens the scheduler's counters and lifecycle state, for a signed-in owner.
visionhttps://liel.tail18e69e.ts.net/api/diagnostics/visionOpens the Vision counters and lifecycle state, for a signed-in owner.
notificationshttps://liel.tail18e69e.ts.net/api/notifications/diagnosticsOpens the notification queue, timer and active sends, for a signed-in owner.
update
How a new version of CodeBot is built, deployed and sent to the guest and family copies.
buildnpm run buildBuilds a new release: type check first, then the web app and service; the served release stays until it succeeds.
deploysh ops/deploy.shDeploys the current code: builds, commits, pushes to the remote, restarts the service and checks it is live; refuses while a Bot is working.
checknpm run checkRuns the type check and then the tests.
typechecknpm run typecheckChecks the TypeScript without building anything.
testsnpm testRuns the Gmail automation tests against a fake Google server, not the real one.
QA copy buildnpm run build:integrationBuilds the disposable QA copy that runs on port 3506.
deploy guardops/deploy-guard.shBlocks finishing a turn while code is unpushed, newer than the running service, or newer than the served build.
guest updateops/guest-update.shRebuilds the guest copy in /opt/codebot-guest and restarts it; needs no password.
family updateops/family-update.shRebuilds /opt/codebot-family and restarts the front door and every family CodeBot; needs no password.
people
The people who use CodeBot on this computer: the guest, the family CodeBots and each person's onboarding.
guestcodebot people guestShows the guest screen: a second CodeBot account on this computer, run as its own Linux user.
familycodebot people familyShows the family screen: one CodeBot for each family member who signs in on the home Wi-Fi.
onboardingcodebot people onboardingShows the onboarding screen: replaying or restarting a person's first-use tour.
people › guest
The guest CodeBot: its service, its sign-in invite, and how it is installed, updated or removed.
statussystemctl status codebot-guest --no-pagerPrints whether the guest CodeBot service is running.
logsjournalctl -u codebot-guestPrints the guest CodeBot service log.
processesps -u codebot-guestLists the processes the guest CodeBot runs.
disk usesudo du -sh /home/codebot-guestPrints how much space the guest's home folder uses.
invitesudo -u codebot-guest /opt/codebot-guest/inviteCreates a one-use Google sign-in link for the guest, valid for ten minutes.
installsudo ops/guest-install.shSets up the guest user, folder, service, settings, sudo rules and Tailscale port 10000; run once, with the password.
updateops/guest-update.shRebuilds and restarts the guest CodeBot; needs no password.
share machineTailscale admin console: Machines, this machine, ShareShows where to share this machine with the guest's Tailscale account instead of adding their device to the tailnet.
removeops/OPERATIONS.md, Host a guest on this machineShows the steps that remove the guest CodeBot, its user and its files; destructive, run by hand.
people › family
The family CodeBots: the helper that manages them, their logs, install and update, and what a full removal takes.
helpercodebot people family helperShows the helper screen: the root commands that show, add, remove, stop and start family CodeBots.
logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the front door's and every family CodeBot's log.
home foldersls /home | grep codebot-fLists the home folders of the family CodeBot users.
front doorhttps://family.codebot.lielbenor.comOpens the family sign-in, which sends a new Google account to its own CodeBot.
installsudo ops/family-install.shSets up the front door user, helper, services, sudo rules and nginx; run once, with the password.
remove allops/OPERATIONS.md, Home Wi-Fi addressShows the steps that remove the whole family setup; destructive, run by hand.
people › family › helper
The root helper for family CodeBots: the commands that show, add, remove, stop and start them.
statussudo codebot-family statusPrints each family CodeBot: whether it runs and whether its Gmail can be connected.
addsudo codebot-family add NCreates family CodeBot N for a new Google account; numbers go up to six.
removesudo codebot-family remove NDeletes family CodeBot N and frees its number; its Google account cannot be linked again without editing the account database.
stop allsudo codebot-family stop-allStops every family CodeBot.
start allsudo codebot-family start-allStarts every family CodeBot.
helper settings/etc/codebot-family.confOpens the helper's settings file.
people › onboarding
Showing a person the onboarding again, or resetting their account on this computer.
replay tourops/OPERATIONS.md, Replay only the first-use tourShows the steps that replay the first-use tour; it works only on a host with no Bots.
fresh CodeBotops/OPERATIONS.md, Restart onboarding with a fresh CodeBot, keeping the accountShows the steps that wipe a host's Bots and conversations but keep its Google account.
full resetops/OPERATIONS.md, Full reset: the person starts as newShows the steps that delete an account with all its Bots, conversations, attachments and recordings; destructive.
identity checkhttps://liel.tail18e69e.ts.net:10000/api/onboarding/identityOpens the guest host's identity, to confirm its serverId is unchanged after a wipe.
owner database~/.local/share/codebot/codebot.sqliteOpens the owner's host database, where a person's first-use receipt is kept.
data
CodeBot's stored data on this computer: its database, its backups and how to restore one.
data folder~/.local/share/codebotOpens the data folder: the database, attachments, recordings and the owner key.
database~/.local/share/codebot/codebot.sqliteOpens the owner's SQLite database; check it only with the read-only integrity check below.
integrity checkops/OPERATIONS.md, Restore into a separate directory firstChecks a restored database with PRAGMA integrity_check and foreign-key checks, reading only.
back upops/OPERATIONS.md, Back up a consistent installationShows how to stop the service and copy its data, settings and unit file into a private backup folder.
backups~/.local/share/codebot-backupsOpens the backup folders, one per UTC timestamp, each with SHA256SUMS.
verify backupsha256sum -c SHA256SUMSChecks a backup's files against their recorded checksums; run it in the backup folder.
restoreops/OPERATIONS.md, Restore into a separate directory firstShows how to restore a backup into an empty staging folder and inspect it before any promotion.
staging~/.local/share/codebot-restore-stagingOpens the staging folder a backup is restored into first, so the original stays intact.
inspection copyhttp://127.0.0.1:3508Opens the restored copy on port 3508 in recovery hold, to check it before promotion.
account
The central account service (Supabase) that handles sign-in and host arrival, and Gmail for Bots.
supabasecodebot account supabaseShows the supabase screen: the account service project, its token, its functions and its migrations.
gmailcodebot account gmailShows the gmail screen: how Bots connect Gmail and the Google app settings.
setup accountnpm run setup-accountRuns ops/setup-account.ts to set this computer up with the account service.
sign-in entryhttps://liel.tail18e69e.ts.net/onboardingOpens the sign-in entry that the host accepts arrivals from; the redirect list must include it.
account › supabase
The central account service's project: its identity, token, functions and database migrations.
projectproject ref wbgrjvqbupgdclaztuouIdentifies the account service project; its CLI needs the mobile-coder token, not the shell's Lebnor token.
token file~/.config/supabase-codebot-tokenOpens the account service's CLI token file (mode 600); never print it.
deploy host-accessSUPABASE_ACCESS_TOKEN=... npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function; run it whenever a contract it parses changes.
gmail-relaysupabase/functions/gmail-relayOpens the Gmail relay function: one fixed address that forwards Google's return to the user's own server.
host-accesssupabase/functions/host-accessOpens the host-access function that validates each host's sign-in arrival and rejects unknown fields.
migrationssupabase/migrationsLists the account database's migrations in order.
first-use resetops/OPERATIONS.md, Replay only the first-use tourShows the SQL that restarts a person's first-use draft in the account database.
account › gmail
How Bots use Gmail: the guide, the generated reference, the review script and the Google app settings.
guidedocs/automation/gmail.mdOpens the Gmail guide: the supervisor guide and the sign-in relay.
referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference of what Bots can do with it.
regeneratenpm run docs:gmailRegenerates the Gmail reference from the code.
reviewnpm run review:gmailRuns the Gmail review script, ops/review/gmail-review.mjs.
google app idCODEBOT_GOOGLE_CLIENT_ID in ~/.config/codebot/service.envSets the Google app ID that lets Bots connect Gmail; without it Gmail stays off.
google app secretCODEBOT_GOOGLE_CLIENT_SECRET in ~/.config/codebot/service.envSets the Google app secret; it is never printed and never placed in a VITE_ variable.
return addressCODEBOT_GOOGLE_REDIRECT_URI in ~/.config/codebot/service.envForces Google's return to one address; leave it empty normally.
project
The project's own files: its documentation, its design, its apps and its operations.
docscodebot project docsShows the docs screen: the specs, architecture, plans and records.
designcodebot project designShows the design screen: design rules, mockups and the playground.
appscodebot project appsShows the apps screen: the service, the web app, the control service, the shared contracts and the checks.
opscodebot project opsShows the ops screen: the build, install and service files and the review scripts.
project › docs
The specs, architecture, plans, objectives and records of this project.
product specPRODUCT-SPEC.mdOpens the product spec: the behaviour contract the code must match.
architectureARCHITECTURE.mdOpens the architecture: how CodeBot is built and where its boundaries are.
implementation statusIMPLEMENTATION-STATUS.mdOpens what was built before the first beta was paused.
deferred workDEFERRED-WORK.mdOpens the deferred work list and the safe restart state.
docs folderdocs/Opens the docs folder: method, onboarding proof, self-hosting practices and the host account exchange.
plansdocs/plans/Opens the plans folder: one plan or design file for each earlier piece of work.
objectivesdocs/objectives/Opens the objectives: the goals for chat-current-session, gmail-widget, schedules and terminal-tabs.
verification recordsdocs/verification/Opens the recorded verification evidence for bot questions and the self-hosted terminal.
module intents.idd/modules/Opens the module intents: one INTENT.md per module, with its constraints and test table.
housekeeping skillskills/codebot-housekeeping/SKILL.mdShows the codebot-housekeeping skill's instructions.
project › design
The design rules, reference images and playground for the app's screens.
design tastedocs/design-taste.mdShows the owner's design rulings and what they rejected; read it before changing a screen.
design methoddocs/design-method.mdShows the design method: research, variants and review in the real app.
design folderdesign/Opens the design folder: screenshots, annotated mockups, fixtures and feature-contract reference images.
playgroundnpm run playgroundStarts a dev server on 127.0.0.1 and opens the Gmail playground page.
critiques.impeccable/critique/Opens the design critiques, one file for each reviewed component.
project › apps
The code of the apps and shared packages, the behaviour tests, and the environment example.
serviceapps/service/Opens the service code: Bots, transcripts, git, avatars, host access and provider adapters.
web appapps/web/Opens the web app code: the screens the owner sees in the browser and on the phone.
control serviceapps/control/Opens the control service, which issues the signed host proofs.
contractspackages/contracts/Opens the shared schemas that the service and the client both validate against.
service testsapps/service/test/Opens the service tests that the npm test command runs.
behaviour features.bdd/features/Opens the Given/When/Then feature files for Bot features, with their steps and QA results in .bdd/.
avatar partsapps/service/assets/avatar-parts/Opens the avatar parts library (eyes, bodies, accessories, head shapes) that Bots are drawn from.
CI workflows.github/workflows/check.ymlShows the check workflow that runs in GitHub; supabase-keepalive.yml keeps the account service awake.
example settings.env.exampleOpens the example development settings; copy it to .env and never commit .env.
project › ops
The operations files: the runbook, service units, build script, example settings and review scripts.
runbookops/OPERATIONS.mdOpens the runbook for running, recovering, backing up and resetting CodeBot.
service unitsops/*.serviceOpens the systemd unit files: CodeBot, the terminal broker, the guest, the family front door and the family CodeBots.
environment exampleops/environment.exampleShows the example service settings; the real copy is ~/.config/codebot/service.env with mode 0600.
build scriptops/build.mjsOpens the build script that publishes a release and swaps the served link.
review scriptsops/review/Opens the review scripts for Gmail, schedules, the Google redirect, the schedule drill and the terminal tabs stack.
sync agentsnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
Questions
  • Scope: should the map include the phone app's own screens (Bot chat, settings, queue), or only the operations and project layer? Recommendation: only the operations and project layer; the app is reached through its address alone.
  • Destructive and sudo steps (full reset, fresh CodeBot, guest or family removal, restore promotion, emergency stop, sudo installs): should the CLI run them or only print them? Recommendation: only print them; the owner runs them in a real terminal.
  • Facade name: use codebot with no alias? Recommendation: codebot, plus a short alias only if whence -a shows it free (not checked here).
  • cli/codebot.py is mentioned in the README but is not in the file list. Does it exist? Recommendation: if yes, add its commands to the map; if no, fix the README line.
  • The service screen has 10 rows. Split it into start/stop/restart and files? Recommendation: keep one screen until it passes 12 rows.
  • Two plan folders: docs/plans/ and .plans/ (one file). Which is canonical? Recommendation: docs/plans/, and move the .plans/ file there.
As phone screens

Home

Everything this computer's CodeBot reaches, grouped by what you are trying to do.

appShows the app screen: the addresses, phone install, notifications and device connection.
›
serviceShows the service screen: whether CodeBot is running, and how to start, stop, restart and read it.
›
updateShows the update screen: how a new version is built, deployed and sent to the guest and family copies.
›
peopleShows the people screen: the guest, the family CodeBots and onboarding.
›
dataShows the data screen: the database, backups and restores.
›
accountShows the account screen: the central account service (Supabase) and Gmail.
›
projectShows the project screen: the docs, design, apps and ops files.
›
‹ Home

app

Where to open CodeBot from, how to install it on a phone, and how to connect a device.

owner addressOpens the owner's CodeBot over the private Tailscale address, from a device on the tailnet.
›
family addressOpens the family sign-in on the home Wi-Fi, where each family member gets their own CodeBot.
›
local addressOpens the owner's CodeBot on this computer only.
›
tailscale mappingPrints how Tailscale maps the private HTTPS address to port 3505; the root handler must stay as it is.
›
install on phoneShows how to install CodeBot on the phone's home screen from the private address.
›
notificationsShows how to turn on notifications for a device and for each Bot, and how to send a test.
›
connect a deviceShows how to connect a new device to the private address with the entrance key.
›
entrance keyOpens the file holding the entrance key, to type on a new device; codebot never prints the key.
›
change addressShows the nine places to update, in order, when the private address changes.
›
‹ Home

service

Whether CodeBot's service is running on this computer, and how to start, stop, restart or read it.

statusPrints whether the service is running, with its last log lines.
›
startStarts the CodeBot service on port 3505.
›
stopStops the service: scheduling halts, Bot turns are interrupted and recordings are finalized.
›
restartRestarts the service to load a new build; wait for active turns and recordings to finish first.
›
logsPrints the last 80 lines of the service log.
›
settings fileOpens the private service settings, which hold provider credentials; never paste them anywhere.
›
recovery holdPauses automatic sends and schedules when set to 1; explicit Send, Continue and Retry still work.
›
emergency stopShows the forced stop for when a normal stop cannot finish; a forced stop can lose unsaved recording footage.
›
terminal brokerPrints whether the optional per-user terminal broker is running; it is separate from the service.
›
diagnosticsShows the screen of checks on the running service.
›
‹ service

diagnostics

The checks on the running service: whether it answers, which process holds its port, and its own status.

answersChecks that the service answers on port 3505; an unauthenticated answer counts as up.
›
port holderPrints which process listens on port 3505, so only that one process is stopped if needed.
›
host statusOpens the host's migration, queued and running turns and recovery hold, for a signed-in owner.
›
schedulerOpens the scheduler's counters and lifecycle state, for a signed-in owner.
›
visionOpens the Vision counters and lifecycle state, for a signed-in owner.
›
notificationsOpens the notification queue, timer and active sends, for a signed-in owner.
›
‹ Home

update

How a new version of CodeBot is built, deployed and sent to the guest and family copies.

buildBuilds a new release: type check first, then the web app and service; the served release stays until it succeeds.
›
deployDeploys the current code: builds, commits, pushes to the remote, restarts the service and checks it is live; refuses while a Bot is working.
›
checkRuns the type check and then the tests.
›
typecheckChecks the TypeScript without building anything.
›
testsRuns the Gmail automation tests against a fake Google server, not the real one.
›
QA copy buildBuilds the disposable QA copy that runs on port 3506.
›
deploy guardBlocks finishing a turn while code is unpushed, newer than the running service, or newer than the served build.
›
guest updateRebuilds the guest copy in /opt/codebot-guest and restarts it; needs no password.
›
family updateRebuilds /opt/codebot-family and restarts the front door and every family CodeBot; needs no password.
›
‹ Home

people

The people who use CodeBot on this computer: the guest, the family CodeBots and each person's onboarding.

guestShows the guest screen: a second CodeBot account on this computer, run as its own Linux user.
›
familyShows the family screen: one CodeBot for each family member who signs in on the home Wi-Fi.
›
onboardingShows the onboarding screen: replaying or restarting a person's first-use tour.
›
‹ people

guest

The guest CodeBot: its service, its sign-in invite, and how it is installed, updated or removed.

statusPrints whether the guest CodeBot service is running.
›
logsPrints the guest CodeBot service log.
›
processesLists the processes the guest CodeBot runs.
›
disk usePrints how much space the guest's home folder uses.
›
inviteCreates a one-use Google sign-in link for the guest, valid for ten minutes.
›
installSets up the guest user, folder, service, settings, sudo rules and Tailscale port 10000; run once, with the password.
›
updateRebuilds and restarts the guest CodeBot; needs no password.
›
share machineShows where to share this machine with the guest's Tailscale account instead of adding their device to the tailnet.
›
removeShows the steps that remove the guest CodeBot, its user and its files; destructive, run by hand.
›
‹ people

family

The family CodeBots: the helper that manages them, their logs, install and update, and what a full removal takes.

helperShows the helper screen: the root commands that show, add, remove, stop and start family CodeBots.
›
logsPrints the front door's and every family CodeBot's log.
›
home foldersLists the home folders of the family CodeBot users.
›
front doorOpens the family sign-in, which sends a new Google account to its own CodeBot.
›
installSets up the front door user, helper, services, sudo rules and nginx; run once, with the password.
›
remove allShows the steps that remove the whole family setup; destructive, run by hand.
›
‹ family

helper

The root helper for family CodeBots: the commands that show, add, remove, stop and start them.

statusPrints each family CodeBot: whether it runs and whether its Gmail can be connected.
›
addCreates family CodeBot N for a new Google account; numbers go up to six.
›
removeDeletes family CodeBot N and frees its number; its Google account cannot be linked again without editing the account database.
›
stop allStops every family CodeBot.
›
start allStarts every family CodeBot.
›
helper settingsOpens the helper's settings file.
›
‹ people

onboarding

Showing a person the onboarding again, or resetting their account on this computer.

replay tourShows the steps that replay the first-use tour; it works only on a host with no Bots.
›
fresh CodeBotShows the steps that wipe a host's Bots and conversations but keep its Google account.
›
full resetShows the steps that delete an account with all its Bots, conversations, attachments and recordings; destructive.
›
identity checkOpens the guest host's identity, to confirm its serverId is unchanged after a wipe.
›
owner databaseOpens the owner's host database, where a person's first-use receipt is kept.
›
‹ Home

data

CodeBot's stored data on this computer: its database, its backups and how to restore one.

data folderOpens the data folder: the database, attachments, recordings and the owner key.
›
databaseOpens the owner's SQLite database; check it only with the read-only integrity check below.
›
integrity checkChecks a restored database with PRAGMA integrity_check and foreign-key checks, reading only.
›
back upShows how to stop the service and copy its data, settings and unit file into a private backup folder.
›
backupsOpens the backup folders, one per UTC timestamp, each with SHA256SUMS.
›
verify backupChecks a backup's files against their recorded checksums; run it in the backup folder.
›
restoreShows how to restore a backup into an empty staging folder and inspect it before any promotion.
›
stagingOpens the staging folder a backup is restored into first, so the original stays intact.
›
inspection copyOpens the restored copy on port 3508 in recovery hold, to check it before promotion.
›
‹ Home

account

The central account service (Supabase) that handles sign-in and host arrival, and Gmail for Bots.

supabaseShows the supabase screen: the account service project, its token, its functions and its migrations.
›
gmailShows the gmail screen: how Bots connect Gmail and the Google app settings.
›
setup accountRuns ops/setup-account.ts to set this computer up with the account service.
›
sign-in entryOpens the sign-in entry that the host accepts arrivals from; the redirect list must include it.
›
‹ account

supabase

The central account service's project: its identity, token, functions and database migrations.

projectIdentifies the account service project; its CLI needs the mobile-coder token, not the shell's Lebnor token.
›
token fileOpens the account service's CLI token file (mode 600); never print it.
›
deploy host-accessDeploys the host-access function; run it whenever a contract it parses changes.
›
gmail-relayOpens the Gmail relay function: one fixed address that forwards Google's return to the user's own server.
›
host-accessOpens the host-access function that validates each host's sign-in arrival and rejects unknown fields.
›
migrationsLists the account database's migrations in order.
›
first-use resetShows the SQL that restarts a person's first-use draft in the account database.
›
‹ account

gmail

How Bots use Gmail: the guide, the generated reference, the review script and the Google app settings.

guideOpens the Gmail guide: the supervisor guide and the sign-in relay.
›
referenceOpens the generated Gmail reference of what Bots can do with it.
›
regenerateRegenerates the Gmail reference from the code.
›
reviewRuns the Gmail review script, ops/review/gmail-review.mjs.
›
google app idSets the Google app ID that lets Bots connect Gmail; without it Gmail stays off.
›
google app secretSets the Google app secret; it is never printed and never placed in a VITE_ variable.
›
return addressForces Google's return to one address; leave it empty normally.
›
‹ Home

project

The project's own files: its documentation, its design, its apps and its operations.

docsShows the docs screen: the specs, architecture, plans and records.
›
designShows the design screen: design rules, mockups and the playground.
›
appsShows the apps screen: the service, the web app, the control service, the shared contracts and the checks.
›
opsShows the ops screen: the build, install and service files and the review scripts.
›
‹ project

docs

The specs, architecture, plans, objectives and records of this project.

product specOpens the product spec: the behaviour contract the code must match.
›
architectureOpens the architecture: how CodeBot is built and where its boundaries are.
›
implementation statusOpens what was built before the first beta was paused.
›
deferred workOpens the deferred work list and the safe restart state.
›
docs folderOpens the docs folder: method, onboarding proof, self-hosting practices and the host account exchange.
›
plansOpens the plans folder: one plan or design file for each earlier piece of work.
›
objectivesOpens the objectives: the goals for chat-current-session, gmail-widget, schedules and terminal-tabs.
›
verification recordsOpens the recorded verification evidence for bot questions and the self-hosted terminal.
›
module intentsOpens the module intents: one INTENT.md per module, with its constraints and test table.
›
housekeeping skillShows the codebot-housekeeping skill's instructions.
›
‹ project

design

The design rules, reference images and playground for the app's screens.

design tasteShows the owner's design rulings and what they rejected; read it before changing a screen.
›
design methodShows the design method: research, variants and review in the real app.
›
design folderOpens the design folder: screenshots, annotated mockups, fixtures and feature-contract reference images.
›
playgroundStarts a dev server on 127.0.0.1 and opens the Gmail playground page.
›
critiquesOpens the design critiques, one file for each reviewed component.
›
‹ project

apps

The code of the apps and shared packages, the behaviour tests, and the environment example.

serviceOpens the service code: Bots, transcripts, git, avatars, host access and provider adapters.
›
web appOpens the web app code: the screens the owner sees in the browser and on the phone.
›
control serviceOpens the control service, which issues the signed host proofs.
›
contractsOpens the shared schemas that the service and the client both validate against.
›
service testsOpens the service tests that the npm test command runs.
›
behaviour featuresOpens the Given/When/Then feature files for Bot features, with their steps and QA results in .bdd/.
›
avatar partsOpens the avatar parts library (eyes, bodies, accessories, head shapes) that Bots are drawn from.
›
CI workflowsShows the check workflow that runs in GitHub; supabase-keepalive.yml keeps the account service awake.
›
example settingsOpens the example development settings; copy it to .env and never commit .env.
›
‹ project

ops

The operations files: the runbook, service units, build script, example settings and review scripts.

runbookOpens the runbook for running, recovering, backing up and resetting CodeBot.
›
service unitsOpens the systemd unit files: CodeBot, the terminal broker, the guest, the family front door and the family CodeBots.
›
environment exampleShows the example service settings; the real copy is ~/.config/codebot/service.env with mode 0600.
›
build scriptOpens the build script that publishes a release and swaps the served link.
›
review scriptsOpens the review scripts for Gmail, schedules, the Google redirect, the schedule drill and the terminal tabs stack.
›
sync agentsRegenerates AGENTS.md from CLAUDE.md.
›
Raw answer
**Scenario (reasoning from experience, drawn from CLAUDE.md and ops/OPERATIONS.md):** The owner, usually on a phone, opens CodeBot to check a Bot or sign in. At the desk, they deploy after a change, restart or check the service, add a family member or guest, connect a new device, or back up and restore. They reach for the right procedure when something has broken, so each screen has to say what it does before they act.

**Judgment calls**

- **Dump is truncated.** The `ops/`, `docs/plans/`, and `apps/` listings are cut off. Rows come from the visible files and from names that package.json, the README, and OPERATIONS.md reference. Verify these before building: `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md`, `MASTER-PLAN.md`, `ops/deploy.sh`, `ops/setup-account.ts`, `ops/build-integration.mjs`, `ops/sync-agents.ts`, `ops/terminal-broker.ts`.
- **Inferred purposes** (from names only): `build:integration` for the port-3506 QA copy, `setup-account`, and the two `.github/workflows` files.
- **Excluded:** the V2–V4 apps (their own repos, ports 3512–3514, `ops/app-run.sh`), and `ops/agent-start.sh` (its purpose is not in the dump).
- **Procedures with no command** point at their OPERATIONS.md section as the form. The CLI can only show them.
- **Secrets:** the owner key, `service.env`, the Supabase token file, and backups are shown as paths only. Their contents are never printed.
- **Group name `people`** is my word. The project says "guest", "family", and "person" for different things. If you want a project word, the alternative is to make `guest`, `family`, and `onboarding` top-level groups (8 rows).
- **Asset folders** (avatar parts, tool icons, reference screenshots) get one row each, not one per file.
- **Sign-in-gated endpoints** open in a browser. The CLI does not call them with its own token.
- **`deploy`** commits and pushes, which is outward-facing. Its row says so.

**Questions for you**

1. **Scope.** Should the map include the phone app's own screens (Bot chat, settings, queue), or only the operations and project layer? *Recommend:* only the operations and project layer. The app's screens belong to `minimal-ux-flow`, and the map reaches the app through its address alone.
2. **Destructive and sudo steps.** Should the CLI run the full reset, fresh-CodeBot reset, guest or family removal, restore promotion, emergency stop, and the sudo installs, or only print them? *Recommend:* only print them. You run them in a real terminal, as OPERATIONS.md already requires for the password step.
3. **Facade name.** Use `codebot` with no alias? *Recommend:* `codebot`, plus a short alias only if `whence -a` shows it free. I could not run that check here.
4. **`cli/codebot.py`.** The README mentions it, but it is not in the file list. Does it exist? *Recommend:* if yes, its commands join the map. If no, fix the broken README line. The map is complete without it.
5. **Service screen size.** It has 10 rows, at the upper limit. Split it into start/stop/restart and files? *Recommend:* keep it as one screen until it passes 12 rows.
6. **Two plan folders.** `docs/plans/` holds many files, and `.plans/` holds one (`answer-bot-questions.md`). Which is canonical? *Recommend:* `docs/plans/`, and move the `.plans/` file there.

```json
{"screens": [
{"path": [], "sentence": "Everything this computer's CodeBot reaches, grouped by what you are trying to do.", "rows": [
{"name": "app", "form": "codebot app", "what": "Shows the app screen: the addresses, phone install, notifications and device connection."},
{"name": "service", "form": "codebot service", "what": "Shows the service screen: whether CodeBot is running, and how to start, stop, restart and read it."},
{"name": "update", "form": "codebot update", "what": "Shows the update screen: how a new version is built, deployed and sent to the guest and family copies."},
{"name": "people", "form": "codebot people", "what": "Shows the people screen: the guest, the family CodeBots and onboarding."},
{"name": "data", "form": "codebot data", "what": "Shows the data screen: the database, backups and restores."},
{"name": "account", "form": "codebot account", "what": "Shows the account screen: the central account service (Supabase) and Gmail."},
{"name": "project", "form": "codebot project", "what": "Shows the project screen: the docs, design, apps and ops files."}
]},
{"path": ["app"], "sentence": "Where to open CodeBot from, how to install it on a phone, and how to connect a device.", "rows": [
{"name": "owner address", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the owner's CodeBot over the private Tailscale address, from a device on the tailnet."},
{"name": "family address", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in on the home Wi-Fi, where each family member gets their own CodeBot."},
{"name": "local address", "form": "http://127.0.0.1:3505", "what": "Opens the owner's CodeBot on this computer only."},
{"name": "tailscale mapping", "form": "tailscale serve status --json", "what": "Prints how Tailscale maps the private HTTPS address to port 3505; the root handler must stay as it is."},
{"name": "install on phone", "form": "ops/OPERATIONS.md, Private access and PWA installation", "what": "Shows how to install CodeBot on the phone's home screen from the private address."},
{"name": "notifications", "form": "ops/OPERATIONS.md, Background notifications", "what": "Shows how to turn on notifications for a device and for each Bot, and how to send a test."},
{"name": "connect a device", "form": "ops/OPERATIONS.md, Connect a device", "what": "Shows how to connect a new device to the private address with the entrance key."},
{"name": "entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Opens the file holding the entrance key, to type on a new device; codebot never prints the key."},
{"name": "change address", "form": "ops/OPERATIONS.md, Change this machine's address", "what": "Shows the nine places to update, in order, when the private address changes."}
]},
{"path": ["service"], "sentence": "Whether CodeBot's service is running on this computer, and how to start, stop, restart or read it.", "rows": [
{"name": "status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether the service is running, with its last log lines."},
{"name": "start", "form": "systemctl --user start codebot.service", "what": "Starts the CodeBot service on port 3505."},
{"name": "stop", "form": "systemctl --user stop codebot.service", "what": "Stops the service: scheduling halts, Bot turns are interrupted and recordings are finalized."},
{"name": "restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service to load a new build; wait for active turns and recordings to finish first."},
{"name": "logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 lines of the service log."},
{"name": "settings file", "form": "~/.config/codebot/service.env", "what": "Opens the private service settings, which hold provider credentials; never paste them anywhere."},
{"name": "recovery hold", "form": "CODEBOT_RECOVERY_HOLD in ~/.config/codebot/service.env", "what": "Pauses automatic sends and schedules when set to 1; explicit Send, Continue and Retry still work."},
{"name": "emergency stop", "form": "ops/OPERATIONS.md, Emergency stop and rollback", "what": "Shows the forced stop for when a normal stop cannot finish; a forced stop can lose unsaved recording footage."},
{"name": "terminal broker", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the optional per-user terminal broker is running; it is separate from the service."},
{"name": "diagnostics", "form": "codebot service diagnostics", "what": "Shows the screen of checks on the running service."}
]},
{"path": ["service", "diagnostics"], "sentence": "The checks on the running service: whether it answers, which process holds its port, and its own status.", "rows": [
{"name": "answers", "form": "curl --fail --silent --show-error http://127.0.0.1:3505/api/session", "what": "Checks that the service answers on port 3505; an unauthenticated answer counts as up."},
{"name": "port holder", "form": "ss -ltnp 'sport = :3505'", "what": "Prints which process listens on port 3505, so only that one process is stopped if needed."},
{"name": "host status", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/host", "what": "Opens the host's migration, queued and running turns and recovery hold, for a signed-in owner."},
{"name": "scheduler", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/scheduler", "what": "Opens the scheduler's counters and lifecycle state, for a signed-in owner."},
{"name": "vision", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/vision", "what": "Opens the Vision counters and lifecycle state, for a signed-in owner."},
{"name": "notifications", "form": "https://liel.tail18e69e.ts.net/api/notifications/diagnostics", "what": "Opens the notification queue, timer and active sends, for a signed-in owner."}
]},
{"path": ["update"], "sentence": "How a new version of CodeBot is built, deployed and sent to the guest and family copies.", "rows": [
{"name": "build", "form": "npm run build", "what": "Builds a new release: type check first, then the web app and service; the served release stays until it succeeds."},
{"name": "deploy", "form": "sh ops/deploy.sh", "what": "Deploys the current code: builds, commits, pushes to the remote, restarts the service and checks it is live; refuses while a Bot is working."},
{"name": "check", "form": "npm run check", "what": "Runs the type check and then the tests."},
{"name": "typecheck", "form": "npm run typecheck", "what": "Checks the TypeScript without building anything."},
{"name": "tests", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server, not the real one."},
{"name": "QA copy build", "form": "npm run build:integration", "what": "Builds the disposable QA copy that runs on port 3506."},
{"name": "deploy guard", "form": "ops/deploy-guard.sh", "what": "Blocks finishing a turn while code is unpushed, newer than the running service, or newer than the served build."},
{"name": "guest update", "form": "ops/guest-update.sh", "what": "Rebuilds the guest copy in /opt/codebot-guest and restarts it; needs no password."},
{"name": "family update", "form": "ops/family-update.sh", "what": "Rebuilds /opt/codebot-family and restarts the front door and every family CodeBot; needs no password."}
]},
{"path": ["people"], "sentence": "The people who use CodeBot on this computer: the guest, the family CodeBots and each person's onboarding.", "rows": [
{"name": "guest", "form": "codebot people guest", "what": "Shows the guest screen: a second CodeBot account on this computer, run as its own Linux user."},
{"name": "family", "form": "codebot people family", "what": "Shows the family screen: one CodeBot for each family member who signs in on the home Wi-Fi."},
{"name": "onboarding", "form": "codebot people onboarding", "what": "Shows the onboarding screen: replaying or restarting a person's first-use tour."}
]},
{"path": ["people", "guest"], "sentence": "The guest CodeBot: its service, its sign-in invite, and how it is installed, updated or removed.", "rows": [
{"name": "status", "form": "systemctl status codebot-guest --no-pager", "what": "Prints whether the guest CodeBot service is running."},
{"name": "logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest CodeBot service log."},
{"name": "processes", "form": "ps -u codebot-guest", "what": "Lists the processes the guest CodeBot runs."},
{"name": "disk use", "form": "sudo du -sh /home/codebot-guest", "what": "Prints how much space the guest's home folder uses."},
{"name": "invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Creates a one-use Google sign-in link for the guest, valid for ten minutes."},
{"name": "install", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, folder, service, settings, sudo rules and Tailscale port 10000; run once, with the password."},
{"name": "update", "form": "ops/guest-update.sh", "what": "Rebuilds and restarts the guest CodeBot; needs no password."},
{"name": "share machine", "form": "Tailscale admin console: Machines, this machine, Share", "what": "Shows where to share this machine with the guest's Tailscale account instead of adding their device to the tailnet."},
{"name": "remove", "form": "ops/OPERATIONS.md, Host a guest on this machine", "what": "Shows the steps that remove the guest CodeBot, its user and its files; destructive, run by hand."}
]},
{"path": ["people", "family"], "sentence": "The family CodeBots: the helper that manages them, their logs, install and update, and what a full removal takes.", "rows": [
{"name": "helper", "form": "codebot people family helper", "what": "Shows the helper screen: the root commands that show, add, remove, stop and start family CodeBots."},
{"name": "logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the front door's and every family CodeBot's log."},
{"name": "home folders", "form": "ls /home | grep codebot-f", "what": "Lists the home folders of the family CodeBot users."},
{"name": "front door", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in, which sends a new Google account to its own CodeBot."},
{"name": "install", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, helper, services, sudo rules and nginx; run once, with the password."},
{"name": "remove all", "form": "ops/OPERATIONS.md, Home Wi-Fi address", "what": "Shows the steps that remove the whole family setup; destructive, run by hand."}
]},
{"path": ["people", "family", "helper"], "sentence": "The root helper for family CodeBots: the commands that show, add, remove, stop and start them.", "rows": [
{"name": "status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot: whether it runs and whether its Gmail can be connected."},
{"name": "add", "form": "sudo codebot-family add N", "what": "Creates family CodeBot N for a new Google account; numbers go up to six."},
{"name": "remove", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number; its Google account cannot be linked again without editing the account database."},
{"name": "stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
{"name": "start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot."},
{"name": "helper settings", "form": "/etc/codebot-family.conf", "what": "Opens the helper's settings file."}
]},
{"path": ["people", "onboarding"], "sentence": "Showing a person the onboarding again, or resetting their account on this computer.", "rows": [
{"name": "replay tour", "form": "ops/OPERATIONS.md, Replay only the first-use tour", "what": "Shows the steps that replay the first-use tour; it works only on a host with no Bots."},
{"name": "fresh CodeBot", "form": "ops/OPERATIONS.md, Restart onboarding with a fresh CodeBot, keeping the account", "what": "Shows the steps that wipe a host's Bots and conversations but keep its Google account."},
{"name": "full reset", "form": "ops/OPERATIONS.md, Full reset: the person starts as new", "what": "Shows the steps that delete an account with all its Bots, conversations, attachments and recordings; destructive."},
{"name": "identity check", "form": "https://liel.tail18e69e.ts.net:10000/api/onboarding/identity", "what": "Opens the guest host's identity, to confirm its serverId is unchanged after a wipe."},
{"name": "owner database", "form": "~/.local/share/codebot/codebot.sqlite", "what": "Opens the owner's host database, where a person's first-use receipt is kept."}
]},
{"path": ["data"], "sentence": "CodeBot's stored data on this computer: its database, its backups and how to restore one.", "rows": [
{"name": "data folder", "form": "~/.local/share/codebot", "what": "Opens the data folder: the database, attachments, recordings and the owner key."},
{"name": "database", "form": "~/.local/share/codebot/codebot.sqlite", "what": "Opens the owner's SQLite database; check it only with the read-only integrity check below."},
{"name": "integrity check", "form": "ops/OPERATIONS.md, Restore into a separate directory first", "what": "Checks a restored database with PRAGMA integrity_check and foreign-key checks, reading only."},
{"name": "back up", "form": "ops/OPERATIONS.md, Back up a consistent installation", "what": "Shows how to stop the service and copy its data, settings and unit file into a private backup folder."},
{"name": "backups", "form": "~/.local/share/codebot-backups", "what": "Opens the backup folders, one per UTC timestamp, each with SHA256SUMS."},
{"name": "verify backup", "form": "sha256sum -c SHA256SUMS", "what": "Checks a backup's files against their recorded checksums; run it in the backup folder."},
{"name": "restore", "form": "ops/OPERATIONS.md, Restore into a separate directory first", "what": "Shows how to restore a backup into an empty staging folder and inspect it before any promotion."},
{"name": "staging", "form": "~/.local/share/codebot-restore-staging", "what": "Opens the staging folder a backup is restored into first, so the original stays intact."},
{"name": "inspection copy", "form": "http://127.0.0.1:3508", "what": "Opens the restored copy on port 3508 in recovery hold, to check it before promotion."}
]},
{"path": ["account"], "sentence": "The central account service (Supabase) that handles sign-in and host arrival, and Gmail for Bots.", "rows": [
{"name": "supabase", "form": "codebot account supabase", "what": "Shows the supabase screen: the account service project, its token, its functions and its migrations."},
{"name": "gmail", "form": "codebot account gmail", "what": "Shows the gmail screen: how Bots connect Gmail and the Google app settings."},
{"name": "setup account", "form": "npm run setup-account", "what": "Runs ops/setup-account.ts to set this computer up with the account service."},
{"name": "sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Opens the sign-in entry that the host accepts arrivals from; the redirect list must include it."}
]},
{"path": ["account", "supabase"], "sentence": "The central account service's project: its identity, token, functions and database migrations.", "rows": [
{"name": "project", "form": "project ref wbgrjvqbupgdclaztuou", "what": "Identifies the account service project; its CLI needs the mobile-coder token, not the shell's Lebnor token."},
{"name": "token file", "form": "~/.config/supabase-codebot-token", "what": "Opens the account service's CLI token file (mode 600); never print it."},
{"name": "deploy host-access", "form": "SUPABASE_ACCESS_TOKEN=... npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function; run it whenever a contract it parses changes."},
{"name": "gmail-relay", "form": "supabase/functions/gmail-relay", "what": "Opens the Gmail relay function: one fixed address that forwards Google's return to the user's own server."},
{"name": "host-access", "form": "supabase/functions/host-access", "what": "Opens the host-access function that validates each host's sign-in arrival and rejects unknown fields."},
{"name": "migrations", "form": "supabase/migrations", "what": "Lists the account database's migrations in order."},
{"name": "first-use reset", "form": "ops/OPERATIONS.md, Replay only the first-use tour", "what": "Shows the SQL that restarts a person's first-use draft in the account database."}
]},
{"path": ["account", "gmail"], "sentence": "How Bots use Gmail: the guide, the generated reference, the review script and the Google app settings.", "rows": [
{"name": "guide", "form": "docs/automation/gmail.md", "what": "Opens the Gmail guide: the supervisor guide and the sign-in relay."},
{"name": "reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference of what Bots can do with it."},
{"name": "regenerate", "form": "npm run docs:gmail", "what": "Regenerates the Gmail reference from the code."},
{"name": "review", "form": "npm run review:gmail", "what": "Runs the Gmail review script, ops/review/gmail-review.mjs."},
{"name": "google app id", "form": "CODEBOT_GOOGLE_CLIENT_ID in ~/.config/codebot/service.env", "what": "Sets the Google app ID that lets Bots connect Gmail; without it Gmail stays off."},
{"name": "google app secret", "form": "CODEBOT_GOOGLE_CLIENT_SECRET in ~/.config/codebot/service.env", "what": "Sets the Google app secret; it is never printed and never placed in a VITE_ variable."},
{"name": "return address", "form": "CODEBOT_GOOGLE_REDIRECT_URI in ~/.config/codebot/service.env", "what": "Forces Google's return to one address; leave it empty normally."}
]},
{"path": ["project"], "sentence": "The project's own files: its documentation, its design, its apps and its operations.", "rows": [
{"name": "docs", "form": "codebot project docs", "what": "Shows the docs screen: the specs, architecture, plans and records."},
{"name": "design", "form": "codebot project design", "what": "Shows the design screen: design rules, mockups and the playground."},
{"name": "apps", "form": "codebot project apps", "what": "Shows the apps screen: the service, the web app, the control service, the shared contracts and the checks."},
{"name": "ops", "form": "codebot project ops", "what": "Shows the ops screen: the build, install and service files and the review scripts."}
]},
{"path": ["project", "docs"], "sentence": "The specs, architecture, plans, objectives and records of this project.", "rows": [
{"name": "product spec", "form": "PRODUCT-SPEC.md", "what": "Opens the product spec: the behaviour contract the code must match."},
{"name": "architecture", "form": "ARCHITECTURE.md", "what": "Opens the architecture: how CodeBot is built and where its boundaries are."},
{"name": "implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what was built before the first beta was paused."},
{"name": "deferred work", "form": "DEFERRED-WORK.md", "what": "Opens the deferred work list and the safe restart state."},
{"name": "docs folder", "form": "docs/", "what": "Opens the docs folder: method, onboarding proof, self-hosting practices and the host account exchange."},
{"name": "plans", "form": "docs/plans/", "what": "Opens the plans folder: one plan or design file for each earlier piece of work."},
{"name": "objectives", "form": "docs/objectives/", "what": "Opens the objectives: the goals for chat-current-session, gmail-widget, schedules and terminal-tabs."},
{"name": "verification records", "form": "docs/verification/", "what": "Opens the recorded verification evidence for bot questions and the self-hosted terminal."},
{"name": "module intents", "form": ".idd/modules/", "what": "Opens the module intents: one INTENT.md per module, with its constraints and test table."},
{"name": "housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Shows the codebot-housekeeping skill's instructions."}
]},
{"path": ["project", "design"], "sentence": "The design rules, reference images and playground for the app's screens.", "rows": [
{"name": "design taste", "form": "docs/design-taste.md", "what": "Shows the owner's design rulings and what they rejected; read it before changing a screen."},
{"name": "design method", "form": "docs/design-method.md", "what": "Shows the design method: research, variants and review in the real app."},
{"name": "design folder", "form": "design/", "what": "Opens the design folder: screenshots, annotated mockups, fixtures and feature-contract reference images."},
{"name": "playground", "form": "npm run playground", "what": "Starts a dev server on 127.0.0.1 and opens the Gmail playground page."},
{"name": "critiques", "form": ".impeccable/critique/", "what": "Opens the design critiques, one file for each reviewed component."}
]},
{"path": ["project", "apps"], "sentence": "The code of the apps and shared packages, the behaviour tests, and the environment example.", "rows": [
{"name": "service", "form": "apps/service/", "what": "Opens the service code: Bots, transcripts, git, avatars, host access and provider adapters."},
{"name": "web app", "form": "apps/web/", "what": "Opens the web app code: the screens the owner sees in the browser and on the phone."},
{"name": "control service", "form": "apps/control/", "what": "Opens the control service, which issues the signed host proofs."},
{"name": "contracts", "form": "packages/contracts/", "what": "Opens the shared schemas that the service and the client both validate against."},
{"name": "service tests", "form": "apps/service/test/", "what": "Opens the service tests that the npm test command runs."},
{"name": "behaviour features", "form": ".bdd/features/", "what": "Opens the Given/When/Then feature files for Bot features, with their steps and QA results in .bdd/."},
{"name": "avatar parts", "form": "apps/service/assets/avatar-parts/", "what": "Opens the avatar parts library (eyes, bodies, accessories, head shapes) that Bots are drawn from."},
{"name": "CI workflows", "form": ".github/workflows/check.yml", "what": "Shows the check workflow that runs in GitHub; supabase-keepalive.yml keeps the account service awake."},
{"name": "example settings", "form": ".env.example", "what": "Opens the example development settings; copy it to .env and never commit .env."}
]},
{"path": ["project", "ops"], "sentence": "The operations files: the runbook, service units, build script, example settings and review scripts.", "rows": [
{"name": "runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for running, recovering, backing up and resetting CodeBot."},
{"name": "service units", "form": "ops/*.service", "what": "Opens the systemd unit files: CodeBot, the terminal broker, the guest, the family front door and the family CodeBots."},
{"name": "environment example", "form": "ops/environment.example", "what": "Shows the example service settings; the real copy is ~/.config/codebot/service.env with mode 0600."},
{"name": "build script", "form": "ops/build.mjs", "what": "Opens the build script that publishes a release and swaps the served link."},
{"name": "review scripts", "form": "ops/review/", "what": "Opens the review scripts for Gmail, schedules, the Google redirect, the schedule drill and the terminal tabs stack."},
{"name": "sync agents", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."}
]}
],
"questions": [
"Scope: should the map include the phone app's own screens (Bot chat, settings, queue), or only the operations and project layer? Recommendation: only the operations and project layer; the app is reached through its address alone.",
"Destructive and sudo steps (full reset, fresh CodeBot, guest or family removal, restore promotion, emergency stop, sudo installs): should the CLI run them or only print them? Recommendation: only print them; the owner runs them in a real terminal.",
"Facade name: use codebot with no alias? Recommendation: codebot, plus a short alias only if whence -a shows it free (not checked here).",
"cli/codebot.py is mentioned in the README but is not in the file list. Does it exist? Recommendation: if yes, add its commands to the map; if no, fix the README line.",
"The service screen has 10 rows. Split it into start/stop/restart and files? Recommendation: keep one screen until it passes 12 rows.",
"Two plan folders: docs/plans/ and .plans/ (one file). Which is canonical? Recommendation: docs/plans/, and move the .plans/ file there."
]}
```

screen-decomposition, final · run 3 exit=0 seconds=145 · prompt

P1 Recall: 0.41P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.541
As terminal help
The CodeBot map: the app you watch Bots in, and the groups that run, check, back up, host and document it.
appcodebot appOpens the app screen: the private address and the steps to reach it from a device.
servicecodebot serviceOpens the service screen: start, stop, restart, read the logs and check that it answers.
checkscodebot checksOpens the checks screen: typecheck, build, test, the playground and the review scripts.
backupcodebot backupOpens the backup screen: back up, restore, and stop or roll back safely.
hostscodebot hostsOpens the hosts screen: the guest host, the family front door and changing the machine's address.
accountcodebot accountOpens the account screen: the Supabase account service, its functions and the onboarding resets.
docscodebot docsOpens the docs screen: the runbook, the architecture, the rules and the other written references.
app
The CodeBot app on your devices, and the private address and setup steps that reach it.
open the apphttps://liel.tail18e69e.ts.netOpens the app at the private address, where you watch and steer your Bots.
tailscale serve statustailscale serve status --jsonPrints how Tailscale maps the private address to the service on port 3505.
entrance key~/.local/share/codebot/owner-keyOpens the file with the entrance key a new device needs; keep it private.
connect a deviceops/OPERATIONS.md, 'Connect a device'Explains how to join a phone through Tailscale and install the app to its Home Screen.
background notificationsops/OPERATIONS.md, 'Background notifications'Explains how to turn on notifications for a device and what the host needs for them.
service
The service that runs CodeBot on this computer, and the commands that start, stop, read and check it.
developnpm run devStarts the service in watch mode, restarting on code changes, for development.
startnpm startStarts the service in production mode, the way codebot.service runs it.
statussystemctl --user status codebot.service --no-pagerPrints whether codebot.service is running and its recent state.
restartsystemctl --user restart codebot.serviceRestarts the service to load a new build, once active turns and recordings have finished.
stopsystemctl --user stop codebot.serviceStops the service: ends scheduling, interrupts Bot turns and finishes recordings.
logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 lines of the service log.
answering checkcurl --fail http://127.0.0.1:3505/api/sessionChecks that the service answers on port 3505 after a restart.
deploysh ops/deploy.shRuns the whole deploy: build, push, wait for Bots to finish, restart and verify.
diagnosticscodebot service diagnosticsOpens the diagnostics screen: the host's own readings, with no credentials.
terminal brokersystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the optional per-user terminal broker runs.
service › diagnostics
The diagnostic readings the signed-in owner can open from the running host: counters and lifecycle state, with no provider tokens.
hosthttps://liel.tail18e69e.ts.net/api/diagnostics/hostOpens the host reading: migration, event cursor, queued and running turns, and recovery hold.
schedulerhttps://liel.tail18e69e.ts.net/api/diagnostics/schedulerOpens the scheduler reading: its counters and lifecycle state.
visionhttps://liel.tail18e69e.ts.net/api/diagnostics/visionOpens the vision reading: its counters and lifecycle state.
notificationshttps://liel.tail18e69e.ts.net/api/notifications/diagnosticsOpens the notifications reading: the queue, the timer and the active sends.
checks
The commands that typecheck, build, test and review the project, and the playground.
typechecknpm run typecheckRuns tsc --noEmit to confirm the code compiles; it says little about Bot behavior.
buildnpm run buildRuns the typecheck, then builds a new release that the service serves.
checknpm run checkRuns the typecheck and the tests together.
testnpm testRuns the Gmail automation tests against a fake Google server, not the real one.
build integrationnpm run build:integrationRuns the typecheck, then ops/build-integration.mjs for the disposable QA instance on port 3506.
playgroundnpm run playgroundStarts Vite and opens the Gmail playground in the browser.
gmail reviewnpm run review:gmailRuns ops/review/gmail-review.mjs against the Gmail automation.
schedules reviewnpm run review:schedulesRuns ops/review/schedules-review.mjs against the schedules.
other review scriptsops/review/Opens the folder of scripts npm does not run: redirect-google, schedule-drill, seed-gmail and terminal-tabs-stack.
backup
How to back up CodeBot's data and settings, restore a copy into a separate folder, and stop or roll back safely.
back upops/OPERATIONS.md, 'Back up a consistent installation'Explains the stop, copy and start steps for a consistent backup; the archive holds sessions and keys.
restoreops/OPERATIONS.md, 'Restore into a separate directory first'Explains how to restore into a new folder and check the database before any promotion.
emergency stop and rollbackops/OPERATIONS.md, 'Emergency stop and rollback'Explains how to stop at once and roll back; a forced kill can lose uncommitted media.
hosts
The computers and addresses that host CodeBot besides the owner's own service: the guest host, the family front door and the machine's address.
guestcodebot hosts guestOpens the guest screen: the second CodeBot on this machine, run as its own Linux user.
familycodebot hosts familyOpens the family screen: the front door and one CodeBot per family member.
change the addressops/OPERATIONS.md, 'Change this machine's address'Explains the places to update when the machine's Tailscale name changes.
hosts › guest
The guest CodeBot on this machine: its setup, update, invite, status, logs and removal.
set upsudo ops/guest-install.shSets up the guest once: user, program folder, service, settings, sudo rules and port 10000.
updateops/guest-update.shBuilds the guest program, replaces /opt/codebot-guest and restarts it; needs no password.
invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google sign-in link for the guest, valid for ten minutes.
statussystemctl status codebot-guestPrints whether the guest service is running.
logsjournalctl -u codebot-guestPrints the guest service log.
disk usesudo du -sh /home/codebot-guestPrints how much disk the guest's data uses.
removeops/OPERATIONS.md, 'Host a guest on this machine'Explains the steps that remove the guest service, its user and its program.
hosts › family
The family front door and one CodeBot per family member, each in its own Linux user.
set upsudo ops/family-install.shSets up the front door user, helper, services, sudo rules and nginx, once.
updateops/family-update.shBuilds the family program and restarts every family CodeBot; needs no password.
statussudo codebot-family statusPrints which family CodeBots are running and whether each can connect Gmail.
add a membersudo codebot-family add NStarts a CodeBot for family member N, at most six in total.
remove a membersudo codebot-family remove NDeletes family CodeBot N and frees its number; the Google account stays linked.
stop allsudo codebot-family stop-allStops every family CodeBot.
start allsudo codebot-family start-allStarts every family CodeBot.
logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the logs of the front door and every family CodeBot.
home addressops/OPERATIONS.md, 'Home Wi-Fi address'Explains the home Wi-Fi address, its certificate, and how to reach it away from home.
remove everythingops/OPERATIONS.md, 'Home Wi-Fi address'Explains how to remove the whole family setup, including nginx and the certificate.
account
The central account service (Supabase) that handles sign-in, its functions, and the admin steps for onboarding.
setup accountnpm run setup-accountRuns ops/setup-account.ts, the account setup for this computer.
supabase projectwbgrjvqbupgdclaztuouShows which Supabase project holds the account service, under the mobile-coder login.
host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function with the token in ~/.config/supabase-codebot-token; redeploy when a contract it parses changes.
gmail relaysupabase/functions/gmail-relay/index.tsOpens the function that forwards Google sign-in back to the user's own server.
onboardingcodebot account onboardingOpens the onboarding screen: the replay, restart and full reset steps for one person.
account › onboarding
The admin steps that reset or replay one person's onboarding, on their host and in Supabase, and the onboarding records.
replay first-use tourops/OPERATIONS.md, 'Replay only the first-use tour'Explains how to replay the first-use tour; it works only when the host has no Bots.
restart with a fresh CodeBotops/OPERATIONS.md, 'Restart onboarding with a fresh CodeBot, keeping the account'Explains how to restart onboarding on a guest host and keep the person's account.
full resetops/OPERATIONS.md, 'Full reset: the person starts as new'Explains how to delete an account and its data so the person starts as new; destructive, not yet run.
onboarding implementationdocs/onboarding-implementation.mdOpens the record of how onboarding is built.
onboarding review gatedocs/onboarding-review-gate.mdOpens the review gate that onboarding must pass.
docs
The owner's written references: the runbook, the architecture, the rules, the product contract and the rest of the docs folder.
runbookops/OPERATIONS.mdOpens the runbook for running, backing up, hosting and resetting CodeBot.
architectureARCHITECTURE.mdOpens the technical boundaries: the volatility map, turns, transcript and persistence.
rulesCLAUDE.mdOpens the fundamentals every task assumes and the rules for designing screens.
overviewREADME.mdOpens the project overview, how the pieces fit, and the test commands.
product specPRODUCT-SPEC.mdOpens the behavior contract the product follows.
deferred workDEFERRED-WORK.mdOpens the remaining checklist and the safe restart state.
implementation statusIMPLEMENTATION-STATUS.mdOpens what was built before the first beta was paused.
master planMASTER-PLAN.mdOpens the release scope.
bot modelsops/OPERATIONS.md, 'Bot model selection'Explains which model a Bot uses by default, for ordinary messages and for /goal.
gmailcodebot docs gmailOpens the Gmail screen: the supervisor guide and its generated reference.
designcodebot docs designOpens the design screen: the method and the owner's rulings on screens.
plansdocs/plans/Opens the folder of plans, one per piece of work.
verificationdocs/verification/Opens the recorded verification evidence.
other docsdocs/Opens the docs folder: the remaining guides, such as self-hosting, agentic development and AI readiness.
docs › gmail
The Gmail for Bots guides: how to supervise it, and its generated reference.
supervisor guidedocs/automation/gmail.mdOpens the supervisor guide for Gmail for Bots.
referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference.
regeneratenpm run docs:gmailRegenerates docs/automation/gmail-reference.md from the code.
docs › design
The design method, and the owner's rulings on screens and what they rejected.
tastedocs/design-taste.mdOpens the owner's rulings on screens and what they rejected.
methoddocs/design-method.mdOpens the method for designing and reviewing a screen.
Questions
  • Facade name: the map uses 'codebot' (the project name) as the facade. Recommendation: keep 'codebot'; add a short alias only if 'whence -a' shows it is free.
  • Guest and family on this map: they are operator commands for hosts the owner runs. Recommendation: keep them here, and move them to their own map only if the hosts screen grows.
  • Four docs named by the README and CLAUDE.md (PRODUCT-SPEC.md, DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md, MASTER-PLAN.md) are not in the file tree. Recommendation: confirm they exist, and drop any that do not.
  • The entrance key row opens a secret file. Recommendation: keep it, marked 'keep it private', because a new device needs it.
  • The experimental V2 to V4 apps are left off because the README says they are not part of CodeBot. Recommendation: leave them off, or give them their own map.
As phone screens

Home

The CodeBot map: the app you watch Bots in, and the groups that run, check, back up, host and document it.

appOpens the app screen: the private address and the steps to reach it from a device.
›
serviceOpens the service screen: start, stop, restart, read the logs and check that it answers.
›
checksOpens the checks screen: typecheck, build, test, the playground and the review scripts.
›
backupOpens the backup screen: back up, restore, and stop or roll back safely.
›
hostsOpens the hosts screen: the guest host, the family front door and changing the machine's address.
›
accountOpens the account screen: the Supabase account service, its functions and the onboarding resets.
›
docsOpens the docs screen: the runbook, the architecture, the rules and the other written references.
›
‹ Home

app

The CodeBot app on your devices, and the private address and setup steps that reach it.

open the appOpens the app at the private address, where you watch and steer your Bots.
›
tailscale serve statusPrints how Tailscale maps the private address to the service on port 3505.
›
entrance keyOpens the file with the entrance key a new device needs; keep it private.
›
connect a deviceExplains how to join a phone through Tailscale and install the app to its Home Screen.
›
background notificationsExplains how to turn on notifications for a device and what the host needs for them.
›
‹ Home

service

The service that runs CodeBot on this computer, and the commands that start, stop, read and check it.

developStarts the service in watch mode, restarting on code changes, for development.
›
startStarts the service in production mode, the way codebot.service runs it.
›
statusPrints whether codebot.service is running and its recent state.
›
restartRestarts the service to load a new build, once active turns and recordings have finished.
›
stopStops the service: ends scheduling, interrupts Bot turns and finishes recordings.
›
logsPrints the last 80 lines of the service log.
›
answering checkChecks that the service answers on port 3505 after a restart.
›
deployRuns the whole deploy: build, push, wait for Bots to finish, restart and verify.
›
diagnosticsOpens the diagnostics screen: the host's own readings, with no credentials.
›
terminal brokerPrints whether the optional per-user terminal broker runs.
›
‹ service

diagnostics

The diagnostic readings the signed-in owner can open from the running host: counters and lifecycle state, with no provider tokens.

hostOpens the host reading: migration, event cursor, queued and running turns, and recovery hold.
›
schedulerOpens the scheduler reading: its counters and lifecycle state.
›
visionOpens the vision reading: its counters and lifecycle state.
›
notificationsOpens the notifications reading: the queue, the timer and the active sends.
›
‹ Home

checks

The commands that typecheck, build, test and review the project, and the playground.

typecheckRuns tsc --noEmit to confirm the code compiles; it says little about Bot behavior.
›
buildRuns the typecheck, then builds a new release that the service serves.
›
checkRuns the typecheck and the tests together.
›
testRuns the Gmail automation tests against a fake Google server, not the real one.
›
build integrationRuns the typecheck, then ops/build-integration.mjs for the disposable QA instance on port 3506.
›
playgroundStarts Vite and opens the Gmail playground in the browser.
›
gmail reviewRuns ops/review/gmail-review.mjs against the Gmail automation.
›
schedules reviewRuns ops/review/schedules-review.mjs against the schedules.
›
other review scriptsOpens the folder of scripts npm does not run: redirect-google, schedule-drill, seed-gmail and terminal-tabs-stack.
›
‹ Home

backup

How to back up CodeBot's data and settings, restore a copy into a separate folder, and stop or roll back safely.

back upExplains the stop, copy and start steps for a consistent backup; the archive holds sessions and keys.
›
restoreExplains how to restore into a new folder and check the database before any promotion.
›
emergency stop and rollbackExplains how to stop at once and roll back; a forced kill can lose uncommitted media.
›
‹ Home

hosts

The computers and addresses that host CodeBot besides the owner's own service: the guest host, the family front door and the machine's address.

guestOpens the guest screen: the second CodeBot on this machine, run as its own Linux user.
›
familyOpens the family screen: the front door and one CodeBot per family member.
›
change the addressExplains the places to update when the machine's Tailscale name changes.
›
‹ hosts

guest

The guest CodeBot on this machine: its setup, update, invite, status, logs and removal.

set upSets up the guest once: user, program folder, service, settings, sudo rules and port 10000.
›
updateBuilds the guest program, replaces /opt/codebot-guest and restarts it; needs no password.
›
invitePrints a one-use Google sign-in link for the guest, valid for ten minutes.
›
statusPrints whether the guest service is running.
›
logsPrints the guest service log.
›
disk usePrints how much disk the guest's data uses.
›
removeExplains the steps that remove the guest service, its user and its program.
›
‹ hosts

family

The family front door and one CodeBot per family member, each in its own Linux user.

set upSets up the front door user, helper, services, sudo rules and nginx, once.
›
updateBuilds the family program and restarts every family CodeBot; needs no password.
›
statusPrints which family CodeBots are running and whether each can connect Gmail.
›
add a memberStarts a CodeBot for family member N, at most six in total.
›
remove a memberDeletes family CodeBot N and frees its number; the Google account stays linked.
›
stop allStops every family CodeBot.
›
start allStarts every family CodeBot.
›
logsPrints the logs of the front door and every family CodeBot.
›
home addressExplains the home Wi-Fi address, its certificate, and how to reach it away from home.
›
remove everythingExplains how to remove the whole family setup, including nginx and the certificate.
›
‹ Home

account

The central account service (Supabase) that handles sign-in, its functions, and the admin steps for onboarding.

setup accountRuns ops/setup-account.ts, the account setup for this computer.
›
supabase projectShows which Supabase project holds the account service, under the mobile-coder login.
›
host-accessDeploys the host-access function with the token in ~/.config/supabase-codebot-token; redeploy when a contract it parses changes.
›
gmail relayOpens the function that forwards Google sign-in back to the user's own server.
›
onboardingOpens the onboarding screen: the replay, restart and full reset steps for one person.
›
‹ account

onboarding

The admin steps that reset or replay one person's onboarding, on their host and in Supabase, and the onboarding records.

replay first-use tourExplains how to replay the first-use tour; it works only when the host has no Bots.
›
restart with a fresh CodeBotExplains how to restart onboarding on a guest host and keep the person's account.
›
full resetExplains how to delete an account and its data so the person starts as new; destructive, not yet run.
›
onboarding implementationOpens the record of how onboarding is built.
›
onboarding review gateOpens the review gate that onboarding must pass.
›
‹ Home

docs

The owner's written references: the runbook, the architecture, the rules, the product contract and the rest of the docs folder.

runbookOpens the runbook for running, backing up, hosting and resetting CodeBot.
›
architectureOpens the technical boundaries: the volatility map, turns, transcript and persistence.
›
rulesOpens the fundamentals every task assumes and the rules for designing screens.
›
overviewOpens the project overview, how the pieces fit, and the test commands.
›
product specOpens the behavior contract the product follows.
›
deferred workOpens the remaining checklist and the safe restart state.
›
implementation statusOpens what was built before the first beta was paused.
›
master planOpens the release scope.
›
bot modelsExplains which model a Bot uses by default, for ordinary messages and for /goal.
›
gmailOpens the Gmail screen: the supervisor guide and its generated reference.
›
designOpens the design screen: the method and the owner's rulings on screens.
›
plansOpens the folder of plans, one per piece of work.
›
verificationOpens the recorded verification evidence.
›
other docsOpens the docs folder: the remaining guides, such as self-hosting, agentic development and AI readiness.
›
‹ docs

gmail

The Gmail for Bots guides: how to supervise it, and its generated reference.

supervisor guideOpens the supervisor guide for Gmail for Bots.
›
referenceOpens the generated Gmail reference.
›
regenerateRegenerates docs/automation/gmail-reference.md from the code.
›
‹ docs

design

The design method, and the owner's rulings on screens and what they rejected.

tasteOpens the owner's rulings on screens and what they rejected.
›
methodOpens the method for designing and reviewing a screen.
›
Raw answer
**Scenario** (reasoned from the runbook, not observed): The owner runs CodeBot on one computer. They reach for it to open the app from a phone, to check and restart the service after a change, to read a log or diagnostic when a Bot stalls, to back up or restore the data, to run the guest and family hosts, to move the private address, and to reset someone's onboarding.

**Inventory:** The rows in the JSON are the inventory. Each form says where the thing is defined: a file, a section of `ops/OPERATIONS.md`, an npm script, or a unit name.

**Judgment calls**
- The top screen has seven groups. That is within "a few". `backup` stays its own group because restores are rare and high-stakes, so it should not sit under a routine screen.
- `service` holds both the development and production starts, since the owner uses both. Each row says which.
- Left off, named once: the experimental V2 to V4 apps (README: "not part of CodeBot"); `codebot-preview.service` (retired, transient); `AGENTS.md` (generated, so `CLAUDE.md` is the source); `.claude/settings.json` and `ops/deploy-guard.sh` (agent hook); `.idd/`, `.bdd/`, `.impeccable/`, `.plans/` and `skills/codebot-housekeeping` (agent working files); the Windows terminal broker (disabled, not qualified per the runbook); `supabase/migrations` and the tests (not something the owner reaches); `ops/agent-start.sh` and `ops/avatar-thumbnails.ts` (purpose not stated in the dump).
- The README fragment mentions `cli/codebot.py`, but no `cli/` folder appears in the dump, so it has no row.
- `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md` and `MASTER-PLAN.md` are named by the README and `CLAUDE.md` but are not in the file tree. They are listed as rows; their existence is unverified.
- Forms such as `codebot service` are proposed facade paths. Nothing with that name exists yet.
- The dump is cut off: `OPERATIONS.md` at 32,000 characters, `ARCHITECTURE.md` at 14,000, and the file tree is summarised. Rows come only from what was visible.
- The reset procedures are marked in the runbook as not yet run; their rows say so.

**Questions**
1. **Facade name.** Recommend `codebot`, the project name. Add a short alias only if `whence -a` shows it is free.
2. **Guest and family on this map.** Recommend keeping them, since the owner runs both. Move them to their own map only if `hosts` grows.
3. **Four named docs not in the dump.** Recommend confirming that `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md` and `MASTER-PLAN.md` exist, and dropping any that do not.
4. **Entrance key row opens a secret file.** Recommend keeping it, marked "keep it private", because a new device needs it.
5. **V2 to V4 apps.** Recommend leaving them off, or giving them their own map.

```json
{"screens": [
{"path": [], "sentence": "The CodeBot map: the app you watch Bots in, and the groups that run, check, back up, host and document it.", "rows": [
{"name": "app", "form": "codebot app", "what": "Opens the app screen: the private address and the steps to reach it from a device."},
{"name": "service", "form": "codebot service", "what": "Opens the service screen: start, stop, restart, read the logs and check that it answers."},
{"name": "checks", "form": "codebot checks", "what": "Opens the checks screen: typecheck, build, test, the playground and the review scripts."},
{"name": "backup", "form": "codebot backup", "what": "Opens the backup screen: back up, restore, and stop or roll back safely."},
{"name": "hosts", "form": "codebot hosts", "what": "Opens the hosts screen: the guest host, the family front door and changing the machine's address."},
{"name": "account", "form": "codebot account", "what": "Opens the account screen: the Supabase account service, its functions and the onboarding resets."},
{"name": "docs", "form": "codebot docs", "what": "Opens the docs screen: the runbook, the architecture, the rules and the other written references."}
]},
{"path": ["app"], "sentence": "The CodeBot app on your devices, and the private address and setup steps that reach it.", "rows": [
{"name": "open the app", "form": "https://liel.tail18e69e.ts.net", "what": "Opens the app at the private address, where you watch and steer your Bots."},
{"name": "tailscale serve status", "form": "tailscale serve status --json", "what": "Prints how Tailscale maps the private address to the service on port 3505."},
{"name": "entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Opens the file with the entrance key a new device needs; keep it private."},
{"name": "connect a device", "form": "ops/OPERATIONS.md, 'Connect a device'", "what": "Explains how to join a phone through Tailscale and install the app to its Home Screen."},
{"name": "background notifications", "form": "ops/OPERATIONS.md, 'Background notifications'", "what": "Explains how to turn on notifications for a device and what the host needs for them."}
]},
{"path": ["service"], "sentence": "The service that runs CodeBot on this computer, and the commands that start, stop, read and check it.", "rows": [
{"name": "develop", "form": "npm run dev", "what": "Starts the service in watch mode, restarting on code changes, for development."},
{"name": "start", "form": "npm start", "what": "Starts the service in production mode, the way codebot.service runs it."},
{"name": "status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether codebot.service is running and its recent state."},
{"name": "restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service to load a new build, once active turns and recordings have finished."},
{"name": "stop", "form": "systemctl --user stop codebot.service", "what": "Stops the service: ends scheduling, interrupts Bot turns and finishes recordings."},
{"name": "logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 lines of the service log."},
{"name": "answering check", "form": "curl --fail http://127.0.0.1:3505/api/session", "what": "Checks that the service answers on port 3505 after a restart."},
{"name": "deploy", "form": "sh ops/deploy.sh", "what": "Runs the whole deploy: build, push, wait for Bots to finish, restart and verify."},
{"name": "diagnostics", "form": "codebot service diagnostics", "what": "Opens the diagnostics screen: the host's own readings, with no credentials."},
{"name": "terminal broker", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the optional per-user terminal broker runs."}
]},
{"path": ["service", "diagnostics"], "sentence": "The diagnostic readings the signed-in owner can open from the running host: counters and lifecycle state, with no provider tokens.", "rows": [
{"name": "host", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/host", "what": "Opens the host reading: migration, event cursor, queued and running turns, and recovery hold."},
{"name": "scheduler", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/scheduler", "what": "Opens the scheduler reading: its counters and lifecycle state."},
{"name": "vision", "form": "https://liel.tail18e69e.ts.net/api/diagnostics/vision", "what": "Opens the vision reading: its counters and lifecycle state."},
{"name": "notifications", "form": "https://liel.tail18e69e.ts.net/api/notifications/diagnostics", "what": "Opens the notifications reading: the queue, the timer and the active sends."}
]},
{"path": ["checks"], "sentence": "The commands that typecheck, build, test and review the project, and the playground.", "rows": [
{"name": "typecheck", "form": "npm run typecheck", "what": "Runs tsc --noEmit to confirm the code compiles; it says little about Bot behavior."},
{"name": "build", "form": "npm run build", "what": "Runs the typecheck, then builds a new release that the service serves."},
{"name": "check", "form": "npm run check", "what": "Runs the typecheck and the tests together."},
{"name": "test", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server, not the real one."},
{"name": "build integration", "form": "npm run build:integration", "what": "Runs the typecheck, then ops/build-integration.mjs for the disposable QA instance on port 3506."},
{"name": "playground", "form": "npm run playground", "what": "Starts Vite and opens the Gmail playground in the browser."},
{"name": "gmail review", "form": "npm run review:gmail", "what": "Runs ops/review/gmail-review.mjs against the Gmail automation."},
{"name": "schedules review", "form": "npm run review:schedules", "what": "Runs ops/review/schedules-review.mjs against the schedules."},
{"name": "other review scripts", "form": "ops/review/", "what": "Opens the folder of scripts npm does not run: redirect-google, schedule-drill, seed-gmail and terminal-tabs-stack."}
]},
{"path": ["backup"], "sentence": "How to back up CodeBot's data and settings, restore a copy into a separate folder, and stop or roll back safely.", "rows": [
{"name": "back up", "form": "ops/OPERATIONS.md, 'Back up a consistent installation'", "what": "Explains the stop, copy and start steps for a consistent backup; the archive holds sessions and keys."},
{"name": "restore", "form": "ops/OPERATIONS.md, 'Restore into a separate directory first'", "what": "Explains how to restore into a new folder and check the database before any promotion."},
{"name": "emergency stop and rollback", "form": "ops/OPERATIONS.md, 'Emergency stop and rollback'", "what": "Explains how to stop at once and roll back; a forced kill can lose uncommitted media."}
]},
{"path": ["hosts"], "sentence": "The computers and addresses that host CodeBot besides the owner's own service: the guest host, the family front door and the machine's address.", "rows": [
{"name": "guest", "form": "codebot hosts guest", "what": "Opens the guest screen: the second CodeBot on this machine, run as its own Linux user."},
{"name": "family", "form": "codebot hosts family", "what": "Opens the family screen: the front door and one CodeBot per family member."},
{"name": "change the address", "form": "ops/OPERATIONS.md, 'Change this machine's address'", "what": "Explains the places to update when the machine's Tailscale name changes."}
]},
{"path": ["hosts", "guest"], "sentence": "The guest CodeBot on this machine: its setup, update, invite, status, logs and removal.", "rows": [
{"name": "set up", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest once: user, program folder, service, settings, sudo rules and port 10000."},
{"name": "update", "form": "ops/guest-update.sh", "what": "Builds the guest program, replaces /opt/codebot-guest and restarts it; needs no password."},
{"name": "invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google sign-in link for the guest, valid for ten minutes."},
{"name": "status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest service is running."},
{"name": "logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest service log."},
{"name": "disk use", "form": "sudo du -sh /home/codebot-guest", "what": "Prints how much disk the guest's data uses."},
{"name": "remove", "form": "ops/OPERATIONS.md, 'Host a guest on this machine'", "what": "Explains the steps that remove the guest service, its user and its program."}
]},
{"path": ["hosts", "family"], "sentence": "The family front door and one CodeBot per family member, each in its own Linux user.", "rows": [
{"name": "set up", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, helper, services, sudo rules and nginx, once."},
{"name": "update", "form": "ops/family-update.sh", "what": "Builds the family program and restarts every family CodeBot; needs no password."},
{"name": "status", "form": "sudo codebot-family status", "what": "Prints which family CodeBots are running and whether each can connect Gmail."},
{"name": "add a member", "form": "sudo codebot-family add N", "what": "Starts a CodeBot for family member N, at most six in total."},
{"name": "remove a member", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number; the Google account stays linked."},
{"name": "stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
{"name": "start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot."},
{"name": "logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the logs of the front door and every family CodeBot."},
{"name": "home address", "form": "ops/OPERATIONS.md, 'Home Wi-Fi address'", "what": "Explains the home Wi-Fi address, its certificate, and how to reach it away from home."},
{"name": "remove everything", "form": "ops/OPERATIONS.md, 'Home Wi-Fi address'", "what": "Explains how to remove the whole family setup, including nginx and the certificate."}
]},
{"path": ["account"], "sentence": "The central account service (Supabase) that handles sign-in, its functions, and the admin steps for onboarding.", "rows": [
{"name": "setup account", "form": "npm run setup-account", "what": "Runs ops/setup-account.ts, the account setup for this computer."},
{"name": "supabase project", "form": "wbgrjvqbupgdclaztuou", "what": "Shows which Supabase project holds the account service, under the mobile-coder login."},
{"name": "host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function with the token in ~/.config/supabase-codebot-token; redeploy when a contract it parses changes."},
{"name": "gmail relay", "form": "supabase/functions/gmail-relay/index.ts", "what": "Opens the function that forwards Google sign-in back to the user's own server."},
{"name": "onboarding", "form": "codebot account onboarding", "what": "Opens the onboarding screen: the replay, restart and full reset steps for one person."}
]},
{"path": ["account", "onboarding"], "sentence": "The admin steps that reset or replay one person's onboarding, on their host and in Supabase, and the onboarding records.", "rows": [
{"name": "replay first-use tour", "form": "ops/OPERATIONS.md, 'Replay only the first-use tour'", "what": "Explains how to replay the first-use tour; it works only when the host has no Bots."},
{"name": "restart with a fresh CodeBot", "form": "ops/OPERATIONS.md, 'Restart onboarding with a fresh CodeBot, keeping the account'", "what": "Explains how to restart onboarding on a guest host and keep the person's account."},
{"name": "full reset", "form": "ops/OPERATIONS.md, 'Full reset: the person starts as new'", "what": "Explains how to delete an account and its data so the person starts as new; destructive, not yet run."},
{"name": "onboarding implementation", "form": "docs/onboarding-implementation.md", "what": "Opens the record of how onboarding is built."},
{"name": "onboarding review gate", "form": "docs/onboarding-review-gate.md", "what": "Opens the review gate that onboarding must pass."}
]},
{"path": ["docs"], "sentence": "The owner's written references: the runbook, the architecture, the rules, the product contract and the rest of the docs folder.", "rows": [
{"name": "runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for running, backing up, hosting and resetting CodeBot."},
{"name": "architecture", "form": "ARCHITECTURE.md", "what": "Opens the technical boundaries: the volatility map, turns, transcript and persistence."},
{"name": "rules", "form": "CLAUDE.md", "what": "Opens the fundamentals every task assumes and the rules for designing screens."},
{"name": "overview", "form": "README.md", "what": "Opens the project overview, how the pieces fit, and the test commands."},
{"name": "product spec", "form": "PRODUCT-SPEC.md", "what": "Opens the behavior contract the product follows."},
{"name": "deferred work", "form": "DEFERRED-WORK.md", "what": "Opens the remaining checklist and the safe restart state."},
{"name": "implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what was built before the first beta was paused."},
{"name": "master plan", "form": "MASTER-PLAN.md", "what": "Opens the release scope."},
{"name": "bot models", "form": "ops/OPERATIONS.md, 'Bot model selection'", "what": "Explains which model a Bot uses by default, for ordinary messages and for /goal."},
{"name": "gmail", "form": "codebot docs gmail", "what": "Opens the Gmail screen: the supervisor guide and its generated reference."},
{"name": "design", "form": "codebot docs design", "what": "Opens the design screen: the method and the owner's rulings on screens."},
{"name": "plans", "form": "docs/plans/", "what": "Opens the folder of plans, one per piece of work."},
{"name": "verification", "form": "docs/verification/", "what": "Opens the recorded verification evidence."},
{"name": "other docs", "form": "docs/", "what": "Opens the docs folder: the remaining guides, such as self-hosting, agentic development and AI readiness."}
]},
{"path": ["docs", "gmail"], "sentence": "The Gmail for Bots guides: how to supervise it, and its generated reference.", "rows": [
{"name": "supervisor guide", "form": "docs/automation/gmail.md", "what": "Opens the supervisor guide for Gmail for Bots."},
{"name": "reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference."},
{"name": "regenerate", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md from the code."}
]},
{"path": ["docs", "design"], "sentence": "The design method, and the owner's rulings on screens and what they rejected.", "rows": [
{"name": "taste", "form": "docs/design-taste.md", "what": "Opens the owner's rulings on screens and what they rejected."},
{"name": "method", "form": "docs/design-method.md", "what": "Opens the method for designing and reviewing a screen."}
]}
],
"questions": [
"Facade name: the map uses 'codebot' (the project name) as the facade. Recommendation: keep 'codebot'; add a short alias only if 'whence -a' shows it is free.",
"Guest and family on this map: they are operator commands for hosts the owner runs. Recommendation: keep them here, and move them to their own map only if the hosts screen grows.",
"Four docs named by the README and CLAUDE.md (PRODUCT-SPEC.md, DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md, MASTER-PLAN.md) are not in the file tree. Recommendation: confirm they exist, and drop any that do not.",
"The entrance key row opens a secret file. Recommendation: keep it, marked 'keep it private', because a new device needs it.",
"The experimental V2 to V4 apps are left off because the README says they are not part of CodeBot. Recommendation: leave them off, or give them their own map."
]}
```

No skill · run 4 exit=0 seconds=121 · prompt

P1 Recall: 0.205P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.566P5 Short top: 13P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.721
As terminal help
CodeBot on this computer: whether it is running, which Bots need you, and the areas below.
BotsbotsYour enduring coding teammates: chat, queue, files, settings.
TerminalterminalShell tabs on this computer, when the terminal broker is on.
GmailgmailGmail for Bots: connection, access, approvals, activity.
SchedulesschedulesWork that runs at set times.
WidgetswidgetsWhat appears on the main screen and in what order.
NotificationsnotificationsWhether alerts reach this device.
HosthostThis computer's service, address, diagnostics, backup and update.
FamilyfamilyFamily CodeBots on this machine.
GuestguestThe guest CodeBot, run as its own Linux user.
AccountaccountSign-in, the first-use tour and the server address.
SettingssettingsApp-wide preferences such as theme.
Developer commandsdevCheck, build, test, review and deploy commands run in the checkout.
Experimental appsexperimentsLocal V2 to V4 experiments in their own repositories.
bots
Every Bot on this host, with the ones that need you listed first.
A Botbots <bot>Open one Bot: its chat, queue, files, contract and settings.
New Botbots newCreate a Bot with a provider, a home folder and a model.
Bots needing youbots --needs-youOnly Bots waiting for a reply, an approval or an answer.
bots › new
Create a Bot: name, provider, home folder and model.
Providerbots new --provider <codex|claude|opencode>The engine that runs the Bot.
Home folderbots new --folder <path>Where the Bot works; must lie inside an allowed project root.
Modelbots new --model <name>Leave empty to use the automatic model policy.
bots › <bot>
One Bot: whether it is working, waiting for you or idle, and where you can step in.
Chatbots <bot> chatThe Bot's one conversation, with a divider at each new chat.
Queuebots <bot> queueMessages held behind the current reply.
Questions and approvalsbots <bot> questionsWhat the Bot is asking you and what it is waiting on.
Filesbots <bot> filesFiles the Bot made or you attached, and pinned files.
Contractbots <bot> contractThe Bot's current feature contract.
Browser viewbots <bot> visionLive view of the Bot's browser, with control handoff.
Screenshotsbots <bot> screenshotsCaptured screenshots, newest first.
Gitbots <bot> gitThe repository the Bot works in, with quick actions.
Earlier chatsbots <bot> historyPast chats, each with its label and kind of work.
Settingsbots <bot> settingsProvider, model, folder, skills, automatic actions and notifications.
Avatarbots <bot> avatarThe Bot's body, eyes, accessories and colours.
bots › <bot> › chat
The Bot's conversation: your messages, its replies and the chat dividers.
Send a messagebots <bot> send <text>Sends a message; it joins the queue if a reply is running.
Stop the replybots <bot> stopInterrupts the reply (Esc); the queue is kept.
Attach a filebots <bot> attach <path>Adds a file to the next message.
Queuebots <bot> queueMessages waiting behind the reply.
Earlier chatsbots <bot> historyPast chats of this Bot.
bots › <bot> › queue
Messages waiting behind the current reply, in order.
Take backbots <bot> queue takeReturns queued messages to the composer to edit and send again.
Send nowbots <bot> queue send-nowHands the queue over at once, interrupting the reply where the provider needs it.
bots › <bot> › questions
What the Bot is asking you, and which approvals it is waiting for.
Answer a questionbots <bot> answer <question>Replies to a question the Bot asked.
Approve or declinebots <bot> approve|decline <item>Decides a pending request from the Bot.
bots › <bot> › files
Files the Bot made or you attached, and the ones you pinned.
Pinned filesbots <bot> files --pinnedFiles you pinned so they stay at hand.
Show a filebots <bot> files show <name>Opens a file's preview.
Attach a filebots <bot> attach <path>Adds a file to the Bot.
bots › <bot> › contract
The Bot's current feature contract: its revisions, conflicts, files and components.
Historybots <bot> contract historyEach revision and what changed from the one before.
Conflictsbots <bot> contract conflictsPlaces where the contract disagrees with itself or with the Bot's work.
Filesbots <bot> contract filesFiles the contract covers and their state.
Components and relationshipsbots <bot> contract relationshipsHow the contract's components depend on each other.
bots › <bot> › contract › history
Each revision of the contract, in order, with before and after.
Show a revisionbots <bot> contract diff <revision>Shows what that revision changed.
bots › <bot> › contract › conflicts
Contract conflicts that need a decision before the Bot continues.
Resolve a conflictbots <bot> contract resolve <conflict>Records which side wins.
bots › <bot> › contract › files
The files the contract covers, and whether each matches the contract.
Show a filebots <bot> files show <name>Opens the file in the Bot's file view.
bots › <bot> › contract › relationships
How the contract's components relate to one another.
One componentbots <bot> contract relationships <component>Shows what this component depends on and what depends on it.
bots › <bot> › vision
Live view of the Bot's browser: take control, hand it back, or review recordings.
Recordingsbots <bot> vision recordingsSaved recordings of the Bot's browser.
Take controlbots <bot> vision controlPauses the Bot's browser automation and gives you control.
Give control backbots <bot> vision releaseResumes the Bot's browser automation.
bots › <bot> › vision › recordings
Saved recordings of the Bot's browser, newest first.
Play a recordingbots <bot> vision play <recording>Plays one recording.
bots › <bot> › screenshots
Screenshots the Bot captured, newest first.
Capture nowbots <bot> screenshotTakes a fresh capture into the gallery.
bots › <bot> › git
The repository the Bot works in: branch, changed files and quick actions.
Statusbots <bot> git statusShows the branch and changed files.
Commit and pushbots <bot> git pushSends commits to the remote; this leaves the machine, so confirm first.
bots › <bot> › history
Earlier chats of this Bot, each with its label and kind of work.
Open a chatbots <bot> chat <chat>Shows that chat's messages in the conversation view.
bots › <bot> › settings
One Bot's settings: provider, model, folder, skills, automatic actions and notifications.
Modelbots <bot> settings model <name>Pins a model; leave empty for the automatic policy.
Notifications for this Botbots <bot> settings notifications on|offWhether this Bot's replies, approvals and failures send alerts.
Skillsbots <bot> settings skillsSkills attached to the Bot.
Automatic actionsbots <bot> settings automaticWhat the Bot may do without asking.
bots › <bot> › avatar
The Bot's avatar: body, eyes, accessories and colours.
Set a partbots <bot> avatar set <part> <value>Chooses one avatar part.
terminal
Shell tabs pinned to this computer. Shown as off with the enabling step when the terminal broker is not running.
A tabterminal <tab>Opens one shell tab.
New tabterminal newStarts a shell in an allowed folder.
terminal › <tab>
One shell tab: its live output and keys.
Send keysterminal <tab> send <keys>Types into the shell.
Closeterminal <tab> closeEnds the shell in this tab.
gmail
Whether Gmail is connected for Bots, and what needs your decision.
Connectgmail connectStarts Google sign-in; it returns through the account service relay.
Accessgmail accessWhich Bots may read or send mail.
Approvalsgmail approvalsGmail actions waiting for your allowance.
Daily summarygmail dailyToday's digest: what arrived and what Bots handled.
Activitygmail activityWhat Bots did in Gmail, newest first.
gmail › access
Which Bots may read or send mail, and at what level.
Change a Bot's accessgmail access set <bot> <level>Grants or changes one Bot's Gmail level.
Revoke all accessgmail access revokeStops every Bot's Gmail access.
gmail › activity
What Bots did in Gmail, newest first.
Filter by Botgmail activity --bot <bot>Shows only one Bot's Gmail actions.
gmail › approvals
Gmail actions Bots want to take, waiting for you to allow or decline.
Approvegmail approve <item>Allows the action; it acts on your real mail, so confirm.
Declinegmail decline <item>Stops the action.
gmail › daily
Today's Gmail digest.
A past daygmail daily --date <yyyy-mm-dd>Shows the digest for another day.
schedules
Work set to run at fixed times: what is next and what ran last.
A scheduleschedules <schedule>Opens one schedule.
New scheduleschedules new --bot <bot> --at <time>Creates a schedule that wakes a Bot.
schedules › <schedule>
One schedule: when it fires, which Bot it wakes, and its last outcome.
Pause or resumeschedules <schedule> pause|resumeStops or restarts this schedule.
Run nowschedules <schedule> runStarts it now; any outward action it takes happens for real.
host
This computer's CodeBot: whether the service is up, its address, and its recovery state.
Open CodeBothttps://liel.tail18e69e.ts.net/The private address the owner uses from phone or desktop.
Local listener127.0.0.1:3505The loopback port the service binds; for diagnosis only.
Diagnosticshost diagnosticsQueued turns, event cursor, scheduler, vision and notifications.
Deviceshost devicesConnect a new phone or tablet.
Backup and restorehost backupCopy and restore the whole data folder.
Addresshost addressChange this machine's Tailscale name, which is also the sign-in address.
Updatehost updateWhether the running build is current, and how to deploy.
Restart the servicesystemctl --user restart codebot.serviceRestarts after active turns and recordings finish.
Logsjournalctl --user -u codebot.service -n 80The last 80 lines of the service log.
Allowed foldershost rootsShows the folders Bots may reach (CODEBOT_PROJECT_ROOTS).
Recovery holdhost recovery-hold on|offPauses automatic sends and schedules while you inspect.
host › diagnostics
Counters and lifecycle state: queued and running turns, scheduler timers, vision and notifications.
Host/api/diagnostics/hostMigration, event cursor, queued and running turns, recovery hold.
Scheduler/api/diagnostics/schedulerScheduler timers and their state.
Vision/api/diagnostics/visionBrowser vision counters.
Notifications/api/notifications/diagnosticsNotice queue, timer and active sends.
host › devices
Connect a new phone or tablet to this host.
Show the entrance keyhost owner-keyPrints the key the new device needs; it grants access, so keep it private.
Phone addresshttps://liel.tail18e69e.ts.net/Open on the phone with Tailscale on, then Install app.
host › backup
A stop-and-copy backup of the whole data folder, and restore into a separate folder first.
Make a backuphost backup createStops the service, copies the data, starts it again, and writes checksums.
Verify a backupsha256sum -c SHA256SUMSChecks a backup folder against its checksums.
Restore to a staging folderhost backup restore <dir>Restores into a new folder under recovery hold; never over a running install.
host › address
Changing this machine's Tailscale name, which doubles as the sign-in address.
Address checklistops/OPERATIONS.mdThe nine places to update, in order; follow it step by step.
host › update
Whether the running service matches the latest build, and how to deploy it.
Deploysh ops/deploy.shBuilds, pushes, waits for active turns, restarts and verifies.
Session check/api/sessionConfirms the service answers after a restart.
notifications
Whether this device gets Bot alerts.
Enable this devicenotifications enableAllows alerts on this device; the browser asks permission.
Send a testnotifications testSends a test alert to the selected device.
Reconnect this devicenotifications reconnectRenews an expired or rejected subscription.
Other devicesnotifications devicesDevices subscribed to alerts.
notifications › devices
Devices subscribed to alerts; up to 16 are kept.
Remove a devicenotifications devices remove <device>Removes an old subscription.
family
Family CodeBots: one per Google account, each with its own Linux user and port.
Statuscodebot-family statusWhich family CodeBots run and whether Gmail can connect.
Add a personsudo codebot-family add <N>Creates a family CodeBot in slot N (up to six).
Remove a personsudo codebot-family remove <N>Deletes that CodeBot and frees its number.
Start or stop allsudo codebot-family start-all|stop-allStarts or stops every family CodeBot.
Family addresshttps://family.codebot.lielbenor.comSign-in for family members; each CodeBot uses port 10100 plus N.
Updateops/family-update.shRebuilds and restarts all family CodeBots.
guest
The guest's CodeBot on this machine: its status, a one-use invite, updates and removal.
Invitesudo -u codebot-guest /opt/codebot-guest/inviteA one-use Google link, valid for ten minutes.
Statussystemctl status codebot-guestWhether the guest service is running.
Updateops/guest-update.shRebuilds the guest copy and restarts it.
Guest addresshttps://liel.tail18e69e.ts.net:10000The guest's address on this host, port 10000.
Removal stepsops/OPERATIONS.mdThe ordered steps to remove the guest completely.
account
Your sign-in and the server you are connected to.
Sign-in entryhttps://liel.tail18e69e.ts.net/onboardingWhere sign-in starts and Google returns.
Onboardingaccount onboardingThe first-use tour, and how it is replayed or reset.
Account serviceproject wbgrjvqbupgdclaztuou (Supabase)The central account service that holds sign-in and host bindings.
account › onboarding
The first-use tour for a person, and how to show it again.
Replay the tourops/OPERATIONS.mdRestarts only the tour; works only when the host has no Bots.
Full resetops/OPERATIONS.mdDeletes the person's account data; back up first.
settings
App-wide preferences.
Themesettings theme <light|dark>Chooses the light or dark look.
What's newwhats-newChanges since the last update.
widgets
Widgets on the main screen: which are shown and in what order.
Add a widgetwidgets add <widget>Puts a widget on the main screen.
Arrangewidgets arrangeChanges the order of the widgets.
Remove a widgetwidgets remove <widget>Takes a widget off the main screen.
dev
Commands for working on CodeBot in its checkout.
Checknpm run checkType check and the service tests.
Buildnpm run buildType check, then publish a new web release.
Testnpm testRuns the service tests.
Playgroundnpm run playgroundOpens the design variants in the browser.
Review Gmailnpm run review:gmailRuns the Gmail review against the real service and browser.
Review schedulesnpm run review:schedulesRuns the schedules review.
Gmail referencenpm run docs:gmailRegenerates the Gmail reference document.
Sync agent notesnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
Set up accountnpm run setup-accountRuns the account setup script for this host.
Build integrationnpm run build:integrationBuilds the integration instance on port 3506.
Deploysh ops/deploy.shBuilds, pushes and restarts the live service.
experiments
Three local experiments in their own repositories. They reuse this server's code but keep their own data.
V2 Terminal chat127.0.0.1:3512CodeBot's look, with each Bot's chat as the Claude Code terminal. Folder ~/projects/codebot-v2-terminal-chat.
V3 Claude Code mod127.0.0.1:3513Claude Code first, with a Bot list above the prompt. Folder ~/projects/codebot-v3-claude-mod.
V4 Launcher menu127.0.0.1:3514A simple main menu that sets up Claude Code sessions. Folder ~/projects/codebot-v4-launcher-menu.
Questions
  • Should operator and developer commands (host backup, guest, family, dev) share the owner's CLI, or sit in a separate admin help? Recommendation: separate them; the owner's everyday path is bots, gmail, schedules and notifications.
  • Include the experimental V2 to V4 apps at all? Recommendation: leave them out; they live in separate private repos outside CodeBot's scope. The rows above are there only in case you want them.
  • Show the terminal screen when the per-user broker is off? Recommendation: yes, shown as off with the enabling step, so the owner can see why it is missing.
  • May the CLI print the entrance key (host devices, host owner-key)? Recommendation: only with an explicit flag, never into logs, because the key grants access.
  • Which outward actions need a confirmation: git push, gmail approve, schedules run, and deploy? Recommendation: confirm each one interactively, with a --yes flag for scripts.
  • Keep family and guest as two separate nouns? Recommendation: yes for now; they use different mechanisms. Merge them into one people screen only if the guest is retired.
  • Gmail cards and the glance summary exist in the web app but are unclear as CLI screens. Recommendation: fold them into gmail activity and gmail daily until you say what you want to read there.
  • Bot config export and import are planned in docs/plans but not built. Recommendation: leave them out of the map until they exist.
  • The README names cli/codebot.py, which is not in the file list. Should the new CLI replace it or sit beside it? Recommendation: replace it, so there is one entry point.
As phone screens

Home

CodeBot on this computer: whether it is running, which Bots need you, and the areas below.

BotsYour enduring coding teammates: chat, queue, files, settings.
›
TerminalShell tabs on this computer, when the terminal broker is on.
›
GmailGmail for Bots: connection, access, approvals, activity.
›
SchedulesWork that runs at set times.
›
WidgetsWhat appears on the main screen and in what order.
›
NotificationsWhether alerts reach this device.
›
HostThis computer's service, address, diagnostics, backup and update.
›
FamilyFamily CodeBots on this machine.
›
GuestThe guest CodeBot, run as its own Linux user.
›
AccountSign-in, the first-use tour and the server address.
›
SettingsApp-wide preferences such as theme.
›
Developer commandsCheck, build, test, review and deploy commands run in the checkout.
›
Experimental appsLocal V2 to V4 experiments in their own repositories.
›
‹ Home

bots

Every Bot on this host, with the ones that need you listed first.

A BotOpen one Bot: its chat, queue, files, contract and settings.
›
New BotCreate a Bot with a provider, a home folder and a model.
›
Bots needing youOnly Bots waiting for a reply, an approval or an answer.
›
‹ bots

new

Create a Bot: name, provider, home folder and model.

ProviderThe engine that runs the Bot.
›
Home folderWhere the Bot works; must lie inside an allowed project root.
›
ModelLeave empty to use the automatic model policy.
›
‹ bots

<bot>

One Bot: whether it is working, waiting for you or idle, and where you can step in.

ChatThe Bot's one conversation, with a divider at each new chat.
›
QueueMessages held behind the current reply.
›
Questions and approvalsWhat the Bot is asking you and what it is waiting on.
›
FilesFiles the Bot made or you attached, and pinned files.
›
ContractThe Bot's current feature contract.
›
Browser viewLive view of the Bot's browser, with control handoff.
›
ScreenshotsCaptured screenshots, newest first.
›
GitThe repository the Bot works in, with quick actions.
›
Earlier chatsPast chats, each with its label and kind of work.
›
SettingsProvider, model, folder, skills, automatic actions and notifications.
›
AvatarThe Bot's body, eyes, accessories and colours.
›
‹ <bot>

chat

The Bot's conversation: your messages, its replies and the chat dividers.

Send a messageSends a message; it joins the queue if a reply is running.
›
Stop the replyInterrupts the reply (Esc); the queue is kept.
›
Attach a fileAdds a file to the next message.
›
QueueMessages waiting behind the reply.
›
Earlier chatsPast chats of this Bot.
›
‹ <bot>

queue

Messages waiting behind the current reply, in order.

Take backReturns queued messages to the composer to edit and send again.
›
Send nowHands the queue over at once, interrupting the reply where the provider needs it.
›
‹ <bot>

questions

What the Bot is asking you, and which approvals it is waiting for.

Answer a questionReplies to a question the Bot asked.
›
Approve or declineDecides a pending request from the Bot.
›
‹ <bot>

files

Files the Bot made or you attached, and the ones you pinned.

Pinned filesFiles you pinned so they stay at hand.
›
Show a fileOpens a file's preview.
›
Attach a fileAdds a file to the Bot.
›
‹ <bot>

contract

The Bot's current feature contract: its revisions, conflicts, files and components.

HistoryEach revision and what changed from the one before.
›
ConflictsPlaces where the contract disagrees with itself or with the Bot's work.
›
FilesFiles the contract covers and their state.
›
Components and relationshipsHow the contract's components depend on each other.
›
‹ contract

history

Each revision of the contract, in order, with before and after.

Show a revisionShows what that revision changed.
›
‹ contract

conflicts

Contract conflicts that need a decision before the Bot continues.

Resolve a conflictRecords which side wins.
›
‹ contract

files

The files the contract covers, and whether each matches the contract.

Show a fileOpens the file in the Bot's file view.
›
‹ contract

relationships

How the contract's components relate to one another.

One componentShows what this component depends on and what depends on it.
›
‹ <bot>

vision

Live view of the Bot's browser: take control, hand it back, or review recordings.

RecordingsSaved recordings of the Bot's browser.
›
Take controlPauses the Bot's browser automation and gives you control.
›
Give control backResumes the Bot's browser automation.
›
‹ vision

recordings

Saved recordings of the Bot's browser, newest first.

Play a recordingPlays one recording.
›
‹ <bot>

screenshots

Screenshots the Bot captured, newest first.

Capture nowTakes a fresh capture into the gallery.
›
‹ <bot>

git

The repository the Bot works in: branch, changed files and quick actions.

StatusShows the branch and changed files.
›
Commit and pushSends commits to the remote; this leaves the machine, so confirm first.
›
‹ <bot>

history

Earlier chats of this Bot, each with its label and kind of work.

Open a chatShows that chat's messages in the conversation view.
›
‹ <bot>

settings

One Bot's settings: provider, model, folder, skills, automatic actions and notifications.

ModelPins a model; leave empty for the automatic policy.
›
Notifications for this BotWhether this Bot's replies, approvals and failures send alerts.
›
SkillsSkills attached to the Bot.
›
Automatic actionsWhat the Bot may do without asking.
›
‹ <bot>

avatar

The Bot's avatar: body, eyes, accessories and colours.

Set a partChooses one avatar part.
›
‹ Home

terminal

Shell tabs pinned to this computer. Shown as off with the enabling step when the terminal broker is not running.

A tabOpens one shell tab.
›
New tabStarts a shell in an allowed folder.
›
‹ terminal

<tab>

One shell tab: its live output and keys.

Send keysTypes into the shell.
›
CloseEnds the shell in this tab.
›
‹ Home

gmail

Whether Gmail is connected for Bots, and what needs your decision.

ConnectStarts Google sign-in; it returns through the account service relay.
›
AccessWhich Bots may read or send mail.
›
ApprovalsGmail actions waiting for your allowance.
›
Daily summaryToday's digest: what arrived and what Bots handled.
›
ActivityWhat Bots did in Gmail, newest first.
›
‹ gmail

access

Which Bots may read or send mail, and at what level.

Change a Bot's accessGrants or changes one Bot's Gmail level.
›
Revoke all accessStops every Bot's Gmail access.
›
‹ gmail

activity

What Bots did in Gmail, newest first.

Filter by BotShows only one Bot's Gmail actions.
›
‹ gmail

approvals

Gmail actions Bots want to take, waiting for you to allow or decline.

ApproveAllows the action; it acts on your real mail, so confirm.
›
DeclineStops the action.
›
‹ gmail

daily

Today's Gmail digest.

A past dayShows the digest for another day.
›
‹ Home

schedules

Work set to run at fixed times: what is next and what ran last.

A scheduleOpens one schedule.
›
New scheduleCreates a schedule that wakes a Bot.
›
‹ schedules

<schedule>

One schedule: when it fires, which Bot it wakes, and its last outcome.

Pause or resumeStops or restarts this schedule.
›
Run nowStarts it now; any outward action it takes happens for real.
›
‹ Home

host

This computer's CodeBot: whether the service is up, its address, and its recovery state.

Open CodeBotThe private address the owner uses from phone or desktop.
›
Local listenerThe loopback port the service binds; for diagnosis only.
›
DiagnosticsQueued turns, event cursor, scheduler, vision and notifications.
›
DevicesConnect a new phone or tablet.
›
Backup and restoreCopy and restore the whole data folder.
›
AddressChange this machine's Tailscale name, which is also the sign-in address.
›
UpdateWhether the running build is current, and how to deploy.
›
Restart the serviceRestarts after active turns and recordings finish.
›
LogsThe last 80 lines of the service log.
›
Allowed foldersShows the folders Bots may reach (CODEBOT_PROJECT_ROOTS).
›
Recovery holdPauses automatic sends and schedules while you inspect.
›
‹ host

diagnostics

Counters and lifecycle state: queued and running turns, scheduler timers, vision and notifications.

HostMigration, event cursor, queued and running turns, recovery hold.
›
SchedulerScheduler timers and their state.
›
VisionBrowser vision counters.
›
NotificationsNotice queue, timer and active sends.
›
‹ host

devices

Connect a new phone or tablet to this host.

Show the entrance keyPrints the key the new device needs; it grants access, so keep it private.
›
Phone addressOpen on the phone with Tailscale on, then Install app.
›
‹ host

backup

A stop-and-copy backup of the whole data folder, and restore into a separate folder first.

Make a backupStops the service, copies the data, starts it again, and writes checksums.
›
Verify a backupChecks a backup folder against its checksums.
›
Restore to a staging folderRestores into a new folder under recovery hold; never over a running install.
›
‹ host

address

Changing this machine's Tailscale name, which doubles as the sign-in address.

Address checklistThe nine places to update, in order; follow it step by step.
›
‹ host

update

Whether the running service matches the latest build, and how to deploy it.

DeployBuilds, pushes, waits for active turns, restarts and verifies.
›
Session checkConfirms the service answers after a restart.
›
‹ Home

notifications

Whether this device gets Bot alerts.

Enable this deviceAllows alerts on this device; the browser asks permission.
›
Send a testSends a test alert to the selected device.
›
Reconnect this deviceRenews an expired or rejected subscription.
›
Other devicesDevices subscribed to alerts.
›
‹ notifications

devices

Devices subscribed to alerts; up to 16 are kept.

Remove a deviceRemoves an old subscription.
›
‹ Home

family

Family CodeBots: one per Google account, each with its own Linux user and port.

StatusWhich family CodeBots run and whether Gmail can connect.
›
Add a personCreates a family CodeBot in slot N (up to six).
›
Remove a personDeletes that CodeBot and frees its number.
›
Start or stop allStarts or stops every family CodeBot.
›
Family addressSign-in for family members; each CodeBot uses port 10100 plus N.
›
UpdateRebuilds and restarts all family CodeBots.
›
‹ Home

guest

The guest's CodeBot on this machine: its status, a one-use invite, updates and removal.

InviteA one-use Google link, valid for ten minutes.
›
StatusWhether the guest service is running.
›
UpdateRebuilds the guest copy and restarts it.
›
Guest addressThe guest's address on this host, port 10000.
›
Removal stepsThe ordered steps to remove the guest completely.
›
‹ Home

account

Your sign-in and the server you are connected to.

Sign-in entryWhere sign-in starts and Google returns.
›
OnboardingThe first-use tour, and how it is replayed or reset.
›
Account serviceThe central account service that holds sign-in and host bindings.
›
‹ account

onboarding

The first-use tour for a person, and how to show it again.

Replay the tourRestarts only the tour; works only when the host has no Bots.
›
Full resetDeletes the person's account data; back up first.
›
‹ Home

settings

App-wide preferences.

ThemeChooses the light or dark look.
›
What's newChanges since the last update.
›
‹ Home

widgets

Widgets on the main screen: which are shown and in what order.

Add a widgetPuts a widget on the main screen.
›
ArrangeChanges the order of the widgets.
›
Remove a widgetTakes a widget off the main screen.
›
‹ Home

dev

Commands for working on CodeBot in its checkout.

CheckType check and the service tests.
›
BuildType check, then publish a new web release.
›
TestRuns the service tests.
›
PlaygroundOpens the design variants in the browser.
›
Review GmailRuns the Gmail review against the real service and browser.
›
Review schedulesRuns the schedules review.
›
Gmail referenceRegenerates the Gmail reference document.
›
Sync agent notesRegenerates AGENTS.md from CLAUDE.md.
›
Set up accountRuns the account setup script for this host.
›
Build integrationBuilds the integration instance on port 3506.
›
DeployBuilds, pushes and restarts the live service.
›
‹ Home

experiments

Three local experiments in their own repositories. They reuse this server's code but keep their own data.

V2 Terminal chatCodeBot's look, with each Bot's chat as the Claude Code terminal. Folder ~/projects/codebot-v2-terminal-chat.
›
V3 Claude Code modClaude Code first, with a Bot list above the prompt. Folder ~/projects/codebot-v3-claude-mod.
›
V4 Launcher menuA simple main menu that sets up Claude Code sessions. Folder ~/projects/codebot-v4-launcher-menu.
›
Raw answer
This is a planning map only; nothing is built. It is built from the file dump, which cuts off `OPERATIONS.md` and `ARCHITECTURE.md`, so a few screens are inferred from file names: the Contract*, Gmail*, and Vision components. The owner is the main reader: phone-first, sign-in through Tailscale. Operator and developer commands are kept in separate branches so they can be split off. The questions field lists the choices that belong to you, each with my recommendation.

```json
{"screens": [
{"path": [], "sentence": "CodeBot on this computer: whether it is running, which Bots need you, and the areas below.", "rows": [
 {"name": "Bots", "form": "bots", "what": "Your enduring coding teammates: chat, queue, files, settings."},
 {"name": "Terminal", "form": "terminal", "what": "Shell tabs on this computer, when the terminal broker is on."},
 {"name": "Gmail", "form": "gmail", "what": "Gmail for Bots: connection, access, approvals, activity."},
 {"name": "Schedules", "form": "schedules", "what": "Work that runs at set times."},
 {"name": "Widgets", "form": "widgets", "what": "What appears on the main screen and in what order."},
 {"name": "Notifications", "form": "notifications", "what": "Whether alerts reach this device."},
 {"name": "Host", "form": "host", "what": "This computer's service, address, diagnostics, backup and update."},
 {"name": "Family", "form": "family", "what": "Family CodeBots on this machine."},
 {"name": "Guest", "form": "guest", "what": "The guest CodeBot, run as its own Linux user."},
 {"name": "Account", "form": "account", "what": "Sign-in, the first-use tour and the server address."},
 {"name": "Settings", "form": "settings", "what": "App-wide preferences such as theme."},
 {"name": "Developer commands", "form": "dev", "what": "Check, build, test, review and deploy commands run in the checkout."},
 {"name": "Experimental apps", "form": "experiments", "what": "Local V2 to V4 experiments in their own repositories."}
]},
{"path": ["bots"], "sentence": "Every Bot on this host, with the ones that need you listed first.", "rows": [
 {"name": "A Bot", "form": "bots <bot>", "what": "Open one Bot: its chat, queue, files, contract and settings."},
 {"name": "New Bot", "form": "bots new", "what": "Create a Bot with a provider, a home folder and a model."},
 {"name": "Bots needing you", "form": "bots --needs-you", "what": "Only Bots waiting for a reply, an approval or an answer."}
]},
{"path": ["bots", "new"], "sentence": "Create a Bot: name, provider, home folder and model.", "rows": [
 {"name": "Provider", "form": "bots new --provider <codex|claude|opencode>", "what": "The engine that runs the Bot."},
 {"name": "Home folder", "form": "bots new --folder <path>", "what": "Where the Bot works; must lie inside an allowed project root."},
 {"name": "Model", "form": "bots new --model <name>", "what": "Leave empty to use the automatic model policy."}
]},
{"path": ["bots", "<bot>"], "sentence": "One Bot: whether it is working, waiting for you or idle, and where you can step in.", "rows": [
 {"name": "Chat", "form": "bots <bot> chat", "what": "The Bot's one conversation, with a divider at each new chat."},
 {"name": "Queue", "form": "bots <bot> queue", "what": "Messages held behind the current reply."},
 {"name": "Questions and approvals", "form": "bots <bot> questions", "what": "What the Bot is asking you and what it is waiting on."},
 {"name": "Files", "form": "bots <bot> files", "what": "Files the Bot made or you attached, and pinned files."},
 {"name": "Contract", "form": "bots <bot> contract", "what": "The Bot's current feature contract."},
 {"name": "Browser view", "form": "bots <bot> vision", "what": "Live view of the Bot's browser, with control handoff."},
 {"name": "Screenshots", "form": "bots <bot> screenshots", "what": "Captured screenshots, newest first."},
 {"name": "Git", "form": "bots <bot> git", "what": "The repository the Bot works in, with quick actions."},
 {"name": "Earlier chats", "form": "bots <bot> history", "what": "Past chats, each with its label and kind of work."},
 {"name": "Settings", "form": "bots <bot> settings", "what": "Provider, model, folder, skills, automatic actions and notifications."},
 {"name": "Avatar", "form": "bots <bot> avatar", "what": "The Bot's body, eyes, accessories and colours."}
]},
{"path": ["bots", "<bot>", "chat"], "sentence": "The Bot's conversation: your messages, its replies and the chat dividers.", "rows": [
 {"name": "Send a message", "form": "bots <bot> send <text>", "what": "Sends a message; it joins the queue if a reply is running."},
 {"name": "Stop the reply", "form": "bots <bot> stop", "what": "Interrupts the reply (Esc); the queue is kept."},
 {"name": "Attach a file", "form": "bots <bot> attach <path>", "what": "Adds a file to the next message."},
 {"name": "Queue", "form": "bots <bot> queue", "what": "Messages waiting behind the reply."},
 {"name": "Earlier chats", "form": "bots <bot> history", "what": "Past chats of this Bot."}
]},
{"path": ["bots", "<bot>", "queue"], "sentence": "Messages waiting behind the current reply, in order.", "rows": [
 {"name": "Take back", "form": "bots <bot> queue take", "what": "Returns queued messages to the composer to edit and send again."},
 {"name": "Send now", "form": "bots <bot> queue send-now", "what": "Hands the queue over at once, interrupting the reply where the provider needs it."}
]},
{"path": ["bots", "<bot>", "questions"], "sentence": "What the Bot is asking you, and which approvals it is waiting for.", "rows": [
 {"name": "Answer a question", "form": "bots <bot> answer <question>", "what": "Replies to a question the Bot asked."},
 {"name": "Approve or decline", "form": "bots <bot> approve|decline <item>", "what": "Decides a pending request from the Bot."}
]},
{"path": ["bots", "<bot>", "files"], "sentence": "Files the Bot made or you attached, and the ones you pinned.", "rows": [
 {"name": "Pinned files", "form": "bots <bot> files --pinned", "what": "Files you pinned so they stay at hand."},
 {"name": "Show a file", "form": "bots <bot> files show <name>", "what": "Opens a file's preview."},
 {"name": "Attach a file", "form": "bots <bot> attach <path>", "what": "Adds a file to the Bot."}
]},
{"path": ["bots", "<bot>", "contract"], "sentence": "The Bot's current feature contract: its revisions, conflicts, files and components.", "rows": [
 {"name": "History", "form": "bots <bot> contract history", "what": "Each revision and what changed from the one before."},
 {"name": "Conflicts", "form": "bots <bot> contract conflicts", "what": "Places where the contract disagrees with itself or with the Bot's work."},
 {"name": "Files", "form": "bots <bot> contract files", "what": "Files the contract covers and their state."},
 {"name": "Components and relationships", "form": "bots <bot> contract relationships", "what": "How the contract's components depend on each other."}
]},
{"path": ["bots", "<bot>", "contract", "history"], "sentence": "Each revision of the contract, in order, with before and after.", "rows": [
 {"name": "Show a revision", "form": "bots <bot> contract diff <revision>", "what": "Shows what that revision changed."}
]},
{"path": ["bots", "<bot>", "contract", "conflicts"], "sentence": "Contract conflicts that need a decision before the Bot continues.", "rows": [
 {"name": "Resolve a conflict", "form": "bots <bot> contract resolve <conflict>", "what": "Records which side wins."}
]},
{"path": ["bots", "<bot>", "contract", "files"], "sentence": "The files the contract covers, and whether each matches the contract.", "rows": [
 {"name": "Show a file", "form": "bots <bot> files show <name>", "what": "Opens the file in the Bot's file view."}
]},
{"path": ["bots", "<bot>", "contract", "relationships"], "sentence": "How the contract's components relate to one another.", "rows": [
 {"name": "One component", "form": "bots <bot> contract relationships <component>", "what": "Shows what this component depends on and what depends on it."}
]},
{"path": ["bots", "<bot>", "vision"], "sentence": "Live view of the Bot's browser: take control, hand it back, or review recordings.", "rows": [
 {"name": "Recordings", "form": "bots <bot> vision recordings", "what": "Saved recordings of the Bot's browser."},
 {"name": "Take control", "form": "bots <bot> vision control", "what": "Pauses the Bot's browser automation and gives you control."},
 {"name": "Give control back", "form": "bots <bot> vision release", "what": "Resumes the Bot's browser automation."}
]},
{"path": ["bots", "<bot>", "vision", "recordings"], "sentence": "Saved recordings of the Bot's browser, newest first.", "rows": [
 {"name": "Play a recording", "form": "bots <bot> vision play <recording>", "what": "Plays one recording."}
]},
{"path": ["bots", "<bot>", "screenshots"], "sentence": "Screenshots the Bot captured, newest first.", "rows": [
 {"name": "Capture now", "form": "bots <bot> screenshot", "what": "Takes a fresh capture into the gallery."}
]},
{"path": ["bots", "<bot>", "git"], "sentence": "The repository the Bot works in: branch, changed files and quick actions.", "rows": [
 {"name": "Status", "form": "bots <bot> git status", "what": "Shows the branch and changed files."},
 {"name": "Commit and push", "form": "bots <bot> git push", "what": "Sends commits to the remote; this leaves the machine, so confirm first."}
]},
{"path": ["bots", "<bot>", "history"], "sentence": "Earlier chats of this Bot, each with its label and kind of work.", "rows": [
 {"name": "Open a chat", "form": "bots <bot> chat <chat>", "what": "Shows that chat's messages in the conversation view."}
]},
{"path": ["bots", "<bot>", "settings"], "sentence": "One Bot's settings: provider, model, folder, skills, automatic actions and notifications.", "rows": [
 {"name": "Model", "form": "bots <bot> settings model <name>", "what": "Pins a model; leave empty for the automatic policy."},
 {"name": "Notifications for this Bot", "form": "bots <bot> settings notifications on|off", "what": "Whether this Bot's replies, approvals and failures send alerts."},
 {"name": "Skills", "form": "bots <bot> settings skills", "what": "Skills attached to the Bot."},
 {"name": "Automatic actions", "form": "bots <bot> settings automatic", "what": "What the Bot may do without asking."}
]},
{"path": ["bots", "<bot>", "avatar"], "sentence": "The Bot's avatar: body, eyes, accessories and colours.", "rows": [
 {"name": "Set a part", "form": "bots <bot> avatar set <part> <value>", "what": "Chooses one avatar part."}
]},
{"path": ["terminal"], "sentence": "Shell tabs pinned to this computer. Shown as off with the enabling step when the terminal broker is not running.", "rows": [
 {"name": "A tab", "form": "terminal <tab>", "what": "Opens one shell tab."},
 {"name": "New tab", "form": "terminal new", "what": "Starts a shell in an allowed folder."}
]},
{"path": ["terminal", "<tab>"], "sentence": "One shell tab: its live output and keys.", "rows": [
 {"name": "Send keys", "form": "terminal <tab> send <keys>", "what": "Types into the shell."},
 {"name": "Close", "form": "terminal <tab> close", "what": "Ends the shell in this tab."}
]},
{"path": ["gmail"], "sentence": "Whether Gmail is connected for Bots, and what needs your decision.", "rows": [
 {"name": "Connect", "form": "gmail connect", "what": "Starts Google sign-in; it returns through the account service relay."},
 {"name": "Access", "form": "gmail access", "what": "Which Bots may read or send mail."},
 {"name": "Approvals", "form": "gmail approvals", "what": "Gmail actions waiting for your allowance."},
 {"name": "Daily summary", "form": "gmail daily", "what": "Today's digest: what arrived and what Bots handled."},
 {"name": "Activity", "form": "gmail activity", "what": "What Bots did in Gmail, newest first."}
]},
{"path": ["gmail", "access"], "sentence": "Which Bots may read or send mail, and at what level.", "rows": [
 {"name": "Change a Bot's access", "form": "gmail access set <bot> <level>", "what": "Grants or changes one Bot's Gmail level."},
 {"name": "Revoke all access", "form": "gmail access revoke", "what": "Stops every Bot's Gmail access."}
]},
{"path": ["gmail", "activity"], "sentence": "What Bots did in Gmail, newest first.", "rows": [
 {"name": "Filter by Bot", "form": "gmail activity --bot <bot>", "what": "Shows only one Bot's Gmail actions."}
]},
{"path": ["gmail", "approvals"], "sentence": "Gmail actions Bots want to take, waiting for you to allow or decline.", "rows": [
 {"name": "Approve", "form": "gmail approve <item>", "what": "Allows the action; it acts on your real mail, so confirm."},
 {"name": "Decline", "form": "gmail decline <item>", "what": "Stops the action."}
]},
{"path": ["gmail", "daily"], "sentence": "Today's Gmail digest.", "rows": [
 {"name": "A past day", "form": "gmail daily --date <yyyy-mm-dd>", "what": "Shows the digest for another day."}
]},
{"path": ["schedules"], "sentence": "Work set to run at fixed times: what is next and what ran last.", "rows": [
 {"name": "A schedule", "form": "schedules <schedule>", "what": "Opens one schedule."},
 {"name": "New schedule", "form": "schedules new --bot <bot> --at <time>", "what": "Creates a schedule that wakes a Bot."}
]},
{"path": ["schedules", "<schedule>"], "sentence": "One schedule: when it fires, which Bot it wakes, and its last outcome.", "rows": [
 {"name": "Pause or resume", "form": "schedules <schedule> pause|resume", "what": "Stops or restarts this schedule."},
 {"name": "Run now", "form": "schedules <schedule> run", "what": "Starts it now; any outward action it takes happens for real."}
]},
{"path": ["host"], "sentence": "This computer's CodeBot: whether the service is up, its address, and its recovery state.", "rows": [
 {"name": "Open CodeBot", "form": "https://liel.tail18e69e.ts.net/", "what": "The private address the owner uses from phone or desktop."},
 {"name": "Local listener", "form": "127.0.0.1:3505", "what": "The loopback port the service binds; for diagnosis only."},
 {"name": "Diagnostics", "form": "host diagnostics", "what": "Queued turns, event cursor, scheduler, vision and notifications."},
 {"name": "Devices", "form": "host devices", "what": "Connect a new phone or tablet."},
 {"name": "Backup and restore", "form": "host backup", "what": "Copy and restore the whole data folder."},
 {"name": "Address", "form": "host address", "what": "Change this machine's Tailscale name, which is also the sign-in address."},
 {"name": "Update", "form": "host update", "what": "Whether the running build is current, and how to deploy."},
 {"name": "Restart the service", "form": "systemctl --user restart codebot.service", "what": "Restarts after active turns and recordings finish."},
 {"name": "Logs", "form": "journalctl --user -u codebot.service -n 80", "what": "The last 80 lines of the service log."},
 {"name": "Allowed folders", "form": "host roots", "what": "Shows the folders Bots may reach (CODEBOT_PROJECT_ROOTS)."},
 {"name": "Recovery hold", "form": "host recovery-hold on|off", "what": "Pauses automatic sends and schedules while you inspect."}
]},
{"path": ["host", "diagnostics"], "sentence": "Counters and lifecycle state: queued and running turns, scheduler timers, vision and notifications.", "rows": [
 {"name": "Host", "form": "/api/diagnostics/host", "what": "Migration, event cursor, queued and running turns, recovery hold."},
 {"name": "Scheduler", "form": "/api/diagnostics/scheduler", "what": "Scheduler timers and their state."},
 {"name": "Vision", "form": "/api/diagnostics/vision", "what": "Browser vision counters."},
 {"name": "Notifications", "form": "/api/notifications/diagnostics", "what": "Notice queue, timer and active sends."}
]},
{"path": ["host", "devices"], "sentence": "Connect a new phone or tablet to this host.", "rows": [
 {"name": "Show the entrance key", "form": "host owner-key", "what": "Prints the key the new device needs; it grants access, so keep it private."},
 {"name": "Phone address", "form": "https://liel.tail18e69e.ts.net/", "what": "Open on the phone with Tailscale on, then Install app."}
]},
{"path": ["host", "backup"], "sentence": "A stop-and-copy backup of the whole data folder, and restore into a separate folder first.", "rows": [
 {"name": "Make a backup", "form": "host backup create", "what": "Stops the service, copies the data, starts it again, and writes checksums."},
 {"name": "Verify a backup", "form": "sha256sum -c SHA256SUMS", "what": "Checks a backup folder against its checksums."},
 {"name": "Restore to a staging folder", "form": "host backup restore <dir>", "what": "Restores into a new folder under recovery hold; never over a running install."}
]},
{"path": ["host", "address"], "sentence": "Changing this machine's Tailscale name, which doubles as the sign-in address.", "rows": [
 {"name": "Address checklist", "form": "ops/OPERATIONS.md", "what": "The nine places to update, in order; follow it step by step."}
]},
{"path": ["host", "update"], "sentence": "Whether the running service matches the latest build, and how to deploy it.", "rows": [
 {"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, pushes, waits for active turns, restarts and verifies."},
 {"name": "Session check", "form": "/api/session", "what": "Confirms the service answers after a restart."}
]},
{"path": ["notifications"], "sentence": "Whether this device gets Bot alerts.", "rows": [
 {"name": "Enable this device", "form": "notifications enable", "what": "Allows alerts on this device; the browser asks permission."},
 {"name": "Send a test", "form": "notifications test", "what": "Sends a test alert to the selected device."},
 {"name": "Reconnect this device", "form": "notifications reconnect", "what": "Renews an expired or rejected subscription."},
 {"name": "Other devices", "form": "notifications devices", "what": "Devices subscribed to alerts."}
]},
{"path": ["notifications", "devices"], "sentence": "Devices subscribed to alerts; up to 16 are kept.", "rows": [
 {"name": "Remove a device", "form": "notifications devices remove <device>", "what": "Removes an old subscription."}
]},
{"path": ["family"], "sentence": "Family CodeBots: one per Google account, each with its own Linux user and port.", "rows": [
 {"name": "Status", "form": "codebot-family status", "what": "Which family CodeBots run and whether Gmail can connect."},
 {"name": "Add a person", "form": "sudo codebot-family add <N>", "what": "Creates a family CodeBot in slot N (up to six)."},
 {"name": "Remove a person", "form": "sudo codebot-family remove <N>", "what": "Deletes that CodeBot and frees its number."},
 {"name": "Start or stop all", "form": "sudo codebot-family start-all|stop-all", "what": "Starts or stops every family CodeBot."},
 {"name": "Family address", "form": "https://family.codebot.lielbenor.com", "what": "Sign-in for family members; each CodeBot uses port 10100 plus N."},
 {"name": "Update", "form": "ops/family-update.sh", "what": "Rebuilds and restarts all family CodeBots."}
]},
{"path": ["guest"], "sentence": "The guest's CodeBot on this machine: its status, a one-use invite, updates and removal.", "rows": [
 {"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "A one-use Google link, valid for ten minutes."},
 {"name": "Status", "form": "systemctl status codebot-guest", "what": "Whether the guest service is running."},
 {"name": "Update", "form": "ops/guest-update.sh", "what": "Rebuilds the guest copy and restarts it."},
 {"name": "Guest address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "The guest's address on this host, port 10000."},
 {"name": "Removal steps", "form": "ops/OPERATIONS.md", "what": "The ordered steps to remove the guest completely."}
]},
{"path": ["account"], "sentence": "Your sign-in and the server you are connected to.", "rows": [
 {"name": "Sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Where sign-in starts and Google returns."},
 {"name": "Onboarding", "form": "account onboarding", "what": "The first-use tour, and how it is replayed or reset."},
 {"name": "Account service", "form": "project wbgrjvqbupgdclaztuou (Supabase)", "what": "The central account service that holds sign-in and host bindings."}
]},
{"path": ["account", "onboarding"], "sentence": "The first-use tour for a person, and how to show it again.", "rows": [
 {"name": "Replay the tour", "form": "ops/OPERATIONS.md", "what": "Restarts only the tour; works only when the host has no Bots."},
 {"name": "Full reset", "form": "ops/OPERATIONS.md", "what": "Deletes the person's account data; back up first."}
]},
{"path": ["settings"], "sentence": "App-wide preferences.", "rows": [
 {"name": "Theme", "form": "settings theme <light|dark>", "what": "Chooses the light or dark look."},
 {"name": "What's new", "form": "whats-new", "what": "Changes since the last update."}
]},
{"path": ["widgets"], "sentence": "Widgets on the main screen: which are shown and in what order.", "rows": [
 {"name": "Add a widget", "form": "widgets add <widget>", "what": "Puts a widget on the main screen."},
 {"name": "Arrange", "form": "widgets arrange", "what": "Changes the order of the widgets."},
 {"name": "Remove a widget", "form": "widgets remove <widget>", "what": "Takes a widget off the main screen."}
]},
{"path": ["dev"], "sentence": "Commands for working on CodeBot in its checkout.", "rows": [
 {"name": "Check", "form": "npm run check", "what": "Type check and the service tests."},
 {"name": "Build", "form": "npm run build", "what": "Type check, then publish a new web release."},
 {"name": "Test", "form": "npm test", "what": "Runs the service tests."},
 {"name": "Playground", "form": "npm run playground", "what": "Opens the design variants in the browser."},
 {"name": "Review Gmail", "form": "npm run review:gmail", "what": "Runs the Gmail review against the real service and browser."},
 {"name": "Review schedules", "form": "npm run review:schedules", "what": "Runs the schedules review."},
 {"name": "Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates the Gmail reference document."},
 {"name": "Sync agent notes", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."},
 {"name": "Set up account", "form": "npm run setup-account", "what": "Runs the account setup script for this host."},
 {"name": "Build integration", "form": "npm run build:integration", "what": "Builds the integration instance on port 3506."},
 {"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, pushes and restarts the live service."}
]},
{"path": ["experiments"], "sentence": "Three local experiments in their own repositories. They reuse this server's code but keep their own data.", "rows": [
 {"name": "V2 Terminal chat", "form": "127.0.0.1:3512", "what": "CodeBot's look, with each Bot's chat as the Claude Code terminal. Folder ~/projects/codebot-v2-terminal-chat."},
 {"name": "V3 Claude Code mod", "form": "127.0.0.1:3513", "what": "Claude Code first, with a Bot list above the prompt. Folder ~/projects/codebot-v3-claude-mod."},
 {"name": "V4 Launcher menu", "form": "127.0.0.1:3514", "what": "A simple main menu that sets up Claude Code sessions. Folder ~/projects/codebot-v4-launcher-menu."}
]}
],
"questions": [
 "Should operator and developer commands (host backup, guest, family, dev) share the owner's CLI, or sit in a separate admin help? Recommendation: separate them; the owner's everyday path is bots, gmail, schedules and notifications.",
 "Include the experimental V2 to V4 apps at all? Recommendation: leave them out; they live in separate private repos outside CodeBot's scope. The rows above are there only in case you want them.",
 "Show the terminal screen when the per-user broker is off? Recommendation: yes, shown as off with the enabling step, so the owner can see why it is missing.",
 "May the CLI print the entrance key (host devices, host owner-key)? Recommendation: only with an explicit flag, never into logs, because the key grants access.",
 "Which outward actions need a confirmation: git push, gmail approve, schedules run, and deploy? Recommendation: confirm each one interactively, with a --yes flag for scripts.",
 "Keep family and guest as two separate nouns? Recommendation: yes for now; they use different mechanisms. Merge them into one people screen only if the guest is retired.",
 "Gmail cards and the glance summary exist in the web app but are unclear as CLI screens. Recommendation: fold them into gmail activity and gmail daily until you say what you want to read there.",
 "Bot config export and import are planned in docs/plans but not built. Recommendation: leave them out of the map until they exist.",
 "The README names cli/codebot.py, which is not in the file list. Should the new CLI replace it or sit beside it? Recommendation: replace it, so there is one entry point."
]}
```

Today's skills · run 4 exit=0 seconds=100 · prompt

P1 Recall: 0.513P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.4
As terminal help
The CodeBot project: the host that runs the Bots, the apps behind it, its docs and checks, its settings, and the account service that signs people in.
Runcodebot runPrints the run screen: starting, stopping and checking the host on this computer.
Operationscodebot opsPrints the operations screen: the runbooks for updating, backing up, moving and hosting CodeBot.
Appscodebot appsPrints the apps screen: the folders that hold the service, the web app, the control service and the shared contracts.
Docscodebot docsPrints the docs screen: the guides, plans, design record and recorded evidence.
Testcodebot testPrints the test screen: the checks, the reviews and the record of what was specified and found.
Configcodebot configPrints the config screen: the host's private settings, data folder, project folders and installed service.
Account servicecodebot accountPrints the account screen: the Supabase sign-in service, its functions, migrations and dashboard.
run
Starting, stopping and checking the CodeBot host on this computer.
Development hostnpm run devStarts the host in development, reloading on each code change, on port 3505 by default.
Owner's host statussystemctl --user status codebot.service --no-pagerPrints whether the owner's installed host is running and its recent state.
Owner's host restartsystemctl --user restart codebot.serviceRestarts the owner's installed host after a build, once no Bot is working.
Owner's host stopsystemctl --user stop codebot.serviceStops the owner's installed host, interrupting Bot turns and finishing recordings.
Owner's host logjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the owner's host.
Port listenerss -ltnp 'sport = :3505'Prints which process holds port 3505, so you can find the host before stopping it.
Session checkcurl --fail --silent http://127.0.0.1:3505/api/sessionChecks that the host answers on this computer.
Host diagnosticshttp://127.0.0.1:3505/api/diagnostics/hostOpens the host's diagnostics in the browser, after sign-in.
Owner's addresshttps://liel.tail18e69e.ts.net/Opens the owner's private host in a browser.
ops
The runbooks for keeping the installed CodeBot running: updating it, protecting its data and moving it.
Update the hostsh ops/deploy.sh (after npm run build)Runs the update: build, push, restart and verify the host, waiting while a Bot is working.
Back upops/OPERATIONS.md#back-up-a-consistent-installationOpens the backup steps: stop the host, copy its data folder and check the copy.
Restoreops/OPERATIONS.md#restore-into-a-separate-directory-firstOpens the restore steps: check a backup in a separate folder before it replaces live data.
Emergency stopops/OPERATIONS.md#emergency-stop-and-rollbackOpens the emergency stop and rollback steps.
Diagnoseops/OPERATIONS.md#diagnose-without-exposing-credentialsOpens the steps for reading the host's status without exposing credentials.
Change addressops/OPERATIONS.md#change-this-machines-addressOpens the nine places to change when the machine's Tailscale name changes.
Bot modelsops/OPERATIONS.md#bot-model-selectionOpens the default model for each provider, for ordinary messages and for /goal messages.
Hostingcodebot ops hostingPrints the hosting screen: guest and family CodeBots and the terminal broker.
Peoplecodebot ops peoplePrints the people screen: connecting devices, notifications and onboarding resets.
ops › hosting
Other people's CodeBots that run on this machine, and the terminal broker.
Guest setupsudo ops/guest-install.shRuns the one-time guest setup: user, program folder, service, settings, sudo rules and port 10000.
Guest updateops/guest-update.shRuns the guest update: builds, replaces the guest's program and restarts it.
Guest inviteops/OPERATIONS.md#host-a-guest-on-this-machineOpens the invite steps for a one-use Google link valid for ten minutes.
Family front doorops/codebot-family-lobby.serviceOpens the family front door's service file: Google sign-in on port 3530.
Family statussudo codebot-family statusPrints each family CodeBot, whether it runs, and whether Gmail can connect.
Family setupsudo ops/family-install.shRuns the one-time family setup: front door user, helper, services, sudo rules and nginx.
Family updateops/family-update.shRuns the update for the front door and every family CodeBot, then restarts them.
Family add or removesudo codebot-family add N | remove NRuns add or remove for one family number; remove deletes that CodeBot and frees its number.
Terminal brokersystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the per-user terminal broker is running.
ops › people
Connecting a person's device, their notifications, and resetting their onboarding.
Connect a deviceops/OPERATIONS.md#connect-a-deviceOpens the steps for connecting a new phone or laptop; the entrance key is read by hand, never printed.
Notificationsops/OPERATIONS.md#background-notificationsOpens the push notification setup and the checks for a device.
Replay first-use tourops/OPERATIONS.md#replay-only-the-first-use-tourOpens the steps that replay the first-use tour for one person.
Restart onboardingops/OPERATIONS.md#restart-onboarding-with-a-fresh-codebot-keeping-the-accountOpens the steps that give a person a fresh CodeBot and keep their account.
Full resetops/OPERATIONS.md#full-reset-the-person-starts-as-newOpens the steps that delete a person's data and account, which destroys their data.
apps
The folders that hold the code of CodeBot's parts: the service, the web app, the control service and the shared contracts.
Serviceapps/service/Opens the local service: Bots, providers, transcripts, git, avatars and host access.
Providersapps/service/src/providers/Opens the provider adapters for Claude, Codex and OpenCode.
Terminalapps/service/src/terminal/Opens the terminal code: the broker and the Linux and Windows sessions.
Web appapps/web/Opens the web app, the interface you watch and steer Bots from.
Playgroundnpm run playgroundStarts the playground in the browser to compare screen variants.
Control serviceapps/control/Opens the trusted control service that signs host proofs.
Shared contractspackages/contracts/Opens the schemas that the service and the client share.
Avatar partsapps/service/assets/avatar-parts/Opens the avatar art: bodies, eyes, accessories and heads.
docs
The written guides, plans and records about CodeBot.
OverviewREADME.mdOpens the project overview and how to run it.
ArchitectureARCHITECTURE.mdOpens how CodeBot is built: its boundaries, invariants and volatility.
Working rulesCLAUDE.mdOpens the rules every agent follows on this project; AGENTS.md is generated from it.
Operations runbookops/OPERATIONS.mdOpens the full runbook for the installed host.
Plansdocs/plans/Opens the plan documents, one per piece of work.
Objectivesdocs/objectives/Opens the objectives for chat, Gmail, schedules and terminal tabs.
Gmail guidedocs/automation/gmail.mdOpens the Gmail guide for Bots: setup and supervision.
Gmail referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference; npm run docs:gmail rewrites it.
Verification recordsdocs/verification/Opens the recorded verification evidence.
Designcodebot docs designPrints the design screen: the method, the owner's rulings and the reference images.
Housekeeping skillskills/codebot-housekeeping/SKILL.mdOpens the housekeeping skill that agents use on this project.
Changes for the ownerapps/web/src/whatsNew.tsOpens the list of changes the owner is told about after an update.
docs › design
How CodeBot's screens are designed: the method, the owner's rulings and the reference images.
Design methoddocs/design-method.mdOpens the method for designing or reworking any screen.
Owner's rulingsdocs/design-taste.mdOpens what the owner accepted and rejected, so it is not proposed again.
Screenshotsdesign/Opens the design screenshots: main, create bot, mobile chat and content previews.
Annotated screenshotsdesign/annotated/Opens the screenshots with the design notes drawn on them.
Onboarding referencesdesign/onboarding/grokbot-reference/Opens the onboarding reference screens.
Feature contract diagramsdesign/streamables/feature-contract/Opens the feature contract diagrams: backend, endpoints, files, components and types.
Terminal referencesdesign/reference/Opens the remote terminal reference screenshots.
test
The checks that prove CodeBot works, the reviews of its screens, and the record of what was specified and found.
Type checknpm run typecheckRuns the type check over the whole project; no output means it compiles.
Unit testsnpm testRuns the Gmail automation tests against a fake Google server.
Both checksnpm run checkRuns the type check and the tests together.
Buildnpm run buildRuns the type check, then builds the release into dist/releases.
Gmail reviewnpm run review:gmailRuns the Gmail review against the real service, build and browser.
Schedules reviewnpm run review:schedulesRuns the schedules review.
Schedule drillops/review/schedule-drill.mjsOpens the script for the schedule drill.
CI checks.github/workflows/check.ymlOpens the CI workflow that runs the checks.
Recordscodebot test recordsPrints the records screen: feature files, step code, QA findings and module intents.
test › records
The record of what was specified and found: feature files, step code, QA findings and module intents.
Feature files.bdd/features/Opens the Given-When-Then feature files, one folder per feature.
Step code.bdd/steps/Opens the code behind the feature steps.
QA findings.bdd/qa/findings/Opens the QA findings from browser runs.
QA resolutions.bdd/qa/resolutions/Opens how each QA finding was resolved.
Module intents.idd/modules/Opens each module's intent: its constraints and the tests that prove them.
config
The host's settings: its private settings file, its data folder, its project folders and its installed service.
Private settings~/.config/codebot/service.envOpens the host's private settings file (mode 0600); its secrets are never printed here.
Settings templateops/environment.exampleOpens the template for the private settings, with each setting explained.
Dev settings template.env.exampleOpens the template for the settings of the dev run.
Data folder~/.local/share/codebotOpens the host's data folder: database, owner key and recordings.
Project folders~/projectsOpens the project folders that Bots may reach (CODEBOT_PROJECT_ROOTS).
Installed service~/.config/systemd/user/codebot.serviceOpens the installed service unit that runs the host.
Service templateops/codebot.serviceOpens the service template the installed unit is copied from.
account
The central sign-in service: its database, its functions, and the dashboard that runs it.
Supabase projecthttps://supabase.com/dashboard/project/wbgrjvqbupgdclaztuouOpens the account service's dashboard in the browser, under the mobile-coder login.
Migrationssupabase/migrations/Opens the database migrations, one per schema change.
Gmail relaysupabase/functions/gmail-relay/Opens the Gmail relay that returns Google sign-in to each person's server.
Host accesssupabase/functions/host-access/Opens the host access function that checks arrivals and host bindings.
Deploy host accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys host-access live to the account service; confirm first.
Onboarding resetops/OPERATIONS.md#reset-someones-onboardingOpens the steps that reset a person's onboarding in the account database.
Keepalive.github/workflows/supabase-keepalive.ymlOpens the workflow that keeps the account service awake.
Service configurationsupabase/config.tomlOpens the account service's configuration file.
Questions
  • Does cli/codebot.py already exist? README mentions it in a garbled line, and the dump's listing was cut before the root files. If it exists, the facade should reuse it, not add a second command. Recommendation: check it before building.
  • Facade name and alias: codebot, with cb as the short alias? Recommendation: yes. Names still need the whence/type clash check, which I could not run.
  • Which commands may run from the CLI? Recommendation: read-only checks, build and test run directly. Restart, stop, deploy, the setup and update scripts, family remove and the account deploy ask for confirmation first, since they change the live service or outside systems.
  • Should the CLI print secrets? Recommendation: no. The owner key and the invite link stay in runbook rows only, so nothing prints them.
  • Should the ops screens be split further (address and models into their own screen)? Recommendation: keep the current split until a screen shows more than about nine rows.
  • Scope: include the experimental V2 to V4 apps (separate repos, per README) and runtime Bot data? Recommendation: exclude both. The apps are reachable by a note only, and the app already shows Bot data.
  • Unverified paths: the dump was truncated, and these are named in the docs but not confirmed in the listing: PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md, DEFERRED-WORK.md, ops/deploy.sh, ops/guest-install.sh, ops/guest-update.sh, ops/family-install.sh, ops/family-update.sh, ops/terminal-broker.ts and the codebot-family helper. Recommendation: verify each exists before the build step, since a missing row makes a broken link.
As phone screens

Home

The CodeBot project: the host that runs the Bots, the apps behind it, its docs and checks, its settings, and the account service that signs people in.

RunPrints the run screen: starting, stopping and checking the host on this computer.
›
OperationsPrints the operations screen: the runbooks for updating, backing up, moving and hosting CodeBot.
›
AppsPrints the apps screen: the folders that hold the service, the web app, the control service and the shared contracts.
›
DocsPrints the docs screen: the guides, plans, design record and recorded evidence.
›
TestPrints the test screen: the checks, the reviews and the record of what was specified and found.
›
ConfigPrints the config screen: the host's private settings, data folder, project folders and installed service.
›
Account servicePrints the account screen: the Supabase sign-in service, its functions, migrations and dashboard.
›
‹ Home

run

Starting, stopping and checking the CodeBot host on this computer.

Development hostStarts the host in development, reloading on each code change, on port 3505 by default.
›
Owner's host statusPrints whether the owner's installed host is running and its recent state.
›
Owner's host restartRestarts the owner's installed host after a build, once no Bot is working.
›
Owner's host stopStops the owner's installed host, interrupting Bot turns and finishing recordings.
›
Owner's host logPrints the last 80 log lines of the owner's host.
›
Port listenerPrints which process holds port 3505, so you can find the host before stopping it.
›
Session checkChecks that the host answers on this computer.
›
Host diagnosticsOpens the host's diagnostics in the browser, after sign-in.
›
Owner's addressOpens the owner's private host in a browser.
›
‹ Home

ops

The runbooks for keeping the installed CodeBot running: updating it, protecting its data and moving it.

Update the hostRuns the update: build, push, restart and verify the host, waiting while a Bot is working.
›
Back upOpens the backup steps: stop the host, copy its data folder and check the copy.
›
RestoreOpens the restore steps: check a backup in a separate folder before it replaces live data.
›
Emergency stopOpens the emergency stop and rollback steps.
›
DiagnoseOpens the steps for reading the host's status without exposing credentials.
›
Change addressOpens the nine places to change when the machine's Tailscale name changes.
›
Bot modelsOpens the default model for each provider, for ordinary messages and for /goal messages.
›
HostingPrints the hosting screen: guest and family CodeBots and the terminal broker.
›
PeoplePrints the people screen: connecting devices, notifications and onboarding resets.
›
‹ ops

hosting

Other people's CodeBots that run on this machine, and the terminal broker.

Guest setupRuns the one-time guest setup: user, program folder, service, settings, sudo rules and port 10000.
›
Guest updateRuns the guest update: builds, replaces the guest's program and restarts it.
›
Guest inviteOpens the invite steps for a one-use Google link valid for ten minutes.
›
Family front doorOpens the family front door's service file: Google sign-in on port 3530.
›
Family statusPrints each family CodeBot, whether it runs, and whether Gmail can connect.
›
Family setupRuns the one-time family setup: front door user, helper, services, sudo rules and nginx.
›
Family updateRuns the update for the front door and every family CodeBot, then restarts them.
›
Family add or removeRuns add or remove for one family number; remove deletes that CodeBot and frees its number.
›
Terminal brokerPrints whether the per-user terminal broker is running.
›
‹ ops

people

Connecting a person's device, their notifications, and resetting their onboarding.

Connect a deviceOpens the steps for connecting a new phone or laptop; the entrance key is read by hand, never printed.
›
NotificationsOpens the push notification setup and the checks for a device.
›
Replay first-use tourOpens the steps that replay the first-use tour for one person.
›
Restart onboardingOpens the steps that give a person a fresh CodeBot and keep their account.
›
Full resetOpens the steps that delete a person's data and account, which destroys their data.
›
‹ Home

apps

The folders that hold the code of CodeBot's parts: the service, the web app, the control service and the shared contracts.

ServiceOpens the local service: Bots, providers, transcripts, git, avatars and host access.
›
ProvidersOpens the provider adapters for Claude, Codex and OpenCode.
›
TerminalOpens the terminal code: the broker and the Linux and Windows sessions.
›
Web appOpens the web app, the interface you watch and steer Bots from.
›
PlaygroundStarts the playground in the browser to compare screen variants.
›
Control serviceOpens the trusted control service that signs host proofs.
›
Shared contractsOpens the schemas that the service and the client share.
›
Avatar partsOpens the avatar art: bodies, eyes, accessories and heads.
›
‹ Home

docs

The written guides, plans and records about CodeBot.

OverviewOpens the project overview and how to run it.
›
ArchitectureOpens how CodeBot is built: its boundaries, invariants and volatility.
›
Working rulesOpens the rules every agent follows on this project; AGENTS.md is generated from it.
›
Operations runbookOpens the full runbook for the installed host.
›
PlansOpens the plan documents, one per piece of work.
›
ObjectivesOpens the objectives for chat, Gmail, schedules and terminal tabs.
›
Gmail guideOpens the Gmail guide for Bots: setup and supervision.
›
Gmail referenceOpens the generated Gmail reference; npm run docs:gmail rewrites it.
›
Verification recordsOpens the recorded verification evidence.
›
DesignPrints the design screen: the method, the owner's rulings and the reference images.
›
Housekeeping skillOpens the housekeeping skill that agents use on this project.
›
Changes for the ownerOpens the list of changes the owner is told about after an update.
›
‹ docs

design

How CodeBot's screens are designed: the method, the owner's rulings and the reference images.

Design methodOpens the method for designing or reworking any screen.
›
Owner's rulingsOpens what the owner accepted and rejected, so it is not proposed again.
›
ScreenshotsOpens the design screenshots: main, create bot, mobile chat and content previews.
›
Annotated screenshotsOpens the screenshots with the design notes drawn on them.
›
Onboarding referencesOpens the onboarding reference screens.
›
Feature contract diagramsOpens the feature contract diagrams: backend, endpoints, files, components and types.
›
Terminal referencesOpens the remote terminal reference screenshots.
›
‹ Home

test

The checks that prove CodeBot works, the reviews of its screens, and the record of what was specified and found.

Type checkRuns the type check over the whole project; no output means it compiles.
›
Unit testsRuns the Gmail automation tests against a fake Google server.
›
Both checksRuns the type check and the tests together.
›
BuildRuns the type check, then builds the release into dist/releases.
›
Gmail reviewRuns the Gmail review against the real service, build and browser.
›
Schedules reviewRuns the schedules review.
›
Schedule drillOpens the script for the schedule drill.
›
CI checksOpens the CI workflow that runs the checks.
›
RecordsPrints the records screen: feature files, step code, QA findings and module intents.
›
‹ test

records

The record of what was specified and found: feature files, step code, QA findings and module intents.

Feature filesOpens the Given-When-Then feature files, one folder per feature.
›
Step codeOpens the code behind the feature steps.
›
QA findingsOpens the QA findings from browser runs.
›
QA resolutionsOpens how each QA finding was resolved.
›
Module intentsOpens each module's intent: its constraints and the tests that prove them.
›
‹ Home

config

The host's settings: its private settings file, its data folder, its project folders and its installed service.

Private settingsOpens the host's private settings file (mode 0600); its secrets are never printed here.
›
Settings templateOpens the template for the private settings, with each setting explained.
›
Dev settings templateOpens the template for the settings of the dev run.
›
Data folderOpens the host's data folder: database, owner key and recordings.
›
Project foldersOpens the project folders that Bots may reach (CODEBOT_PROJECT_ROOTS).
›
Installed serviceOpens the installed service unit that runs the host.
›
Service templateOpens the service template the installed unit is copied from.
›
‹ Home

account

The central sign-in service: its database, its functions, and the dashboard that runs it.

Supabase projectOpens the account service's dashboard in the browser, under the mobile-coder login.
›
MigrationsOpens the database migrations, one per schema change.
›
Gmail relayOpens the Gmail relay that returns Google sign-in to each person's server.
›
Host accessOpens the host access function that checks arrivals and host bindings.
›
Deploy host accessDeploys host-access live to the account service; confirm first.
›
Onboarding resetOpens the steps that reset a person's onboarding in the account database.
›
KeepaliveOpens the workflow that keeps the account service awake.
›
Service configurationOpens the account service's configuration file.
›
Raw answer
The map below has 10 screens and 7 top-level groups. I made these calls:

- **Top screen:** seven groups, so the first screen stays short.
- **`ops`:** split into `hosting` and `people`, so no screen has more than about nine rows. Whether to split further is a question below.
- **Secrets:** the entrance key and the one-use invite link are never printed by a command. Their rows open the runbook steps instead.
- **Excluded:** the experimental V2–V4 apps (separate repos) and runtime Bot data, which the app already shows.
- **Unverified:** the file listing in the dump was truncated, so the paths I could not see are marked in the questions. I could not run `whence`, so no names are checked against existing commands.

```json
{"screens": [
 {"path": [], "sentence": "The CodeBot project: the host that runs the Bots, the apps behind it, its docs and checks, its settings, and the account service that signs people in.", "rows": [
  {"name": "Run", "form": "codebot run", "what": "Prints the run screen: starting, stopping and checking the host on this computer."},
  {"name": "Operations", "form": "codebot ops", "what": "Prints the operations screen: the runbooks for updating, backing up, moving and hosting CodeBot."},
  {"name": "Apps", "form": "codebot apps", "what": "Prints the apps screen: the folders that hold the service, the web app, the control service and the shared contracts."},
  {"name": "Docs", "form": "codebot docs", "what": "Prints the docs screen: the guides, plans, design record and recorded evidence."},
  {"name": "Test", "form": "codebot test", "what": "Prints the test screen: the checks, the reviews and the record of what was specified and found."},
  {"name": "Config", "form": "codebot config", "what": "Prints the config screen: the host's private settings, data folder, project folders and installed service."},
  {"name": "Account service", "form": "codebot account", "what": "Prints the account screen: the Supabase sign-in service, its functions, migrations and dashboard."}
 ]},
 {"path": ["run"], "sentence": "Starting, stopping and checking the CodeBot host on this computer.", "rows": [
  {"name": "Development host", "form": "npm run dev", "what": "Starts the host in development, reloading on each code change, on port 3505 by default."},
  {"name": "Owner's host status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether the owner's installed host is running and its recent state."},
  {"name": "Owner's host restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the owner's installed host after a build, once no Bot is working."},
  {"name": "Owner's host stop", "form": "systemctl --user stop codebot.service", "what": "Stops the owner's installed host, interrupting Bot turns and finishing recordings."},
  {"name": "Owner's host log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the owner's host."},
  {"name": "Port listener", "form": "ss -ltnp 'sport = :3505'", "what": "Prints which process holds port 3505, so you can find the host before stopping it."},
  {"name": "Session check", "form": "curl --fail --silent http://127.0.0.1:3505/api/session", "what": "Checks that the host answers on this computer."},
  {"name": "Host diagnostics", "form": "http://127.0.0.1:3505/api/diagnostics/host", "what": "Opens the host's diagnostics in the browser, after sign-in."},
  {"name": "Owner's address", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the owner's private host in a browser."}
 ]},
 {"path": ["ops"], "sentence": "The runbooks for keeping the installed CodeBot running: updating it, protecting its data and moving it.", "rows": [
  {"name": "Update the host", "form": "sh ops/deploy.sh (after npm run build)", "what": "Runs the update: build, push, restart and verify the host, waiting while a Bot is working."},
  {"name": "Back up", "form": "ops/OPERATIONS.md#back-up-a-consistent-installation", "what": "Opens the backup steps: stop the host, copy its data folder and check the copy."},
  {"name": "Restore", "form": "ops/OPERATIONS.md#restore-into-a-separate-directory-first", "what": "Opens the restore steps: check a backup in a separate folder before it replaces live data."},
  {"name": "Emergency stop", "form": "ops/OPERATIONS.md#emergency-stop-and-rollback", "what": "Opens the emergency stop and rollback steps."},
  {"name": "Diagnose", "form": "ops/OPERATIONS.md#diagnose-without-exposing-credentials", "what": "Opens the steps for reading the host's status without exposing credentials."},
  {"name": "Change address", "form": "ops/OPERATIONS.md#change-this-machines-address", "what": "Opens the nine places to change when the machine's Tailscale name changes."},
  {"name": "Bot models", "form": "ops/OPERATIONS.md#bot-model-selection", "what": "Opens the default model for each provider, for ordinary messages and for /goal messages."},
  {"name": "Hosting", "form": "codebot ops hosting", "what": "Prints the hosting screen: guest and family CodeBots and the terminal broker."},
  {"name": "People", "form": "codebot ops people", "what": "Prints the people screen: connecting devices, notifications and onboarding resets."}
 ]},
 {"path": ["ops", "hosting"], "sentence": "Other people's CodeBots that run on this machine, and the terminal broker.", "rows": [
  {"name": "Guest setup", "form": "sudo ops/guest-install.sh", "what": "Runs the one-time guest setup: user, program folder, service, settings, sudo rules and port 10000."},
  {"name": "Guest update", "form": "ops/guest-update.sh", "what": "Runs the guest update: builds, replaces the guest's program and restarts it."},
  {"name": "Guest invite", "form": "ops/OPERATIONS.md#host-a-guest-on-this-machine", "what": "Opens the invite steps for a one-use Google link valid for ten minutes."},
  {"name": "Family front door", "form": "ops/codebot-family-lobby.service", "what": "Opens the family front door's service file: Google sign-in on port 3530."},
  {"name": "Family status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot, whether it runs, and whether Gmail can connect."},
  {"name": "Family setup", "form": "sudo ops/family-install.sh", "what": "Runs the one-time family setup: front door user, helper, services, sudo rules and nginx."},
  {"name": "Family update", "form": "ops/family-update.sh", "what": "Runs the update for the front door and every family CodeBot, then restarts them."},
  {"name": "Family add or remove", "form": "sudo codebot-family add N | remove N", "what": "Runs add or remove for one family number; remove deletes that CodeBot and frees its number."},
  {"name": "Terminal broker", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the per-user terminal broker is running."}
 ]},
 {"path": ["ops", "people"], "sentence": "Connecting a person's device, their notifications, and resetting their onboarding.", "rows": [
  {"name": "Connect a device", "form": "ops/OPERATIONS.md#connect-a-device", "what": "Opens the steps for connecting a new phone or laptop; the entrance key is read by hand, never printed."},
  {"name": "Notifications", "form": "ops/OPERATIONS.md#background-notifications", "what": "Opens the push notification setup and the checks for a device."},
  {"name": "Replay first-use tour", "form": "ops/OPERATIONS.md#replay-only-the-first-use-tour", "what": "Opens the steps that replay the first-use tour for one person."},
  {"name": "Restart onboarding", "form": "ops/OPERATIONS.md#restart-onboarding-with-a-fresh-codebot-keeping-the-account", "what": "Opens the steps that give a person a fresh CodeBot and keep their account."},
  {"name": "Full reset", "form": "ops/OPERATIONS.md#full-reset-the-person-starts-as-new", "what": "Opens the steps that delete a person's data and account, which destroys their data."}
 ]},
 {"path": ["apps"], "sentence": "The folders that hold the code of CodeBot's parts: the service, the web app, the control service and the shared contracts.", "rows": [
  {"name": "Service", "form": "apps/service/", "what": "Opens the local service: Bots, providers, transcripts, git, avatars and host access."},
  {"name": "Providers", "form": "apps/service/src/providers/", "what": "Opens the provider adapters for Claude, Codex and OpenCode."},
  {"name": "Terminal", "form": "apps/service/src/terminal/", "what": "Opens the terminal code: the broker and the Linux and Windows sessions."},
  {"name": "Web app", "form": "apps/web/", "what": "Opens the web app, the interface you watch and steer Bots from."},
  {"name": "Playground", "form": "npm run playground", "what": "Starts the playground in the browser to compare screen variants."},
  {"name": "Control service", "form": "apps/control/", "what": "Opens the trusted control service that signs host proofs."},
  {"name": "Shared contracts", "form": "packages/contracts/", "what": "Opens the schemas that the service and the client share."},
  {"name": "Avatar parts", "form": "apps/service/assets/avatar-parts/", "what": "Opens the avatar art: bodies, eyes, accessories and heads."}
 ]},
 {"path": ["docs"], "sentence": "The written guides, plans and records about CodeBot.", "rows": [
  {"name": "Overview", "form": "README.md", "what": "Opens the project overview and how to run it."},
  {"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how CodeBot is built: its boundaries, invariants and volatility."},
  {"name": "Working rules", "form": "CLAUDE.md", "what": "Opens the rules every agent follows on this project; AGENTS.md is generated from it."},
  {"name": "Operations runbook", "form": "ops/OPERATIONS.md", "what": "Opens the full runbook for the installed host."},
  {"name": "Plans", "form": "docs/plans/", "what": "Opens the plan documents, one per piece of work."},
  {"name": "Objectives", "form": "docs/objectives/", "what": "Opens the objectives for chat, Gmail, schedules and terminal tabs."},
  {"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "Opens the Gmail guide for Bots: setup and supervision."},
  {"name": "Gmail reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference; npm run docs:gmail rewrites it."},
  {"name": "Verification records", "form": "docs/verification/", "what": "Opens the recorded verification evidence."},
  {"name": "Design", "form": "codebot docs design", "what": "Prints the design screen: the method, the owner's rulings and the reference images."},
  {"name": "Housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the housekeeping skill that agents use on this project."},
  {"name": "Changes for the owner", "form": "apps/web/src/whatsNew.ts", "what": "Opens the list of changes the owner is told about after an update."}
 ]},
 {"path": ["docs", "design"], "sentence": "How CodeBot's screens are designed: the method, the owner's rulings and the reference images.", "rows": [
  {"name": "Design method", "form": "docs/design-method.md", "what": "Opens the method for designing or reworking any screen."},
  {"name": "Owner's rulings", "form": "docs/design-taste.md", "what": "Opens what the owner accepted and rejected, so it is not proposed again."},
  {"name": "Screenshots", "form": "design/", "what": "Opens the design screenshots: main, create bot, mobile chat and content previews."},
  {"name": "Annotated screenshots", "form": "design/annotated/", "what": "Opens the screenshots with the design notes drawn on them."},
  {"name": "Onboarding references", "form": "design/onboarding/grokbot-reference/", "what": "Opens the onboarding reference screens."},
  {"name": "Feature contract diagrams", "form": "design/streamables/feature-contract/", "what": "Opens the feature contract diagrams: backend, endpoints, files, components and types."},
  {"name": "Terminal references", "form": "design/reference/", "what": "Opens the remote terminal reference screenshots."}
 ]},
 {"path": ["test"], "sentence": "The checks that prove CodeBot works, the reviews of its screens, and the record of what was specified and found.", "rows": [
  {"name": "Type check", "form": "npm run typecheck", "what": "Runs the type check over the whole project; no output means it compiles."},
  {"name": "Unit tests", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
  {"name": "Both checks", "form": "npm run check", "what": "Runs the type check and the tests together."},
  {"name": "Build", "form": "npm run build", "what": "Runs the type check, then builds the release into dist/releases."},
  {"name": "Gmail review", "form": "npm run review:gmail", "what": "Runs the Gmail review against the real service, build and browser."},
  {"name": "Schedules review", "form": "npm run review:schedules", "what": "Runs the schedules review."},
  {"name": "Schedule drill", "form": "ops/review/schedule-drill.mjs", "what": "Opens the script for the schedule drill."},
  {"name": "CI checks", "form": ".github/workflows/check.yml", "what": "Opens the CI workflow that runs the checks."},
  {"name": "Records", "form": "codebot test records", "what": "Prints the records screen: feature files, step code, QA findings and module intents."}
 ]},
 {"path": ["test", "records"], "sentence": "The record of what was specified and found: feature files, step code, QA findings and module intents.", "rows": [
  {"name": "Feature files", "form": ".bdd/features/", "what": "Opens the Given-When-Then feature files, one folder per feature."},
  {"name": "Step code", "form": ".bdd/steps/", "what": "Opens the code behind the feature steps."},
  {"name": "QA findings", "form": ".bdd/qa/findings/", "what": "Opens the QA findings from browser runs."},
  {"name": "QA resolutions", "form": ".bdd/qa/resolutions/", "what": "Opens how each QA finding was resolved."},
  {"name": "Module intents", "form": ".idd/modules/", "what": "Opens each module's intent: its constraints and the tests that prove them."}
 ]},
 {"path": ["config"], "sentence": "The host's settings: its private settings file, its data folder, its project folders and its installed service.", "rows": [
  {"name": "Private settings", "form": "~/.config/codebot/service.env", "what": "Opens the host's private settings file (mode 0600); its secrets are never printed here."},
  {"name": "Settings template", "form": "ops/environment.example", "what": "Opens the template for the private settings, with each setting explained."},
  {"name": "Dev settings template", "form": ".env.example", "what": "Opens the template for the settings of the dev run."},
  {"name": "Data folder", "form": "~/.local/share/codebot", "what": "Opens the host's data folder: database, owner key and recordings."},
  {"name": "Project folders", "form": "~/projects", "what": "Opens the project folders that Bots may reach (CODEBOT_PROJECT_ROOTS)."},
  {"name": "Installed service", "form": "~/.config/systemd/user/codebot.service", "what": "Opens the installed service unit that runs the host."},
  {"name": "Service template", "form": "ops/codebot.service", "what": "Opens the service template the installed unit is copied from."}
 ]},
 {"path": ["account"], "sentence": "The central sign-in service: its database, its functions, and the dashboard that runs it.", "rows": [
  {"name": "Supabase project", "form": "https://supabase.com/dashboard/project/wbgrjvqbupgdclaztuou", "what": "Opens the account service's dashboard in the browser, under the mobile-coder login."},
  {"name": "Migrations", "form": "supabase/migrations/", "what": "Opens the database migrations, one per schema change."},
  {"name": "Gmail relay", "form": "supabase/functions/gmail-relay/", "what": "Opens the Gmail relay that returns Google sign-in to each person's server."},
  {"name": "Host access", "form": "supabase/functions/host-access/", "what": "Opens the host access function that checks arrivals and host bindings."},
  {"name": "Deploy host access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys host-access live to the account service; confirm first."},
  {"name": "Onboarding reset", "form": "ops/OPERATIONS.md#reset-someones-onboarding", "what": "Opens the steps that reset a person's onboarding in the account database."},
  {"name": "Keepalive", "form": ".github/workflows/supabase-keepalive.yml", "what": "Opens the workflow that keeps the account service awake."},
  {"name": "Service configuration", "form": "supabase/config.toml", "what": "Opens the account service's configuration file."}
 ]}
],
"questions": [
 "Does cli/codebot.py already exist? README mentions it in a garbled line, and the dump's listing was cut before the root files. If it exists, the facade should reuse it, not add a second command. Recommendation: check it before building.",
 "Facade name and alias: codebot, with cb as the short alias? Recommendation: yes. Names still need the whence/type clash check, which I could not run.",
 "Which commands may run from the CLI? Recommendation: read-only checks, build and test run directly. Restart, stop, deploy, the setup and update scripts, family remove and the account deploy ask for confirmation first, since they change the live service or outside systems.",
 "Should the CLI print secrets? Recommendation: no. The owner key and the invite link stay in runbook rows only, so nothing prints them.",
 "Should the ops screens be split further (address and models into their own screen)? Recommendation: keep the current split until a screen shows more than about nine rows.",
 "Scope: include the experimental V2 to V4 apps (separate repos, per README) and runtime Bot data? Recommendation: exclude both. The apps are reachable by a note only, and the app already shows Bot data.",
 "Unverified paths: the dump was truncated, and these are named in the docs but not confirmed in the listing: PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md, DEFERRED-WORK.md, ops/deploy.sh, ops/guest-install.sh, ops/guest-update.sh, ops/family-install.sh, ops/family-update.sh, ops/terminal-broker.ts and the codebot-family helper. Recommendation: verify each exists before the build step, since a missing row makes a broken link."
]}
```

screen-decomposition, first draft · run 4 exit=0 seconds=211 · prompt

P1 Recall: 0.603P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.993P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 2P9 Grouping (ARI): 0.35
As terminal help
Everything for running CodeBot on this computer: the host, its addresses, its build and deploy commands, its recovery steps, its guests, its docs and its experiments.
hostcodebot hostShows the host screen: the CodeBot service on this computer, its health and its settings.
opencodebot openShows the open screen: the addresses where CodeBot answers, on this computer, a phone and the home Wi-Fi.
buildcodebot buildShows the build screen: the commands that check, regenerate, deploy and run the code.
recovercodebot recoverShows the recover screen: backups, restores, emergency stop and onboarding resets.
guestscodebot guestsShows the guests screen: the guest's CodeBot and the family CodeBots, each run as its own Linux user.
docscodebot docsShows the docs screen: the documents, grouped by subject.
experimentscodebot experimentsShows the experiments screen: the three experimental apps V2, V3 and V4.
host
The CodeBot service on this computer: whether it runs, its logs, its port, its health and its settings.
statussystemctl --user status codebot.serviceShows whether codebot.service is running and since when.
logsjournalctl --user -u codebot.service -n 80Prints the last 80 lines of the host's log.
portss -ltnp 'sport = :3505'Shows which process holds port 3505, the host's port.
healthcurl --fail http://127.0.0.1:3505/api/sessionChecks that the host answers on port 3505; a reply without a session still counts as ready.
restartsystemctl --user restart codebot.serviceRestarts the host so new code runs; wait until no Bot is working and no recording is running.
stopsystemctl --user stop codebot.serviceStops the host, interrupts Bot turns and finishes recordings.
terminal brokersystemctl --user status codebot-terminal-broker.serviceShows whether the per-user terminal broker runs; the terminal stays off without it.
diagnosticscodebot host diagnosticsShows the diagnostics screen: the host's counters and state, read from the running host.
settingscodebot host settingsShows the settings screen: the files the host reads when it starts.
host › diagnostics
The host's own readings from the running host, for a signed-in owner: counters and state, never credentials.
hosthttp://127.0.0.1:3505/api/diagnostics/hostOpens the host's readings: migration, event cursor, queued and running turns, and recovery hold.
schedulerhttp://127.0.0.1:3505/api/diagnostics/schedulerOpens the scheduler's readings: its timers and state.
visionhttp://127.0.0.1:3505/api/diagnostics/visionOpens the Vision readings: the state of the browser view a Bot can see.
notificationshttp://127.0.0.1:3505/api/notifications/diagnosticsOpens the notification readings: the queue, its timer and the sends in progress.
host › settings
The files the host reads when it starts: its settings, its data folder, its entrance key and its account service.
service settings~/.config/codebot/service.envOpens the host's settings file: port, data folder, project roots and provider logins; it holds secrets, so the help never prints it.
data folder~/.local/share/codebotOpens the data folder: the database, attachments, recordings and the owner's files.
entrance key~/.local/share/codebot/owner-keyShows where the entrance key is kept, which a new device types in; the help never prints the key.
account serviceSupabase project wbgrjvqbupgdclaztuouShows the central account service that handles sign-in and the host handshake.
open
The addresses where CodeBot answers: this computer, the private Tailscale address, the sign-in entry, and the family front door on the home Wi-Fi.
this computerhttp://127.0.0.1:3505Opens CodeBot in a browser on this computer.
private addresshttps://liel.tail18e69e.ts.net/Opens CodeBot from a phone or any device on the private Tailscale network.
sign-in entryhttps://liel.tail18e69e.ts.net/onboardingOpens the sign-in page where a new person starts onboarding.
family front doorhttps://family.codebot.lielbenor.comOpens the home Wi-Fi sign-in, where a family member signs in with Google and gets their own CodeBot.
tailscale mappingtailscale serve status --jsonShows which private HTTPS address maps to the host on port 3505.
install on a phoneops/OPERATIONS.md: Connect a deviceShows the steps to install CodeBot on a phone's home screen.
notificationsops/OPERATIONS.md: Background notificationsShows the steps to turn on notifications for a device.
change addressops/OPERATIONS.md: Change this machine's addressShows the steps to move CodeBot to a new address, and every place the old address is written.
build
The commands that check, regenerate, deploy and run the code, run from the checkout.
checkcodebot build checkShows the check screen: the type check, the tests and the reviews.
regeneratecodebot build regenerateShows the regenerate screen: the files the code writes from its sources.
deploycodebot build deployShows the deploy screen: install, build, publish and restart the host.
devnpm run devStarts the host from source in watch mode on port 3505; stop the service first, since both use that port.
playgroundnpm run playgroundOpens the Gmail playground in a browser, for comparing design variants.
setup accountnpm run setup-accountRuns ops/setup-account.ts, the account set-up script; OPERATIONS.md describes what it sets.
build › check
The checks: whether the code compiles, whether the Gmail tests pass, and the reviews.
typechecknpm run typecheckChecks the types without building; a pass means the code compiles, and nothing more about Bot behavior.
testsnpm testRuns the Gmail automation tests against a fake Google server.
checknpm run checkRuns the type check and the tests together.
review gmailnpm run review:gmailRuns the Gmail review, ops/review/gmail-review.mjs.
review schedulesnpm run review:schedulesRuns the schedules review, ops/review/schedules-review.mjs.
build › regenerate
The files the code writes from its sources, so they never drift from them.
gmail referencenpm run docs:gmailRegenerates docs/automation/gmail-reference.md from the code.
agent filesnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
build › deploy
The steps that install, build, publish and restart the host, and the account service function.
install packagesnpm ciInstalls the exact dependencies from the lock file.
buildnpm run buildType-checks, then builds a new release and swaps it in; a failed build leaves the running release intact.
deploysh ops/deploy.shCommits, pushes and restarts the host once no Bot is working; it refuses while someone else has uncommitted edits.
install the hostops/OPERATIONS.md: Install or update the hostShows the steps to install the host's service unit and settings the first time.
integration copynpm run build:integrationBuilds the disposable QA copy that the integration service on port 3506 runs.
account functionnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys host-access to the account service; needed whenever a contract it parses changes.
recover
The procedures that back up and restore the host's data, stop it in an emergency, and reset a person's onboarding.
back upops/OPERATIONS.md: Back up a consistent installationShows the steps to copy the stopped data folder, with checksums, into a private backup folder.
restoreops/OPERATIONS.md: Restore into a separate directory firstShows the steps to restore a backup into a separate folder and check it before it replaces anything.
emergency stopops/OPERATIONS.md: Emergency stop and rollbackShows the steps to force the host to stop when a normal stop does not end it; forcing can lose unfinished recording media.
onboardingcodebot recover onboardingShows the onboarding screen: three ways to show a person onboarding again.
recover › onboarding
The three ways to reset a person's onboarding, from the smallest to the one that deletes their data.
replay the tourops/OPERATIONS.md: Replay only the first-use tourShows the steps to show a person the first-use tour again; it works only when their host has no Bots.
fresh CodeBotops/OPERATIONS.md: Restart onboarding with a fresh CodeBot, keeping the accountShows the steps to wipe a host's Bots and conversations, keeping the account and project folders.
full resetops/OPERATIONS.md: Full reset: the person starts as newShows the steps to delete a person's account, Bots, conversations, attachments and recordings; destructive, so back up first.
guests
The second CodeBots on this machine: the guest's own CodeBot and the family CodeBots, each run as its own Linux user.
guestcodebot guests guestShows the guest screen: the guest's CodeBot, its status, its invite and its removal.
familycodebot guests familyShows the family screen: the front door and each family member's CodeBot.
guests › guest
The guest's CodeBot on this machine: its status, its invite, its address, and how to update or remove it.
statussystemctl status codebot-guestShows whether the guest's CodeBot runs.
logsjournalctl -u codebot-guestPrints the guest's CodeBot log.
processesps -u codebot-guestLists the guest's running processes.
disksudo du -sh /home/codebot-guestShows how much space the guest's home folder uses.
invitesudo -u codebot-guest /opt/codebot-guest/inviteCreates a one-use Google sign-in link, valid for ten minutes; anyone holding it can sign in.
addresshttps://liel.tail18e69e.ts.net:10000Opens the guest's CodeBot in a browser on the private network.
updateops/guest-update.shBuilds the program, replaces the guest's copy and restarts it; needs no password.
installsudo ops/guest-install.shSets up the guest user, service, settings, sudo rules and port 10000; run once.
removeops/OPERATIONS.md: Host a guest on this machineShows the steps to remove the guest's CodeBot and user; destructive.
guests › family
The family CodeBots on the home Wi-Fi: a front door that signs members in, and one CodeBot per member, each with its own Linux user and port.
statussystemctl status codebot-family-lobby 'codebot-family@*'Shows whether the front door and each family CodeBot runs.
helper statuscodebot-family statusShows which family CodeBots run and whether each can connect Gmail.
addsudo codebot-family add NCreates a family CodeBot at the next free number, up to six; the front door runs this when a new Google account signs in.
removeops/OPERATIONS.md: Home Wi-Fi addressShows the steps to remove a family CodeBot and free its number; its Google account stays linked to it for good.
stop allsudo codebot-family stop-allStops every family CodeBot.
start allsudo codebot-family start-allStarts every family CodeBot.
member addresshttps://family.codebot.lielbenor.com:10100+NOpens family CodeBot N's app; N is the number the status shows.
updateops/family-update.shBuilds the program, replaces it for every family CodeBot and restarts them all; needs no password.
installsudo ops/family-install.shSets up the front door user, helper, services, sudo rules and nginx; run once.
experiments
Three experimental apps that reuse the CodeBot server on this computer, each in its own private repo.
V2codebot experiments V2Shows the V2 screen: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.
V3codebot experiments V3Shows the V3 screen: Claude Code first, with a mod that draws the Bot list above the prompt.
V4codebot experiments V4Shows the V4 screen: a simple main menu whose buttons set up the Claude Code sessions.
experiments › V2
The V2 terminal chat app: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.
folder~/projects/codebot-v2-terminal-chatOpens the app's folder: its code, and its own data in .data/app.
startsh ops/app-run.sh devStarts the app on port 3512 with its own terminal broker; run it in its own terminal window.
openhttp://127.0.0.1:3512Opens the app in Chrome; reload the tab once after the app restarts.
portss -ltnp 'sport = :3512'Shows the process holding port 3512, the only one to stop.
notesdocs/experiment/ in the app's folderOpens the owner's vision, decision log and report for this app.
experiments › V3
The V3 Claude Code mod app: Claude Code first, with a mod that draws the Bot list above the prompt.
folder~/projects/codebot-v3-claude-modOpens the app's folder: its code, and its own data in .data/app.
startsh ops/app-run.sh devStarts the app on port 3513 with its own terminal broker; run it in its own terminal window.
openhttp://127.0.0.1:3513Opens the app in Chrome; reload the tab once after the app restarts.
portss -ltnp 'sport = :3513'Shows the process holding port 3513, the only one to stop.
old test Botsclaude stop <id>Stops an old test Bot; claude agents lists their ids.
notesdocs/experiment/ in the app's folderOpens the owner's vision, decision log and report for this app.
experiments › V4
The V4 launcher menu app: a simple main menu whose buttons set up the Claude Code sessions.
folder~/projects/codebot-v4-launcher-menuOpens the app's folder: its code, and its own data in .data/app.
startsh ops/app-run.sh devStarts the app on port 3514 with its own terminal broker; run it in its own terminal window.
openhttp://127.0.0.1:3514Opens the app in Chrome; reload the tab once after the app restarts.
portss -ltnp 'sport = :3514'Shows the process holding port 3514, the only one to stop.
notesdocs/experiment/ in the app's folderOpens the owner's vision, decision log and report for this app.
docs
The documents about CodeBot, grouped by subject.
productcodebot docs productShows the product screen: what CodeBot is, how it is built and what is still open.
operationscodebot docs operationsShows the operations screen: running, self-hosting, settings files and service units.
automationcodebot docs automationShows the automation screen: how Bots use Gmail, and its generated reference.
designcodebot docs designShows the design screen: the design method, the owner's rulings and the reference images.
planscodebot docs plansShows the plans screen: plans, objectives, tasks and onboarding implementation.
verificationcodebot docs verificationShows the verification screen: recorded checks, behavior specs, module intents and QA findings.
agentscodebot docs agentsShows the agents screen: the rules for coding agents and the housekeeping skill.
docs › product
The documents that say what CodeBot is, how it is built and what is still open.
READMEREADME.mdOpens the README: what CodeBot is, how to run it and how its pieces fit.
architectureARCHITECTURE.mdOpens the architecture: the boundaries, domain ownership and provider runtime.
product specPRODUCT-SPEC.mdOpens the behavior contract the product is held to; referenced by the README, not in the dump.
implementation statusIMPLEMENTATION-STATUS.mdOpens what the first beta built before it was paused; referenced, not in the dump.
deferred workDEFERRED-WORK.mdOpens the open work checklist and the safe restart state; referenced, not in the dump.
release scopeMASTER-PLAN.mdOpens the release scope; the dump has docs/plans/MASER_PLAN.md, so confirm which is real.
docs › operations
The documents for running CodeBot on a machine you control, and keeping it safe.
runbookops/OPERATIONS.mdOpens the runbook: install, service, backups, restores, addresses, guests, family and emergencies.
self-hostingdocs/self-hosting-practices.mdOpens the self-hosting practices.
host and accountdocs/host-account-exchange.mdOpens how a host and the account service exchange identity.
settings templateops/environment.exampleOpens the template for the host's settings file; keep the real copy outside the checkout.
service unitsops/codebot.service, ops/codebot-guest.service, ops/codebot-family-lobby.service, ops/codebot-family@.service, ops/codebot-terminal-broker.serviceOpens the systemd unit files that run the host, the guest, the family and the terminal broker.
docs › automation
How Bots use Gmail: the supervisor's guide and a reference generated from the code.
gmail guidedocs/automation/gmail.mdOpens the supervisor's guide to Gmail for Bots, including how Google sign-in returns through the relay.
gmail referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference; it is regenerated, not edited.
gmail relaysupabase/functions/gmail-relay/index.tsOpens the stateless relay that forwards Google sign-in back to the host it came from.
docs › design
How screens are designed here: the method, the owner's rulings, and the reference images.
design methoddocs/design-method.mdOpens the method for designing or changing a screen.
design tastedocs/design-taste.mdOpens the owner's rulings and what they rejected.
design folderdesign/README.mdOpens the reference screenshots, their annotated versions and their notes.
docs › plans
The plans, objectives, tasks and onboarding implementation: the work done and the work still planned.
plansdocs/plans/Opens the plan documents, one file per piece of work.
superpowers plansdocs/superpowers/plans/Opens the plans written under the superpowers workflow.
objectivesdocs/objectives/Opens the objectives, with their README index.
tasksdocs/tasks/Opens the task records, including the shared storage backup task.
onboarding implementationdocs/onboarding-implementation.mdOpens how onboarding was built.
docs › verification
The recorded checks, behavior specs, module intents and QA findings that show what was verified and how.
verificationdocs/verification/Opens the recorded checks and their evidence.
ai readinessdocs/ai-readiness-verification.mdOpens the AI readiness check record.
onboarding proofdocs/onboarding-recorded-proof-2026-09-14.mdOpens the recorded onboarding proof from 2026-09-14.
onboarding review gatedocs/onboarding-review-gate.mdOpens the review gate that onboarding had to pass.
module intents.idd/modules/Opens each module's INTENT.md: its constraints and Given / When / Then table.
behavior specs.bdd/features/Opens the Given / When / Then feature specs for attachments, bot questions, chat, navigation and updates.
qa findings.bdd/qa/Opens the QA findings and how each was resolved.
docs › agents
The rules and skills for coding agents that work in this repository.
rulesCLAUDE.mdOpens the rules every task assumes; AGENTS.md is generated from it.
agentic developmentdocs/agentic-development.mdOpens how agents work on this project.
housekeeping skillskills/codebot-housekeeping/SKILL.mdOpens the housekeeping skill.
global rulesops/global/CLAUDE.mdOpens the global rules file for the agent.
Questions
  • Does cli/codebot.py exist, and what does it do? The README mentions it for data and docs, but cli/ is not in the dump. Recommendation: check it first; if it exists, extend it rather than adding a second CLI.
  • Which facade name will you type? Recommendation: codebot, the project's own word. I could not run a clash check here, so confirm no existing codebot command before building.
  • Should the app's own screens (Bots, Gmail, Terminal, Contracts, Avatars, Settings, Onboarding) appear in this map? Recommendation: no. Leave them to the app's own navigation, so each screen has one source.
  • Should destructive steps (full reset, emergency stop, removing a guest or family CodeBot) be one-line commands in the help? Recommendation: no. The help points to the runbook section and offers no command.
  • Do you accept the splits in this map: host (diagnostics, settings), build (check, regenerate, deploy), recover (onboarding), guests (guest, family), docs (seven subjects), experiments (V2, V3, V4)? Recommendation: keep them as drafted; tell me which to merge or cut.
  • Should the experiments stay in this map, since they live in other private repos? Recommendation: keep them, because the README documents them and the owner reaches them from here.
As phone screens

Home

Everything for running CodeBot on this computer: the host, its addresses, its build and deploy commands, its recovery steps, its guests, its docs and its experiments.

hostShows the host screen: the CodeBot service on this computer, its health and its settings.
›
openShows the open screen: the addresses where CodeBot answers, on this computer, a phone and the home Wi-Fi.
›
buildShows the build screen: the commands that check, regenerate, deploy and run the code.
›
recoverShows the recover screen: backups, restores, emergency stop and onboarding resets.
›
guestsShows the guests screen: the guest's CodeBot and the family CodeBots, each run as its own Linux user.
›
docsShows the docs screen: the documents, grouped by subject.
›
experimentsShows the experiments screen: the three experimental apps V2, V3 and V4.
›
‹ Home

host

The CodeBot service on this computer: whether it runs, its logs, its port, its health and its settings.

statusShows whether codebot.service is running and since when.
›
logsPrints the last 80 lines of the host's log.
›
portShows which process holds port 3505, the host's port.
›
healthChecks that the host answers on port 3505; a reply without a session still counts as ready.
›
restartRestarts the host so new code runs; wait until no Bot is working and no recording is running.
›
stopStops the host, interrupts Bot turns and finishes recordings.
›
terminal brokerShows whether the per-user terminal broker runs; the terminal stays off without it.
›
diagnosticsShows the diagnostics screen: the host's counters and state, read from the running host.
›
settingsShows the settings screen: the files the host reads when it starts.
›
‹ host

diagnostics

The host's own readings from the running host, for a signed-in owner: counters and state, never credentials.

hostOpens the host's readings: migration, event cursor, queued and running turns, and recovery hold.
›
schedulerOpens the scheduler's readings: its timers and state.
›
visionOpens the Vision readings: the state of the browser view a Bot can see.
›
notificationsOpens the notification readings: the queue, its timer and the sends in progress.
›
‹ host

settings

The files the host reads when it starts: its settings, its data folder, its entrance key and its account service.

service settingsOpens the host's settings file: port, data folder, project roots and provider logins; it holds secrets, so the help never prints it.
›
data folderOpens the data folder: the database, attachments, recordings and the owner's files.
›
entrance keyShows where the entrance key is kept, which a new device types in; the help never prints the key.
›
account serviceShows the central account service that handles sign-in and the host handshake.
›
‹ Home

open

The addresses where CodeBot answers: this computer, the private Tailscale address, the sign-in entry, and the family front door on the home Wi-Fi.

this computerOpens CodeBot in a browser on this computer.
›
private addressOpens CodeBot from a phone or any device on the private Tailscale network.
›
sign-in entryOpens the sign-in page where a new person starts onboarding.
›
family front doorOpens the home Wi-Fi sign-in, where a family member signs in with Google and gets their own CodeBot.
›
tailscale mappingShows which private HTTPS address maps to the host on port 3505.
›
install on a phoneShows the steps to install CodeBot on a phone's home screen.
›
notificationsShows the steps to turn on notifications for a device.
›
change addressShows the steps to move CodeBot to a new address, and every place the old address is written.
›
‹ Home

build

The commands that check, regenerate, deploy and run the code, run from the checkout.

checkShows the check screen: the type check, the tests and the reviews.
›
regenerateShows the regenerate screen: the files the code writes from its sources.
›
deployShows the deploy screen: install, build, publish and restart the host.
›
devStarts the host from source in watch mode on port 3505; stop the service first, since both use that port.
›
playgroundOpens the Gmail playground in a browser, for comparing design variants.
›
setup accountRuns ops/setup-account.ts, the account set-up script; OPERATIONS.md describes what it sets.
›
‹ build

check

The checks: whether the code compiles, whether the Gmail tests pass, and the reviews.

typecheckChecks the types without building; a pass means the code compiles, and nothing more about Bot behavior.
›
testsRuns the Gmail automation tests against a fake Google server.
›
checkRuns the type check and the tests together.
›
review gmailRuns the Gmail review, ops/review/gmail-review.mjs.
›
review schedulesRuns the schedules review, ops/review/schedules-review.mjs.
›
‹ build

regenerate

The files the code writes from its sources, so they never drift from them.

gmail referenceRegenerates docs/automation/gmail-reference.md from the code.
›
agent filesRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
›
‹ build

deploy

The steps that install, build, publish and restart the host, and the account service function.

install packagesInstalls the exact dependencies from the lock file.
›
buildType-checks, then builds a new release and swaps it in; a failed build leaves the running release intact.
›
deployCommits, pushes and restarts the host once no Bot is working; it refuses while someone else has uncommitted edits.
›
install the hostShows the steps to install the host's service unit and settings the first time.
›
integration copyBuilds the disposable QA copy that the integration service on port 3506 runs.
›
account functionDeploys host-access to the account service; needed whenever a contract it parses changes.
›
‹ Home

recover

The procedures that back up and restore the host's data, stop it in an emergency, and reset a person's onboarding.

back upShows the steps to copy the stopped data folder, with checksums, into a private backup folder.
›
restoreShows the steps to restore a backup into a separate folder and check it before it replaces anything.
›
emergency stopShows the steps to force the host to stop when a normal stop does not end it; forcing can lose unfinished recording media.
›
onboardingShows the onboarding screen: three ways to show a person onboarding again.
›
‹ recover

onboarding

The three ways to reset a person's onboarding, from the smallest to the one that deletes their data.

replay the tourShows the steps to show a person the first-use tour again; it works only when their host has no Bots.
›
fresh CodeBotShows the steps to wipe a host's Bots and conversations, keeping the account and project folders.
›
full resetShows the steps to delete a person's account, Bots, conversations, attachments and recordings; destructive, so back up first.
›
‹ Home

guests

The second CodeBots on this machine: the guest's own CodeBot and the family CodeBots, each run as its own Linux user.

guestShows the guest screen: the guest's CodeBot, its status, its invite and its removal.
›
familyShows the family screen: the front door and each family member's CodeBot.
›
‹ guests

guest

The guest's CodeBot on this machine: its status, its invite, its address, and how to update or remove it.

statusShows whether the guest's CodeBot runs.
›
logsPrints the guest's CodeBot log.
›
processesLists the guest's running processes.
›
diskShows how much space the guest's home folder uses.
›
inviteCreates a one-use Google sign-in link, valid for ten minutes; anyone holding it can sign in.
›
addressOpens the guest's CodeBot in a browser on the private network.
›
updateBuilds the program, replaces the guest's copy and restarts it; needs no password.
›
installSets up the guest user, service, settings, sudo rules and port 10000; run once.
›
removeShows the steps to remove the guest's CodeBot and user; destructive.
›
‹ guests

family

The family CodeBots on the home Wi-Fi: a front door that signs members in, and one CodeBot per member, each with its own Linux user and port.

statusShows whether the front door and each family CodeBot runs.
›
helper statusShows which family CodeBots run and whether each can connect Gmail.
›
addCreates a family CodeBot at the next free number, up to six; the front door runs this when a new Google account signs in.
›
removeShows the steps to remove a family CodeBot and free its number; its Google account stays linked to it for good.
›
stop allStops every family CodeBot.
›
start allStarts every family CodeBot.
›
member addressOpens family CodeBot N's app; N is the number the status shows.
›
updateBuilds the program, replaces it for every family CodeBot and restarts them all; needs no password.
›
installSets up the front door user, helper, services, sudo rules and nginx; run once.
›
‹ Home

experiments

Three experimental apps that reuse the CodeBot server on this computer, each in its own private repo.

V2Shows the V2 screen: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.
›
V3Shows the V3 screen: Claude Code first, with a mod that draws the Bot list above the prompt.
›
V4Shows the V4 screen: a simple main menu whose buttons set up the Claude Code sessions.
›
‹ experiments

V2

The V2 terminal chat app: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.

folderOpens the app's folder: its code, and its own data in .data/app.
›
startStarts the app on port 3512 with its own terminal broker; run it in its own terminal window.
›
openOpens the app in Chrome; reload the tab once after the app restarts.
›
portShows the process holding port 3512, the only one to stop.
›
notesOpens the owner's vision, decision log and report for this app.
›
‹ experiments

V3

The V3 Claude Code mod app: Claude Code first, with a mod that draws the Bot list above the prompt.

folderOpens the app's folder: its code, and its own data in .data/app.
›
startStarts the app on port 3513 with its own terminal broker; run it in its own terminal window.
›
openOpens the app in Chrome; reload the tab once after the app restarts.
›
portShows the process holding port 3513, the only one to stop.
›
old test BotsStops an old test Bot; claude agents lists their ids.
›
notesOpens the owner's vision, decision log and report for this app.
›
‹ experiments

V4

The V4 launcher menu app: a simple main menu whose buttons set up the Claude Code sessions.

folderOpens the app's folder: its code, and its own data in .data/app.
›
startStarts the app on port 3514 with its own terminal broker; run it in its own terminal window.
›
openOpens the app in Chrome; reload the tab once after the app restarts.
›
portShows the process holding port 3514, the only one to stop.
›
notesOpens the owner's vision, decision log and report for this app.
›
‹ Home

docs

The documents about CodeBot, grouped by subject.

productShows the product screen: what CodeBot is, how it is built and what is still open.
›
operationsShows the operations screen: running, self-hosting, settings files and service units.
›
automationShows the automation screen: how Bots use Gmail, and its generated reference.
›
designShows the design screen: the design method, the owner's rulings and the reference images.
›
plansShows the plans screen: plans, objectives, tasks and onboarding implementation.
›
verificationShows the verification screen: recorded checks, behavior specs, module intents and QA findings.
›
agentsShows the agents screen: the rules for coding agents and the housekeeping skill.
›
‹ docs

product

The documents that say what CodeBot is, how it is built and what is still open.

READMEOpens the README: what CodeBot is, how to run it and how its pieces fit.
›
architectureOpens the architecture: the boundaries, domain ownership and provider runtime.
›
product specOpens the behavior contract the product is held to; referenced by the README, not in the dump.
›
implementation statusOpens what the first beta built before it was paused; referenced, not in the dump.
›
deferred workOpens the open work checklist and the safe restart state; referenced, not in the dump.
›
release scopeOpens the release scope; the dump has docs/plans/MASER_PLAN.md, so confirm which is real.
›
‹ docs

operations

The documents for running CodeBot on a machine you control, and keeping it safe.

runbookOpens the runbook: install, service, backups, restores, addresses, guests, family and emergencies.
›
self-hostingOpens the self-hosting practices.
›
host and accountOpens how a host and the account service exchange identity.
›
settings templateOpens the template for the host's settings file; keep the real copy outside the checkout.
›
service unitsOpens the systemd unit files that run the host, the guest, the family and the terminal broker.
›
‹ docs

automation

How Bots use Gmail: the supervisor's guide and a reference generated from the code.

gmail guideOpens the supervisor's guide to Gmail for Bots, including how Google sign-in returns through the relay.
›
gmail referenceOpens the generated Gmail reference; it is regenerated, not edited.
›
gmail relayOpens the stateless relay that forwards Google sign-in back to the host it came from.
›
‹ docs

design

How screens are designed here: the method, the owner's rulings, and the reference images.

design methodOpens the method for designing or changing a screen.
›
design tasteOpens the owner's rulings and what they rejected.
›
design folderOpens the reference screenshots, their annotated versions and their notes.
›
‹ docs

plans

The plans, objectives, tasks and onboarding implementation: the work done and the work still planned.

plansOpens the plan documents, one file per piece of work.
›
superpowers plansOpens the plans written under the superpowers workflow.
›
objectivesOpens the objectives, with their README index.
›
tasksOpens the task records, including the shared storage backup task.
›
onboarding implementationOpens how onboarding was built.
›
‹ docs

verification

The recorded checks, behavior specs, module intents and QA findings that show what was verified and how.

verificationOpens the recorded checks and their evidence.
›
ai readinessOpens the AI readiness check record.
›
onboarding proofOpens the recorded onboarding proof from 2026-09-14.
›
onboarding review gateOpens the review gate that onboarding had to pass.
›
module intentsOpens each module's INTENT.md: its constraints and Given / When / Then table.
›
behavior specsOpens the Given / When / Then feature specs for attachments, bot questions, chat, navigation and updates.
›
qa findingsOpens the QA findings and how each was resolved.
›
‹ docs

agents

The rules and skills for coding agents that work in this repository.

rulesOpens the rules every task assumes; AGENTS.md is generated from it.
›
agentic developmentOpens how agents work on this project.
›
housekeeping skillOpens the housekeeping skill.
›
global rulesOpens the global rules file for the agent.
›
Raw answer
## Planning map: CodeBot

**Scenario** (reasoning from the files, not observed use): The owner, usually on a phone, opens CodeBot to check or steer a Bot over the private Tailscale address. The operator, at the workstation, starts, stops, checks, backs up and deploys the host, and resets a person's onboarding when asked. Guest and family members reach only their own CodeBot.

**Inventory** (what the dump shows):

| Kind | Items | Defined in |
| --- | --- | --- |
| npm scripts | dev, build, start, typecheck, test, check, setup-account, docs:gmail, sync:agents, review:gmail, review:schedules, playground, build:integration | package.json |
| Ops scripts | guest-install, guest-update, family-install, family-update, build, build-integration, review/* | ops/ |
| Services | codebot.service, codebot-terminal-broker.service (user); codebot-guest.service (system); codebot-family-lobby.service, codebot-family@.service | ops/*.service |
| Ports | 3505 host, 3506 QA, 3512 to 3514 V2 to V4, 3530 family front door, 3540+N family CodeBots, 10000 guest, 10100+N family addresses | OPERATIONS.md, README |
| Addresses | private tailnet address, sign-in entry, family front door | OPERATIONS.md, environment.example |
| Settings and data | service.env, data folder, owner-key | ops/environment.example, OPERATIONS.md |
| Docs and specs | README, ARCHITECTURE, OPERATIONS, docs/, .idd/, .bdd/ | file tree |
| Experiments | three sibling folders in other private repos | README |

Referenced but not in the dump, so their rows are unverified: `ops/deploy.sh`, `ops/family-helper.sh`, `ops/terminal-broker.ts`, `cli/codebot.py`, `PRODUCT-SPEC.md`, `IMPLEMENTATION-STATUS.md`, `DEFERRED-WORK.md`, `MASTER-PLAN.md`, `codebot-integration.service`. The dump also cuts off `OPERATIONS.md` and `ARCHITECTURE.md`, and several folders show "(N files)" without listing them, so I used only the visible parts.

**Questions for you**

1. **Does `cli/codebot.py` exist?** The README mentions it for data and docs, but `cli/` is not in the dump. Recommendation: check it first. If it exists, extend it rather than adding a second CLI.
2. **Facade name.** Recommendation: `codebot`, the project's own word. I could not run a clash check here, so confirm no existing `codebot` command before building.
3. **The app's own screens** (Bots, Gmail, Terminal, Contracts, Avatars, Settings, Onboarding) are not in this map. Recommendation: leave them to the app and keep them out of here, so each screen has one source.
4. **Destructive steps** (full reset, emergency stop, removing a guest or family CodeBot). Recommendation: the help points to the runbook section and offers no one-line command.
5. **My splits:** host (diagnostics, settings), build (check, regenerate, deploy), recover (onboarding), guests (guest, family), docs (seven subjects), experiments (V2, V3, V4). Recommendation: keep them as drafted. Tell me which to merge or cut.
6. **Experiments in this map at all**, since they live in other repos. Recommendation: keep them, because the README documents them and the owner reaches them from here.

**Judgment calls and reasons**

- Group names are the project's own words (host, guest, family, recover, deploy, docs, experiments). I did not use "learn" or "ship".
- The entrance key's path is shown, but the help never prints the key.
- Stop and restart rows warn to wait for active turns and recordings, as OPERATIONS.md and CLAUDE.md require.
- `codebot ...` forms are proposed commands. No command exists yet.
- The dev row says to stop the service first, because both use port 3505.
- `README.md` names `MASTER-PLAN.md`, but the dump has `docs/plans/MASER_PLAN.md`. Check which is real before shipping.
- Not mapped, because their purpose is not in the dump: `ops/avatar-thumbnails.ts`, `ops/agent-start.sh`.
- Build: nothing written, nothing run.

```json
{"screens": [
{"path": [], "sentence": "Everything for running CodeBot on this computer: the host, its addresses, its build and deploy commands, its recovery steps, its guests, its docs and its experiments.", "rows": [
{"name": "host", "form": "codebot host", "what": "Shows the host screen: the CodeBot service on this computer, its health and its settings."},
{"name": "open", "form": "codebot open", "what": "Shows the open screen: the addresses where CodeBot answers, on this computer, a phone and the home Wi-Fi."},
{"name": "build", "form": "codebot build", "what": "Shows the build screen: the commands that check, regenerate, deploy and run the code."},
{"name": "recover", "form": "codebot recover", "what": "Shows the recover screen: backups, restores, emergency stop and onboarding resets."},
{"name": "guests", "form": "codebot guests", "what": "Shows the guests screen: the guest's CodeBot and the family CodeBots, each run as its own Linux user."},
{"name": "docs", "form": "codebot docs", "what": "Shows the docs screen: the documents, grouped by subject."},
{"name": "experiments", "form": "codebot experiments", "what": "Shows the experiments screen: the three experimental apps V2, V3 and V4."}
]},
{"path": ["host"], "sentence": "The CodeBot service on this computer: whether it runs, its logs, its port, its health and its settings.", "rows": [
{"name": "status", "form": "systemctl --user status codebot.service", "what": "Shows whether codebot.service is running and since when."},
{"name": "logs", "form": "journalctl --user -u codebot.service -n 80", "what": "Prints the last 80 lines of the host's log."},
{"name": "port", "form": "ss -ltnp 'sport = :3505'", "what": "Shows which process holds port 3505, the host's port."},
{"name": "health", "form": "curl --fail http://127.0.0.1:3505/api/session", "what": "Checks that the host answers on port 3505; a reply without a session still counts as ready."},
{"name": "restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the host so new code runs; wait until no Bot is working and no recording is running."},
{"name": "stop", "form": "systemctl --user stop codebot.service", "what": "Stops the host, interrupts Bot turns and finishes recordings."},
{"name": "terminal broker", "form": "systemctl --user status codebot-terminal-broker.service", "what": "Shows whether the per-user terminal broker runs; the terminal stays off without it."},
{"name": "diagnostics", "form": "codebot host diagnostics", "what": "Shows the diagnostics screen: the host's counters and state, read from the running host."},
{"name": "settings", "form": "codebot host settings", "what": "Shows the settings screen: the files the host reads when it starts."}
]},
{"path": ["host", "diagnostics"], "sentence": "The host's own readings from the running host, for a signed-in owner: counters and state, never credentials.", "rows": [
{"name": "host", "form": "http://127.0.0.1:3505/api/diagnostics/host", "what": "Opens the host's readings: migration, event cursor, queued and running turns, and recovery hold."},
{"name": "scheduler", "form": "http://127.0.0.1:3505/api/diagnostics/scheduler", "what": "Opens the scheduler's readings: its timers and state."},
{"name": "vision", "form": "http://127.0.0.1:3505/api/diagnostics/vision", "what": "Opens the Vision readings: the state of the browser view a Bot can see."},
{"name": "notifications", "form": "http://127.0.0.1:3505/api/notifications/diagnostics", "what": "Opens the notification readings: the queue, its timer and the sends in progress."}
]},
{"path": ["host", "settings"], "sentence": "The files the host reads when it starts: its settings, its data folder, its entrance key and its account service.", "rows": [
{"name": "service settings", "form": "~/.config/codebot/service.env", "what": "Opens the host's settings file: port, data folder, project roots and provider logins; it holds secrets, so the help never prints it."},
{"name": "data folder", "form": "~/.local/share/codebot", "what": "Opens the data folder: the database, attachments, recordings and the owner's files."},
{"name": "entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Shows where the entrance key is kept, which a new device types in; the help never prints the key."},
{"name": "account service", "form": "Supabase project wbgrjvqbupgdclaztuou", "what": "Shows the central account service that handles sign-in and the host handshake."}
]},
{"path": ["open"], "sentence": "The addresses where CodeBot answers: this computer, the private Tailscale address, the sign-in entry, and the family front door on the home Wi-Fi.", "rows": [
{"name": "this computer", "form": "http://127.0.0.1:3505", "what": "Opens CodeBot in a browser on this computer."},
{"name": "private address", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens CodeBot from a phone or any device on the private Tailscale network."},
{"name": "sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Opens the sign-in page where a new person starts onboarding."},
{"name": "family front door", "form": "https://family.codebot.lielbenor.com", "what": "Opens the home Wi-Fi sign-in, where a family member signs in with Google and gets their own CodeBot."},
{"name": "tailscale mapping", "form": "tailscale serve status --json", "what": "Shows which private HTTPS address maps to the host on port 3505."},
{"name": "install on a phone", "form": "ops/OPERATIONS.md: Connect a device", "what": "Shows the steps to install CodeBot on a phone's home screen."},
{"name": "notifications", "form": "ops/OPERATIONS.md: Background notifications", "what": "Shows the steps to turn on notifications for a device."},
{"name": "change address", "form": "ops/OPERATIONS.md: Change this machine's address", "what": "Shows the steps to move CodeBot to a new address, and every place the old address is written."}
]},
{"path": ["build"], "sentence": "The commands that check, regenerate, deploy and run the code, run from the checkout.", "rows": [
{"name": "check", "form": "codebot build check", "what": "Shows the check screen: the type check, the tests and the reviews."},
{"name": "regenerate", "form": "codebot build regenerate", "what": "Shows the regenerate screen: the files the code writes from its sources."},
{"name": "deploy", "form": "codebot build deploy", "what": "Shows the deploy screen: install, build, publish and restart the host."},
{"name": "dev", "form": "npm run dev", "what": "Starts the host from source in watch mode on port 3505; stop the service first, since both use that port."},
{"name": "playground", "form": "npm run playground", "what": "Opens the Gmail playground in a browser, for comparing design variants."},
{"name": "setup account", "form": "npm run setup-account", "what": "Runs ops/setup-account.ts, the account set-up script; OPERATIONS.md describes what it sets."}
]},
{"path": ["build", "check"], "sentence": "The checks: whether the code compiles, whether the Gmail tests pass, and the reviews.", "rows": [
{"name": "typecheck", "form": "npm run typecheck", "what": "Checks the types without building; a pass means the code compiles, and nothing more about Bot behavior."},
{"name": "tests", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
{"name": "check", "form": "npm run check", "what": "Runs the type check and the tests together."},
{"name": "review gmail", "form": "npm run review:gmail", "what": "Runs the Gmail review, ops/review/gmail-review.mjs."},
{"name": "review schedules", "form": "npm run review:schedules", "what": "Runs the schedules review, ops/review/schedules-review.mjs."}
]},
{"path": ["build", "regenerate"], "sentence": "The files the code writes from its sources, so they never drift from them.", "rows": [
{"name": "gmail reference", "form": "npm run docs:gmail", "what": "Regenerates docs/automation/gmail-reference.md from the code."},
{"name": "agent files", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md."}
]},
{"path": ["build", "deploy"], "sentence": "The steps that install, build, publish and restart the host, and the account service function.", "rows": [
{"name": "install packages", "form": "npm ci", "what": "Installs the exact dependencies from the lock file."},
{"name": "build", "form": "npm run build", "what": "Type-checks, then builds a new release and swaps it in; a failed build leaves the running release intact."},
{"name": "deploy", "form": "sh ops/deploy.sh", "what": "Commits, pushes and restarts the host once no Bot is working; it refuses while someone else has uncommitted edits."},
{"name": "install the host", "form": "ops/OPERATIONS.md: Install or update the host", "what": "Shows the steps to install the host's service unit and settings the first time."},
{"name": "integration copy", "form": "npm run build:integration", "what": "Builds the disposable QA copy that the integration service on port 3506 runs."},
{"name": "account function", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys host-access to the account service; needed whenever a contract it parses changes."}
]},
{"path": ["recover"], "sentence": "The procedures that back up and restore the host's data, stop it in an emergency, and reset a person's onboarding.", "rows": [
{"name": "back up", "form": "ops/OPERATIONS.md: Back up a consistent installation", "what": "Shows the steps to copy the stopped data folder, with checksums, into a private backup folder."},
{"name": "restore", "form": "ops/OPERATIONS.md: Restore into a separate directory first", "what": "Shows the steps to restore a backup into a separate folder and check it before it replaces anything."},
{"name": "emergency stop", "form": "ops/OPERATIONS.md: Emergency stop and rollback", "what": "Shows the steps to force the host to stop when a normal stop does not end it; forcing can lose unfinished recording media."},
{"name": "onboarding", "form": "codebot recover onboarding", "what": "Shows the onboarding screen: three ways to show a person onboarding again."}
]},
{"path": ["recover", "onboarding"], "sentence": "The three ways to reset a person's onboarding, from the smallest to the one that deletes their data.", "rows": [
{"name": "replay the tour", "form": "ops/OPERATIONS.md: Replay only the first-use tour", "what": "Shows the steps to show a person the first-use tour again; it works only when their host has no Bots."},
{"name": "fresh CodeBot", "form": "ops/OPERATIONS.md: Restart onboarding with a fresh CodeBot, keeping the account", "what": "Shows the steps to wipe a host's Bots and conversations, keeping the account and project folders."},
{"name": "full reset", "form": "ops/OPERATIONS.md: Full reset: the person starts as new", "what": "Shows the steps to delete a person's account, Bots, conversations, attachments and recordings; destructive, so back up first."}
]},
{"path": ["guests"], "sentence": "The second CodeBots on this machine: the guest's own CodeBot and the family CodeBots, each run as its own Linux user.", "rows": [
{"name": "guest", "form": "codebot guests guest", "what": "Shows the guest screen: the guest's CodeBot, its status, its invite and its removal."},
{"name": "family", "form": "codebot guests family", "what": "Shows the family screen: the front door and each family member's CodeBot."}
]},
{"path": ["guests", "guest"], "sentence": "The guest's CodeBot on this machine: its status, its invite, its address, and how to update or remove it.", "rows": [
{"name": "status", "form": "systemctl status codebot-guest", "what": "Shows whether the guest's CodeBot runs."},
{"name": "logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest's CodeBot log."},
{"name": "processes", "form": "ps -u codebot-guest", "what": "Lists the guest's running processes."},
{"name": "disk", "form": "sudo du -sh /home/codebot-guest", "what": "Shows how much space the guest's home folder uses."},
{"name": "invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Creates a one-use Google sign-in link, valid for ten minutes; anyone holding it can sign in."},
{"name": "address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's CodeBot in a browser on the private network."},
{"name": "update", "form": "ops/guest-update.sh", "what": "Builds the program, replaces the guest's copy and restarts it; needs no password."},
{"name": "install", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, service, settings, sudo rules and port 10000; run once."},
{"name": "remove", "form": "ops/OPERATIONS.md: Host a guest on this machine", "what": "Shows the steps to remove the guest's CodeBot and user; destructive."}
]},
{"path": ["guests", "family"], "sentence": "The family CodeBots on the home Wi-Fi: a front door that signs members in, and one CodeBot per member, each with its own Linux user and port.", "rows": [
{"name": "status", "form": "systemctl status codebot-family-lobby 'codebot-family@*'", "what": "Shows whether the front door and each family CodeBot runs."},
{"name": "helper status", "form": "codebot-family status", "what": "Shows which family CodeBots run and whether each can connect Gmail."},
{"name": "add", "form": "sudo codebot-family add N", "what": "Creates a family CodeBot at the next free number, up to six; the front door runs this when a new Google account signs in."},
{"name": "remove", "form": "ops/OPERATIONS.md: Home Wi-Fi address", "what": "Shows the steps to remove a family CodeBot and free its number; its Google account stays linked to it for good."},
{"name": "stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
{"name": "start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot."},
{"name": "member address", "form": "https://family.codebot.lielbenor.com:10100+N", "what": "Opens family CodeBot N's app; N is the number the status shows."},
{"name": "update", "form": "ops/family-update.sh", "what": "Builds the program, replaces it for every family CodeBot and restarts them all; needs no password."},
{"name": "install", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, helper, services, sudo rules and nginx; run once."}
]},
{"path": ["experiments"], "sentence": "Three experimental apps that reuse the CodeBot server on this computer, each in its own private repo.", "rows": [
{"name": "V2", "form": "codebot experiments V2", "what": "Shows the V2 screen: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal."},
{"name": "V3", "form": "codebot experiments V3", "what": "Shows the V3 screen: Claude Code first, with a mod that draws the Bot list above the prompt."},
{"name": "V4", "form": "codebot experiments V4", "what": "Shows the V4 screen: a simple main menu whose buttons set up the Claude Code sessions."}
]},
{"path": ["experiments", "V2"], "sentence": "The V2 terminal chat app: CodeBot's look and Bot list, where a Bot's chat is the Claude Code terminal.", "rows": [
{"name": "folder", "form": "~/projects/codebot-v2-terminal-chat", "what": "Opens the app's folder: its code, and its own data in .data/app."},
{"name": "start", "form": "sh ops/app-run.sh dev", "what": "Starts the app on port 3512 with its own terminal broker; run it in its own terminal window."},
{"name": "open", "form": "http://127.0.0.1:3512", "what": "Opens the app in Chrome; reload the tab once after the app restarts."},
{"name": "port", "form": "ss -ltnp 'sport = :3512'", "what": "Shows the process holding port 3512, the only one to stop."},
{"name": "notes", "form": "docs/experiment/ in the app's folder", "what": "Opens the owner's vision, decision log and report for this app."}
]},
{"path": ["experiments", "V3"], "sentence": "The V3 Claude Code mod app: Claude Code first, with a mod that draws the Bot list above the prompt.", "rows": [
{"name": "folder", "form": "~/projects/codebot-v3-claude-mod", "what": "Opens the app's folder: its code, and its own data in .data/app."},
{"name": "start", "form": "sh ops/app-run.sh dev", "what": "Starts the app on port 3513 with its own terminal broker; run it in its own terminal window."},
{"name": "open", "form": "http://127.0.0.1:3513", "what": "Opens the app in Chrome; reload the tab once after the app restarts."},
{"name": "port", "form": "ss -ltnp 'sport = :3513'", "what": "Shows the process holding port 3513, the only one to stop."},
{"name": "old test Bots", "form": "claude stop <id>", "what": "Stops an old test Bot; claude agents lists their ids."},
{"name": "notes", "form": "docs/experiment/ in the app's folder", "what": "Opens the owner's vision, decision log and report for this app."}
]},
{"path": ["experiments", "V4"], "sentence": "The V4 launcher menu app: a simple main menu whose buttons set up the Claude Code sessions.", "rows": [
{"name": "folder", "form": "~/projects/codebot-v4-launcher-menu", "what": "Opens the app's folder: its code, and its own data in .data/app."},
{"name": "start", "form": "sh ops/app-run.sh dev", "what": "Starts the app on port 3514 with its own terminal broker; run it in its own terminal window."},
{"name": "open", "form": "http://127.0.0.1:3514", "what": "Opens the app in Chrome; reload the tab once after the app restarts."},
{"name": "port", "form": "ss -ltnp 'sport = :3514'", "what": "Shows the process holding port 3514, the only one to stop."},
{"name": "notes", "form": "docs/experiment/ in the app's folder", "what": "Opens the owner's vision, decision log and report for this app."}
]},
{"path": ["docs"], "sentence": "The documents about CodeBot, grouped by subject.", "rows": [
{"name": "product", "form": "codebot docs product", "what": "Shows the product screen: what CodeBot is, how it is built and what is still open."},
{"name": "operations", "form": "codebot docs operations", "what": "Shows the operations screen: running, self-hosting, settings files and service units."},
{"name": "automation", "form": "codebot docs automation", "what": "Shows the automation screen: how Bots use Gmail, and its generated reference."},
{"name": "design", "form": "codebot docs design", "what": "Shows the design screen: the design method, the owner's rulings and the reference images."},
{"name": "plans", "form": "codebot docs plans", "what": "Shows the plans screen: plans, objectives, tasks and onboarding implementation."},
{"name": "verification", "form": "codebot docs verification", "what": "Shows the verification screen: recorded checks, behavior specs, module intents and QA findings."},
{"name": "agents", "form": "codebot docs agents", "what": "Shows the agents screen: the rules for coding agents and the housekeeping skill."}
]},
{"path": ["docs", "product"], "sentence": "The documents that say what CodeBot is, how it is built and what is still open.", "rows": [
{"name": "README", "form": "README.md", "what": "Opens the README: what CodeBot is, how to run it and how its pieces fit."},
{"name": "architecture", "form": "ARCHITECTURE.md", "what": "Opens the architecture: the boundaries, domain ownership and provider runtime."},
{"name": "product spec", "form": "PRODUCT-SPEC.md", "what": "Opens the behavior contract the product is held to; referenced by the README, not in the dump."},
{"name": "implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what the first beta built before it was paused; referenced, not in the dump."},
{"name": "deferred work", "form": "DEFERRED-WORK.md", "what": "Opens the open work checklist and the safe restart state; referenced, not in the dump."},
{"name": "release scope", "form": "MASTER-PLAN.md", "what": "Opens the release scope; the dump has docs/plans/MASER_PLAN.md, so confirm which is real."}
]},
{"path": ["docs", "operations"], "sentence": "The documents for running CodeBot on a machine you control, and keeping it safe.", "rows": [
{"name": "runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook: install, service, backups, restores, addresses, guests, family and emergencies."},
{"name": "self-hosting", "form": "docs/self-hosting-practices.md", "what": "Opens the self-hosting practices."},
{"name": "host and account", "form": "docs/host-account-exchange.md", "what": "Opens how a host and the account service exchange identity."},
{"name": "settings template", "form": "ops/environment.example", "what": "Opens the template for the host's settings file; keep the real copy outside the checkout."},
{"name": "service units", "form": "ops/codebot.service, ops/codebot-guest.service, ops/codebot-family-lobby.service, ops/codebot-family@.service, ops/codebot-terminal-broker.service", "what": "Opens the systemd unit files that run the host, the guest, the family and the terminal broker."}
]},
{"path": ["docs", "automation"], "sentence": "How Bots use Gmail: the supervisor's guide and a reference generated from the code.", "rows": [
{"name": "gmail guide", "form": "docs/automation/gmail.md", "what": "Opens the supervisor's guide to Gmail for Bots, including how Google sign-in returns through the relay."},
{"name": "gmail reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference; it is regenerated, not edited."},
{"name": "gmail relay", "form": "supabase/functions/gmail-relay/index.ts", "what": "Opens the stateless relay that forwards Google sign-in back to the host it came from."}
]},
{"path": ["docs", "design"], "sentence": "How screens are designed here: the method, the owner's rulings, and the reference images.", "rows": [
{"name": "design method", "form": "docs/design-method.md", "what": "Opens the method for designing or changing a screen."},
{"name": "design taste", "form": "docs/design-taste.md", "what": "Opens the owner's rulings and what they rejected."},
{"name": "design folder", "form": "design/README.md", "what": "Opens the reference screenshots, their annotated versions and their notes."}
]},
{"path": ["docs", "plans"], "sentence": "The plans, objectives, tasks and onboarding implementation: the work done and the work still planned.", "rows": [
{"name": "plans", "form": "docs/plans/", "what": "Opens the plan documents, one file per piece of work."},
{"name": "superpowers plans", "form": "docs/superpowers/plans/", "what": "Opens the plans written under the superpowers workflow."},
{"name": "objectives", "form": "docs/objectives/", "what": "Opens the objectives, with their README index."},
{"name": "tasks", "form": "docs/tasks/", "what": "Opens the task records, including the shared storage backup task."},
{"name": "onboarding implementation", "form": "docs/onboarding-implementation.md", "what": "Opens how onboarding was built."}
]},
{"path": ["docs", "verification"], "sentence": "The recorded checks, behavior specs, module intents and QA findings that show what was verified and how.", "rows": [
{"name": "verification", "form": "docs/verification/", "what": "Opens the recorded checks and their evidence."},
{"name": "ai readiness", "form": "docs/ai-readiness-verification.md", "what": "Opens the AI readiness check record."},
{"name": "onboarding proof", "form": "docs/onboarding-recorded-proof-2026-09-14.md", "what": "Opens the recorded onboarding proof from 2026-09-14."},
{"name": "onboarding review gate", "form": "docs/onboarding-review-gate.md", "what": "Opens the review gate that onboarding had to pass."},
{"name": "module intents", "form": ".idd/modules/", "what": "Opens each module's INTENT.md: its constraints and Given / When / Then table."},
{"name": "behavior specs", "form": ".bdd/features/", "what": "Opens the Given / When / Then feature specs for attachments, bot questions, chat, navigation and updates."},
{"name": "qa findings", "form": ".bdd/qa/", "what": "Opens the QA findings and how each was resolved."}
]},
{"path": ["docs", "agents"], "sentence": "The rules and skills for coding agents that work in this repository.", "rows": [
{"name": "rules", "form": "CLAUDE.md", "what": "Opens the rules every task assumes; AGENTS.md is generated from it."},
{"name": "agentic development", "form": "docs/agentic-development.md", "what": "Opens how agents work on this project."},
{"name": "housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the housekeeping skill."},
{"name": "global rules", "form": "ops/global/CLAUDE.md", "what": "Opens the global rules file for the agent."}
]}
],
"questions": [
"Does cli/codebot.py exist, and what does it do? The README mentions it for data and docs, but cli/ is not in the dump. Recommendation: check it first; if it exists, extend it rather than adding a second CLI.",
"Which facade name will you type? Recommendation: codebot, the project's own word. I could not run a clash check here, so confirm no existing codebot command before building.",
"Should the app's own screens (Bots, Gmail, Terminal, Contracts, Avatars, Settings, Onboarding) appear in this map? Recommendation: no. Leave them to the app's own navigation, so each screen has one source.",
"Should destructive steps (full reset, emergency stop, removing a guest or family CodeBot) be one-line commands in the help? Recommendation: no. The help points to the runbook section and offers no command.",
"Do you accept the splits in this map: host (diagnostics, settings), build (check, regenerate, deploy), recover (onboarding), guests (guest, family), docs (seven subjects), experiments (V2, V3, V4)? Recommendation: keep them as drafted; tell me which to merge or cut.",
"Should the experiments stay in this map, since they live in other private repos? Recommendation: keep them, because the README documents them and the owner reaches them from here."
]}
```

screen-decomposition, final · run 4 exit=0 seconds=224 · prompt

P1 Recall: 0.462P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.968P5 Short top: 5P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.36
As terminal help
What you can reach in CodeBot, grouped by what you are doing with it.
Botscodebot botsOpens the Bots on this host: each Bot's chat, widgets, settings and files, and how to start one.
Gmailcodebot gmailOpens Gmail for your Bots: connecting Google, approvals, activity and summaries.
Hostcodebot hostOpens running this computer's CodeBot: service, data, people, network, account service and deploy.
Buildcodebot buildOpens the commands that run, check and build CodeBot from its source.
Docscodebot docsOpens the written guides and records for CodeBot.
bots
The Bots on this host, with the ways to start one and reach the first-use tour.
Each Botcodebot bots <bot> (one row per Bot, generated from the host's Bot list)Opens one Bot's screen: its chat, widgets, settings and pinned files.
New Botapps/web/src/workspace/BotForm.tsxOpens the form that creates a Bot: its name, provider and folder.
Terminal tabsapps/web/src/TerminalPage.tsxOpens the shell tabs on this host, when the terminal is turned on.
Onboardinghttps://<address>/onboardingOpens the first-use tour a new person goes through, which creates their first Bot.
bots › <bot>
One Bot: its chat, and what belongs to it: its widgets, settings and pinned files.
Widgetscodebot bots <bot> widgetsOpens this Bot's widgets: live browser, screenshots, contract, git, Gmail and recordings.
Settingsapps/web/src/ui/Settings.tsxOpens this Bot's settings behind the cog button: provider, folder and whether it sends notices.
Pinned filesapps/web/src/resources/PinnedFiles.tsxOpens the files and resources pinned to this Bot.
bots › <bot> › widgets
This Bot's widgets: live browser view, screenshot gallery, feature contract, git status, Gmail and recordings.
VisionStreamable kind vision (component not in the dump)Opens the live view of this Bot's browser, with control passed between owner and Bot.
ScreenshotsStreamable kind screenshot_galleryOpens the gallery of screenshots this Bot captured.
Contractapps/web/src/widgets/ContractWidget.tsxOpens the screens of this Bot's feature contract.
GitStreamable kind git_quick_infoOpens this Bot's repository status and quick git actions.
Gmailapps/web/src/widgets/GmailWidget.tsxOpens the Gmail items this Bot produced, for this Bot only.
Add or arrange widgetsapps/web/src/widgets/WidgetBrowser.tsxOpens the list of widgets to add to this Bot, and their order.
Recordingsapps/web/src/resources/RecordingPlayer.tsxPlays a recording of this Bot's browser session.
bots › <bot> › widgets › contract
This Bot's feature contract: its catalog, files, history, changes and conflicts.
Catalogapps/web/src/contracts/ContractCatalog.tsxOpens the list of this Bot's contract items.
Filesapps/web/src/contracts/ContractFiles.tsxOpens the files the contract covers.
Historyapps/web/src/contracts/ContractHistory.tsxOpens the contract's revisions in order.
Diffapps/web/src/contracts/ContractDiff.tsxOpens the changes between two revisions.
Conflictsapps/web/src/contracts/ContractConflict.tsxOpens the conflicts the contract has found, to resolve.
Relationshipsapps/web/src/contracts/ComponentRelationships.tsxOpens how the contract's components depend on each other.
gmail
Gmail for your Bots: connecting Google, what waits for approval, what Bots did, and summaries.
Connect Googleapps/web/src/gmail/GmailAccess.tsxOpens the sign-in that connects your Google account to this host.
Approvalsapps/web/src/gmail/GmailApprovals.tsxOpens the Gmail actions waiting for your approval.
Activityapps/web/src/gmail/GmailActivity.tsxOpens the record of what Bots did in Gmail.
Dailyapps/web/src/gmail/GmailDaily.tsxOpens the day's Gmail summary.
Glanceapps/web/src/gmail/GmailGlance.tsxOpens the at-a-glance view of the newest Gmail items.
Cardsapps/web/src/gmail/GmailCards.tsxOpens the cards Bots made from Gmail.
host
Running this computer's CodeBot: its service, data, people, network, account service and deploy.
Servicecodebot host serviceOpens the service's status, logs, port check, restart and emergency stop.
Datacodebot host dataOpens the settings, data folder, backups and restores.
Peoplecodebot host peopleOpens devices, the guest, the family, and onboarding resets.
Networkcodebot host networkOpens the private address and how to change it.
Account servicecodebot host accountOpens the Supabase account service that handles sign-in.
Deploysh ops/deploy.shBuilds, pushes and restarts the service once no Bot is working.
host › service
This computer's CodeBot service: whether it runs, what it logged, which process holds its port, and how to stop it.
Statussystemctl --user status codebot.service --no-pager; curl the /api/session check on port 3505Prints whether the service runs and answers on port 3505.
Logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the service's last 80 log lines.
Port ownerss -ltnp 'sport = :3505'Prints which process holds port 3505.
Restartsystemctl --user restart codebot.serviceRestarts the service after a build, once no Bot is working.
Host diagnostics/api/diagnostics/host on the host's addressShows the host's counters: queued and running turns, and recovery hold.
Terminal brokersystemctl --user status codebot-terminal-broker.service (install steps: OPERATIONS.md, Persistent terminal broker)Prints whether the optional terminal broker runs; its install steps are in the runbook.
Emergency stopsystemctl --user stop --no-block codebot.service, then systemctl --user kill (OPERATIONS.md, Emergency stop and rollback)Stops the service at once and kills its processes, when a normal stop is not enough.
host › data
The settings, data and backups of this computer's CodeBot, and how to restore them.
Backupops/OPERATIONS.md, Back up a consistent installationStops the service, copies its data, source and settings into a dated backup folder, and restarts it.
Restoreops/OPERATIONS.md, Restore into a separate directory firstRestores a backup into a separate folder and checks it before anything replaces the original.
Settings file~/.config/codebot/service.envSets the service's values: port, data folder, project roots, provider login and Gmail keys.
Example settingsops/environment.exampleShows every setting with its comment, to copy into the settings file.
Data folder~/.local/share/codebotHolds the database, transcripts and attachments.
Project folders~/projects (CODEBOT_PROJECT_ROOTS)Holds the project folders Bots are allowed to reach.
Entrance key~/.local/share/codebot/owner-keyHolds the key a new device types to sign in; read it only locally.
host › people
The people this computer's CodeBot serves: your devices, a guest, family members, and first-use resets.
Devicescodebot host people devicesOpens connecting a phone or computer, installing the app and turning on notices.
Guestcodebot host people guestOpens setting up a second CodeBot for a guest, as its own Linux user.
Familycodebot host people familyOpens the family CodeBots: their setup, list and removal.
Onboardingcodebot host people onboardingOpens the ways to restart a person's first-use tour.
host › people › devices
Connecting a phone or computer to this host, and its background notices.
Connect a deviceops/OPERATIONS.md, Connect a device (tailscale serve status --json)Connects a new phone or computer through the private address.
Install on phoneops/OPERATIONS.md, Private access and PWA installationAdds CodeBot to the phone's home screen as an app.
Background noticesops/OPERATIONS.md, Background notificationsTurns on alerts for Bot replies, approvals and failures on a device.
Reconnectops/OPERATIONS.md, Background notificationsRenews a device whose notice subscription expired or was rejected.
host › people › guest
A second CodeBot for one guest on this machine, run as its own Linux user.
Set upsudo ops/guest-install.shSets up the guest's user, program, service and sudo rules, once.
Updateops/guest-update.shBuilds the guest's program, replaces it and restarts the guest's service.
Invitesudo -u codebot-guest /opt/codebot-guest/inviteCreates a one-use Google sign-in link, valid for ten minutes.
Statussystemctl status codebot-guestPrints whether the guest's service runs.
Removeops/OPERATIONS.md, Host a guest on this machine (removal steps)Stops the guest's service and deletes its user, home folder and program.
host › people › family
Family CodeBots on this machine: a front door, one CodeBot per family member, and their helper.
Set upsudo ops/family-install.shSets up the front door, helper, services and nginx, once.
Updateops/family-update.shBuilds the family program and restarts every family CodeBot.
Add or removesudo codebot-family add N / sudo codebot-family remove NAdds one family CodeBot, or removes one and frees its number.
Statuscodebot-family statusPrints each family CodeBot and whether it can connect Gmail.
Stop or start allsudo codebot-family stop-all / sudo codebot-family start-allStops or starts every family CodeBot.
Remove everythingops/OPERATIONS.md, Home Wi-Fi address (removal steps)Removes the front door, helper, services, nginx entries and family program.
host › people › onboarding
Restarting a person's first-use tour, keeping or wiping their account.
Replay the tourops/OPERATIONS.md, Replay only the first-use tourRestarts the first-use tour from its first step, on a host with no Bots.
Fresh CodeBotops/OPERATIONS.md, Restart onboarding with a fresh CodeBotWipes the host's Bots and conversations, and keeps the account and project folders.
Full resetops/OPERATIONS.md, Full reset: the person starts as newDeletes the account with its Bots, conversations, attachments and recordings, so the person starts as new.
host › network
How this computer's CodeBot is reached: its private address and its home Wi-Fi address.
Private addresstailscale serve status --jsonPrints where the private HTTPS address forwards on this computer.
Change the addressops/OPERATIONS.md, Change this machine's addressMoves CodeBot to a new address and updates every place that holds the old one.
Home Wi-Fi addressops/OPERATIONS.md, Home Wi-Fi addressExplains the family address: its certificate, DNS record and routes.
host › account
The Supabase account service that handles sign-in and the host handshake.
Deploy host-accessSUPABASE_ACCESS_TOKEN="$(cat ~/.config/supabase-codebot-token)" npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function; redeploy whenever a contract it parses changes.
Gmail relaysupabase/functions/gmail-relay/index.tsForwards Google sign-in back to the owner's own server.
Token~/.config/supabase-codebot-tokenHolds the Supabase token for CLI work; keep it at mode 600.
Migrationssupabase/migrations/Creates the account service's tables, one file per change.
Sign-in settingsSupabase dashboard, Authentication, URL ConfigurationSets the sign-in redirect list and the site address.
build
The commands that run, check and build CodeBot from its source.
Runcodebot build runOpens the commands that start the service and the playground.
Checkcodebot build checkOpens the commands that type-check, test and review the code.
Buildnpm run buildType-checks, then builds the web app into a new release folder.
Build QA copynpm run build:integrationType-checks, then builds the copy the QA instance on port 3506 runs.
Sync agents filenpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
Set up accountnpm run setup-accountRuns the account setup script, ops/setup-account.ts.
build › run
The commands that start CodeBot's service and its playground.
Dev servernpm run devStarts the service in watch mode, reloading on each change.
Startnpm run startStarts the service in production mode, the way the host runs it.
Playgroundnpm run playgroundStarts Vite on 127.0.0.1 and opens the Gmail playground, to compare screen variants.
build › check
The commands that check CodeBot's code, its Gmail flow and its schedules.
Typechecknpm run typecheckType-checks the code without building it.
Testsnpm testRuns the Gmail automation tests against a fake Google.
Checknpm run checkType-checks, then runs the tests.
Review Gmailnpm run review:gmailChecks the Gmail flow against the real service in a real browser.
Review schedulesnpm run review:schedulesChecks schedules against the real service.
docs
The written guides and records for CodeBot: how to run it, how it is built, and why it is that way.
Start herecodebot docs startOpens the guides to read first: overview, product, architecture, rules and runbook.
Statuscodebot docs statusOpens what is built, what is open, the release scope and what's new.
Designcodebot docs designOpens the design method, the owner's past design rulings and the design references.
Gmailcodebot docs gmailOpens the Gmail guide and its generated reference.
Recordscodebot docs recordsOpens the plans, task reports, verification evidence and feature intents.
Agent skillskills/codebot-housekeeping/SKILL.mdOpens the housekeeping skill that agents follow for this project.
docs › start
The guides to read first: the overview, the product, how it is built, the working rules and the operator runbook.
OverviewREADME.mdOpens the overview, the commands and how the pieces fit.
Product behaviorPRODUCT-SPEC.mdOpens the behavior contract the app has to match.
ArchitectureARCHITECTURE.mdOpens how CodeBot is built: boundaries, Bots, transcripts and providers.
Working rulesCLAUDE.mdOpens the rules for Bots, screens and deploys; AGENTS.md is generated from it.
Operator runbookops/OPERATIONS.mdOpens the install, backup, restore, recovery and address procedures.
Self-hosting practicesdocs/self-hosting-practices.mdOpens the practices for running CodeBot on a machine you control.
docs › status
What CodeBot has built so far, what is still open, and what changed for the owner.
Built so farIMPLEMENTATION-STATUS.mdOpens what the first beta built, as recorded.
Open workDEFERRED-WORK.mdOpens the open work and the safe state to restart from.
Release scopeMASTER-PLAN.mdOpens the release scope; an internal milestone is not a finished product.
What's newapps/web/src/whatsNew.tsOpens the changes the owner was told about in the app.
Objectivesdocs/objectives/README.mdOpens the goals for chats, Gmail, schedules and terminal tabs.
docs › design
The design method, the owner's design rulings, and the design references for the app.
Design methoddocs/design-method.mdOpens the steps for designing or reworking a screen.
Design tastedocs/design-taste.mdOpens the owner's past design rulings, to check a new screen against.
Design referencesdesign/Opens the mockups and screenshots of the design.
docs › gmail
How Bots use Gmail: the guide to set it up and supervise it, and the generated reference of its tools.
Gmail guidedocs/automation/gmail.mdOpens how Bots use Gmail: setup and supervision.
Gmail referencedocs/automation/gmail-reference.mdOpens the generated list of the Gmail tools; rebuilt by npm run docs:gmail.
docs › records
The plans, task reports, verification evidence and feature intents recorded for CodeBot.
Plansdocs/plans/ and .plans/Opens the plans and designs, one file per piece of work.
Tasksdocs/tasks/Opens the task reports and the audits of self-hosted work.
Verificationdocs/verification/ and .bdd/qa/Opens the recorded test evidence and QA resolutions.
Feature intents.idd/modules/*/INTENT.md and .bdd/features/Opens each module's intent and its Given / When / Then tests.
Onboarding recordsdocs/onboarding-implementation.md and docs/onboarding-recorded-proof-2026-09-14.mdOpens how onboarding was built and its recorded proof.
Account exchangedocs/host-account-exchange.mdOpens how the host and the account service exchange sign-in.
Agentic developmentdocs/agentic-development.mdOpens the notes on developing CodeBot with agents.
Questions
  • Should the operator's Host group stay in the same map as the owner's app (recommended, since one owner does both), or should the operator work become its own CLI?
  • Confirm the facade name: I recommend codebot, with a short alias if the clash check passes. The README mentions cli/codebot.py, which is not in the repo.
  • Keep the V2, V3 and V4 experimental apps off this map? I recommend yes: the README says they are in their own private repos and are not part of CodeBot.
  • Which plan file is real, MASTER-PLAN.md (the name the docs use) or docs/plans/MASER_PLAN.md (the name in the dump)? I recommend fixing the name so docs and file agree.
As phone screens

Home

What you can reach in CodeBot, grouped by what you are doing with it.

BotsOpens the Bots on this host: each Bot's chat, widgets, settings and files, and how to start one.
›
GmailOpens Gmail for your Bots: connecting Google, approvals, activity and summaries.
›
HostOpens running this computer's CodeBot: service, data, people, network, account service and deploy.
›
BuildOpens the commands that run, check and build CodeBot from its source.
›
DocsOpens the written guides and records for CodeBot.
›
‹ Home

bots

The Bots on this host, with the ways to start one and reach the first-use tour.

Each BotOpens one Bot's screen: its chat, widgets, settings and pinned files.
›
New BotOpens the form that creates a Bot: its name, provider and folder.
›
Terminal tabsOpens the shell tabs on this host, when the terminal is turned on.
›
OnboardingOpens the first-use tour a new person goes through, which creates their first Bot.
›
‹ bots

<bot>

One Bot: its chat, and what belongs to it: its widgets, settings and pinned files.

WidgetsOpens this Bot's widgets: live browser, screenshots, contract, git, Gmail and recordings.
›
SettingsOpens this Bot's settings behind the cog button: provider, folder and whether it sends notices.
›
Pinned filesOpens the files and resources pinned to this Bot.
›
‹ <bot>

widgets

This Bot's widgets: live browser view, screenshot gallery, feature contract, git status, Gmail and recordings.

VisionOpens the live view of this Bot's browser, with control passed between owner and Bot.
›
ScreenshotsOpens the gallery of screenshots this Bot captured.
›
ContractOpens the screens of this Bot's feature contract.
›
GitOpens this Bot's repository status and quick git actions.
›
GmailOpens the Gmail items this Bot produced, for this Bot only.
›
Add or arrange widgetsOpens the list of widgets to add to this Bot, and their order.
›
RecordingsPlays a recording of this Bot's browser session.
›
‹ widgets

contract

This Bot's feature contract: its catalog, files, history, changes and conflicts.

CatalogOpens the list of this Bot's contract items.
›
FilesOpens the files the contract covers.
›
HistoryOpens the contract's revisions in order.
›
DiffOpens the changes between two revisions.
›
ConflictsOpens the conflicts the contract has found, to resolve.
›
RelationshipsOpens how the contract's components depend on each other.
›
‹ Home

gmail

Gmail for your Bots: connecting Google, what waits for approval, what Bots did, and summaries.

Connect GoogleOpens the sign-in that connects your Google account to this host.
›
ApprovalsOpens the Gmail actions waiting for your approval.
›
ActivityOpens the record of what Bots did in Gmail.
›
DailyOpens the day's Gmail summary.
›
GlanceOpens the at-a-glance view of the newest Gmail items.
›
CardsOpens the cards Bots made from Gmail.
›
‹ Home

host

Running this computer's CodeBot: its service, data, people, network, account service and deploy.

ServiceOpens the service's status, logs, port check, restart and emergency stop.
›
DataOpens the settings, data folder, backups and restores.
›
PeopleOpens devices, the guest, the family, and onboarding resets.
›
NetworkOpens the private address and how to change it.
›
Account serviceOpens the Supabase account service that handles sign-in.
›
DeployBuilds, pushes and restarts the service once no Bot is working.
›
‹ host

service

This computer's CodeBot service: whether it runs, what it logged, which process holds its port, and how to stop it.

StatusPrints whether the service runs and answers on port 3505.
›
LogsPrints the service's last 80 log lines.
›
Port ownerPrints which process holds port 3505.
›
RestartRestarts the service after a build, once no Bot is working.
›
Host diagnosticsShows the host's counters: queued and running turns, and recovery hold.
›
Terminal brokerPrints whether the optional terminal broker runs; its install steps are in the runbook.
›
Emergency stopStops the service at once and kills its processes, when a normal stop is not enough.
›
‹ host

data

The settings, data and backups of this computer's CodeBot, and how to restore them.

BackupStops the service, copies its data, source and settings into a dated backup folder, and restarts it.
›
RestoreRestores a backup into a separate folder and checks it before anything replaces the original.
›
Settings fileSets the service's values: port, data folder, project roots, provider login and Gmail keys.
›
Example settingsShows every setting with its comment, to copy into the settings file.
›
Data folderHolds the database, transcripts and attachments.
›
Project foldersHolds the project folders Bots are allowed to reach.
›
Entrance keyHolds the key a new device types to sign in; read it only locally.
›
‹ host

people

The people this computer's CodeBot serves: your devices, a guest, family members, and first-use resets.

DevicesOpens connecting a phone or computer, installing the app and turning on notices.
›
GuestOpens setting up a second CodeBot for a guest, as its own Linux user.
›
FamilyOpens the family CodeBots: their setup, list and removal.
›
OnboardingOpens the ways to restart a person's first-use tour.
›
‹ people

devices

Connecting a phone or computer to this host, and its background notices.

Connect a deviceConnects a new phone or computer through the private address.
›
Install on phoneAdds CodeBot to the phone's home screen as an app.
›
Background noticesTurns on alerts for Bot replies, approvals and failures on a device.
›
ReconnectRenews a device whose notice subscription expired or was rejected.
›
‹ people

guest

A second CodeBot for one guest on this machine, run as its own Linux user.

Set upSets up the guest's user, program, service and sudo rules, once.
›
UpdateBuilds the guest's program, replaces it and restarts the guest's service.
›
InviteCreates a one-use Google sign-in link, valid for ten minutes.
›
StatusPrints whether the guest's service runs.
›
RemoveStops the guest's service and deletes its user, home folder and program.
›
‹ people

family

Family CodeBots on this machine: a front door, one CodeBot per family member, and their helper.

Set upSets up the front door, helper, services and nginx, once.
›
UpdateBuilds the family program and restarts every family CodeBot.
›
Add or removeAdds one family CodeBot, or removes one and frees its number.
›
StatusPrints each family CodeBot and whether it can connect Gmail.
›
Stop or start allStops or starts every family CodeBot.
›
Remove everythingRemoves the front door, helper, services, nginx entries and family program.
›
‹ people

onboarding

Restarting a person's first-use tour, keeping or wiping their account.

Replay the tourRestarts the first-use tour from its first step, on a host with no Bots.
›
Fresh CodeBotWipes the host's Bots and conversations, and keeps the account and project folders.
›
Full resetDeletes the account with its Bots, conversations, attachments and recordings, so the person starts as new.
›
‹ host

network

How this computer's CodeBot is reached: its private address and its home Wi-Fi address.

Private addressPrints where the private HTTPS address forwards on this computer.
›
Change the addressMoves CodeBot to a new address and updates every place that holds the old one.
›
Home Wi-Fi addressExplains the family address: its certificate, DNS record and routes.
›
‹ host

account

The Supabase account service that handles sign-in and the host handshake.

Deploy host-accessDeploys the host-access function; redeploy whenever a contract it parses changes.
›
Gmail relayForwards Google sign-in back to the owner's own server.
›
TokenHolds the Supabase token for CLI work; keep it at mode 600.
›
MigrationsCreates the account service's tables, one file per change.
›
Sign-in settingsSets the sign-in redirect list and the site address.
›
‹ Home

build

The commands that run, check and build CodeBot from its source.

RunOpens the commands that start the service and the playground.
›
CheckOpens the commands that type-check, test and review the code.
›
BuildType-checks, then builds the web app into a new release folder.
›
Build QA copyType-checks, then builds the copy the QA instance on port 3506 runs.
›
Sync agents fileRegenerates AGENTS.md from CLAUDE.md.
›
Set up accountRuns the account setup script, ops/setup-account.ts.
›
‹ build

run

The commands that start CodeBot's service and its playground.

Dev serverStarts the service in watch mode, reloading on each change.
›
StartStarts the service in production mode, the way the host runs it.
›
PlaygroundStarts Vite on 127.0.0.1 and opens the Gmail playground, to compare screen variants.
›
‹ build

check

The commands that check CodeBot's code, its Gmail flow and its schedules.

TypecheckType-checks the code without building it.
›
TestsRuns the Gmail automation tests against a fake Google.
›
CheckType-checks, then runs the tests.
›
Review GmailChecks the Gmail flow against the real service in a real browser.
›
Review schedulesChecks schedules against the real service.
›
‹ Home

docs

The written guides and records for CodeBot: how to run it, how it is built, and why it is that way.

Start hereOpens the guides to read first: overview, product, architecture, rules and runbook.
›
StatusOpens what is built, what is open, the release scope and what's new.
›
DesignOpens the design method, the owner's past design rulings and the design references.
›
GmailOpens the Gmail guide and its generated reference.
›
RecordsOpens the plans, task reports, verification evidence and feature intents.
›
Agent skillOpens the housekeeping skill that agents follow for this project.
›
‹ docs

start

The guides to read first: the overview, the product, how it is built, the working rules and the operator runbook.

OverviewOpens the overview, the commands and how the pieces fit.
›
Product behaviorOpens the behavior contract the app has to match.
›
ArchitectureOpens how CodeBot is built: boundaries, Bots, transcripts and providers.
›
Working rulesOpens the rules for Bots, screens and deploys; AGENTS.md is generated from it.
›
Operator runbookOpens the install, backup, restore, recovery and address procedures.
›
Self-hosting practicesOpens the practices for running CodeBot on a machine you control.
›
‹ docs

status

What CodeBot has built so far, what is still open, and what changed for the owner.

Built so farOpens what the first beta built, as recorded.
›
Open workOpens the open work and the safe state to restart from.
›
Release scopeOpens the release scope; an internal milestone is not a finished product.
›
What's newOpens the changes the owner was told about in the app.
›
ObjectivesOpens the goals for chats, Gmail, schedules and terminal tabs.
›
‹ docs

design

The design method, the owner's design rulings, and the design references for the app.

Design methodOpens the steps for designing or reworking a screen.
›
Design tasteOpens the owner's past design rulings, to check a new screen against.
›
Design referencesOpens the mockups and screenshots of the design.
›
‹ docs

gmail

How Bots use Gmail: the guide to set it up and supervise it, and the generated reference of its tools.

Gmail guideOpens how Bots use Gmail: setup and supervision.
›
Gmail referenceOpens the generated list of the Gmail tools; rebuilt by npm run docs:gmail.
›
‹ docs

records

The plans, task reports, verification evidence and feature intents recorded for CodeBot.

PlansOpens the plans and designs, one file per piece of work.
›
TasksOpens the task reports and the audits of self-hosted work.
›
VerificationOpens the recorded test evidence and QA resolutions.
›
Feature intentsOpens each module's intent and its Given / When / Then tests.
›
Onboarding recordsOpens how onboarding was built and its recorded proof.
›
Account exchangeOpens how the host and the account service exchange sign-in.
›
Agentic developmentOpens the notes on developing CodeBot with agents.
›
Raw answer
# Screen map: codebot

This is a plan only. Nothing is built.

## Scenario

*Reasoning from the README and `ops/OPERATIONS.md`, not an observed session:* the owner runs CodeBot on their own computer. Most of the time they use it from a phone to watch and steer their Bots. At the desk, the same person deploys a change, checks the service, backs it up, connects a device, adds a guest or family member, and fixes things when they break.

## Inventory (by source)

- **App screens** (`apps/web/src`, from file names): Bots and their chat, widgets, settings and files; the feature contract (catalog, files, history, diff, conflicts, relationships); Gmail (access, approvals, activity, daily, glance, cards); terminal tabs; recordings; onboarding; What's new. The Vision, Git and screenshot components are not in the dump, so their rows cite the streamable kind.
- **Commands** (`package.json`, 13 scripts): all mapped.
- **Operator scripts**: `ops/deploy.sh` (named in CLAUDE.md, not in the dump), `guest-install.sh`, `guest-update.sh`, `family-install.sh`, `family-update.sh`, `setup-account.ts`, `sync-agents.ts`, `environment.example`.
- **Services**: `codebot.service` (port 3505), `codebot-terminal-broker.service` (optional), `codebot-guest.service`, `codebot-family-lobby.service`, `codebot-family@.service`.
- **Runbooks** (`ops/OPERATIONS.md` sections): backup, restore, emergency stop, device connection, notices, guest, family, address change, onboarding resets, Home Wi-Fi address.
- **Data and settings**: `~/.config/codebot/service.env`, `~/.local/share/codebot`, `~/projects`, the owner key, the Supabase token.
- **Account service**: `host-access` and `gmail-relay` functions, migrations.
- **Diagnostics**: `/api/session`, `/api/diagnostics/{host,scheduler,vision}`, `/api/notifications/diagnostics`.
- **Docs**: README, PRODUCT-SPEC, ARCHITECTURE, CLAUDE.md, the status files, the design docs, Gmail docs, plans, tasks, verification, intents, and the housekeeping skill.

## Screens

```
codebot
├─ bots
│  └─ <bot>
│     └─ widgets
│        └─ contract
├─ gmail
├─ host
│  ├─ service
│  ├─ data
│  ├─ people
│  │  ├─ devices
│  │  ├─ guest
│  │  ├─ family
│  │  └─ onboarding
│  ├─ network
│  └─ account
├─ build
│  ├─ run
│  └─ check
└─ docs
   ├─ start
   ├─ status
   ├─ design
   ├─ gmail
   └─ records
```

25 screens in total. Each screen's path, sentence and rows are in the JSON at the end.

## Questions for you

1. **One map or two?** I recommend one map, since the same owner does both the phone use and the desk work. The operator work sits under `host`. A separate operator CLI would be the alternative.
2. **Facade name.** The README mentions `cli/codebot.py`, which is not in the repo. I recommend `codebot` as the facade. Tell me if you want a short alias, and `cli-engineer` will check it for clashes.
3. **V2, V3 and V4 apps.** I recommend keeping them off this map. The README says they live in their own private repos and are not part of CodeBot.
4. **Plan file name.** The docs point to `MASTER-PLAN.md`, but the dump has `docs/plans/MASER_PLAN.md`. Which one is real? I recommend fixing the name so the docs and the file agree.

## Judgment calls

- **Runbooks are rows, not screens.** Each runbook is a multi-step procedure with no single command, so its form is the section name in `OPERATIONS.md`. Making a command for each would duplicate the runbook.
- **Destructive procedures are pointers, not commands.** Full reset, `userdel`, and the other removal steps appear with plain warnings. The CLI should link to them and never run them.
- **Deploy is a leaf, not a screen.** It is the most common operator action and is one step, so it sits on the top `host` screen.
- **Gmail appears twice.** Once at top level (all Bots) and once in each Bot's widgets (this Bot only). The two lines differ.
- **Terminal sits under Bots, not at top level.** A top-level group with one item is weak. The broker install stays under `host > service` because it runs on the server.
- **Bot rows are live.** The `<bot>` placeholder is filled from the host's Bot list, so the map is never typed out by hand.
- **Off the map:** `ops/deploy-guard.sh` (a Stop hook no one reaches), `AGENTS.md` (generated from CLAUDE.md, so CLAUDE.md is the one to reach), the V2–V4 apps, and the missing `cli/codebot.py`.
- **Not verified.** `ops/agent-start.sh`, `ops/deploy.sh`, and `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md` and `MASTER-PLAN.md` are named in the docs but not in the dump. Their rows are kept, and each should be checked before the CLI is built. `agent-start.sh` has no row because its purpose is not in the dump.

## Map

```json
{"screens": [
{"path": [], "sentence": "What you can reach in CodeBot, grouped by what you are doing with it.", "rows": [
{"name": "Bots", "form": "codebot bots", "what": "Opens the Bots on this host: each Bot's chat, widgets, settings and files, and how to start one."},
{"name": "Gmail", "form": "codebot gmail", "what": "Opens Gmail for your Bots: connecting Google, approvals, activity and summaries."},
{"name": "Host", "form": "codebot host", "what": "Opens running this computer's CodeBot: service, data, people, network, account service and deploy."},
{"name": "Build", "form": "codebot build", "what": "Opens the commands that run, check and build CodeBot from its source."},
{"name": "Docs", "form": "codebot docs", "what": "Opens the written guides and records for CodeBot."}
]},
{"path": ["bots"], "sentence": "The Bots on this host, with the ways to start one and reach the first-use tour.", "rows": [
{"name": "Each Bot", "form": "codebot bots <bot> (one row per Bot, generated from the host's Bot list)", "what": "Opens one Bot's screen: its chat, widgets, settings and pinned files."},
{"name": "New Bot", "form": "apps/web/src/workspace/BotForm.tsx", "what": "Opens the form that creates a Bot: its name, provider and folder."},
{"name": "Terminal tabs", "form": "apps/web/src/TerminalPage.tsx", "what": "Opens the shell tabs on this host, when the terminal is turned on."},
{"name": "Onboarding", "form": "https://<address>/onboarding", "what": "Opens the first-use tour a new person goes through, which creates their first Bot."}
]},
{"path": ["bots", "<bot>"], "sentence": "One Bot: its chat, and what belongs to it: its widgets, settings and pinned files.", "rows": [
{"name": "Widgets", "form": "codebot bots <bot> widgets", "what": "Opens this Bot's widgets: live browser, screenshots, contract, git, Gmail and recordings."},
{"name": "Settings", "form": "apps/web/src/ui/Settings.tsx", "what": "Opens this Bot's settings behind the cog button: provider, folder and whether it sends notices."},
{"name": "Pinned files", "form": "apps/web/src/resources/PinnedFiles.tsx", "what": "Opens the files and resources pinned to this Bot."}
]},
{"path": ["bots", "<bot>", "widgets"], "sentence": "This Bot's widgets: live browser view, screenshot gallery, feature contract, git status, Gmail and recordings.", "rows": [
{"name": "Vision", "form": "Streamable kind vision (component not in the dump)", "what": "Opens the live view of this Bot's browser, with control passed between owner and Bot."},
{"name": "Screenshots", "form": "Streamable kind screenshot_gallery", "what": "Opens the gallery of screenshots this Bot captured."},
{"name": "Contract", "form": "apps/web/src/widgets/ContractWidget.tsx", "what": "Opens the screens of this Bot's feature contract."},
{"name": "Git", "form": "Streamable kind git_quick_info", "what": "Opens this Bot's repository status and quick git actions."},
{"name": "Gmail", "form": "apps/web/src/widgets/GmailWidget.tsx", "what": "Opens the Gmail items this Bot produced, for this Bot only."},
{"name": "Add or arrange widgets", "form": "apps/web/src/widgets/WidgetBrowser.tsx", "what": "Opens the list of widgets to add to this Bot, and their order."},
{"name": "Recordings", "form": "apps/web/src/resources/RecordingPlayer.tsx", "what": "Plays a recording of this Bot's browser session."}
]},
{"path": ["bots", "<bot>", "widgets", "contract"], "sentence": "This Bot's feature contract: its catalog, files, history, changes and conflicts.", "rows": [
{"name": "Catalog", "form": "apps/web/src/contracts/ContractCatalog.tsx", "what": "Opens the list of this Bot's contract items."},
{"name": "Files", "form": "apps/web/src/contracts/ContractFiles.tsx", "what": "Opens the files the contract covers."},
{"name": "History", "form": "apps/web/src/contracts/ContractHistory.tsx", "what": "Opens the contract's revisions in order."},
{"name": "Diff", "form": "apps/web/src/contracts/ContractDiff.tsx", "what": "Opens the changes between two revisions."},
{"name": "Conflicts", "form": "apps/web/src/contracts/ContractConflict.tsx", "what": "Opens the conflicts the contract has found, to resolve."},
{"name": "Relationships", "form": "apps/web/src/contracts/ComponentRelationships.tsx", "what": "Opens how the contract's components depend on each other."}
]},
{"path": ["gmail"], "sentence": "Gmail for your Bots: connecting Google, what waits for approval, what Bots did, and summaries.", "rows": [
{"name": "Connect Google", "form": "apps/web/src/gmail/GmailAccess.tsx", "what": "Opens the sign-in that connects your Google account to this host."},
{"name": "Approvals", "form": "apps/web/src/gmail/GmailApprovals.tsx", "what": "Opens the Gmail actions waiting for your approval."},
{"name": "Activity", "form": "apps/web/src/gmail/GmailActivity.tsx", "what": "Opens the record of what Bots did in Gmail."},
{"name": "Daily", "form": "apps/web/src/gmail/GmailDaily.tsx", "what": "Opens the day's Gmail summary."},
{"name": "Glance", "form": "apps/web/src/gmail/GmailGlance.tsx", "what": "Opens the at-a-glance view of the newest Gmail items."},
{"name": "Cards", "form": "apps/web/src/gmail/GmailCards.tsx", "what": "Opens the cards Bots made from Gmail."}
]},
{"path": ["host"], "sentence": "Running this computer's CodeBot: its service, data, people, network, account service and deploy.", "rows": [
{"name": "Service", "form": "codebot host service", "what": "Opens the service's status, logs, port check, restart and emergency stop."},
{"name": "Data", "form": "codebot host data", "what": "Opens the settings, data folder, backups and restores."},
{"name": "People", "form": "codebot host people", "what": "Opens devices, the guest, the family, and onboarding resets."},
{"name": "Network", "form": "codebot host network", "what": "Opens the private address and how to change it."},
{"name": "Account service", "form": "codebot host account", "what": "Opens the Supabase account service that handles sign-in."},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, pushes and restarts the service once no Bot is working."}
]},
{"path": ["host", "service"], "sentence": "This computer's CodeBot service: whether it runs, what it logged, which process holds its port, and how to stop it.", "rows": [
{"name": "Status", "form": "systemctl --user status codebot.service --no-pager; curl the /api/session check on port 3505", "what": "Prints whether the service runs and answers on port 3505."},
{"name": "Logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the service's last 80 log lines."},
{"name": "Port owner", "form": "ss -ltnp 'sport = :3505'", "what": "Prints which process holds port 3505."},
{"name": "Restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service after a build, once no Bot is working."},
{"name": "Host diagnostics", "form": "/api/diagnostics/host on the host's address", "what": "Shows the host's counters: queued and running turns, and recovery hold."},
{"name": "Terminal broker", "form": "systemctl --user status codebot-terminal-broker.service (install steps: OPERATIONS.md, Persistent terminal broker)", "what": "Prints whether the optional terminal broker runs; its install steps are in the runbook."},
{"name": "Emergency stop", "form": "systemctl --user stop --no-block codebot.service, then systemctl --user kill (OPERATIONS.md, Emergency stop and rollback)", "what": "Stops the service at once and kills its processes, when a normal stop is not enough."}
]},
{"path": ["host", "data"], "sentence": "The settings, data and backups of this computer's CodeBot, and how to restore them.", "rows": [
{"name": "Backup", "form": "ops/OPERATIONS.md, Back up a consistent installation", "what": "Stops the service, copies its data, source and settings into a dated backup folder, and restarts it."},
{"name": "Restore", "form": "ops/OPERATIONS.md, Restore into a separate directory first", "what": "Restores a backup into a separate folder and checks it before anything replaces the original."},
{"name": "Settings file", "form": "~/.config/codebot/service.env", "what": "Sets the service's values: port, data folder, project roots, provider login and Gmail keys."},
{"name": "Example settings", "form": "ops/environment.example", "what": "Shows every setting with its comment, to copy into the settings file."},
{"name": "Data folder", "form": "~/.local/share/codebot", "what": "Holds the database, transcripts and attachments."},
{"name": "Project folders", "form": "~/projects (CODEBOT_PROJECT_ROOTS)", "what": "Holds the project folders Bots are allowed to reach."},
{"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Holds the key a new device types to sign in; read it only locally."}
]},
{"path": ["host", "people"], "sentence": "The people this computer's CodeBot serves: your devices, a guest, family members, and first-use resets.", "rows": [
{"name": "Devices", "form": "codebot host people devices", "what": "Opens connecting a phone or computer, installing the app and turning on notices."},
{"name": "Guest", "form": "codebot host people guest", "what": "Opens setting up a second CodeBot for a guest, as its own Linux user."},
{"name": "Family", "form": "codebot host people family", "what": "Opens the family CodeBots: their setup, list and removal."},
{"name": "Onboarding", "form": "codebot host people onboarding", "what": "Opens the ways to restart a person's first-use tour."}
]},
{"path": ["host", "people", "devices"], "sentence": "Connecting a phone or computer to this host, and its background notices.", "rows": [
{"name": "Connect a device", "form": "ops/OPERATIONS.md, Connect a device (tailscale serve status --json)", "what": "Connects a new phone or computer through the private address."},
{"name": "Install on phone", "form": "ops/OPERATIONS.md, Private access and PWA installation", "what": "Adds CodeBot to the phone's home screen as an app."},
{"name": "Background notices", "form": "ops/OPERATIONS.md, Background notifications", "what": "Turns on alerts for Bot replies, approvals and failures on a device."},
{"name": "Reconnect", "form": "ops/OPERATIONS.md, Background notifications", "what": "Renews a device whose notice subscription expired or was rejected."}
]},
{"path": ["host", "people", "guest"], "sentence": "A second CodeBot for one guest on this machine, run as its own Linux user.", "rows": [
{"name": "Set up", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest's user, program, service and sudo rules, once."},
{"name": "Update", "form": "ops/guest-update.sh", "what": "Builds the guest's program, replaces it and restarts the guest's service."},
{"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Creates a one-use Google sign-in link, valid for ten minutes."},
{"name": "Status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest's service runs."},
{"name": "Remove", "form": "ops/OPERATIONS.md, Host a guest on this machine (removal steps)", "what": "Stops the guest's service and deletes its user, home folder and program."}
]},
{"path": ["host", "people", "family"], "sentence": "Family CodeBots on this machine: a front door, one CodeBot per family member, and their helper.", "rows": [
{"name": "Set up", "form": "sudo ops/family-install.sh", "what": "Sets up the front door, helper, services and nginx, once."},
{"name": "Update", "form": "ops/family-update.sh", "what": "Builds the family program and restarts every family CodeBot."},
{"name": "Add or remove", "form": "sudo codebot-family add N / sudo codebot-family remove N", "what": "Adds one family CodeBot, or removes one and frees its number."},
{"name": "Status", "form": "codebot-family status", "what": "Prints each family CodeBot and whether it can connect Gmail."},
{"name": "Stop or start all", "form": "sudo codebot-family stop-all / sudo codebot-family start-all", "what": "Stops or starts every family CodeBot."},
{"name": "Remove everything", "form": "ops/OPERATIONS.md, Home Wi-Fi address (removal steps)", "what": "Removes the front door, helper, services, nginx entries and family program."}
]},
{"path": ["host", "people", "onboarding"], "sentence": "Restarting a person's first-use tour, keeping or wiping their account.", "rows": [
{"name": "Replay the tour", "form": "ops/OPERATIONS.md, Replay only the first-use tour", "what": "Restarts the first-use tour from its first step, on a host with no Bots."},
{"name": "Fresh CodeBot", "form": "ops/OPERATIONS.md, Restart onboarding with a fresh CodeBot", "what": "Wipes the host's Bots and conversations, and keeps the account and project folders."},
{"name": "Full reset", "form": "ops/OPERATIONS.md, Full reset: the person starts as new", "what": "Deletes the account with its Bots, conversations, attachments and recordings, so the person starts as new."}
]},
{"path": ["host", "network"], "sentence": "How this computer's CodeBot is reached: its private address and its home Wi-Fi address.", "rows": [
{"name": "Private address", "form": "tailscale serve status --json", "what": "Prints where the private HTTPS address forwards on this computer."},
{"name": "Change the address", "form": "ops/OPERATIONS.md, Change this machine's address", "what": "Moves CodeBot to a new address and updates every place that holds the old one."},
{"name": "Home Wi-Fi address", "form": "ops/OPERATIONS.md, Home Wi-Fi address", "what": "Explains the family address: its certificate, DNS record and routes."}
]},
{"path": ["host", "account"], "sentence": "The Supabase account service that handles sign-in and the host handshake.", "rows": [
{"name": "Deploy host-access", "form": "SUPABASE_ACCESS_TOKEN=\"$(cat ~/.config/supabase-codebot-token)\" npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function; redeploy whenever a contract it parses changes."},
{"name": "Gmail relay", "form": "supabase/functions/gmail-relay/index.ts", "what": "Forwards Google sign-in back to the owner's own server."},
{"name": "Token", "form": "~/.config/supabase-codebot-token", "what": "Holds the Supabase token for CLI work; keep it at mode 600."},
{"name": "Migrations", "form": "supabase/migrations/", "what": "Creates the account service's tables, one file per change."},
{"name": "Sign-in settings", "form": "Supabase dashboard, Authentication, URL Configuration", "what": "Sets the sign-in redirect list and the site address."}
]},
{"path": ["build"], "sentence": "The commands that run, check and build CodeBot from its source.", "rows": [
{"name": "Run", "form": "codebot build run", "what": "Opens the commands that start the service and the playground."},
{"name": "Check", "form": "codebot build check", "what": "Opens the commands that type-check, test and review the code."},
{"name": "Build", "form": "npm run build", "what": "Type-checks, then builds the web app into a new release folder."},
{"name": "Build QA copy", "form": "npm run build:integration", "what": "Type-checks, then builds the copy the QA instance on port 3506 runs."},
{"name": "Sync agents file", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."},
{"name": "Set up account", "form": "npm run setup-account", "what": "Runs the account setup script, ops/setup-account.ts."}
]},
{"path": ["build", "run"], "sentence": "The commands that start CodeBot's service and its playground.", "rows": [
{"name": "Dev server", "form": "npm run dev", "what": "Starts the service in watch mode, reloading on each change."},
{"name": "Start", "form": "npm run start", "what": "Starts the service in production mode, the way the host runs it."},
{"name": "Playground", "form": "npm run playground", "what": "Starts Vite on 127.0.0.1 and opens the Gmail playground, to compare screen variants."}
]},
{"path": ["build", "check"], "sentence": "The commands that check CodeBot's code, its Gmail flow and its schedules.", "rows": [
{"name": "Typecheck", "form": "npm run typecheck", "what": "Type-checks the code without building it."},
{"name": "Tests", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google."},
{"name": "Check", "form": "npm run check", "what": "Type-checks, then runs the tests."},
{"name": "Review Gmail", "form": "npm run review:gmail", "what": "Checks the Gmail flow against the real service in a real browser."},
{"name": "Review schedules", "form": "npm run review:schedules", "what": "Checks schedules against the real service."}
]},
{"path": ["docs"], "sentence": "The written guides and records for CodeBot: how to run it, how it is built, and why it is that way.", "rows": [
{"name": "Start here", "form": "codebot docs start", "what": "Opens the guides to read first: overview, product, architecture, rules and runbook."},
{"name": "Status", "form": "codebot docs status", "what": "Opens what is built, what is open, the release scope and what's new."},
{"name": "Design", "form": "codebot docs design", "what": "Opens the design method, the owner's past design rulings and the design references."},
{"name": "Gmail", "form": "codebot docs gmail", "what": "Opens the Gmail guide and its generated reference."},
{"name": "Records", "form": "codebot docs records", "what": "Opens the plans, task reports, verification evidence and feature intents."},
{"name": "Agent skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the housekeeping skill that agents follow for this project."}
]},
{"path": ["docs", "start"], "sentence": "The guides to read first: the overview, the product, how it is built, the working rules and the operator runbook.", "rows": [
{"name": "Overview", "form": "README.md", "what": "Opens the overview, the commands and how the pieces fit."},
{"name": "Product behavior", "form": "PRODUCT-SPEC.md", "what": "Opens the behavior contract the app has to match."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how CodeBot is built: boundaries, Bots, transcripts and providers."},
{"name": "Working rules", "form": "CLAUDE.md", "what": "Opens the rules for Bots, screens and deploys; AGENTS.md is generated from it."},
{"name": "Operator runbook", "form": "ops/OPERATIONS.md", "what": "Opens the install, backup, restore, recovery and address procedures."},
{"name": "Self-hosting practices", "form": "docs/self-hosting-practices.md", "what": "Opens the practices for running CodeBot on a machine you control."}
]},
{"path": ["docs", "status"], "sentence": "What CodeBot has built so far, what is still open, and what changed for the owner.", "rows": [
{"name": "Built so far", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what the first beta built, as recorded."},
{"name": "Open work", "form": "DEFERRED-WORK.md", "what": "Opens the open work and the safe state to restart from."},
{"name": "Release scope", "form": "MASTER-PLAN.md", "what": "Opens the release scope; an internal milestone is not a finished product."},
{"name": "What's new", "form": "apps/web/src/whatsNew.ts", "what": "Opens the changes the owner was told about in the app."},
{"name": "Objectives", "form": "docs/objectives/README.md", "what": "Opens the goals for chats, Gmail, schedules and terminal tabs."}
]},
{"path": ["docs", "design"], "sentence": "The design method, the owner's design rulings, and the design references for the app.", "rows": [
{"name": "Design method", "form": "docs/design-method.md", "what": "Opens the steps for designing or reworking a screen."},
{"name": "Design taste", "form": "docs/design-taste.md", "what": "Opens the owner's past design rulings, to check a new screen against."},
{"name": "Design references", "form": "design/", "what": "Opens the mockups and screenshots of the design."}
]},
{"path": ["docs", "gmail"], "sentence": "How Bots use Gmail: the guide to set it up and supervise it, and the generated reference of its tools.", "rows": [
{"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "Opens how Bots use Gmail: setup and supervision."},
{"name": "Gmail reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated list of the Gmail tools; rebuilt by npm run docs:gmail."}
]},
{"path": ["docs", "records"], "sentence": "The plans, task reports, verification evidence and feature intents recorded for CodeBot.", "rows": [
{"name": "Plans", "form": "docs/plans/ and .plans/", "what": "Opens the plans and designs, one file per piece of work."},
{"name": "Tasks", "form": "docs/tasks/", "what": "Opens the task reports and the audits of self-hosted work."},
{"name": "Verification", "form": "docs/verification/ and .bdd/qa/", "what": "Opens the recorded test evidence and QA resolutions."},
{"name": "Feature intents", "form": ".idd/modules/*/INTENT.md and .bdd/features/", "what": "Opens each module's intent and its Given / When / Then tests."},
{"name": "Onboarding records", "form": "docs/onboarding-implementation.md and docs/onboarding-recorded-proof-2026-09-14.md", "what": "Opens how onboarding was built and its recorded proof."},
{"name": "Account exchange", "form": "docs/host-account-exchange.md", "what": "Opens how the host and the account service exchange sign-in."},
{"name": "Agentic development", "form": "docs/agentic-development.md", "what": "Opens the notes on developing CodeBot with agents."}
]}
],
"questions": [
"Should the operator's Host group stay in the same map as the owner's app (recommended, since one owner does both), or should the operator work become its own CLI?",
"Confirm the facade name: I recommend codebot, with a short alias if the clash check passes. The README mentions cli/codebot.py, which is not in the repo.",
"Keep the V2, V3 and V4 experimental apps off this map? I recommend yes: the README says they are in their own private repos and are not part of CodeBot.",
"Which plan file is real, MASTER-PLAN.md (the name the docs use) or docs/plans/MASER_PLAN.md (the name in the dump)? I recommend fixing the name so docs and file agree."
]}
```

No skill · run 5 exit=0 seconds=96 · prompt

P1 Recall: 0.423P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.343P5 Short top: 16P6 Own words: 1.0P8 Worded per screen: 1P9 Grouping (ARI): 0.267
As terminal help
CodeBot's top screen: run it, open it, and reach each area of the owner's and operator's work.
Run the servicenpm start (production) or npm run dev (development)starts the local CodeBot service on port 3505
Web app on this computerhttp://127.0.0.1:3505the interface for watching and steering Bots on this machine
Web app on phone or tablethttps://liel.tail18e69e.ts.net/the same app over Tailscale
Botsscreen: bots (proposed: codebot bots)every Bot, its state, and which one needs you
Gmailscreen: gmail (proposed: codebot gmail)connect Gmail, approve what Bots may do, see what they did
Schedulesscreen: schedules (proposed: codebot schedules)scheduled wakeups for Bots and whether they run
This computer's hostscreen: host (proposed: codebot host)is the service up, how to restart it, where its data lives
Family membersscreen: family (proposed: codebot family)CodeBots for family members on the home network
Guest accountscreen: guest (proposed: codebot guest)the separate-account guest setup on this machine
Onboarding resetsscreen: onboarding (proposed: codebot onboarding)restart how a person is onboarded
Account servicescreen: account (proposed: codebot account)the shared sign-in service (Supabase)
Backup and restorescreen: backup (proposed: codebot backup)save and check a consistent copy of the data
Diagnosticsscreen: diagnostics (proposed: codebot diagnostics)health of the running host, with no credentials shown
Developer checksscreen: checks (proposed: codebot checks)type check, tests, build, and the design playground
Documentsscreen: docs (proposed: codebot docs)where the rules, designs, and runbooks live
What's newscreen: updates (proposed: codebot updates)what changed in the app since the last visit
bots
All Bots with their state, and which ones need the owner.
Create a Botscreen: bots new (proposed: codebot bots new)make a new Bot with a provider, folder, and role
Open a Botscreen: bots <id> (proposed: codebot bots <id>)one Bot's chat, settings, widgets, terminal
bots › new
A form to create a Bot: name, provider, model, and folder.
Bot formBotForm on the create-new-bot screenfill in the details; an empty model uses the automatic policy
bots › <id>
One Bot's name, current state, and what it needs from the owner, with its areas below.
Chatscreen: bots <id> chatthe conversation and the messages waiting behind it
Settingsscreen: bots <id> settings (cog button)provider, model, folder, notifications
Widgetsscreen: bots <id> widgetslive views: Vision, screenshots, contract, Git, Gmail
Terminalscreen: bots <id> terminalshell tabs for this Bot; needs the terminal broker
Avataravatar studio and picker (web)choose or design this Bot's avatar
bots › <id> › chat
The conversation: messages, the reply in progress, and the queue behind it.
Send a messagecomposer on this screensend the next message or queue it while a reply runs
Take queued messages backPOST /bots/:id/queue/takepull queued messages into the composer to edit and resend
Send queued messages nowPOST /bots/:id/queue/send-nowhand the queue over at once; interrupts Codex and non-Claude replies
Stop the replyEsc keyinterrupts the reply and keeps the queue
Continue or retryContinue and Retry buttonsresume a stopped or failed turn
Attachmentsattachment picker on this screenadd files and images to a message
Pinned filespinned files panel on this screenkeep files close at hand
Preview files and recordingsresource viewer and recording playeropen a file, screenshot, or recording
Approve a file linkapprove file link on this screenlet a Bot open a file it asked for
Earlier chatschats/ folder in the Bot's hometranscripts of finished chats; the Bot reads them when you refer back
bots › <id> › settings
This Bot's settings, all behind one cog button; the defaults are automatic.
Provider and modelBot form; empty model uses the automatic policyClaude, Codex, or OpenCode, and which model
Primary folderBot form; path must sit under CODEBOT_PROJECT_ROOTSwhere the Bot works; inside the allowed roots only
Notifications switchswitch on this screenalerts for replies, approvals, and failures
Enable this devicebrowser notification permissionallow alerts on this phone or computer
Send testSend test buttoncheck the selected device shows an alert; a queued test is not proof
Other devicesOther devices list (16 kept)remove old notification subscriptions
Skills and automatic actionsBot formattached skills and what the Bot may do on its own
bots › <id> › widgets
This Bot's live views, arranged by the owner.
VisionVision widget (browser stream)watch the browser the Bot drives
Screenshot galleryscreenshot gallery widgetthe Bot's captures
Feature contractscreen: bots <id> contractwhat the code promises, its history, and conflicts
Git quick infoGit quick-info widgetrepository status and quick actions
GmailGmail widgetthis Bot's Gmail cards and approvals
Widget browserWidgetBrowser on this screenadd or rearrange widgets
bots › <id> › contract
The Bot's feature contract: its catalog, files, history, and conflicts.
CatalogContractCatalog sectionthe contract entries
FilesContractFiles sectionfiles the contract covers
HistoryContractHistory sectionearlier revisions
DiffContractDiff sectionwhat changed between revisions
ConflictsContractConflict sectionentries that disagree and need a decision
Component relationshipsComponentRelationships sectionhow the parts depend on each other
bots › <id> › terminal
Shell tabs on this computer for this Bot. They exist only while the terminal broker runs.
New tabterminal tab (web)open a shell for this Bot
Switch tabsTabRowmove between open tabs
gmail
Gmail for Bots: connect the account, approve what Bots may do, and review what they did.
Connect GmailGoogle sign-in through gmail-relay; needs CODEBOT_GOOGLE_CLIENT_ID and CODEBOT_GOOGLE_CLIENT_SECRETlink a Google account to this server
AccessAccess section (GmailAccess)what each Bot may read or send
ApprovalsApprovals section (GmailApprovals)actions waiting for a yes or no
ActivityActivity section (GmailActivity)what Bots did in Gmail
Daily summaryDaily section (GmailDaily)one day at a glance
Gmail referencedocs/automation/gmail-reference.md; regenerate with npm run docs:gmailthe generated list of Gmail actions
Gmail checknpm run review:gmailrun the Gmail flow against the real service
schedules
Scheduled wakeups for Bots: what runs when, and whether it is working.
Schedule reviewnpm run review:schedulescheck the schedules
Schedule drillnode ops/review/schedule-drill.mjsrehearse a schedule firing
Schedules guidedocs/objectives/schedules.mdthe goal and the rules
host
This computer's CodeBot: whether it is up, how to restart it, and where its data lives.
Service statussystemctl --user status codebot.service --no-pagerrunning, and on port 3505
Restart servicesystemctl --user restart codebot.serviceapply a new build; only after active turns finish
Logsjournalctl --user -u codebot.service -n 80 --no-pagerrecent service output
Buildnpm run buildtype check, then publish the web app
Deploysh ops/deploy.shcommit, push, restart, and verify; refuses while a Bot is working
Emergency stopsystemctl --user stop codebot.servicestops scheduling and Bot turns cleanly; the force-kill steps are in ops/OPERATIONS.md
Recovery holdCODEBOT_RECOVERY_HOLD=1 in the service environment filepause automatic work while inspecting
Devicesscreen: host devicesphones and their alerts
Addressscreen: host addresschange the Tailscale name
Terminal brokersystemctl --user enable --now codebot-terminal-broker.serviceturns on terminal access; off by default
Owner key~/.local/share/codebot/owner-key (show the path only)the entrance key for a new device; never paste it
Tailscale mappingtailscale serve status --jsonthe private HTTPS mapping to port 3505
Integration QA copycodebot-integration.service on port 3506a disposable test copy, not the production host
host › devices
Phones, tablets, and computers connected to this CodeBot, and whether each gets alerts.
Install on a phonehttps://liel.tail18e69e.ts.net/, then Add to Home Screeninstall CodeBot as an app; Tailscale must be on
Reconnect this deviceReconnect this device buttonfix an expired or rejected alert subscription
Other devicesOther devices listremove old devices (16 kept)
Send testSend test buttoncheck the device shows an alert
host › address
Runbook for changing this computer's Tailscale name, which doubles as CodeBot's address. Nine places must agree.
Read the new nametailscale status --json (Self.DNSName)the name to move to
Sign-in allow listSupabase: Authentication, URL Configurationadd the new /onboarding address first
Owner settingsservice environment file and apps/web/.env.local, then npm run build and restartpoint the owner's host at the new name
Guest settings/home/codebot-guest/.config/codebot/service.env, then ops/guest-update.shpoint the guest host at the new name
Account rowsSQL update on codebot_account_progress.server_urlsend each person to the right host
Domain forwardcodebot.lielbenor.com at the registrarpoint the old address at the new one
Full checklistops/OPERATIONS.md, section Change this machine's addressthe nine places and their order
backup
Save a consistent copy of CodeBot's data, and verify a copy before relying on it.
Make a backupprocedure in ops/OPERATIONS.md (stops the service briefly)copy data, source, and settings into a private folder
Verify a backupsha256sum -c SHA256SUMS in the backup folderconfirm the files match
Restore into stagingextract to ~/.local/share/codebot-restore-staging; run on port 3508 with CODEBOT_RECOVERY_HOLD=1inspect a copy without starting automatic work
Promote a restoreops/OPERATIONS.md, section Restore into a separate directory firstswitch the live host to a verified copy
Backup folder~/.local/share/codebot-backups/where backups go; they hold keys, so keep them private
family
CodeBots for family members on the home network. Each person gets their own Linux account and sign-in.
Family sign-in pagehttps://family.codebot.lielbenor.comGoogle sign-in, then the person's own CodeBot
Add a membersudo codebot-family add Ncreate a CodeBot in slot N (six at most)
Remove a membersudo codebot-family remove Ndelete that CodeBot; the Google account stays linked
Family statuscodebot-family statuswhich are running and whether Gmail can connect
Stop or start allsudo codebot-family stop-all, or start-allpause or resume every family CodeBot
Installsudo ops/family-install.shone-time setup
Updateops/family-update.shrebuild and restart all of them; no password needed
guest
A separate setup for one guest on this machine, run as its own Linux user.
Invite linksudo -u codebot-guest /opt/codebot-guest/invitea one-use Google link, valid ten minutes
Guest addresshttps://liel.tail18e69e.ts.net:10000where the guest signs in
Update the guestops/guest-update.shrebuild and replace the guest copy
Guest statussystemctl status codebot-guestrunning or not
Reset onboardingscreen: onboardingstart the guest's onboarding again
Remove the guestops/OPERATIONS.md, section Host a guest on this machine (removal)delete the guest account and its program
onboarding
Reset how a person is onboarded. Each option keeps or removes different things.
Replay the first-use tourSQL on codebot_account_progress, plus deleting the first_use_receipts rowthe tour starts again; only works when the host has no Bots
Fresh CodeBot, same accountstop the host, wipe data except identity files, then the Supabase statementnew Bots and conversations; Google account and folders stay
Full resetdelete the data folder and the auth.users roweverything goes, including the account; destructive
Send a fresh invitesudo -u codebot-guest /opt/codebot-guest/invitea new sign-in link for the person
account
The shared sign-in service (Supabase) that every CodeBot server uses.
Sign-in entryhttps://liel.tail18e69e.ts.net/onboarding (CODEBOT_ACCOUNT_ENTRY_URL)where people start
Set up the accountnpm run setup-accountone-time operator setup
Deploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouredeploy after contract changes
Supabase CLI token~/.config/supabase-codebot-token (mode 600)the token for the mobile-coder login
Gmail relaysupabase/functions/gmail-relaythe fixed address Google redirects to
diagnostics
Health of the running host: counters and states, never credentials. The web checks need a signed-in browser.
Session/api/sessionanswers when the service is ready
Host/api/diagnostics/hostmigration, queue, running turns, recovery hold
Scheduler/api/diagnostics/schedulertimers and schedule state
Vision/api/diagnostics/visionbrowser stream health
Notifications/api/notifications/diagnosticsalert queue, timer, active sends
Recent logjournalctl --user -u codebot.service -n 80 --no-pagerrecent service output
Port ownerss -ltnp 'sport = :3505'which process holds the port
checks
Developer checks to run before a deploy: compile, test, build, and preview.
Type checknpm run typecheckcompiles the code; says little about Bot behaviour
Testsnpm testGmail tests against a fake Google
Full checknpm run checktype check plus tests
Buildnpm run buildtype check, then publish
Design playgroundnpm run playground (opens on http://127.0.0.1)compare design variants
Integration buildnpm run build:integrationbuild for the QA copy on port 3506
Sync agent docsnpm run sync:agentsregenerate AGENTS.md from CLAUDE.md
docs
Where the written rules, designs, and runbooks live.
READMEREADME.mdlayout, commands, how the pieces fit
ArchitectureARCHITECTURE.mdboundaries and invariants
Operationsops/OPERATIONS.mdrun, back up, restore, change the address
Design methoddocs/design-method.mdhow screens are designed
Design tastedocs/design-taste.mdthe owner's rulings
Plansdocs/plans/design and plan documents
Objectivesdocs/objectives/goals for each feature
Gmail guidedocs/automation/gmail.mdhow Bots use Gmail
updates
What changed in the app since the owner last looked.
What's new notesapps/web/src/whatsNew.tsowner-worded notes, shown once after an update
Update noticeUpdateNotice (web app)says a new version is ready; reopen to load it
Questions
  • Does a codebot command exist? README mentions cli/codebot.py, but no cli/ folder is in the file list. Recommendation: confirm. Until then, treat every codebot ... (proposed) form as a name to reserve, not a command that exists.
  • Who is the help for? The owner only, or also family and guest members? Recommendation: the owner and operator, with family and guest sections kept to operator commands. Family members use the web app and need no CLI help.
  • Should destructive resets be in the help (full reset, fresh CodeBot, removing a family member or guest)? Recommendation: include them, each requiring the person's name typed back and a confirmation, so one command cannot wipe data by accident.
  • Should the experimental apps V2, V3 and V4 appear? Recommendation: leave them out. The README says they are separate repos and CodeBot's rules do not apply to them.
  • Guest and family are two ways to host another person. Recommendation: make family the main screen and mark guest as legacy, then decide whether to keep running it.
  • Should planned features show in the help, such as Bot config export and import, or the offline command queue? Recommendation: show only shipped features; planned ones stay in docs/plans until they ship.
  • Should the terminal broker's enable step stay in host help? Recommendation: yes, with a warning that it gives a per-user shell and is off by default. Whether to enable it on this machine is the owner's call.
  • PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md and DEFERRED-WORK.md are referenced in README and ARCHITECTURE but are not in the file list. Recommendation: confirm they exist before the docs screen links to them.
As phone screens

Home

CodeBot's top screen: run it, open it, and reach each area of the owner's and operator's work.

Run the servicestarts the local CodeBot service on port 3505
›
Web app on this computerthe interface for watching and steering Bots on this machine
›
Web app on phone or tabletthe same app over Tailscale
›
Botsevery Bot, its state, and which one needs you
›
Gmailconnect Gmail, approve what Bots may do, see what they did
›
Schedulesscheduled wakeups for Bots and whether they run
›
This computer's hostis the service up, how to restart it, where its data lives
›
Family membersCodeBots for family members on the home network
›
Guest accountthe separate-account guest setup on this machine
›
Onboarding resetsrestart how a person is onboarded
›
Account servicethe shared sign-in service (Supabase)
›
Backup and restoresave and check a consistent copy of the data
›
Diagnosticshealth of the running host, with no credentials shown
›
Developer checkstype check, tests, build, and the design playground
›
Documentswhere the rules, designs, and runbooks live
›
What's newwhat changed in the app since the last visit
›
‹ Home

bots

All Bots with their state, and which ones need the owner.

Create a Botmake a new Bot with a provider, folder, and role
›
Open a Botone Bot's chat, settings, widgets, terminal
›
‹ bots

new

A form to create a Bot: name, provider, model, and folder.

Bot formfill in the details; an empty model uses the automatic policy
›
‹ bots

<id>

One Bot's name, current state, and what it needs from the owner, with its areas below.

Chatthe conversation and the messages waiting behind it
›
Settingsprovider, model, folder, notifications
›
Widgetslive views: Vision, screenshots, contract, Git, Gmail
›
Terminalshell tabs for this Bot; needs the terminal broker
›
Avatarchoose or design this Bot's avatar
›
‹ <id>

chat

The conversation: messages, the reply in progress, and the queue behind it.

Send a messagesend the next message or queue it while a reply runs
›
Take queued messages backpull queued messages into the composer to edit and resend
›
Send queued messages nowhand the queue over at once; interrupts Codex and non-Claude replies
›
Stop the replyinterrupts the reply and keeps the queue
›
Continue or retryresume a stopped or failed turn
›
Attachmentsadd files and images to a message
›
Pinned fileskeep files close at hand
›
Preview files and recordingsopen a file, screenshot, or recording
›
Approve a file linklet a Bot open a file it asked for
›
Earlier chatstranscripts of finished chats; the Bot reads them when you refer back
›
‹ <id>

settings

This Bot's settings, all behind one cog button; the defaults are automatic.

Provider and modelClaude, Codex, or OpenCode, and which model
›
Primary folderwhere the Bot works; inside the allowed roots only
›
Notifications switchalerts for replies, approvals, and failures
›
Enable this deviceallow alerts on this phone or computer
›
Send testcheck the selected device shows an alert; a queued test is not proof
›
Other devicesremove old notification subscriptions
›
Skills and automatic actionsattached skills and what the Bot may do on its own
›
‹ <id>

widgets

This Bot's live views, arranged by the owner.

Visionwatch the browser the Bot drives
›
Screenshot gallerythe Bot's captures
›
Feature contractwhat the code promises, its history, and conflicts
›
Git quick inforepository status and quick actions
›
Gmailthis Bot's Gmail cards and approvals
›
Widget browseradd or rearrange widgets
›
‹ <id>

contract

The Bot's feature contract: its catalog, files, history, and conflicts.

Catalogthe contract entries
›
Filesfiles the contract covers
›
Historyearlier revisions
›
Diffwhat changed between revisions
›
Conflictsentries that disagree and need a decision
›
Component relationshipshow the parts depend on each other
›
‹ <id>

terminal

Shell tabs on this computer for this Bot. They exist only while the terminal broker runs.

New tabopen a shell for this Bot
›
Switch tabsmove between open tabs
›
‹ Home

gmail

Gmail for Bots: connect the account, approve what Bots may do, and review what they did.

Connect Gmaillink a Google account to this server
›
Accesswhat each Bot may read or send
›
Approvalsactions waiting for a yes or no
›
Activitywhat Bots did in Gmail
›
Daily summaryone day at a glance
›
Gmail referencethe generated list of Gmail actions
›
Gmail checkrun the Gmail flow against the real service
›
‹ Home

schedules

Scheduled wakeups for Bots: what runs when, and whether it is working.

Schedule reviewcheck the schedules
›
Schedule drillrehearse a schedule firing
›
Schedules guidethe goal and the rules
›
‹ Home

host

This computer's CodeBot: whether it is up, how to restart it, and where its data lives.

Service statusrunning, and on port 3505
›
Restart serviceapply a new build; only after active turns finish
›
Logsrecent service output
›
Buildtype check, then publish the web app
›
Deploycommit, push, restart, and verify; refuses while a Bot is working
›
Emergency stopstops scheduling and Bot turns cleanly; the force-kill steps are in ops/OPERATIONS.md
›
Recovery holdpause automatic work while inspecting
›
Devicesphones and their alerts
›
Addresschange the Tailscale name
›
Terminal brokerturns on terminal access; off by default
›
Owner keythe entrance key for a new device; never paste it
›
Tailscale mappingthe private HTTPS mapping to port 3505
›
Integration QA copya disposable test copy, not the production host
›
‹ host

devices

Phones, tablets, and computers connected to this CodeBot, and whether each gets alerts.

Install on a phoneinstall CodeBot as an app; Tailscale must be on
›
Reconnect this devicefix an expired or rejected alert subscription
›
Other devicesremove old devices (16 kept)
›
Send testcheck the device shows an alert
›
‹ host

address

Runbook for changing this computer's Tailscale name, which doubles as CodeBot's address. Nine places must agree.

Read the new namethe name to move to
›
Sign-in allow listadd the new /onboarding address first
›
Owner settingspoint the owner's host at the new name
›
Guest settingspoint the guest host at the new name
›
Account rowssend each person to the right host
›
Domain forwardpoint the old address at the new one
›
Full checklistthe nine places and their order
›
‹ Home

backup

Save a consistent copy of CodeBot's data, and verify a copy before relying on it.

Make a backupcopy data, source, and settings into a private folder
›
Verify a backupconfirm the files match
›
Restore into staginginspect a copy without starting automatic work
›
Promote a restoreswitch the live host to a verified copy
›
Backup folderwhere backups go; they hold keys, so keep them private
›
‹ Home

family

CodeBots for family members on the home network. Each person gets their own Linux account and sign-in.

Family sign-in pageGoogle sign-in, then the person's own CodeBot
›
Add a membercreate a CodeBot in slot N (six at most)
›
Remove a memberdelete that CodeBot; the Google account stays linked
›
Family statuswhich are running and whether Gmail can connect
›
Stop or start allpause or resume every family CodeBot
›
Installone-time setup
›
Updaterebuild and restart all of them; no password needed
›
‹ Home

guest

A separate setup for one guest on this machine, run as its own Linux user.

Invite linka one-use Google link, valid ten minutes
›
Guest addresswhere the guest signs in
›
Update the guestrebuild and replace the guest copy
›
Guest statusrunning or not
›
Reset onboardingstart the guest's onboarding again
›
Remove the guestdelete the guest account and its program
›
‹ Home

onboarding

Reset how a person is onboarded. Each option keeps or removes different things.

Replay the first-use tourthe tour starts again; only works when the host has no Bots
›
Fresh CodeBot, same accountnew Bots and conversations; Google account and folders stay
›
Full reseteverything goes, including the account; destructive
›
Send a fresh invitea new sign-in link for the person
›
‹ Home

account

The shared sign-in service (Supabase) that every CodeBot server uses.

Sign-in entrywhere people start
›
Set up the accountone-time operator setup
›
Deploy host-accessredeploy after contract changes
›
Supabase CLI tokenthe token for the mobile-coder login
›
Gmail relaythe fixed address Google redirects to
›
‹ Home

diagnostics

Health of the running host: counters and states, never credentials. The web checks need a signed-in browser.

Sessionanswers when the service is ready
›
Hostmigration, queue, running turns, recovery hold
›
Schedulertimers and schedule state
›
Visionbrowser stream health
›
Notificationsalert queue, timer, active sends
›
Recent logrecent service output
›
Port ownerwhich process holds the port
›
‹ Home

checks

Developer checks to run before a deploy: compile, test, build, and preview.

Type checkcompiles the code; says little about Bot behaviour
›
TestsGmail tests against a fake Google
›
Full checktype check plus tests
›
Buildtype check, then publish
›
Design playgroundcompare design variants
›
Integration buildbuild for the QA copy on port 3506
›
Sync agent docsregenerate AGENTS.md from CLAUDE.md
›
‹ Home

docs

Where the written rules, designs, and runbooks live.

READMElayout, commands, how the pieces fit
›
Architectureboundaries and invariants
›
Operationsrun, back up, restore, change the address
›
Design methodhow screens are designed
›
Design tastethe owner's rulings
›
Plansdesign and plan documents
›
Objectivesgoals for each feature
›
Gmail guidehow Bots use Gmail
›
‹ Home

updates

What changed in the app since the owner last looked.

What's new notesowner-worded notes, shown once after an update
›
Update noticesays a new version is ready; reopen to load it
›
Raw answer
This is a plan only. The dump was cut off partway through `ops/OPERATIONS.md` and `ARCHITECTURE.md`, so some forms may be incomplete. Forms marked "(proposed)" are names to reserve for a future `codebot` command. They are not commands that exist today. The questions at the end each include my recommendation.

```json
{"screens": [
{"path": [], "sentence": "CodeBot's top screen: run it, open it, and reach each area of the owner's and operator's work.", "rows": [
{"name": "Run the service", "form": "npm start (production) or npm run dev (development)", "what": "starts the local CodeBot service on port 3505"},
{"name": "Web app on this computer", "form": "http://127.0.0.1:3505", "what": "the interface for watching and steering Bots on this machine"},
{"name": "Web app on phone or tablet", "form": "https://liel.tail18e69e.ts.net/", "what": "the same app over Tailscale"},
{"name": "Bots", "form": "screen: bots (proposed: codebot bots)", "what": "every Bot, its state, and which one needs you"},
{"name": "Gmail", "form": "screen: gmail (proposed: codebot gmail)", "what": "connect Gmail, approve what Bots may do, see what they did"},
{"name": "Schedules", "form": "screen: schedules (proposed: codebot schedules)", "what": "scheduled wakeups for Bots and whether they run"},
{"name": "This computer's host", "form": "screen: host (proposed: codebot host)", "what": "is the service up, how to restart it, where its data lives"},
{"name": "Family members", "form": "screen: family (proposed: codebot family)", "what": "CodeBots for family members on the home network"},
{"name": "Guest account", "form": "screen: guest (proposed: codebot guest)", "what": "the separate-account guest setup on this machine"},
{"name": "Onboarding resets", "form": "screen: onboarding (proposed: codebot onboarding)", "what": "restart how a person is onboarded"},
{"name": "Account service", "form": "screen: account (proposed: codebot account)", "what": "the shared sign-in service (Supabase)"},
{"name": "Backup and restore", "form": "screen: backup (proposed: codebot backup)", "what": "save and check a consistent copy of the data"},
{"name": "Diagnostics", "form": "screen: diagnostics (proposed: codebot diagnostics)", "what": "health of the running host, with no credentials shown"},
{"name": "Developer checks", "form": "screen: checks (proposed: codebot checks)", "what": "type check, tests, build, and the design playground"},
{"name": "Documents", "form": "screen: docs (proposed: codebot docs)", "what": "where the rules, designs, and runbooks live"},
{"name": "What's new", "form": "screen: updates (proposed: codebot updates)", "what": "what changed in the app since the last visit"}
]},
{"path": ["bots"], "sentence": "All Bots with their state, and which ones need the owner.", "rows": [
{"name": "Create a Bot", "form": "screen: bots new (proposed: codebot bots new)", "what": "make a new Bot with a provider, folder, and role"},
{"name": "Open a Bot", "form": "screen: bots <id> (proposed: codebot bots <id>)", "what": "one Bot's chat, settings, widgets, terminal"}
]},
{"path": ["bots", "new"], "sentence": "A form to create a Bot: name, provider, model, and folder.", "rows": [
{"name": "Bot form", "form": "BotForm on the create-new-bot screen", "what": "fill in the details; an empty model uses the automatic policy"}
]},
{"path": ["bots", "<id>"], "sentence": "One Bot's name, current state, and what it needs from the owner, with its areas below.", "rows": [
{"name": "Chat", "form": "screen: bots <id> chat", "what": "the conversation and the messages waiting behind it"},
{"name": "Settings", "form": "screen: bots <id> settings (cog button)", "what": "provider, model, folder, notifications"},
{"name": "Widgets", "form": "screen: bots <id> widgets", "what": "live views: Vision, screenshots, contract, Git, Gmail"},
{"name": "Terminal", "form": "screen: bots <id> terminal", "what": "shell tabs for this Bot; needs the terminal broker"},
{"name": "Avatar", "form": "avatar studio and picker (web)", "what": "choose or design this Bot's avatar"}
]},
{"path": ["bots", "<id>", "chat"], "sentence": "The conversation: messages, the reply in progress, and the queue behind it.", "rows": [
{"name": "Send a message", "form": "composer on this screen", "what": "send the next message or queue it while a reply runs"},
{"name": "Take queued messages back", "form": "POST /bots/:id/queue/take", "what": "pull queued messages into the composer to edit and resend"},
{"name": "Send queued messages now", "form": "POST /bots/:id/queue/send-now", "what": "hand the queue over at once; interrupts Codex and non-Claude replies"},
{"name": "Stop the reply", "form": "Esc key", "what": "interrupts the reply and keeps the queue"},
{"name": "Continue or retry", "form": "Continue and Retry buttons", "what": "resume a stopped or failed turn"},
{"name": "Attachments", "form": "attachment picker on this screen", "what": "add files and images to a message"},
{"name": "Pinned files", "form": "pinned files panel on this screen", "what": "keep files close at hand"},
{"name": "Preview files and recordings", "form": "resource viewer and recording player", "what": "open a file, screenshot, or recording"},
{"name": "Approve a file link", "form": "approve file link on this screen", "what": "let a Bot open a file it asked for"},
{"name": "Earlier chats", "form": "chats/ folder in the Bot's home", "what": "transcripts of finished chats; the Bot reads them when you refer back"}
]},
{"path": ["bots", "<id>", "settings"], "sentence": "This Bot's settings, all behind one cog button; the defaults are automatic.", "rows": [
{"name": "Provider and model", "form": "Bot form; empty model uses the automatic policy", "what": "Claude, Codex, or OpenCode, and which model"},
{"name": "Primary folder", "form": "Bot form; path must sit under CODEBOT_PROJECT_ROOTS", "what": "where the Bot works; inside the allowed roots only"},
{"name": "Notifications switch", "form": "switch on this screen", "what": "alerts for replies, approvals, and failures"},
{"name": "Enable this device", "form": "browser notification permission", "what": "allow alerts on this phone or computer"},
{"name": "Send test", "form": "Send test button", "what": "check the selected device shows an alert; a queued test is not proof"},
{"name": "Other devices", "form": "Other devices list (16 kept)", "what": "remove old notification subscriptions"},
{"name": "Skills and automatic actions", "form": "Bot form", "what": "attached skills and what the Bot may do on its own"}
]},
{"path": ["bots", "<id>", "widgets"], "sentence": "This Bot's live views, arranged by the owner.", "rows": [
{"name": "Vision", "form": "Vision widget (browser stream)", "what": "watch the browser the Bot drives"},
{"name": "Screenshot gallery", "form": "screenshot gallery widget", "what": "the Bot's captures"},
{"name": "Feature contract", "form": "screen: bots <id> contract", "what": "what the code promises, its history, and conflicts"},
{"name": "Git quick info", "form": "Git quick-info widget", "what": "repository status and quick actions"},
{"name": "Gmail", "form": "Gmail widget", "what": "this Bot's Gmail cards and approvals"},
{"name": "Widget browser", "form": "WidgetBrowser on this screen", "what": "add or rearrange widgets"}
]},
{"path": ["bots", "<id>", "contract"], "sentence": "The Bot's feature contract: its catalog, files, history, and conflicts.", "rows": [
{"name": "Catalog", "form": "ContractCatalog section", "what": "the contract entries"},
{"name": "Files", "form": "ContractFiles section", "what": "files the contract covers"},
{"name": "History", "form": "ContractHistory section", "what": "earlier revisions"},
{"name": "Diff", "form": "ContractDiff section", "what": "what changed between revisions"},
{"name": "Conflicts", "form": "ContractConflict section", "what": "entries that disagree and need a decision"},
{"name": "Component relationships", "form": "ComponentRelationships section", "what": "how the parts depend on each other"}
]},
{"path": ["bots", "<id>", "terminal"], "sentence": "Shell tabs on this computer for this Bot. They exist only while the terminal broker runs.", "rows": [
{"name": "New tab", "form": "terminal tab (web)", "what": "open a shell for this Bot"},
{"name": "Switch tabs", "form": "TabRow", "what": "move between open tabs"}
]},
{"path": ["gmail"], "sentence": "Gmail for Bots: connect the account, approve what Bots may do, and review what they did.", "rows": [
{"name": "Connect Gmail", "form": "Google sign-in through gmail-relay; needs CODEBOT_GOOGLE_CLIENT_ID and CODEBOT_GOOGLE_CLIENT_SECRET", "what": "link a Google account to this server"},
{"name": "Access", "form": "Access section (GmailAccess)", "what": "what each Bot may read or send"},
{"name": "Approvals", "form": "Approvals section (GmailApprovals)", "what": "actions waiting for a yes or no"},
{"name": "Activity", "form": "Activity section (GmailActivity)", "what": "what Bots did in Gmail"},
{"name": "Daily summary", "form": "Daily section (GmailDaily)", "what": "one day at a glance"},
{"name": "Gmail reference", "form": "docs/automation/gmail-reference.md; regenerate with npm run docs:gmail", "what": "the generated list of Gmail actions"},
{"name": "Gmail check", "form": "npm run review:gmail", "what": "run the Gmail flow against the real service"}
]},
{"path": ["schedules"], "sentence": "Scheduled wakeups for Bots: what runs when, and whether it is working.", "rows": [
{"name": "Schedule review", "form": "npm run review:schedules", "what": "check the schedules"},
{"name": "Schedule drill", "form": "node ops/review/schedule-drill.mjs", "what": "rehearse a schedule firing"},
{"name": "Schedules guide", "form": "docs/objectives/schedules.md", "what": "the goal and the rules"}
]},
{"path": ["host"], "sentence": "This computer's CodeBot: whether it is up, how to restart it, and where its data lives.", "rows": [
{"name": "Service status", "form": "systemctl --user status codebot.service --no-pager", "what": "running, and on port 3505"},
{"name": "Restart service", "form": "systemctl --user restart codebot.service", "what": "apply a new build; only after active turns finish"},
{"name": "Logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "recent service output"},
{"name": "Build", "form": "npm run build", "what": "type check, then publish the web app"},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "commit, push, restart, and verify; refuses while a Bot is working"},
{"name": "Emergency stop", "form": "systemctl --user stop codebot.service", "what": "stops scheduling and Bot turns cleanly; the force-kill steps are in ops/OPERATIONS.md"},
{"name": "Recovery hold", "form": "CODEBOT_RECOVERY_HOLD=1 in the service environment file", "what": "pause automatic work while inspecting"},
{"name": "Devices", "form": "screen: host devices", "what": "phones and their alerts"},
{"name": "Address", "form": "screen: host address", "what": "change the Tailscale name"},
{"name": "Terminal broker", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "turns on terminal access; off by default"},
{"name": "Owner key", "form": "~/.local/share/codebot/owner-key (show the path only)", "what": "the entrance key for a new device; never paste it"},
{"name": "Tailscale mapping", "form": "tailscale serve status --json", "what": "the private HTTPS mapping to port 3505"},
{"name": "Integration QA copy", "form": "codebot-integration.service on port 3506", "what": "a disposable test copy, not the production host"}
]},
{"path": ["host", "devices"], "sentence": "Phones, tablets, and computers connected to this CodeBot, and whether each gets alerts.", "rows": [
{"name": "Install on a phone", "form": "https://liel.tail18e69e.ts.net/, then Add to Home Screen", "what": "install CodeBot as an app; Tailscale must be on"},
{"name": "Reconnect this device", "form": "Reconnect this device button", "what": "fix an expired or rejected alert subscription"},
{"name": "Other devices", "form": "Other devices list", "what": "remove old devices (16 kept)"},
{"name": "Send test", "form": "Send test button", "what": "check the device shows an alert"}
]},
{"path": ["host", "address"], "sentence": "Runbook for changing this computer's Tailscale name, which doubles as CodeBot's address. Nine places must agree.", "rows": [
{"name": "Read the new name", "form": "tailscale status --json (Self.DNSName)", "what": "the name to move to"},
{"name": "Sign-in allow list", "form": "Supabase: Authentication, URL Configuration", "what": "add the new /onboarding address first"},
{"name": "Owner settings", "form": "service environment file and apps/web/.env.local, then npm run build and restart", "what": "point the owner's host at the new name"},
{"name": "Guest settings", "form": "/home/codebot-guest/.config/codebot/service.env, then ops/guest-update.sh", "what": "point the guest host at the new name"},
{"name": "Account rows", "form": "SQL update on codebot_account_progress.server_url", "what": "send each person to the right host"},
{"name": "Domain forward", "form": "codebot.lielbenor.com at the registrar", "what": "point the old address at the new one"},
{"name": "Full checklist", "form": "ops/OPERATIONS.md, section Change this machine's address", "what": "the nine places and their order"}
]},
{"path": ["backup"], "sentence": "Save a consistent copy of CodeBot's data, and verify a copy before relying on it.", "rows": [
{"name": "Make a backup", "form": "procedure in ops/OPERATIONS.md (stops the service briefly)", "what": "copy data, source, and settings into a private folder"},
{"name": "Verify a backup", "form": "sha256sum -c SHA256SUMS in the backup folder", "what": "confirm the files match"},
{"name": "Restore into staging", "form": "extract to ~/.local/share/codebot-restore-staging; run on port 3508 with CODEBOT_RECOVERY_HOLD=1", "what": "inspect a copy without starting automatic work"},
{"name": "Promote a restore", "form": "ops/OPERATIONS.md, section Restore into a separate directory first", "what": "switch the live host to a verified copy"},
{"name": "Backup folder", "form": "~/.local/share/codebot-backups/", "what": "where backups go; they hold keys, so keep them private"}
]},
{"path": ["family"], "sentence": "CodeBots for family members on the home network. Each person gets their own Linux account and sign-in.", "rows": [
{"name": "Family sign-in page", "form": "https://family.codebot.lielbenor.com", "what": "Google sign-in, then the person's own CodeBot"},
{"name": "Add a member", "form": "sudo codebot-family add N", "what": "create a CodeBot in slot N (six at most)"},
{"name": "Remove a member", "form": "sudo codebot-family remove N", "what": "delete that CodeBot; the Google account stays linked"},
{"name": "Family status", "form": "codebot-family status", "what": "which are running and whether Gmail can connect"},
{"name": "Stop or start all", "form": "sudo codebot-family stop-all, or start-all", "what": "pause or resume every family CodeBot"},
{"name": "Install", "form": "sudo ops/family-install.sh", "what": "one-time setup"},
{"name": "Update", "form": "ops/family-update.sh", "what": "rebuild and restart all of them; no password needed"}
]},
{"path": ["guest"], "sentence": "A separate setup for one guest on this machine, run as its own Linux user.", "rows": [
{"name": "Invite link", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "a one-use Google link, valid ten minutes"},
{"name": "Guest address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "where the guest signs in"},
{"name": "Update the guest", "form": "ops/guest-update.sh", "what": "rebuild and replace the guest copy"},
{"name": "Guest status", "form": "systemctl status codebot-guest", "what": "running or not"},
{"name": "Reset onboarding", "form": "screen: onboarding", "what": "start the guest's onboarding again"},
{"name": "Remove the guest", "form": "ops/OPERATIONS.md, section Host a guest on this machine (removal)", "what": "delete the guest account and its program"}
]},
{"path": ["onboarding"], "sentence": "Reset how a person is onboarded. Each option keeps or removes different things.", "rows": [
{"name": "Replay the first-use tour", "form": "SQL on codebot_account_progress, plus deleting the first_use_receipts row", "what": "the tour starts again; only works when the host has no Bots"},
{"name": "Fresh CodeBot, same account", "form": "stop the host, wipe data except identity files, then the Supabase statement", "what": "new Bots and conversations; Google account and folders stay"},
{"name": "Full reset", "form": "delete the data folder and the auth.users row", "what": "everything goes, including the account; destructive"},
{"name": "Send a fresh invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "a new sign-in link for the person"}
]},
{"path": ["account"], "sentence": "The shared sign-in service (Supabase) that every CodeBot server uses.", "rows": [
{"name": "Sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding (CODEBOT_ACCOUNT_ENTRY_URL)", "what": "where people start"},
{"name": "Set up the account", "form": "npm run setup-account", "what": "one-time operator setup"},
{"name": "Deploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "redeploy after contract changes"},
{"name": "Supabase CLI token", "form": "~/.config/supabase-codebot-token (mode 600)", "what": "the token for the mobile-coder login"},
{"name": "Gmail relay", "form": "supabase/functions/gmail-relay", "what": "the fixed address Google redirects to"}
]},
{"path": ["diagnostics"], "sentence": "Health of the running host: counters and states, never credentials. The web checks need a signed-in browser.", "rows": [
{"name": "Session", "form": "/api/session", "what": "answers when the service is ready"},
{"name": "Host", "form": "/api/diagnostics/host", "what": "migration, queue, running turns, recovery hold"},
{"name": "Scheduler", "form": "/api/diagnostics/scheduler", "what": "timers and schedule state"},
{"name": "Vision", "form": "/api/diagnostics/vision", "what": "browser stream health"},
{"name": "Notifications", "form": "/api/notifications/diagnostics", "what": "alert queue, timer, active sends"},
{"name": "Recent log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "recent service output"},
{"name": "Port owner", "form": "ss -ltnp 'sport = :3505'", "what": "which process holds the port"}
]},
{"path": ["checks"], "sentence": "Developer checks to run before a deploy: compile, test, build, and preview.", "rows": [
{"name": "Type check", "form": "npm run typecheck", "what": "compiles the code; says little about Bot behaviour"},
{"name": "Tests", "form": "npm test", "what": "Gmail tests against a fake Google"},
{"name": "Full check", "form": "npm run check", "what": "type check plus tests"},
{"name": "Build", "form": "npm run build", "what": "type check, then publish"},
{"name": "Design playground", "form": "npm run playground (opens on http://127.0.0.1)", "what": "compare design variants"},
{"name": "Integration build", "form": "npm run build:integration", "what": "build for the QA copy on port 3506"},
{"name": "Sync agent docs", "form": "npm run sync:agents", "what": "regenerate AGENTS.md from CLAUDE.md"}
]},
{"path": ["docs"], "sentence": "Where the written rules, designs, and runbooks live.", "rows": [
{"name": "README", "form": "README.md", "what": "layout, commands, how the pieces fit"},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "boundaries and invariants"},
{"name": "Operations", "form": "ops/OPERATIONS.md", "what": "run, back up, restore, change the address"},
{"name": "Design method", "form": "docs/design-method.md", "what": "how screens are designed"},
{"name": "Design taste", "form": "docs/design-taste.md", "what": "the owner's rulings"},
{"name": "Plans", "form": "docs/plans/", "what": "design and plan documents"},
{"name": "Objectives", "form": "docs/objectives/", "what": "goals for each feature"},
{"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "how Bots use Gmail"}
]},
{"path": ["updates"], "sentence": "What changed in the app since the owner last looked.", "rows": [
{"name": "What's new notes", "form": "apps/web/src/whatsNew.ts", "what": "owner-worded notes, shown once after an update"},
{"name": "Update notice", "form": "UpdateNotice (web app)", "what": "says a new version is ready; reopen to load it"}
]}
],
"questions": [
"Does a codebot command exist? README mentions cli/codebot.py, but no cli/ folder is in the file list. Recommendation: confirm. Until then, treat every codebot ... (proposed) form as a name to reserve, not a command that exists.",
"Who is the help for? The owner only, or also family and guest members? Recommendation: the owner and operator, with family and guest sections kept to operator commands. Family members use the web app and need no CLI help.",
"Should destructive resets be in the help (full reset, fresh CodeBot, removing a family member or guest)? Recommendation: include them, each requiring the person's name typed back and a confirmation, so one command cannot wipe data by accident.",
"Should the experimental apps V2, V3 and V4 appear? Recommendation: leave them out. The README says they are separate repos and CodeBot's rules do not apply to them.",
"Guest and family are two ways to host another person. Recommendation: make family the main screen and mark guest as legacy, then decide whether to keep running it.",
"Should planned features show in the help, such as Bot config export and import, or the offline command queue? Recommendation: show only shipped features; planned ones stay in docs/plans until they ship.",
"Should the terminal broker's enable step stay in host help? Recommendation: yes, with a warning that it gives a per-user shell and is off by default. Whether to enable it on this machine is the owner's call.",
"PRODUCT-SPEC.md, IMPLEMENTATION-STATUS.md and DEFERRED-WORK.md are referenced in README and ARCHITECTURE but are not in the file list. Recommendation: confirm they exist before the docs screen links to them."
]}
```

Today's skills · run 5 exit=0 seconds=86 · prompt

P1 Recall: 0.423P2 Nothing invented: 2P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.492
As terminal help
Everything you reach for in CodeBot on this computer: the service, the app, the data, the guest and family hosts, the account service, development and the docs.
Servicecodebot servicePrints the service screen: whether the owner's CodeBot runs, its logs, how to restart it, its diagnostics and its terminal broker.
Appcodebot appPrints the app screen: the addresses to open CodeBot at and how to connect a new device.
Datacodebot dataPrints the data screen: where CodeBot keeps its state and its backups, and how to save and restore them.
Guestcodebot guestPrints the guest screen: the second CodeBot on this machine for the guest account.
Familycodebot familyPrints the family screen: the home Wi-Fi front door and a CodeBot for each family member.
Accountscodebot accountsPrints the accounts screen: the central sign-in service and the onboarding runbooks.
Developmentcodebot devPrints the development screen: the npm commands, the QA copy and the reviews.
Docscodebot docsPrints the docs screen: the runbooks, plans and reference documents in the repo.
service
The owner's CodeBot service on this computer: whether it runs, its logs, how to restart it, its diagnostics and its terminal broker.
Statussystemctl --user status codebot.servicePrints whether the owner's CodeBot service is running and its recent state.
Logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the owner's CodeBot service.
Restartsystemctl --user restart codebot.serviceRestarts the service to load a new build; wait for active Bot turns to finish first.
Deploysh ops/deploy.shBuilds, commits, pushes and restarts the service, and refuses while a Bot is working.
Port ownerss -ltnp 'sport = :3505'Prints which process holds the owner's port 3505.
Service unit~/.config/systemd/user/codebot.serviceOpens the systemd unit that starts the owner's service.
Service settings~/.config/codebot/service.envOpens the private settings file for the service; it holds secrets, so edit it by hand.
Diagnosticscodebot service diagnosticsPrints the diagnostics screen: the health endpoints of the running service.
Terminal brokercodebot service terminalPrints the terminal broker screen: the per-user shell broker behind Bot terminals, off unless installed.
service › diagnostics
Health endpoints of the running service; each needs a signed-in browser, so each prints its address.
Sessionhttp://127.0.0.1:3505/api/sessionPrints whether the service answers; an unauthenticated answer counts as ready.
Host healthhttp://127.0.0.1:3505/api/diagnostics/hostOpens host health: migration, queued and running turns, and recovery hold.
Scheduler healthhttp://127.0.0.1:3505/api/diagnostics/schedulerOpens the scheduler's timers and counters.
Vision healthhttp://127.0.0.1:3505/api/diagnostics/visionOpens the vision counters for the browser capture.
Notification healthhttp://127.0.0.1:3505/api/notifications/diagnosticsOpens the notification queue, its timer and the active-send count.
service › terminal
The per-user terminal broker that runs the shell behind a Bot's terminal; it stays off unless installed.
Broker unit~/.config/systemd/user/codebot-terminal-broker.serviceOpens the systemd unit that runs the broker.
Broker statussystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the broker is running.
Broker socket$XDG_RUNTIME_DIR/codebot-terminal/broker.sockPrints the private socket the service talks to; keep it off Tailscale Serve.
Terminal socket~/.local/state/codebot-terminal/tmux.sockOpens the owner-only tmux socket where the terminals live.
Lingerloginctl show-user "$USER" -p LingerPrints whether the service stays available without a desktop login.
app
The addresses you open CodeBot at, and how to connect a new device to it.
Private addresshttps://liel.tail18e69e.ts.net/Opens the owner's app on a phone or desktop over Tailscale.
Local addresshttp://127.0.0.1:3505Opens the app on this computer without Tailscale.
Sign-in entryhttps://liel.tail18e69e.ts.net/onboardingOpens the onboarding and sign-in page that the account service sends people to.
Serve mappingtailscale serve status --jsonPrints the Tailscale mapping that publishes the service privately.
Entrance key~/.local/share/codebot/owner-keyPrints the path of the file that holds the key a new device types in; the key itself needs a flag (see questions).
data
Where CodeBot keeps what it has built up on this computer, and how to save and restore it.
Data folder~/.local/share/codebotOpens the folder with the database, Bot files and sessions.
Settings folder~/.config/codebotOpens the folder with the service settings.
Database~/.local/share/codebot/codebot.sqliteChecks the database's integrity without changing it.
Backups~/.local/share/codebot-backupsLists the whole-data backups taken so far.
Back up runbookops/OPERATIONS.md, Back up a consistent installationPrints the runbook that stops the service, copies all data, then restarts it.
Restore runbookops/OPERATIONS.md, Restore into a separate directory firstPrints the runbook that restores into a separate folder, checks it, and only then promotes it.
guest
A second CodeBot on this machine under its own Linux user, for the guest account, with its own Bots and data.
Statussystemctl status codebot-guestPrints whether the guest's CodeBot is running.
Logsjournalctl -u codebot-guestPrints the guest's service log.
Guest addresshttps://liel.tail18e69e.ts.net:10000Opens the guest's CodeBot in a browser over Tailscale.
Invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google invite link, valid for ten minutes.
Updateops/guest-update.shBuilds the current version and restarts the guest's CodeBot; needs no password.
Installsudo ops/guest-install.shSets up the guest user, service, settings and Tailscale port, once.
Guest program/opt/codebot-guestOpens the packaged copy that the guest's service runs.
Guest home/home/codebot-guestOpens the guest's home folder: its data, settings and projects.
Removal runbookops/OPERATIONS.md, To remove itPrints the steps that remove the guest's CodeBot and its data for good.
family
The home Wi-Fi front door: people sign in there with Google and get a CodeBot each, up to six.
Home addresshttps://family.codebot.lielbenor.comOpens the front door from home Wi-Fi, or from an invited Tailscale device.
Front door statussystemctl status codebot-family-lobbyPrints whether the sign-in front door is running.
Family memberscodebot family membersPrints the members screen: the six family CodeBot slots and their state.
Family statussudo codebot-family statusPrints each family CodeBot: whether it runs and whether Gmail can connect.
Add membersudo codebot-family add NCreates a CodeBot for family slot N, from 1 to 6.
Remove membersudo codebot-family remove NDeletes that family member's CodeBot and frees its slot number.
Updateops/family-update.shBuilds the current version and restarts all family CodeBots.
Helper settings/etc/codebot-family.confOpens the helper's settings; root owns it.
family › members
The six family CodeBot slots, numbered 1 to 6, each with its own Linux user, port and address.
Member N statussystemctl status codebot-family@NPrints that family member's CodeBot state; N is its slot number, 1 to 6.
Member N addresshttps://family.codebot.lielbenor.com:10100+NOpens that member's CodeBot; its port is 10100 plus N.
Member N data/home/codebot-fNOpens that member's home folder, which no other user can read.
accounts
The central account service that handles sign-in and the host handshake: its project, its functions and the onboarding runbooks.
ProjectSupabase project wbgrjvqbupgdclaztuouPrints the account service's project id and the login it belongs to.
Deploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function; needed whenever a contract it parses changes.
Access token~/.config/supabase-codebot-tokenChecks that the token file exists and is mode 600; it does not print the token.
Functionssupabase/functionsOpens the account functions, gmail-relay and host-access.
Migrationssupabase/migrationsLists the account database migrations in order.
Gmail relaysupabase/functions/gmail-relay/index.tsOpens the fixed sign-in relay that Google returns through.
Address changeops/OPERATIONS.md, Change this machine's addressPrints the checklist for changing the machine's address.
Onboardingcodebot accounts onboardingPrints the onboarding screen: the runbooks for showing someone onboarding again.
accounts › onboarding
Runbooks for showing someone onboarding again; each one changes state, so the CLI prints them and does not run them.
Replay the tourops/OPERATIONS.md, Replay only the first-use tourPrints the steps that replay only the first-use tour, on a host with no Bots.
Fresh CodeBotops/OPERATIONS.md, Restart onboarding with a fresh CodeBotPrints the steps that wipe a host's Bots and keep the person's account.
Full resetops/OPERATIONS.md, Full resetPrints the steps that delete a person's account, Bots and data.
dev
The commands for building, testing and reviewing CodeBot from its checkout.
Dev servernpm run devStarts the local service in watch mode, reloading on code changes.
Startnpm startStarts the service in production mode, without watching.
Buildnpm run buildTypechecks, then builds the web app and publishes a new release.
Typechecknpm run typecheckChecks the TypeScript types without building.
Testnpm testRuns the Gmail automation tests against a fake Google server.
Checknpm run checkTypechecks and runs the tests together.
Playgroundnpm run playgroundOpens the Gmail design playground in the browser.
Gmail reviewnpm run review:gmailRuns the Gmail review against the real service and browser.
Schedules reviewnpm run review:schedulesRuns the schedules review.
Gmail referencenpm run docs:gmailRegenerates the Gmail reference document.
Sync agentsnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md.
Account setupnpm run setup-accountRuns the account setup script.
Integration buildnpm run build:integrationTypechecks and builds the QA bundle.
QA copycodebot dev qaPrints the QA screen: the disposable CodeBot on port 3506, its features and its findings.
dev › qa
The disposable QA copy of CodeBot on port 3506, and the feature tests and QA findings around it.
QA statussystemctl status codebot-integration.servicePrints whether the QA copy is running.
QA addresshttp://127.0.0.1:3506Opens the QA copy on this computer.
Feature tests.bdd/featuresLists the Given/When/Then feature files.
Test steps.bdd/stepsOpens the test steps that run the features.
Findings.bdd/qa/findingsLists the QA findings.
Resolutions.bdd/qa/resolutionsLists how each QA finding was resolved.
docs
The guides, runbooks, plans and reference documents in the repo.
OverviewREADME.mdOpens the project overview and the commands to run it.
Operationsops/OPERATIONS.mdOpens the runbook for running, recovering and backing up CodeBot.
ArchitectureARCHITECTURE.mdOpens how CodeBot is built: its boundaries, provider runtime and persistence.
RulesCLAUDE.mdOpens the fundamentals every task assumes; AGENTS.md is generated from it.
Product specPRODUCT-SPEC.mdOpens the behavior contract; referenced by the README, not in the file dump.
Deferred workDEFERRED-WORK.mdOpens the open work and the safe restart state; referenced, not in the dump.
Gmail guidedocs/automation/gmail.mdOpens the supervisor guide for Gmail for Bots.
Design rulingsdocs/design-taste.mdOpens the owner's design rulings and what they rejected.
Design methoddocs/design-method.mdOpens how screens are designed.
Plansdocs/plansLists the plans for planned work; the dump shows only part of them.
Objectivesdocs/objectivesLists the goals for chats, Gmail, schedules and terminal tabs.
Design filesdesignOpens the screenshots and reference designs.
Questions
  • Name and aliases: I propose `codebot` with the short alias `cb`. The README mentions a `cli/codebot.py` that the file list does not show. If it exists, the new CLI should extend it rather than add a second command. Recommendation: confirm `cb`, and say whether `cli/codebot.py` exists.
  • Entrance key: should `codebot app key` print the owner's entrance key in the terminal? Recommendation: no. It prints the file path only, and the key only with an explicit flag such as `--show`, because terminal scrollback keeps it.
  • Runbooks or running: the backup, restore, onboarding resets, and guest and family removal stop services or delete data. Recommendation: the CLI prints their steps and never runs them. The commands it runs are status, logs, update and invite. Confirm?
  • Deploy from the CLI: `codebot service deploy` would run ops/deploy.sh, which pushes to the git remote. That is outward-facing. Recommendation: show it as a printed row, and add a confirmation step if it is built. Confirm?
  • The inventory is incomplete. The file dump is cut off: root, ops/, docs/plans/ and others are partial, and PRODUCT-SPEC.md, DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md and MASTER-PLAN.md are referenced but not listed. I also could not read the skill's two references, so this map follows the skill text only. Recommendation: re-run with the full file list and those references so the docs and plans screens can be completed.
As phone screens

Home

Everything you reach for in CodeBot on this computer: the service, the app, the data, the guest and family hosts, the account service, development and the docs.

ServicePrints the service screen: whether the owner's CodeBot runs, its logs, how to restart it, its diagnostics and its terminal broker.
›
AppPrints the app screen: the addresses to open CodeBot at and how to connect a new device.
›
DataPrints the data screen: where CodeBot keeps its state and its backups, and how to save and restore them.
›
GuestPrints the guest screen: the second CodeBot on this machine for the guest account.
›
FamilyPrints the family screen: the home Wi-Fi front door and a CodeBot for each family member.
›
AccountsPrints the accounts screen: the central sign-in service and the onboarding runbooks.
›
DevelopmentPrints the development screen: the npm commands, the QA copy and the reviews.
›
DocsPrints the docs screen: the runbooks, plans and reference documents in the repo.
›
‹ Home

service

The owner's CodeBot service on this computer: whether it runs, its logs, how to restart it, its diagnostics and its terminal broker.

StatusPrints whether the owner's CodeBot service is running and its recent state.
›
LogsPrints the last 80 log lines of the owner's CodeBot service.
›
RestartRestarts the service to load a new build; wait for active Bot turns to finish first.
›
DeployBuilds, commits, pushes and restarts the service, and refuses while a Bot is working.
›
Port ownerPrints which process holds the owner's port 3505.
›
Service unitOpens the systemd unit that starts the owner's service.
›
Service settingsOpens the private settings file for the service; it holds secrets, so edit it by hand.
›
DiagnosticsPrints the diagnostics screen: the health endpoints of the running service.
›
Terminal brokerPrints the terminal broker screen: the per-user shell broker behind Bot terminals, off unless installed.
›
‹ service

diagnostics

Health endpoints of the running service; each needs a signed-in browser, so each prints its address.

SessionPrints whether the service answers; an unauthenticated answer counts as ready.
›
Host healthOpens host health: migration, queued and running turns, and recovery hold.
›
Scheduler healthOpens the scheduler's timers and counters.
›
Vision healthOpens the vision counters for the browser capture.
›
Notification healthOpens the notification queue, its timer and the active-send count.
›
‹ service

terminal

The per-user terminal broker that runs the shell behind a Bot's terminal; it stays off unless installed.

Broker unitOpens the systemd unit that runs the broker.
›
Broker statusPrints whether the broker is running.
›
Broker socketPrints the private socket the service talks to; keep it off Tailscale Serve.
›
Terminal socketOpens the owner-only tmux socket where the terminals live.
›
LingerPrints whether the service stays available without a desktop login.
›
‹ Home

app

The addresses you open CodeBot at, and how to connect a new device to it.

Private addressOpens the owner's app on a phone or desktop over Tailscale.
›
Local addressOpens the app on this computer without Tailscale.
›
Sign-in entryOpens the onboarding and sign-in page that the account service sends people to.
›
Serve mappingPrints the Tailscale mapping that publishes the service privately.
›
Entrance keyPrints the path of the file that holds the key a new device types in; the key itself needs a flag (see questions).
›
‹ Home

data

Where CodeBot keeps what it has built up on this computer, and how to save and restore it.

Data folderOpens the folder with the database, Bot files and sessions.
›
Settings folderOpens the folder with the service settings.
›
DatabaseChecks the database's integrity without changing it.
›
BackupsLists the whole-data backups taken so far.
›
Back up runbookPrints the runbook that stops the service, copies all data, then restarts it.
›
Restore runbookPrints the runbook that restores into a separate folder, checks it, and only then promotes it.
›
‹ Home

guest

A second CodeBot on this machine under its own Linux user, for the guest account, with its own Bots and data.

StatusPrints whether the guest's CodeBot is running.
›
LogsPrints the guest's service log.
›
Guest addressOpens the guest's CodeBot in a browser over Tailscale.
›
InvitePrints a one-use Google invite link, valid for ten minutes.
›
UpdateBuilds the current version and restarts the guest's CodeBot; needs no password.
›
InstallSets up the guest user, service, settings and Tailscale port, once.
›
Guest programOpens the packaged copy that the guest's service runs.
›
Guest homeOpens the guest's home folder: its data, settings and projects.
›
Removal runbookPrints the steps that remove the guest's CodeBot and its data for good.
›
‹ Home

family

The home Wi-Fi front door: people sign in there with Google and get a CodeBot each, up to six.

Home addressOpens the front door from home Wi-Fi, or from an invited Tailscale device.
›
Front door statusPrints whether the sign-in front door is running.
›
Family membersPrints the members screen: the six family CodeBot slots and their state.
›
Family statusPrints each family CodeBot: whether it runs and whether Gmail can connect.
›
Add memberCreates a CodeBot for family slot N, from 1 to 6.
›
Remove memberDeletes that family member's CodeBot and frees its slot number.
›
UpdateBuilds the current version and restarts all family CodeBots.
›
Helper settingsOpens the helper's settings; root owns it.
›
‹ family

members

The six family CodeBot slots, numbered 1 to 6, each with its own Linux user, port and address.

Member N statusPrints that family member's CodeBot state; N is its slot number, 1 to 6.
›
Member N addressOpens that member's CodeBot; its port is 10100 plus N.
›
Member N dataOpens that member's home folder, which no other user can read.
›
‹ Home

accounts

The central account service that handles sign-in and the host handshake: its project, its functions and the onboarding runbooks.

ProjectPrints the account service's project id and the login it belongs to.
›
Deploy host-accessDeploys the host-access function; needed whenever a contract it parses changes.
›
Access tokenChecks that the token file exists and is mode 600; it does not print the token.
›
FunctionsOpens the account functions, gmail-relay and host-access.
›
MigrationsLists the account database migrations in order.
›
Gmail relayOpens the fixed sign-in relay that Google returns through.
›
Address changePrints the checklist for changing the machine's address.
›
OnboardingPrints the onboarding screen: the runbooks for showing someone onboarding again.
›
‹ accounts

onboarding

Runbooks for showing someone onboarding again; each one changes state, so the CLI prints them and does not run them.

Replay the tourPrints the steps that replay only the first-use tour, on a host with no Bots.
›
Fresh CodeBotPrints the steps that wipe a host's Bots and keep the person's account.
›
Full resetPrints the steps that delete a person's account, Bots and data.
›
‹ Home

dev

The commands for building, testing and reviewing CodeBot from its checkout.

Dev serverStarts the local service in watch mode, reloading on code changes.
›
StartStarts the service in production mode, without watching.
›
BuildTypechecks, then builds the web app and publishes a new release.
›
TypecheckChecks the TypeScript types without building.
›
TestRuns the Gmail automation tests against a fake Google server.
›
CheckTypechecks and runs the tests together.
›
PlaygroundOpens the Gmail design playground in the browser.
›
Gmail reviewRuns the Gmail review against the real service and browser.
›
Schedules reviewRuns the schedules review.
›
Gmail referenceRegenerates the Gmail reference document.
›
Sync agentsRegenerates AGENTS.md from CLAUDE.md.
›
Account setupRuns the account setup script.
›
Integration buildTypechecks and builds the QA bundle.
›
QA copyPrints the QA screen: the disposable CodeBot on port 3506, its features and its findings.
›
‹ dev

qa

The disposable QA copy of CodeBot on port 3506, and the feature tests and QA findings around it.

QA statusPrints whether the QA copy is running.
›
QA addressOpens the QA copy on this computer.
›
Feature testsLists the Given/When/Then feature files.
›
Test stepsOpens the test steps that run the features.
›
FindingsLists the QA findings.
›
ResolutionsLists how each QA finding was resolved.
›
‹ Home

docs

The guides, runbooks, plans and reference documents in the repo.

OverviewOpens the project overview and the commands to run it.
›
OperationsOpens the runbook for running, recovering and backing up CodeBot.
›
ArchitectureOpens how CodeBot is built: its boundaries, provider runtime and persistence.
›
RulesOpens the fundamentals every task assumes; AGENTS.md is generated from it.
›
Product specOpens the behavior contract; referenced by the README, not in the file dump.
›
Deferred workOpens the open work and the safe restart state; referenced, not in the dump.
›
Gmail guideOpens the supervisor guide for Gmail for Bots.
›
Design rulingsOpens the owner's design rulings and what they rejected.
›
Design methodOpens how screens are designed.
›
PlansLists the plans for planned work; the dump shows only part of them.
›
ObjectivesLists the goals for chats, Gmail, schedules and terminal tabs.
›
Design filesOpens the screenshots and reference designs.
›
Raw answer
This is a planning pass only: nothing was built or run. I worked from the file dump and the skill text. I could not read `references/house-conventions.md` or `references/cli-best-practices.md`, and the file list is truncated (see question 5).

Judgment calls:
- **Eight top-level nouns** (service, app, data, guest, family, accounts, dev, docs) group things by the job the owner does. The top screen stays short.
- **QA sits under dev**, because it is a development check, not something the owner uses day to day.
- **Onboarding resets and removals are printed as runbooks, not run.** They stop services or delete data.
- **The six family slots are one generic row with N**, not six rows.
- **Verbs:** "Prints" for screens, "Opens" for files and addresses, and the action's own verb for commands.

```json
{"screens": [
{"path": [], "sentence": "Everything you reach for in CodeBot on this computer: the service, the app, the data, the guest and family hosts, the account service, development and the docs.", "rows": [
{"name": "Service", "form": "codebot service", "what": "Prints the service screen: whether the owner's CodeBot runs, its logs, how to restart it, its diagnostics and its terminal broker."},
{"name": "App", "form": "codebot app", "what": "Prints the app screen: the addresses to open CodeBot at and how to connect a new device."},
{"name": "Data", "form": "codebot data", "what": "Prints the data screen: where CodeBot keeps its state and its backups, and how to save and restore them."},
{"name": "Guest", "form": "codebot guest", "what": "Prints the guest screen: the second CodeBot on this machine for the guest account."},
{"name": "Family", "form": "codebot family", "what": "Prints the family screen: the home Wi-Fi front door and a CodeBot for each family member."},
{"name": "Accounts", "form": "codebot accounts", "what": "Prints the accounts screen: the central sign-in service and the onboarding runbooks."},
{"name": "Development", "form": "codebot dev", "what": "Prints the development screen: the npm commands, the QA copy and the reviews."},
{"name": "Docs", "form": "codebot docs", "what": "Prints the docs screen: the runbooks, plans and reference documents in the repo."}
]},
{"path": ["service"], "sentence": "The owner's CodeBot service on this computer: whether it runs, its logs, how to restart it, its diagnostics and its terminal broker.", "rows": [
{"name": "Status", "form": "systemctl --user status codebot.service", "what": "Prints whether the owner's CodeBot service is running and its recent state."},
{"name": "Logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the owner's CodeBot service."},
{"name": "Restart", "form": "systemctl --user restart codebot.service", "what": "Restarts the service to load a new build; wait for active Bot turns to finish first."},
{"name": "Deploy", "form": "sh ops/deploy.sh", "what": "Builds, commits, pushes and restarts the service, and refuses while a Bot is working."},
{"name": "Port owner", "form": "ss -ltnp 'sport = :3505'", "what": "Prints which process holds the owner's port 3505."},
{"name": "Service unit", "form": "~/.config/systemd/user/codebot.service", "what": "Opens the systemd unit that starts the owner's service."},
{"name": "Service settings", "form": "~/.config/codebot/service.env", "what": "Opens the private settings file for the service; it holds secrets, so edit it by hand."},
{"name": "Diagnostics", "form": "codebot service diagnostics", "what": "Prints the diagnostics screen: the health endpoints of the running service."},
{"name": "Terminal broker", "form": "codebot service terminal", "what": "Prints the terminal broker screen: the per-user shell broker behind Bot terminals, off unless installed."}
]},
{"path": ["service", "diagnostics"], "sentence": "Health endpoints of the running service; each needs a signed-in browser, so each prints its address.", "rows": [
{"name": "Session", "form": "http://127.0.0.1:3505/api/session", "what": "Prints whether the service answers; an unauthenticated answer counts as ready."},
{"name": "Host health", "form": "http://127.0.0.1:3505/api/diagnostics/host", "what": "Opens host health: migration, queued and running turns, and recovery hold."},
{"name": "Scheduler health", "form": "http://127.0.0.1:3505/api/diagnostics/scheduler", "what": "Opens the scheduler's timers and counters."},
{"name": "Vision health", "form": "http://127.0.0.1:3505/api/diagnostics/vision", "what": "Opens the vision counters for the browser capture."},
{"name": "Notification health", "form": "http://127.0.0.1:3505/api/notifications/diagnostics", "what": "Opens the notification queue, its timer and the active-send count."}
]},
{"path": ["service", "terminal"], "sentence": "The per-user terminal broker that runs the shell behind a Bot's terminal; it stays off unless installed.", "rows": [
{"name": "Broker unit", "form": "~/.config/systemd/user/codebot-terminal-broker.service", "what": "Opens the systemd unit that runs the broker."},
{"name": "Broker status", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the broker is running."},
{"name": "Broker socket", "form": "$XDG_RUNTIME_DIR/codebot-terminal/broker.sock", "what": "Prints the private socket the service talks to; keep it off Tailscale Serve."},
{"name": "Terminal socket", "form": "~/.local/state/codebot-terminal/tmux.sock", "what": "Opens the owner-only tmux socket where the terminals live."},
{"name": "Linger", "form": "loginctl show-user \"$USER\" -p Linger", "what": "Prints whether the service stays available without a desktop login."}
]},
{"path": ["app"], "sentence": "The addresses you open CodeBot at, and how to connect a new device to it.", "rows": [
{"name": "Private address", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the owner's app on a phone or desktop over Tailscale."},
{"name": "Local address", "form": "http://127.0.0.1:3505", "what": "Opens the app on this computer without Tailscale."},
{"name": "Sign-in entry", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Opens the onboarding and sign-in page that the account service sends people to."},
{"name": "Serve mapping", "form": "tailscale serve status --json", "what": "Prints the Tailscale mapping that publishes the service privately."},
{"name": "Entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Prints the path of the file that holds the key a new device types in; the key itself needs a flag (see questions)."}
]},
{"path": ["data"], "sentence": "Where CodeBot keeps what it has built up on this computer, and how to save and restore it.", "rows": [
{"name": "Data folder", "form": "~/.local/share/codebot", "what": "Opens the folder with the database, Bot files and sessions."},
{"name": "Settings folder", "form": "~/.config/codebot", "what": "Opens the folder with the service settings."},
{"name": "Database", "form": "~/.local/share/codebot/codebot.sqlite", "what": "Checks the database's integrity without changing it."},
{"name": "Backups", "form": "~/.local/share/codebot-backups", "what": "Lists the whole-data backups taken so far."},
{"name": "Back up runbook", "form": "ops/OPERATIONS.md, Back up a consistent installation", "what": "Prints the runbook that stops the service, copies all data, then restarts it."},
{"name": "Restore runbook", "form": "ops/OPERATIONS.md, Restore into a separate directory first", "what": "Prints the runbook that restores into a separate folder, checks it, and only then promotes it."}
]},
{"path": ["guest"], "sentence": "A second CodeBot on this machine under its own Linux user, for the guest account, with its own Bots and data.", "rows": [
{"name": "Status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest's CodeBot is running."},
{"name": "Logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest's service log."},
{"name": "Guest address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's CodeBot in a browser over Tailscale."},
{"name": "Invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google invite link, valid for ten minutes."},
{"name": "Update", "form": "ops/guest-update.sh", "what": "Builds the current version and restarts the guest's CodeBot; needs no password."},
{"name": "Install", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, service, settings and Tailscale port, once."},
{"name": "Guest program", "form": "/opt/codebot-guest", "what": "Opens the packaged copy that the guest's service runs."},
{"name": "Guest home", "form": "/home/codebot-guest", "what": "Opens the guest's home folder: its data, settings and projects."},
{"name": "Removal runbook", "form": "ops/OPERATIONS.md, To remove it", "what": "Prints the steps that remove the guest's CodeBot and its data for good."}
]},
{"path": ["family"], "sentence": "The home Wi-Fi front door: people sign in there with Google and get a CodeBot each, up to six.", "rows": [
{"name": "Home address", "form": "https://family.codebot.lielbenor.com", "what": "Opens the front door from home Wi-Fi, or from an invited Tailscale device."},
{"name": "Front door status", "form": "systemctl status codebot-family-lobby", "what": "Prints whether the sign-in front door is running."},
{"name": "Family members", "form": "codebot family members", "what": "Prints the members screen: the six family CodeBot slots and their state."},
{"name": "Family status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot: whether it runs and whether Gmail can connect."},
{"name": "Add member", "form": "sudo codebot-family add N", "what": "Creates a CodeBot for family slot N, from 1 to 6."},
{"name": "Remove member", "form": "sudo codebot-family remove N", "what": "Deletes that family member's CodeBot and frees its slot number."},
{"name": "Update", "form": "ops/family-update.sh", "what": "Builds the current version and restarts all family CodeBots."},
{"name": "Helper settings", "form": "/etc/codebot-family.conf", "what": "Opens the helper's settings; root owns it."}
]},
{"path": ["family", "members"], "sentence": "The six family CodeBot slots, numbered 1 to 6, each with its own Linux user, port and address.", "rows": [
{"name": "Member N status", "form": "systemctl status codebot-family@N", "what": "Prints that family member's CodeBot state; N is its slot number, 1 to 6."},
{"name": "Member N address", "form": "https://family.codebot.lielbenor.com:10100+N", "what": "Opens that member's CodeBot; its port is 10100 plus N."},
{"name": "Member N data", "form": "/home/codebot-fN", "what": "Opens that member's home folder, which no other user can read."}
]},
{"path": ["accounts"], "sentence": "The central account service that handles sign-in and the host handshake: its project, its functions and the onboarding runbooks.", "rows": [
{"name": "Project", "form": "Supabase project wbgrjvqbupgdclaztuou", "what": "Prints the account service's project id and the login it belongs to."},
{"name": "Deploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function; needed whenever a contract it parses changes."},
{"name": "Access token", "form": "~/.config/supabase-codebot-token", "what": "Checks that the token file exists and is mode 600; it does not print the token."},
{"name": "Functions", "form": "supabase/functions", "what": "Opens the account functions, gmail-relay and host-access."},
{"name": "Migrations", "form": "supabase/migrations", "what": "Lists the account database migrations in order."},
{"name": "Gmail relay", "form": "supabase/functions/gmail-relay/index.ts", "what": "Opens the fixed sign-in relay that Google returns through."},
{"name": "Address change", "form": "ops/OPERATIONS.md, Change this machine's address", "what": "Prints the checklist for changing the machine's address."},
{"name": "Onboarding", "form": "codebot accounts onboarding", "what": "Prints the onboarding screen: the runbooks for showing someone onboarding again."}
]},
{"path": ["accounts", "onboarding"], "sentence": "Runbooks for showing someone onboarding again; each one changes state, so the CLI prints them and does not run them.", "rows": [
{"name": "Replay the tour", "form": "ops/OPERATIONS.md, Replay only the first-use tour", "what": "Prints the steps that replay only the first-use tour, on a host with no Bots."},
{"name": "Fresh CodeBot", "form": "ops/OPERATIONS.md, Restart onboarding with a fresh CodeBot", "what": "Prints the steps that wipe a host's Bots and keep the person's account."},
{"name": "Full reset", "form": "ops/OPERATIONS.md, Full reset", "what": "Prints the steps that delete a person's account, Bots and data."}
]},
{"path": ["dev"], "sentence": "The commands for building, testing and reviewing CodeBot from its checkout.", "rows": [
{"name": "Dev server", "form": "npm run dev", "what": "Starts the local service in watch mode, reloading on code changes."},
{"name": "Start", "form": "npm start", "what": "Starts the service in production mode, without watching."},
{"name": "Build", "form": "npm run build", "what": "Typechecks, then builds the web app and publishes a new release."},
{"name": "Typecheck", "form": "npm run typecheck", "what": "Checks the TypeScript types without building."},
{"name": "Test", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server."},
{"name": "Check", "form": "npm run check", "what": "Typechecks and runs the tests together."},
{"name": "Playground", "form": "npm run playground", "what": "Opens the Gmail design playground in the browser."},
{"name": "Gmail review", "form": "npm run review:gmail", "what": "Runs the Gmail review against the real service and browser."},
{"name": "Schedules review", "form": "npm run review:schedules", "what": "Runs the schedules review."},
{"name": "Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates the Gmail reference document."},
{"name": "Sync agents", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md."},
{"name": "Account setup", "form": "npm run setup-account", "what": "Runs the account setup script."},
{"name": "Integration build", "form": "npm run build:integration", "what": "Typechecks and builds the QA bundle."},
{"name": "QA copy", "form": "codebot dev qa", "what": "Prints the QA screen: the disposable CodeBot on port 3506, its features and its findings."}
]},
{"path": ["dev", "qa"], "sentence": "The disposable QA copy of CodeBot on port 3506, and the feature tests and QA findings around it.", "rows": [
{"name": "QA status", "form": "systemctl status codebot-integration.service", "what": "Prints whether the QA copy is running."},
{"name": "QA address", "form": "http://127.0.0.1:3506", "what": "Opens the QA copy on this computer."},
{"name": "Feature tests", "form": ".bdd/features", "what": "Lists the Given/When/Then feature files."},
{"name": "Test steps", "form": ".bdd/steps", "what": "Opens the test steps that run the features."},
{"name": "Findings", "form": ".bdd/qa/findings", "what": "Lists the QA findings."},
{"name": "Resolutions", "form": ".bdd/qa/resolutions", "what": "Lists how each QA finding was resolved."}
]},
{"path": ["docs"], "sentence": "The guides, runbooks, plans and reference documents in the repo.", "rows": [
{"name": "Overview", "form": "README.md", "what": "Opens the project overview and the commands to run it."},
{"name": "Operations", "form": "ops/OPERATIONS.md", "what": "Opens the runbook for running, recovering and backing up CodeBot."},
{"name": "Architecture", "form": "ARCHITECTURE.md", "what": "Opens how CodeBot is built: its boundaries, provider runtime and persistence."},
{"name": "Rules", "form": "CLAUDE.md", "what": "Opens the fundamentals every task assumes; AGENTS.md is generated from it."},
{"name": "Product spec", "form": "PRODUCT-SPEC.md", "what": "Opens the behavior contract; referenced by the README, not in the file dump."},
{"name": "Deferred work", "form": "DEFERRED-WORK.md", "what": "Opens the open work and the safe restart state; referenced, not in the dump."},
{"name": "Gmail guide", "form": "docs/automation/gmail.md", "what": "Opens the supervisor guide for Gmail for Bots."},
{"name": "Design rulings", "form": "docs/design-taste.md", "what": "Opens the owner's design rulings and what they rejected."},
{"name": "Design method", "form": "docs/design-method.md", "what": "Opens how screens are designed."},
{"name": "Plans", "form": "docs/plans", "what": "Lists the plans for planned work; the dump shows only part of them."},
{"name": "Objectives", "form": "docs/objectives", "what": "Lists the goals for chats, Gmail, schedules and terminal tabs."},
{"name": "Design files", "form": "design", "what": "Opens the screenshots and reference designs."}
]}
],
"questions": [
"Name and aliases: I propose `codebot` with the short alias `cb`. The README mentions a `cli/codebot.py` that the file list does not show. If it exists, the new CLI should extend it rather than add a second command. Recommendation: confirm `cb`, and say whether `cli/codebot.py` exists.",
"Entrance key: should `codebot app key` print the owner's entrance key in the terminal? Recommendation: no. It prints the file path only, and the key only with an explicit flag such as `--show`, because terminal scrollback keeps it.",
"Runbooks or running: the backup, restore, onboarding resets, and guest and family removal stop services or delete data. Recommendation: the CLI prints their steps and never runs them. The commands it runs are status, logs, update and invite. Confirm?",
"Deploy from the CLI: `codebot service deploy` would run ops/deploy.sh, which pushes to the git remote. That is outward-facing. Recommendation: show it as a printed row, and add a confirmation step if it is built. Confirm?",
"The inventory is incomplete. The file dump is cut off: root, ops/, docs/plans/ and others are partial, and PRODUCT-SPEC.md, DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md and MASTER-PLAN.md are referenced but not listed. I also could not read the skill's two references, so this map follows the skill text only. Recommendation: re-run with the full file list and those references so the docs and plans screens can be completed."
]}
```

screen-decomposition, first draft · run 5 exit=0 seconds=136 · prompt

P1 Recall: 0.551P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.99P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.379
As terminal help
The codebot commands: running, shipping, checking, backing up and hosting people on this machine.
hostcodebot host (screen)Shows the host screen: whether the host runs, its logs, its address and its health counters.
deploycodebot deploy (screen)Shows the deploy screen: how a change is built, pushed and made live.
checkcodebot check (screen)Shows the check screen: the type check, the tests and the review scripts.
backupcodebot backup (screen)Shows the backup screen: how to copy the host's data and check a copy before using it.
guestcodebot guest (screen)Shows the guest screen: the second CodeBot on this machine, run as the codebot-guest user.
familycodebot family (screen)Shows the family screen: the family CodeBots behind the home Wi-Fi address.
accountcodebot account (screen)Shows the account screen: the central sign-in service in Supabase, Gmail setup and onboarding resets.
docscodebot docs (screen)Shows the docs screen: the runbook, the rules, the design record and the specs, each with its path.
host
The codebot host on this machine: its service, its address and its health.
statussystemctl --user status codebot.service --no-pagerPrints whether codebot.service runs, with its last log lines.
startsystemctl --user start codebot.serviceStarts codebot.service, which serves port 3505 on this machine.
restartsystemctl --user restart codebot.serviceRestarts codebot.service; wait for active turns and recordings to finish first.
stopsystemctl --user stop codebot.serviceStops codebot.service: interrupts Bot turns, ends scheduling and finishes recordings.
logsjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of codebot.service.
readycurl --fail --silent http://127.0.0.1:3505/api/sessionChecks that the host answers on port 3505; a session reply means it is ready.
apphttps://liel.tail18e69e.ts.net/Opens the CodeBot app over the private Tailscale address, where Bots are used.
terminal brokersystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the optional terminal broker runs; without it the terminal stays off.
emergency stopops/OPERATIONS.md, section Emergency stop and rollbackOpens the emergency stop steps: a stop request first, then SIGKILL only if the stop hangs.
settings~/.config/codebot/service.envOpens the private settings file: data folder, project roots and keys. Never print it.
diagnosticscodebot host diagnostics (screen)Shows the diagnostics screen: the host's health counters, read from the signed-in app.
addresscodebot host address (screen)Shows the address screen: how the host is reached and how a device connects to it.
host › diagnostics
The health counters the host reports, read from the signed-in app.
host counters/api/diagnostics/host on the app address (signed-in browser)Opens the host counters: migration, event cursor, queued and running turns, recovery hold.
scheduler counters/api/diagnostics/scheduler on the app address (signed-in browser)Opens the scheduler counters: its timers and the wakeups waiting to run.
Vision counters/api/diagnostics/vision on the app address (signed-in browser)Opens the Vision counters: the browser pages and frames the Bots watch.
notification counters/api/notifications/diagnostics on the app address (signed-in browser)Opens the notification counters: the queue, the timer and the active sends.
notification stepsops/OPERATIONS.md, section Background notificationsOpens the notification steps: enable a device, send a test, and why a push may not show.
host › address
How the host is reached: its private address, connecting a device, the phone app, and changing the address.
address mappingtailscale serve status --jsonPrints the Tailscale mapping from the private HTTPS address to port 3505. Do not reset it.
connect a deviceops/OPERATIONS.md, section Connect a deviceOpens the steps to connect a phone or laptop through Tailscale.
entrance key~/.local/share/codebot/owner-keyPrints the entrance key for a new device; read it locally and never paste it.
phone appops/OPERATIONS.md, section Private access and PWA installationOpens how to install CodeBot to the phone's home screen.
change addressops/OPERATIONS.md, section Change this machine's addressOpens the nine places to update, in order, when the machine's address changes.
deploy
Getting a change live: install, build, push, restart the host and check that it answers.
shipsh ops/deploy.shRuns the full deploy: build, push, wait for active work, restart codebot.service, then check /api/session. Refuses while a Bot is working.
buildnpm run buildBuilds a new release into dist/releases and switches the served link; a failed build leaves the running release in place.
installnpm ciInstalls the locked dependencies; run it after a pull that changed them.
first installops/OPERATIONS.md, section Install or update the hostOpens the first-time install: dependencies, the private settings file and the unit.
deploy guardops/deploy-guard.shRuns as the Stop hook; it blocks finishing a turn while code is unpushed or not yet live.
check
Checks of the code: the type check, the tests, and the review scripts for Gmail and schedules.
all checksnpm run checkRuns the type check and the tests together; run it before you ship.
type checknpm run typecheckRuns tsc --noEmit only: shows the code compiles, and nothing about Bot behaviour.
testsnpm testRuns the Gmail automation tests against a fake Google server, not the real one.
Gmail reviewnpm run review:gmailRuns the Gmail review script, ops/review/gmail-review.mjs.
schedules reviewnpm run review:schedulesRuns the schedules review script, ops/review/schedules-review.mjs.
QA buildnpm run build:integrationType checks and builds the QA copy that codebot-integration.service runs on port 3506.
agents filenpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
backup
Copies of the host's data, settings and unit, and how to check a copy before using it.
make a backupops/OPERATIONS.md, section Back up a consistent installationOpens the backup steps: stop the host, copy its data and settings, write checksums, start it again.
verify a backupsha256sum -c SHA256SUMS (inside a backup folder)Checks a backup's files against its checksums before any restore.
backup folders~/.local/share/codebot-backupsOpens the backup folders, each named by its UTC time. They are private.
restoreops/OPERATIONS.md, section Restore into a separate directory firstOpens the restore steps: extract to a new private folder and check it before use.
check restored databaseops/OPERATIONS.md, restore section, integrity scriptChecks the restored database for integrity and references. Read-only.
inspect restored copyNODE_ENV=production CODEBOT_DATA_DIR=<restore folder> CODEBOT_PORT=3508 CODEBOT_RECOVERY_HOLD=1 node --import tsx apps/service/src/main.tsStarts the restored copy on port 3508 in recovery hold, so nothing runs by itself.
promote a restoreops/OPERATIONS.md, restore section, promotion stepsOpens the promotion steps: keep the old data as rollback, then point the settings at the verified copy.
guest
The guest: a second CodeBot on this machine, run as its own Linux user, codebot-guest.
set upsudo ops/guest-install.shSets up the guest user, service, settings, sudo rules and the Tailscale port 10000. Run once.
updateops/guest-update.shBuilds the guest program, replaces /opt/codebot-guest and restarts it; needs no password.
invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google invite link, valid for ten minutes.
statussystemctl status codebot-guestPrints whether the guest service runs.
logsjournalctl -u codebot-guestPrints the guest service's log.
processesps -u codebot-guestLists the processes the guest's CodeBot runs.
disk usesudo du -sh /home/codebot-guestShows how much disk the guest's data uses.
guest apphttps://liel.tail18e69e.ts.net:10000Opens the guest's app on port 10000, shared with the guest's Tailscale account.
guest settingssudoedit /home/codebot-guest/.config/codebot/service.envOpens the guest's private settings for editing; run guest update afterwards.
guest onboardingcodebot account onboarding (screen)Shows the onboarding resets, including the fresh-CodeBot restart that keeps this guest's account.
remove guestops/OPERATIONS.md, section Host a guest on this machineOpens the removal steps; they delete the guest's user and its data.
family
The family CodeBots behind the home Wi-Fi address: one per family member, at most six.
statussudo codebot-family statusPrints each family CodeBot: whether it runs and whether Gmail can connect.
addsudo codebot-family add NCreates family CodeBot N for a new Google account.
removesudo codebot-family remove NDeletes family CodeBot N and frees its number; that Google account cannot link again.
stop allsudo codebot-family stop-allStops every family CodeBot.
start allsudo codebot-family start-allStarts every family CodeBot again.
logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the front door's and the family CodeBots' logs.
front doorhttps://family.codebot.lielbenor.comOpens the family sign-in front door at the home Wi-Fi address.
set upsudo ops/family-install.shSets up the front door user, the helper, the services, the sudo rules and nginx. Run once.
updateops/family-update.shBuilds one program for the front door and every family CodeBot, and restarts them all.
remove everythingops/OPERATIONS.md, section Home Wi-Fi address (remove everything)Opens the steps to remove the whole family setup, one part at a time.
account
The central account service in Supabase: sign-in, its function, Gmail setup, and the records behind them.
onboardingcodebot account onboarding (screen)Shows the onboarding screen: how to start someone's onboarding again.
Supabase projectwbgrjvqbupgdclaztuou (Supabase dashboard)Opens the central account service in Supabase, under the mobile-coder login.
deploy host-accessSUPABASE_ACCESS_TOKEN from ~/.config/supabase-codebot-token npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function; run it whenever a contract that function reads changes.
token file~/.config/supabase-codebot-tokenOpens the Supabase CLI token file (mode 600). Never print it.
setup accountnpm run setup-accountRuns the account setup script, ops/setup-account.ts.
Gmail setupdocs/automation/gmail.mdOpens the steps to set up Gmail for Bots: Google credentials and the relay.
account › onboarding
Starting someone's onboarding again: which reset to use, and what each one deletes.
replay the tourops/OPERATIONS.md, section Replay only the first-use tourOpens the steps that replay the first-use tour on a host with no Bots; the account stays.
fresh CodeBotops/OPERATIONS.md, section Restart onboarding with a fresh CodeBot, keeping the accountOpens the steps that wipe a guest host's Bots and conversations; the account and folders stay.
full resetops/OPERATIONS.md, section Full reset: the person starts as newOpens the steps that delete the account, its Bots, attachments and recordings. Destructive.
progress rowspublic.codebot_account_progress (Supabase SQL editor)Opens the progress rows: the first-use draft and the computer connection.
receiptsfirst_use_receipts in ~/.local/share/codebot/codebot.sqliteOpens the receipts table, which records which Bot the first-use tour created.
docs
The written record: the runbook, the rules, the design record and the specs.
runbookops/OPERATIONS.mdOpens the runbook: install, backup, restore, emergency stop, address change and resets.
READMEREADME.mdOpens the README: the layout, the local run and the verification commands.
architectureARCHITECTURE.mdOpens the technical boundaries and invariants the code keeps.
working rulesCLAUDE.mdOpens the rules every task assumes: the product, the screen process and the deploy steps.
designdocs/ and design/ (screen docs › design)Shows the design screen: the design method, the owner's rulings and the reference screens.
specsdocs/ and .idd/ and .bdd/ (screen docs › specs)Shows the specs screen: the behaviour contract, open work, plans, verification and per-module tests.
docs › design
The design record: the method, the owner's rulings, the reference screens and the playground.
design methoddocs/design-method.mdOpens the design method: the process for any new or reworked screen.
design rulingsdocs/design-taste.mdOpens the owner's design rulings and the designs they rejected.
reference screensdesign/Opens the design references and the annotated screens.
playgroundnpm run playgroundStarts the design playground on 127.0.0.1 to compare screen variants side by side.
docs › specs
The product and build record: the behaviour contract, open work, plans, verification and per-module tests.
product specPRODUCT-SPEC.mdOpens the behaviour contract the product must meet.
open workDEFERRED-WORK.mdOpens the open-work list and the safe restart state.
implementation statusIMPLEMENTATION-STATUS.mdOpens what was built, and where the paused beta stopped.
objectivesdocs/objectives/README.mdOpens the objectives: what each goal is for.
plansdocs/plans/Opens the plan folder: one design or plan record per change.
verificationdocs/verification/Opens the recorded verification evidence, including the onboarding proof.
Gmail referencedocs/automation/gmail-reference.mdOpens the generated Gmail reference; regenerate it with docs:gmail.
intents and features.idd/modules/ and .bdd/features/Opens the per-module intents and the Given/When/Then features the tests follow.
housekeeping skillskills/codebot-housekeeping/SKILL.mdOpens the codebot-housekeeping skill.
Questions
  • Scope: should the CLI cover only the operator and developer, with Bots, chats and in-app Gmail reached through the app address? Recommend yes: the app already does those, and a CLI copy would drift.
  • Facade name: use codebot, with a short alias? Recommend codebot plus cb, after checking whence -a cb and bash type -a cb show no clash.
  • Run or open: should deploy run ops/deploy.sh directly? Recommend yes, because it refuses while a Bot works. Backup and restore should open the runbook for now, since they stop the host and handle secrets; revisit after one dry run.
  • Guest and family: two groups, or one hosting group? Recommend two: they are different users with different commands (one guest CodeBot versus numbered family CodeBots).
  • Gmail: its own top group, or under account? Recommend under account until Gmail has its own commands; promote it then.
  • Existing CLI: the README mentions cli/codebot.py, which is not in the file listing. If it exists, extend it instead of starting a new file. Recommend checking before building.
  • Unmapped items: ops/agent-start.sh, ops/avatar-thumbnails.ts, ops/review/schedule-drill.mjs, ops/review/redirect-google.mjs, ops/review/seed-gmail.ts, ops/review/terminal-tabs-stack.sh, the .github workflows, and the experimental apps V2 to V4 in other repos. Recommend leaving them out until you say what they are for.
As phone screens

Home

The codebot commands: running, shipping, checking, backing up and hosting people on this machine.

hostShows the host screen: whether the host runs, its logs, its address and its health counters.
›
deployShows the deploy screen: how a change is built, pushed and made live.
›
checkShows the check screen: the type check, the tests and the review scripts.
›
backupShows the backup screen: how to copy the host's data and check a copy before using it.
›
guestShows the guest screen: the second CodeBot on this machine, run as the codebot-guest user.
›
familyShows the family screen: the family CodeBots behind the home Wi-Fi address.
›
accountShows the account screen: the central sign-in service in Supabase, Gmail setup and onboarding resets.
›
docsShows the docs screen: the runbook, the rules, the design record and the specs, each with its path.
›
‹ Home

host

The codebot host on this machine: its service, its address and its health.

statusPrints whether codebot.service runs, with its last log lines.
›
startStarts codebot.service, which serves port 3505 on this machine.
›
restartRestarts codebot.service; wait for active turns and recordings to finish first.
›
stopStops codebot.service: interrupts Bot turns, ends scheduling and finishes recordings.
›
logsPrints the last 80 log lines of codebot.service.
›
readyChecks that the host answers on port 3505; a session reply means it is ready.
›
appOpens the CodeBot app over the private Tailscale address, where Bots are used.
›
terminal brokerPrints whether the optional terminal broker runs; without it the terminal stays off.
›
emergency stopOpens the emergency stop steps: a stop request first, then SIGKILL only if the stop hangs.
›
settingsOpens the private settings file: data folder, project roots and keys. Never print it.
›
diagnosticsShows the diagnostics screen: the host's health counters, read from the signed-in app.
›
addressShows the address screen: how the host is reached and how a device connects to it.
›
‹ host

diagnostics

The health counters the host reports, read from the signed-in app.

host countersOpens the host counters: migration, event cursor, queued and running turns, recovery hold.
›
scheduler countersOpens the scheduler counters: its timers and the wakeups waiting to run.
›
Vision countersOpens the Vision counters: the browser pages and frames the Bots watch.
›
notification countersOpens the notification counters: the queue, the timer and the active sends.
›
notification stepsOpens the notification steps: enable a device, send a test, and why a push may not show.
›
‹ host

address

How the host is reached: its private address, connecting a device, the phone app, and changing the address.

address mappingPrints the Tailscale mapping from the private HTTPS address to port 3505. Do not reset it.
›
connect a deviceOpens the steps to connect a phone or laptop through Tailscale.
›
entrance keyPrints the entrance key for a new device; read it locally and never paste it.
›
phone appOpens how to install CodeBot to the phone's home screen.
›
change addressOpens the nine places to update, in order, when the machine's address changes.
›
‹ Home

deploy

Getting a change live: install, build, push, restart the host and check that it answers.

shipRuns the full deploy: build, push, wait for active work, restart codebot.service, then check /api/session. Refuses while a Bot is working.
›
buildBuilds a new release into dist/releases and switches the served link; a failed build leaves the running release in place.
›
installInstalls the locked dependencies; run it after a pull that changed them.
›
first installOpens the first-time install: dependencies, the private settings file and the unit.
›
deploy guardRuns as the Stop hook; it blocks finishing a turn while code is unpushed or not yet live.
›
‹ Home

check

Checks of the code: the type check, the tests, and the review scripts for Gmail and schedules.

all checksRuns the type check and the tests together; run it before you ship.
›
type checkRuns tsc --noEmit only: shows the code compiles, and nothing about Bot behaviour.
›
testsRuns the Gmail automation tests against a fake Google server, not the real one.
›
Gmail reviewRuns the Gmail review script, ops/review/gmail-review.mjs.
›
schedules reviewRuns the schedules review script, ops/review/schedules-review.mjs.
›
QA buildType checks and builds the QA copy that codebot-integration.service runs on port 3506.
›
agents fileRegenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md.
›
‹ Home

backup

Copies of the host's data, settings and unit, and how to check a copy before using it.

make a backupOpens the backup steps: stop the host, copy its data and settings, write checksums, start it again.
›
verify a backupChecks a backup's files against its checksums before any restore.
›
backup foldersOpens the backup folders, each named by its UTC time. They are private.
›
restoreOpens the restore steps: extract to a new private folder and check it before use.
›
check restored databaseChecks the restored database for integrity and references. Read-only.
›
inspect restored copyStarts the restored copy on port 3508 in recovery hold, so nothing runs by itself.
›
promote a restoreOpens the promotion steps: keep the old data as rollback, then point the settings at the verified copy.
›
‹ Home

guest

The guest: a second CodeBot on this machine, run as its own Linux user, codebot-guest.

set upSets up the guest user, service, settings, sudo rules and the Tailscale port 10000. Run once.
›
updateBuilds the guest program, replaces /opt/codebot-guest and restarts it; needs no password.
›
invitePrints a one-use Google invite link, valid for ten minutes.
›
statusPrints whether the guest service runs.
›
logsPrints the guest service's log.
›
processesLists the processes the guest's CodeBot runs.
›
disk useShows how much disk the guest's data uses.
›
guest appOpens the guest's app on port 10000, shared with the guest's Tailscale account.
›
guest settingsOpens the guest's private settings for editing; run guest update afterwards.
›
guest onboardingShows the onboarding resets, including the fresh-CodeBot restart that keeps this guest's account.
›
remove guestOpens the removal steps; they delete the guest's user and its data.
›
‹ Home

family

The family CodeBots behind the home Wi-Fi address: one per family member, at most six.

statusPrints each family CodeBot: whether it runs and whether Gmail can connect.
›
addCreates family CodeBot N for a new Google account.
›
removeDeletes family CodeBot N and frees its number; that Google account cannot link again.
›
stop allStops every family CodeBot.
›
start allStarts every family CodeBot again.
›
logsPrints the front door's and the family CodeBots' logs.
›
front doorOpens the family sign-in front door at the home Wi-Fi address.
›
set upSets up the front door user, the helper, the services, the sudo rules and nginx. Run once.
›
updateBuilds one program for the front door and every family CodeBot, and restarts them all.
›
remove everythingOpens the steps to remove the whole family setup, one part at a time.
›
‹ Home

account

The central account service in Supabase: sign-in, its function, Gmail setup, and the records behind them.

onboardingShows the onboarding screen: how to start someone's onboarding again.
›
Supabase projectOpens the central account service in Supabase, under the mobile-coder login.
›
deploy host-accessDeploys the host-access function; run it whenever a contract that function reads changes.
›
token fileOpens the Supabase CLI token file (mode 600). Never print it.
›
setup accountRuns the account setup script, ops/setup-account.ts.
›
Gmail setupOpens the steps to set up Gmail for Bots: Google credentials and the relay.
›
‹ account

onboarding

Starting someone's onboarding again: which reset to use, and what each one deletes.

replay the tourOpens the steps that replay the first-use tour on a host with no Bots; the account stays.
›
fresh CodeBotOpens the steps that wipe a guest host's Bots and conversations; the account and folders stay.
›
full resetOpens the steps that delete the account, its Bots, attachments and recordings. Destructive.
›
progress rowsOpens the progress rows: the first-use draft and the computer connection.
›
receiptsOpens the receipts table, which records which Bot the first-use tour created.
›
‹ Home

docs

The written record: the runbook, the rules, the design record and the specs.

runbookOpens the runbook: install, backup, restore, emergency stop, address change and resets.
›
READMEOpens the README: the layout, the local run and the verification commands.
›
architectureOpens the technical boundaries and invariants the code keeps.
›
working rulesOpens the rules every task assumes: the product, the screen process and the deploy steps.
›
designShows the design screen: the design method, the owner's rulings and the reference screens.
›
specsShows the specs screen: the behaviour contract, open work, plans, verification and per-module tests.
›
‹ docs

design

The design record: the method, the owner's rulings, the reference screens and the playground.

design methodOpens the design method: the process for any new or reworked screen.
›
design rulingsOpens the owner's design rulings and the designs they rejected.
›
reference screensOpens the design references and the annotated screens.
›
playgroundStarts the design playground on 127.0.0.1 to compare screen variants side by side.
›
‹ docs

specs

The product and build record: the behaviour contract, open work, plans, verification and per-module tests.

product specOpens the behaviour contract the product must meet.
›
open workOpens the open-work list and the safe restart state.
›
implementation statusOpens what was built, and where the paused beta stopped.
›
objectivesOpens the objectives: what each goal is for.
›
plansOpens the plan folder: one design or plan record per change.
›
verificationOpens the recorded verification evidence, including the onboarding proof.
›
Gmail referenceOpens the generated Gmail reference; regenerate it with docs:gmail.
›
intents and featuresOpens the per-module intents and the Given/When/Then features the tests follow.
›
housekeeping skillOpens the codebot-housekeeping skill.
›
Raw answer
## Scenario

*Reasoned from the project's docs, not from observed use.* The owner usually reaches CodeBot from a phone through the app, so Bots are used there and not in this map. The operator, at a desktop, keeps the host running, ships changes after a pull, checks why a Bot will not answer, adds or removes a family member, and recovers from a bad disk or a bad change. This map covers that operator and developer reach.

## Inventory, by source

- **npm scripts** (`package.json`): dev, build, start, typecheck, test, check, setup-account, docs:gmail, review:gmail, review:schedules, playground, sync:agents, build:integration.
- **Runbook** (`ops/OPERATIONS.md`): install, backup, restore, emergency stop, guest, family, address change, onboarding resets, diagnostics.
- **Scripts named in the runbook or CLAUDE.md:** `ops/deploy.sh`, `ops/deploy-guard.sh`, `ops/guest-install.sh`, `ops/guest-update.sh`, `ops/family-install.sh`, `ops/family-update.sh`, `ops/setup-account.ts`, `ops/review/gmail-review.mjs`, `ops/review/schedules-review.mjs`.
- **Units** (`ops/*.service`): codebot, codebot-terminal-broker, codebot-guest, codebot-family-lobby, codebot-family@.
- **Helpers:** `/usr/local/sbin/codebot-family`, `/opt/codebot-guest/invite`.
- **Endpoints:** `/api/session`, `/api/diagnostics/{host,scheduler,vision}`, `/api/notifications/diagnostics`.
- **Addresses and ports:** 3505 (host), 3506 (QA), 3508 (restore check), 10000 (guest), 10100+N and family.example (family).
- **Docs and files:** README, ARCHITECTURE, CLAUDE.md, `.idd`, `.bdd`, `docs/`, `design/`, `skills/codebot-housekeeping`.
- **Supabase:** project `wbgrjvqbupgdclaztuou`, function `host-access`, token file.

## Judgment calls

- **Group name `host`.** It is the project's word for the running server. The unit is `codebot.service` and appears only in forms.
- **Runbook steps are reached by section, not run.** Backup, restore, resets and removal stop services or delete data, so the map points at the runbook section. It does not run them.
- **Entrance key is listed, with a warning.** The runbook documents reading it locally for a new device, so the map keeps the row and says never to paste it.
- **Left out:** the V2–V4 experimental apps (other repos, ports 3512–3514, their own run script) and scripts whose purpose is not visible in the dump.
- **Could not verify.** The dump is truncated (OPERATIONS, ARCHITECTURE, and the `ops/` listing). Several scripts named in the docs do not appear in the visible listing. `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md` and `MASTER-PLAN.md` are referenced but absent from the listing. Each needs a check before anyone relies on its row.

## Questions for you

Full text, with my recommendation, is in the JSON. In short:

1. **Scope:** keep Bots and chats in the app, with only the app address in the CLI? *Recommend yes.*
2. **Facade name:** `codebot`, plus a short alias? *Recommend `codebot` and `cb` if `whence -a cb` is clear.*
3. **Run or open:** should `deploy` run `ops/deploy.sh`? *Recommend yes, it refuses safely. Backup and restore should open the runbook for now.*
4. **Guest and family:** two groups or one `hosting` group? *Recommend two.*
5. **Gmail:** its own top group, or under `account`? *Recommend under `account` for now.*
6. **Existing CLI:** the README mentions `cli/codebot.py`, which is not in the listing. Does it exist? If so, extend it rather than start a new file.
7. **Unmapped scripts:** `ops/agent-start.sh`, `ops/review/schedule-drill.mjs`, `redirect-google.mjs`, `seed-gmail.ts`, `terminal-tabs-stack.sh`, `ops/avatar-thumbnails.ts`, and the `.github` workflows. *Recommend leaving them out until you say what they are for.*

```json
{"screens": [
 {"path": [], "sentence": "The codebot commands: running, shipping, checking, backing up and hosting people on this machine.", "rows": [
  {"name": "host", "form": "codebot host (screen)", "what": "Shows the host screen: whether the host runs, its logs, its address and its health counters."},
  {"name": "deploy", "form": "codebot deploy (screen)", "what": "Shows the deploy screen: how a change is built, pushed and made live."},
  {"name": "check", "form": "codebot check (screen)", "what": "Shows the check screen: the type check, the tests and the review scripts."},
  {"name": "backup", "form": "codebot backup (screen)", "what": "Shows the backup screen: how to copy the host's data and check a copy before using it."},
  {"name": "guest", "form": "codebot guest (screen)", "what": "Shows the guest screen: the second CodeBot on this machine, run as the codebot-guest user."},
  {"name": "family", "form": "codebot family (screen)", "what": "Shows the family screen: the family CodeBots behind the home Wi-Fi address."},
  {"name": "account", "form": "codebot account (screen)", "what": "Shows the account screen: the central sign-in service in Supabase, Gmail setup and onboarding resets."},
  {"name": "docs", "form": "codebot docs (screen)", "what": "Shows the docs screen: the runbook, the rules, the design record and the specs, each with its path."}
 ]},
 {"path": ["host"], "sentence": "The codebot host on this machine: its service, its address and its health.", "rows": [
  {"name": "status", "form": "systemctl --user status codebot.service --no-pager", "what": "Prints whether codebot.service runs, with its last log lines."},
  {"name": "start", "form": "systemctl --user start codebot.service", "what": "Starts codebot.service, which serves port 3505 on this machine."},
  {"name": "restart", "form": "systemctl --user restart codebot.service", "what": "Restarts codebot.service; wait for active turns and recordings to finish first."},
  {"name": "stop", "form": "systemctl --user stop codebot.service", "what": "Stops codebot.service: interrupts Bot turns, ends scheduling and finishes recordings."},
  {"name": "logs", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of codebot.service."},
  {"name": "ready", "form": "curl --fail --silent http://127.0.0.1:3505/api/session", "what": "Checks that the host answers on port 3505; a session reply means it is ready."},
  {"name": "app", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the CodeBot app over the private Tailscale address, where Bots are used."},
  {"name": "terminal broker", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the optional terminal broker runs; without it the terminal stays off."},
  {"name": "emergency stop", "form": "ops/OPERATIONS.md, section Emergency stop and rollback", "what": "Opens the emergency stop steps: a stop request first, then SIGKILL only if the stop hangs."},
  {"name": "settings", "form": "~/.config/codebot/service.env", "what": "Opens the private settings file: data folder, project roots and keys. Never print it."},
  {"name": "diagnostics", "form": "codebot host diagnostics (screen)", "what": "Shows the diagnostics screen: the host's health counters, read from the signed-in app."},
  {"name": "address", "form": "codebot host address (screen)", "what": "Shows the address screen: how the host is reached and how a device connects to it."}
 ]},
 {"path": ["host", "diagnostics"], "sentence": "The health counters the host reports, read from the signed-in app.", "rows": [
  {"name": "host counters", "form": "/api/diagnostics/host on the app address (signed-in browser)", "what": "Opens the host counters: migration, event cursor, queued and running turns, recovery hold."},
  {"name": "scheduler counters", "form": "/api/diagnostics/scheduler on the app address (signed-in browser)", "what": "Opens the scheduler counters: its timers and the wakeups waiting to run."},
  {"name": "Vision counters", "form": "/api/diagnostics/vision on the app address (signed-in browser)", "what": "Opens the Vision counters: the browser pages and frames the Bots watch."},
  {"name": "notification counters", "form": "/api/notifications/diagnostics on the app address (signed-in browser)", "what": "Opens the notification counters: the queue, the timer and the active sends."},
  {"name": "notification steps", "form": "ops/OPERATIONS.md, section Background notifications", "what": "Opens the notification steps: enable a device, send a test, and why a push may not show."}
 ]},
 {"path": ["host", "address"], "sentence": "How the host is reached: its private address, connecting a device, the phone app, and changing the address.", "rows": [
  {"name": "address mapping", "form": "tailscale serve status --json", "what": "Prints the Tailscale mapping from the private HTTPS address to port 3505. Do not reset it."},
  {"name": "connect a device", "form": "ops/OPERATIONS.md, section Connect a device", "what": "Opens the steps to connect a phone or laptop through Tailscale."},
  {"name": "entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Prints the entrance key for a new device; read it locally and never paste it."},
  {"name": "phone app", "form": "ops/OPERATIONS.md, section Private access and PWA installation", "what": "Opens how to install CodeBot to the phone's home screen."},
  {"name": "change address", "form": "ops/OPERATIONS.md, section Change this machine's address", "what": "Opens the nine places to update, in order, when the machine's address changes."}
 ]},
 {"path": ["deploy"], "sentence": "Getting a change live: install, build, push, restart the host and check that it answers.", "rows": [
  {"name": "ship", "form": "sh ops/deploy.sh", "what": "Runs the full deploy: build, push, wait for active work, restart codebot.service, then check /api/session. Refuses while a Bot is working."},
  {"name": "build", "form": "npm run build", "what": "Builds a new release into dist/releases and switches the served link; a failed build leaves the running release in place."},
  {"name": "install", "form": "npm ci", "what": "Installs the locked dependencies; run it after a pull that changed them."},
  {"name": "first install", "form": "ops/OPERATIONS.md, section Install or update the host", "what": "Opens the first-time install: dependencies, the private settings file and the unit."},
  {"name": "deploy guard", "form": "ops/deploy-guard.sh", "what": "Runs as the Stop hook; it blocks finishing a turn while code is unpushed or not yet live."}
 ]},
 {"path": ["check"], "sentence": "Checks of the code: the type check, the tests, and the review scripts for Gmail and schedules.", "rows": [
  {"name": "all checks", "form": "npm run check", "what": "Runs the type check and the tests together; run it before you ship."},
  {"name": "type check", "form": "npm run typecheck", "what": "Runs tsc --noEmit only: shows the code compiles, and nothing about Bot behaviour."},
  {"name": "tests", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server, not the real one."},
  {"name": "Gmail review", "form": "npm run review:gmail", "what": "Runs the Gmail review script, ops/review/gmail-review.mjs."},
  {"name": "schedules review", "form": "npm run review:schedules", "what": "Runs the schedules review script, ops/review/schedules-review.mjs."},
  {"name": "QA build", "form": "npm run build:integration", "what": "Type checks and builds the QA copy that codebot-integration.service runs on port 3506."},
  {"name": "agents file", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md; edit CLAUDE.md, never AGENTS.md."}
 ]},
 {"path": ["backup"], "sentence": "Copies of the host's data, settings and unit, and how to check a copy before using it.", "rows": [
  {"name": "make a backup", "form": "ops/OPERATIONS.md, section Back up a consistent installation", "what": "Opens the backup steps: stop the host, copy its data and settings, write checksums, start it again."},
  {"name": "verify a backup", "form": "sha256sum -c SHA256SUMS (inside a backup folder)", "what": "Checks a backup's files against its checksums before any restore."},
  {"name": "backup folders", "form": "~/.local/share/codebot-backups", "what": "Opens the backup folders, each named by its UTC time. They are private."},
  {"name": "restore", "form": "ops/OPERATIONS.md, section Restore into a separate directory first", "what": "Opens the restore steps: extract to a new private folder and check it before use."},
  {"name": "check restored database", "form": "ops/OPERATIONS.md, restore section, integrity script", "what": "Checks the restored database for integrity and references. Read-only."},
  {"name": "inspect restored copy", "form": "NODE_ENV=production CODEBOT_DATA_DIR=<restore folder> CODEBOT_PORT=3508 CODEBOT_RECOVERY_HOLD=1 node --import tsx apps/service/src/main.ts", "what": "Starts the restored copy on port 3508 in recovery hold, so nothing runs by itself."},
  {"name": "promote a restore", "form": "ops/OPERATIONS.md, restore section, promotion steps", "what": "Opens the promotion steps: keep the old data as rollback, then point the settings at the verified copy."}
 ]},
 {"path": ["guest"], "sentence": "The guest: a second CodeBot on this machine, run as its own Linux user, codebot-guest.", "rows": [
  {"name": "set up", "form": "sudo ops/guest-install.sh", "what": "Sets up the guest user, service, settings, sudo rules and the Tailscale port 10000. Run once."},
  {"name": "update", "form": "ops/guest-update.sh", "what": "Builds the guest program, replaces /opt/codebot-guest and restarts it; needs no password."},
  {"name": "invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google invite link, valid for ten minutes."},
  {"name": "status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest service runs."},
  {"name": "logs", "form": "journalctl -u codebot-guest", "what": "Prints the guest service's log."},
  {"name": "processes", "form": "ps -u codebot-guest", "what": "Lists the processes the guest's CodeBot runs."},
  {"name": "disk use", "form": "sudo du -sh /home/codebot-guest", "what": "Shows how much disk the guest's data uses."},
  {"name": "guest app", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's app on port 10000, shared with the guest's Tailscale account."},
  {"name": "guest settings", "form": "sudoedit /home/codebot-guest/.config/codebot/service.env", "what": "Opens the guest's private settings for editing; run guest update afterwards."},
  {"name": "guest onboarding", "form": "codebot account onboarding (screen)", "what": "Shows the onboarding resets, including the fresh-CodeBot restart that keeps this guest's account."},
  {"name": "remove guest", "form": "ops/OPERATIONS.md, section Host a guest on this machine", "what": "Opens the removal steps; they delete the guest's user and its data."}
 ]},
 {"path": ["family"], "sentence": "The family CodeBots behind the home Wi-Fi address: one per family member, at most six.", "rows": [
  {"name": "status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot: whether it runs and whether Gmail can connect."},
  {"name": "add", "form": "sudo codebot-family add N", "what": "Creates family CodeBot N for a new Google account."},
  {"name": "remove", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number; that Google account cannot link again."},
  {"name": "stop all", "form": "sudo codebot-family stop-all", "what": "Stops every family CodeBot."},
  {"name": "start all", "form": "sudo codebot-family start-all", "what": "Starts every family CodeBot again."},
  {"name": "logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the front door's and the family CodeBots' logs."},
  {"name": "front door", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in front door at the home Wi-Fi address."},
  {"name": "set up", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, the helper, the services, the sudo rules and nginx. Run once."},
  {"name": "update", "form": "ops/family-update.sh", "what": "Builds one program for the front door and every family CodeBot, and restarts them all."},
  {"name": "remove everything", "form": "ops/OPERATIONS.md, section Home Wi-Fi address (remove everything)", "what": "Opens the steps to remove the whole family setup, one part at a time."}
 ]},
 {"path": ["account"], "sentence": "The central account service in Supabase: sign-in, its function, Gmail setup, and the records behind them.", "rows": [
  {"name": "onboarding", "form": "codebot account onboarding (screen)", "what": "Shows the onboarding screen: how to start someone's onboarding again."},
  {"name": "Supabase project", "form": "wbgrjvqbupgdclaztuou (Supabase dashboard)", "what": "Opens the central account service in Supabase, under the mobile-coder login."},
  {"name": "deploy host-access", "form": "SUPABASE_ACCESS_TOKEN from ~/.config/supabase-codebot-token npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function; run it whenever a contract that function reads changes."},
  {"name": "token file", "form": "~/.config/supabase-codebot-token", "what": "Opens the Supabase CLI token file (mode 600). Never print it."},
  {"name": "setup account", "form": "npm run setup-account", "what": "Runs the account setup script, ops/setup-account.ts."},
  {"name": "Gmail setup", "form": "docs/automation/gmail.md", "what": "Opens the steps to set up Gmail for Bots: Google credentials and the relay."}
 ]},
 {"path": ["account", "onboarding"], "sentence": "Starting someone's onboarding again: which reset to use, and what each one deletes.", "rows": [
  {"name": "replay the tour", "form": "ops/OPERATIONS.md, section Replay only the first-use tour", "what": "Opens the steps that replay the first-use tour on a host with no Bots; the account stays."},
  {"name": "fresh CodeBot", "form": "ops/OPERATIONS.md, section Restart onboarding with a fresh CodeBot, keeping the account", "what": "Opens the steps that wipe a guest host's Bots and conversations; the account and folders stay."},
  {"name": "full reset", "form": "ops/OPERATIONS.md, section Full reset: the person starts as new", "what": "Opens the steps that delete the account, its Bots, attachments and recordings. Destructive."},
  {"name": "progress rows", "form": "public.codebot_account_progress (Supabase SQL editor)", "what": "Opens the progress rows: the first-use draft and the computer connection."},
  {"name": "receipts", "form": "first_use_receipts in ~/.local/share/codebot/codebot.sqlite", "what": "Opens the receipts table, which records which Bot the first-use tour created."}
 ]},
 {"path": ["docs"], "sentence": "The written record: the runbook, the rules, the design record and the specs.", "rows": [
  {"name": "runbook", "form": "ops/OPERATIONS.md", "what": "Opens the runbook: install, backup, restore, emergency stop, address change and resets."},
  {"name": "README", "form": "README.md", "what": "Opens the README: the layout, the local run and the verification commands."},
  {"name": "architecture", "form": "ARCHITECTURE.md", "what": "Opens the technical boundaries and invariants the code keeps."},
  {"name": "working rules", "form": "CLAUDE.md", "what": "Opens the rules every task assumes: the product, the screen process and the deploy steps."},
  {"name": "design", "form": "docs/ and design/ (screen docs › design)", "what": "Shows the design screen: the design method, the owner's rulings and the reference screens."},
  {"name": "specs", "form": "docs/ and .idd/ and .bdd/ (screen docs › specs)", "what": "Shows the specs screen: the behaviour contract, open work, plans, verification and per-module tests."}
 ]},
 {"path": ["docs", "design"], "sentence": "The design record: the method, the owner's rulings, the reference screens and the playground.", "rows": [
  {"name": "design method", "form": "docs/design-method.md", "what": "Opens the design method: the process for any new or reworked screen."},
  {"name": "design rulings", "form": "docs/design-taste.md", "what": "Opens the owner's design rulings and the designs they rejected."},
  {"name": "reference screens", "form": "design/", "what": "Opens the design references and the annotated screens."},
  {"name": "playground", "form": "npm run playground", "what": "Starts the design playground on 127.0.0.1 to compare screen variants side by side."}
 ]},
 {"path": ["docs", "specs"], "sentence": "The product and build record: the behaviour contract, open work, plans, verification and per-module tests.", "rows": [
  {"name": "product spec", "form": "PRODUCT-SPEC.md", "what": "Opens the behaviour contract the product must meet."},
  {"name": "open work", "form": "DEFERRED-WORK.md", "what": "Opens the open-work list and the safe restart state."},
  {"name": "implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what was built, and where the paused beta stopped."},
  {"name": "objectives", "form": "docs/objectives/README.md", "what": "Opens the objectives: what each goal is for."},
  {"name": "plans", "form": "docs/plans/", "what": "Opens the plan folder: one design or plan record per change."},
  {"name": "verification", "form": "docs/verification/", "what": "Opens the recorded verification evidence, including the onboarding proof."},
  {"name": "Gmail reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated Gmail reference; regenerate it with docs:gmail."},
  {"name": "intents and features", "form": ".idd/modules/ and .bdd/features/", "what": "Opens the per-module intents and the Given/When/Then features the tests follow."},
  {"name": "housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the codebot-housekeeping skill."}
 ]}
],
"questions": [
 "Scope: should the CLI cover only the operator and developer, with Bots, chats and in-app Gmail reached through the app address? Recommend yes: the app already does those, and a CLI copy would drift.",
 "Facade name: use codebot, with a short alias? Recommend codebot plus cb, after checking whence -a cb and bash type -a cb show no clash.",
 "Run or open: should deploy run ops/deploy.sh directly? Recommend yes, because it refuses while a Bot works. Backup and restore should open the runbook for now, since they stop the host and handle secrets; revisit after one dry run.",
 "Guest and family: two groups, or one hosting group? Recommend two: they are different users with different commands (one guest CodeBot versus numbered family CodeBots).",
 "Gmail: its own top group, or under account? Recommend under account until Gmail has its own commands; promote it then.",
 "Existing CLI: the README mentions cli/codebot.py, which is not in the file listing. If it exists, extend it instead of starting a new file. Recommend checking before building.",
 "Unmapped items: ops/agent-start.sh, ops/avatar-thumbnails.ts, ops/review/schedule-drill.mjs, ops/review/redirect-google.mjs, ops/review/seed-gmail.ts, ops/review/terminal-tabs-stack.sh, the .github workflows, and the experimental apps V2 to V4 in other repos. Recommend leaving them out until you say what they are for."
]}
```

screen-decomposition, final · run 5 exit=0 seconds=131 · prompt

P1 Recall: 0.654P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.991P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.539
As terminal help
The map of the codebot project: everything its owner can reach, grouped by the job it serves.
servicescreen: serviceOpens the service screen: starting, stopping and checking the host on port 3505.
devicesscreen: devicesOpens the devices screen: connecting a phone, tablet or desktop to the host, and its notifications.
guestsscreen: guestsOpens the guests screen: the guest CodeBot and the family CodeBots on this machine.
accountsscreen: accountsOpens the accounts screen: Google sign-in, Gmail and the central account service.
datascreen: dataOpens the data screen: backing up, restoring and resetting the host's data.
checkscreen: checkOpens the check screen: the commands that compile, build and test the project.
docsscreen: docsOpens the docs screen: the guides, runbooks, plans and design records.
service
The codebot host: the service on port 3505, its unit, its settings, its source and its terminal broker.
run in developmentnpm run devRuns the service in watch mode in this terminal, restarting on each code change.
start in production modenpm startStarts the service in production mode in this terminal.
restart the installed servicesystemctl --user restart codebot.serviceRestarts the installed service once active Bots and recordings have finished.
stop the installed servicesystemctl --user stop codebot.serviceStops the service, interrupts Bot turns and finishes recordings.
force-stop the installed servicesystemctl --user kill --kill-whom=all --signal=SIGKILL codebot.serviceForce-kills the service, which can lose recordings still being written.
read the service logjournalctl --user -u codebot.service -n 80 --no-pagerPrints the last 80 log lines of the installed service.
health checkcurl http://127.0.0.1:3505/api/sessionReads whether the service answers on its port.
host diagnostics/api/diagnostics/host in the signed-in web appShows the host's counters and lifecycle state, with no provider tokens.
deploy after a changesh ops/deploy.shBuilds, pushes and restarts the installed service, after waiting for active Bots to finish.
private settings~/.config/codebot/service.envOpens the private settings the service reads at start (mode 0600).
example settingsops/environment.exampleOpens the example settings, with every variable and what it does.
service unitops/codebot.serviceOpens the systemd unit that runs the service, installed under ~/.config/systemd/user.
terminal brokerscreen: service › terminal brokerOpens the terminal broker screen: the separate per-user process that holds the shell.
service sourceapps/service/src/Opens the service code: Bots, providers, terminal, avatars and storage.
web app sourceapps/web/src/Opens the web app code that phones and desktops show.
shared schemaspackages/contracts/src/Opens the schemas the service and client share, so a bad payload is refused early.
service › terminal broker
The terminal broker: a per-user process that holds the owner's shell, separate from the web service. It is off until enabled.
enable and start the brokersystemctl --user enable --now codebot-terminal-broker.serviceEnables and starts the broker, which keeps running when the web service restarts.
broker statussystemctl --user status codebot-terminal-broker.service --no-pagerPrints whether the broker is running, with its recent output.
linger checkloginctl show-user $USER -p LingerPrints whether the broker keeps running without a desktop login.
broker unitops/codebot-terminal-broker.serviceOpens the systemd unit that runs the broker.
broker programops/terminal-broker.tsOpens the broker program, the process that holds the terminal.
devices
How a phone, tablet or desktop reaches this host and gets its notifications.
web app on the private addresshttps://liel.tail18e69e.ts.net/Opens the web app on the private Tailscale address.
entrance key~/.local/share/codebot/owner-keyPrints the key a new device needs to sign in. Keep it private.
Tailscale mappingtailscale serve status --jsonPrints the private mapping, which must send the root address to port 3505.
app install manifestapps/web/public/manifest.webmanifestOpens the manifest that gives the installed app its name, icon and standalone display.
offline pageapps/web/public/offline.htmlOpens the page shown when the host cannot be reached.
device notificationsweb app: Bot settings › Enable this deviceEnables alerts on this device, once the browser allows notifications.
test notificationweb app: Bot settings › Send testSends a test notification to the selected device, separate from the Bot's switch.
notification diagnostics/api/notifications/diagnostics in the signed-in web appReads the notification queue, its timer and the active sends.
guests
The guest CodeBot and the family CodeBots: second hosts on this machine, each run by its own Linux user.
guestscreen: guests › guestOpens the guest screen: the guest CodeBot, run as its own Linux user.
familyscreen: guests › familyOpens the family screen: the family CodeBots at the home Wi-Fi address.
guests › guest
The guest CodeBot: a second host that runs as the codebot-guest Linux user on port 10000.
guest statussystemctl status codebot-guestPrints whether the guest CodeBot is running.
guest logjournalctl -u codebot-guestPrints the guest CodeBot's log.
guest addresshttps://liel.tail18e69e.ts.net:10000Opens the guest's own web app on port 10000.
set up the guestsudo ops/guest-install.shCreates the guest user, service, settings and sudo rules. Run once.
update the guestops/guest-update.shBuilds the guest copy, replaces /opt/codebot-guest and restarts it. No password needed.
make an invitesudo -u codebot-guest /opt/codebot-guest/invitePrints a one-use Google invite link, valid for ten minutes.
guest program/opt/codebot-guestOpens the packaged copy the guest runs.
guest service unitops/codebot-guest.serviceOpens the systemd unit that runs the guest service.
guests › family
The family CodeBots: one per family Google account, behind a front door at the home Wi-Fi address, up to six.
family statussystemctl status codebot-family-lobby 'codebot-family@*'Prints whether the front door and each family CodeBot are running.
family logsjournalctl -u codebot-family-lobby -u 'codebot-family@*'Prints the logs of the front door and each family CodeBot.
family helper statussudo codebot-family statusPrints each family CodeBot, whether it runs and whether its Gmail can connect.
add a family CodeBotsudo codebot-family add NCreates family CodeBot N, the N-th of up to six slots.
remove a family CodeBotsudo codebot-family remove NDeletes family CodeBot N and frees its number. Its Google account stays linked.
stop or start every family CodeBotsudo codebot-family stop-all, or start-allStops or starts every family CodeBot at once.
set up the familysudo ops/family-install.shSets up the front door user, helper, services, sudo rules and nginx. Run once.
update the familyops/family-update.shBuilds the family program, replaces /opt/codebot-family and restarts every family CodeBot.
family addresshttps://family.codebot.lielbenor.comOpens the family sign-in page at the home Wi-Fi address.
family helper/usr/local/sbin/codebot-familyOpens the root helper that adds, removes and restarts family CodeBots.
family settings/etc/codebot-family.confOpens the settings the family helper reads.
accounts
Google sign-in, Gmail and the central account service that every host shares.
gmailscreen: accounts › gmailOpens the Gmail screen: how Bots reach the owner's Gmail.
sign-in pagehttps://liel.tail18e69e.ts.net/onboardingOpens the sign-in page that new people start from.
account service projectSupabase project wbgrjvqbupgdclaztuouOpens the Supabase project the account service runs in.
deploy host-accessnpx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuouDeploys the host-access function with the Supabase token file. Run again when a contract it parses changes.
account service functionssupabase/functions/Opens the account functions: gmail-relay and host-access.
account service migrationssupabase/migrations/Opens the database migrations for the account service.
control service sourceapps/control/src/Opens the trusted control service that signs host proofs.
account setupnpm run setup-accountRuns the account setup script for this computer (ops/setup-account.ts).
accounts › gmail
Gmail for Bots: the Google app, its settings and the checks behind it.
supervisor guidedocs/automation/gmail.mdOpens the supervisor guide for Gmail for Bots, including the Google sign-in relay.
Gmail referencedocs/automation/gmail-reference.mdOpens the generated reference for Gmail for Bots.
regenerate the Gmail referencenpm run docs:gmailRegenerates the Gmail reference from the code.
review Gmailnpm run review:gmailRuns the Gmail review script (ops/review/gmail-review.mjs).
Google app settings~/.config/codebot/service.env (CODEBOT_GOOGLE_CLIENT_ID, CODEBOT_GOOGLE_CLIENT_SECRET)Opens the Google app settings Gmail sign-in needs. The secret never goes in a VITE_ variable.
data
The host's data folder, its backups, its restores and its resets.
data folder~/.local/share/codebotOpens the owner's data folder, which is kept outside the checkout.
database~/.local/share/codebot/codebot.sqliteOpens the SQLite database that holds Bots, transcripts and state. Do not write to it while the service runs.
backup folder~/.local/share/codebot-backups/Opens the folder where backups are written, with mode 0700.
back upops/OPERATIONS.md › Back up a consistent installationOpens the steps to stop the service and copy its data, config and unit.
restoreops/OPERATIONS.md › Restore into a separate directory firstOpens the steps to restore a backup into a separate directory and check it before promotion.
reset onboardingops/OPERATIONS.md › Reset someone's onboardingOpens the steps to replay the first-use tour or restart onboarding with a fresh CodeBot.
emergency stopops/OPERATIONS.md › Emergency stop and rollbackOpens the steps to stop the service at once and roll back to a retained copy.
recovery holdCODEBOT_RECOVERY_HOLD in ~/.config/codebot/service.envSets the switch that pauses automatic sends and schedules while you inspect the data.
check
The commands that compile, build and test the project, and the workflows that run them.
typechecknpm run typecheckRuns tsc --noEmit: compiles the code and runs no tests.
buildnpm run buildTypechecks, then builds the release into dist/releases and swaps the served link.
testnpm testRuns the Gmail automation tests against a fake Google server. It says little about Bot behavior.
checknpm run checkTypechecks and runs the same tests in one command.
build for QAnpm run build:integrationTypechecks, then builds the integration copy for the QA instance on port 3506.
schedules reviewnpm run review:schedulesRuns the schedules review script (ops/review/schedules-review.mjs).
playgroundnpm run playgroundStarts Vite and opens the Gmail playground page on 127.0.0.1.
regenerate AGENTS.mdnpm run sync:agentsRegenerates AGENTS.md from CLAUDE.md. Edit CLAUDE.md, never AGENTS.md.
service testsapps/service/test/Opens the service tests, including the approved-files and deploy-guard checks.
intents and features.idd/modules/ and .bdd/features/Opens the module intents and the behavior feature files the tests check.
CI workflow.github/workflows/check.ymlOpens the CI workflow that runs the checks.
Supabase keep-alive workflow.github/workflows/supabase-keepalive.ymlOpens the workflow that keeps the Supabase project awake.
docs
The written guides, runbooks, plans and records of the project.
READMEREADME.mdOpens the project overview: what Codebot is and how to run the service.
rulesCLAUDE.mdOpens the rules every task assumes: addresses, screens and deploys.
architectureARCHITECTURE.mdOpens how the system is built: its boundaries, providers and persistence.
product specPRODUCT-SPEC.mdOpens the behavior contract for the product.
operations runbookops/OPERATIONS.mdOpens the full runbook: install, update, recover, notifications and address changes.
open workDEFERRED-WORK.mdOpens the open-work list and the safe restart state.
implementation statusIMPLEMENTATION-STATUS.mdOpens what has been built and where the paused beta stopped.
design methoddocs/design-method.mdOpens the method for designing any screen.
design rulingsdocs/design-taste.mdOpens the owner's design rulings and what they rejected.
plansdocs/plans/Opens the plan documents, one per piece of work.
objectivesdocs/objectives/Opens the objectives for chat, Gmail, schedules and terminal tabs.
verification recordsdocs/verification/Opens the recorded evidence that features were verified.
task recordsdocs/tasks/Opens the task records and the self-hosted session evidence.
onboarding and self-hosting notesdocs/onboarding-*.md, docs/self-hosting-practices.md, docs/host-account-exchange.mdOpens the onboarding notes, recorded proof and self-hosting practices.
design imagesdesign/Opens the design screenshots and annotated references.
housekeeping skillskills/codebot-housekeeping/SKILL.mdOpens the housekeeping skill.
Questions
  • The docs screen has 15 rows. Split it into 'guides' (README, rules, architecture, product spec, runbook, open work, status) and 'records' (design, plans, objectives, verification, tasks, onboarding notes)? Recommendation: yes, so the top-level docs entry stays short.
  • The service screen has 14 rows, three of them source folders. Move the source folders into a new top-level group 'code', so service stays about running the host? Recommendation: yes. That makes eight top groups, still a short list.
  • Confirm the group names you will type: service, devices, guests, accounts, data, check, docs. I used 'check' to match the npm script name, not 'checks'.
  • Keep the family CodeBots on this map? They serve family members rather than the owner, but the owner operates them from this machine. Recommendation: keep them, because the map is for the owner's operations.
  • The README contains a fragment that mentions cli/codebot.py, which is not in the tree. Is that a removed file, a planned one, or a stray line to delete? I left it off the map until you say.
  • Confirm the files I could not see in the listing (PRODUCT-SPEC.md, DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md, ops/deploy.sh, ops/terminal-broker.ts, ops/setup-account.ts, the guest and family scripts). I included them because the docs cite them.
As phone screens

Home

The map of the codebot project: everything its owner can reach, grouped by the job it serves.

serviceOpens the service screen: starting, stopping and checking the host on port 3505.
›
devicesOpens the devices screen: connecting a phone, tablet or desktop to the host, and its notifications.
›
guestsOpens the guests screen: the guest CodeBot and the family CodeBots on this machine.
›
accountsOpens the accounts screen: Google sign-in, Gmail and the central account service.
›
dataOpens the data screen: backing up, restoring and resetting the host's data.
›
checkOpens the check screen: the commands that compile, build and test the project.
›
docsOpens the docs screen: the guides, runbooks, plans and design records.
›
‹ Home

service

The codebot host: the service on port 3505, its unit, its settings, its source and its terminal broker.

run in developmentRuns the service in watch mode in this terminal, restarting on each code change.
›
start in production modeStarts the service in production mode in this terminal.
›
restart the installed serviceRestarts the installed service once active Bots and recordings have finished.
›
stop the installed serviceStops the service, interrupts Bot turns and finishes recordings.
›
force-stop the installed serviceForce-kills the service, which can lose recordings still being written.
›
read the service logPrints the last 80 log lines of the installed service.
›
health checkReads whether the service answers on its port.
›
host diagnosticsShows the host's counters and lifecycle state, with no provider tokens.
›
deploy after a changeBuilds, pushes and restarts the installed service, after waiting for active Bots to finish.
›
private settingsOpens the private settings the service reads at start (mode 0600).
›
example settingsOpens the example settings, with every variable and what it does.
›
service unitOpens the systemd unit that runs the service, installed under ~/.config/systemd/user.
›
terminal brokerOpens the terminal broker screen: the separate per-user process that holds the shell.
›
service sourceOpens the service code: Bots, providers, terminal, avatars and storage.
›
web app sourceOpens the web app code that phones and desktops show.
›
shared schemasOpens the schemas the service and client share, so a bad payload is refused early.
›
‹ service

terminal broker

The terminal broker: a per-user process that holds the owner's shell, separate from the web service. It is off until enabled.

enable and start the brokerEnables and starts the broker, which keeps running when the web service restarts.
›
broker statusPrints whether the broker is running, with its recent output.
›
linger checkPrints whether the broker keeps running without a desktop login.
›
broker unitOpens the systemd unit that runs the broker.
›
broker programOpens the broker program, the process that holds the terminal.
›
‹ Home

devices

How a phone, tablet or desktop reaches this host and gets its notifications.

web app on the private addressOpens the web app on the private Tailscale address.
›
entrance keyPrints the key a new device needs to sign in. Keep it private.
›
Tailscale mappingPrints the private mapping, which must send the root address to port 3505.
›
app install manifestOpens the manifest that gives the installed app its name, icon and standalone display.
›
offline pageOpens the page shown when the host cannot be reached.
›
device notificationsEnables alerts on this device, once the browser allows notifications.
›
test notificationSends a test notification to the selected device, separate from the Bot's switch.
›
notification diagnosticsReads the notification queue, its timer and the active sends.
›
‹ Home

guests

The guest CodeBot and the family CodeBots: second hosts on this machine, each run by its own Linux user.

guestOpens the guest screen: the guest CodeBot, run as its own Linux user.
›
familyOpens the family screen: the family CodeBots at the home Wi-Fi address.
›
‹ guests

guest

The guest CodeBot: a second host that runs as the codebot-guest Linux user on port 10000.

guest statusPrints whether the guest CodeBot is running.
›
guest logPrints the guest CodeBot's log.
›
guest addressOpens the guest's own web app on port 10000.
›
set up the guestCreates the guest user, service, settings and sudo rules. Run once.
›
update the guestBuilds the guest copy, replaces /opt/codebot-guest and restarts it. No password needed.
›
make an invitePrints a one-use Google invite link, valid for ten minutes.
›
guest programOpens the packaged copy the guest runs.
›
guest service unitOpens the systemd unit that runs the guest service.
›
‹ guests

family

The family CodeBots: one per family Google account, behind a front door at the home Wi-Fi address, up to six.

family statusPrints whether the front door and each family CodeBot are running.
›
family logsPrints the logs of the front door and each family CodeBot.
›
family helper statusPrints each family CodeBot, whether it runs and whether its Gmail can connect.
›
add a family CodeBotCreates family CodeBot N, the N-th of up to six slots.
›
remove a family CodeBotDeletes family CodeBot N and frees its number. Its Google account stays linked.
›
stop or start every family CodeBotStops or starts every family CodeBot at once.
›
set up the familySets up the front door user, helper, services, sudo rules and nginx. Run once.
›
update the familyBuilds the family program, replaces /opt/codebot-family and restarts every family CodeBot.
›
family addressOpens the family sign-in page at the home Wi-Fi address.
›
family helperOpens the root helper that adds, removes and restarts family CodeBots.
›
family settingsOpens the settings the family helper reads.
›
‹ Home

accounts

Google sign-in, Gmail and the central account service that every host shares.

gmailOpens the Gmail screen: how Bots reach the owner's Gmail.
›
sign-in pageOpens the sign-in page that new people start from.
›
account service projectOpens the Supabase project the account service runs in.
›
deploy host-accessDeploys the host-access function with the Supabase token file. Run again when a contract it parses changes.
›
account service functionsOpens the account functions: gmail-relay and host-access.
›
account service migrationsOpens the database migrations for the account service.
›
control service sourceOpens the trusted control service that signs host proofs.
›
account setupRuns the account setup script for this computer (ops/setup-account.ts).
›
‹ accounts

gmail

Gmail for Bots: the Google app, its settings and the checks behind it.

supervisor guideOpens the supervisor guide for Gmail for Bots, including the Google sign-in relay.
›
Gmail referenceOpens the generated reference for Gmail for Bots.
›
regenerate the Gmail referenceRegenerates the Gmail reference from the code.
›
review GmailRuns the Gmail review script (ops/review/gmail-review.mjs).
›
Google app settingsOpens the Google app settings Gmail sign-in needs. The secret never goes in a VITE_ variable.
›
‹ Home

data

The host's data folder, its backups, its restores and its resets.

data folderOpens the owner's data folder, which is kept outside the checkout.
›
databaseOpens the SQLite database that holds Bots, transcripts and state. Do not write to it while the service runs.
›
backup folderOpens the folder where backups are written, with mode 0700.
›
back upOpens the steps to stop the service and copy its data, config and unit.
›
restoreOpens the steps to restore a backup into a separate directory and check it before promotion.
›
reset onboardingOpens the steps to replay the first-use tour or restart onboarding with a fresh CodeBot.
›
emergency stopOpens the steps to stop the service at once and roll back to a retained copy.
›
recovery holdSets the switch that pauses automatic sends and schedules while you inspect the data.
›
‹ Home

check

The commands that compile, build and test the project, and the workflows that run them.

typecheckRuns tsc --noEmit: compiles the code and runs no tests.
›
buildTypechecks, then builds the release into dist/releases and swaps the served link.
›
testRuns the Gmail automation tests against a fake Google server. It says little about Bot behavior.
›
checkTypechecks and runs the same tests in one command.
›
build for QATypechecks, then builds the integration copy for the QA instance on port 3506.
›
schedules reviewRuns the schedules review script (ops/review/schedules-review.mjs).
›
playgroundStarts Vite and opens the Gmail playground page on 127.0.0.1.
›
regenerate AGENTS.mdRegenerates AGENTS.md from CLAUDE.md. Edit CLAUDE.md, never AGENTS.md.
›
service testsOpens the service tests, including the approved-files and deploy-guard checks.
›
intents and featuresOpens the module intents and the behavior feature files the tests check.
›
CI workflowOpens the CI workflow that runs the checks.
›
Supabase keep-alive workflowOpens the workflow that keeps the Supabase project awake.
›
‹ Home

docs

The written guides, runbooks, plans and records of the project.

READMEOpens the project overview: what Codebot is and how to run the service.
›
rulesOpens the rules every task assumes: addresses, screens and deploys.
›
architectureOpens how the system is built: its boundaries, providers and persistence.
›
product specOpens the behavior contract for the product.
›
operations runbookOpens the full runbook: install, update, recover, notifications and address changes.
›
open workOpens the open-work list and the safe restart state.
›
implementation statusOpens what has been built and where the paused beta stopped.
›
design methodOpens the method for designing any screen.
›
design rulingsOpens the owner's design rulings and what they rejected.
›
plansOpens the plan documents, one per piece of work.
›
objectivesOpens the objectives for chat, Gmail, schedules and terminal tabs.
›
verification recordsOpens the recorded evidence that features were verified.
›
task recordsOpens the task records and the self-hosted session evidence.
›
onboarding and self-hosting notesOpens the onboarding notes, recorded proof and self-hosting practices.
›
design imagesOpens the design screenshots and annotated references.
›
housekeeping skillOpens the housekeeping skill.
›
Raw answer
The project is a Bot workspace, but the user this map serves is its owner-operator, who runs the service on a workstation and watches Bots from a phone. They need to start, check, deploy, connect a device, back up, or recover without reading the full runbook. The map is organized around those jobs.

Judgment calls:
- **Off the map:** the V2, V3 and V4 experimental apps, which the owner's README says are separate private repos, and `codebot-preview.service`, which the runbook says was transient.
- **Left out for now:** `ops/agent-start.sh`, `ops/review/redirect-google.mjs`, `ops/review/seed-gmail.ts`, `ops/review/terminal-tabs-stack.sh` and `ops/avatar-thumbnails.ts`. The dump doesn't say what they are for, so I didn't guess.
- **Cited but not in the visible listing:** the file tree is truncated, and `PRODUCT-SPEC.md`, `DEFERRED-WORK.md`, `IMPLEMENTATION-STATUS.md`, `ops/deploy.sh`, `ops/terminal-broker.ts` and `ops/setup-account.ts` appear only in the README, the runbook or CLAUDE.md. I included them as referenced, and they need confirming.
- **Shared entries:** the runbook sits under `docs` as a whole and again under `data` for the backup, restore, reset and emergency-stop steps, each worded for its job.
- **Group names:** I used `check` rather than `checks` to match the npm script name.
- **Stray README fragment:** the README mentions `cli/codebot.py`, which isn't in the tree, so it isn't mapped.

```json
{"screens": [
 {"path": [], "sentence": "The map of the codebot project: everything its owner can reach, grouped by the job it serves.", "rows": [
  {"name": "service", "form": "screen: service", "what": "Opens the service screen: starting, stopping and checking the host on port 3505."},
  {"name": "devices", "form": "screen: devices", "what": "Opens the devices screen: connecting a phone, tablet or desktop to the host, and its notifications."},
  {"name": "guests", "form": "screen: guests", "what": "Opens the guests screen: the guest CodeBot and the family CodeBots on this machine."},
  {"name": "accounts", "form": "screen: accounts", "what": "Opens the accounts screen: Google sign-in, Gmail and the central account service."},
  {"name": "data", "form": "screen: data", "what": "Opens the data screen: backing up, restoring and resetting the host's data."},
  {"name": "check", "form": "screen: check", "what": "Opens the check screen: the commands that compile, build and test the project."},
  {"name": "docs", "form": "screen: docs", "what": "Opens the docs screen: the guides, runbooks, plans and design records."}
 ]},
 {"path": ["service"], "sentence": "The codebot host: the service on port 3505, its unit, its settings, its source and its terminal broker.", "rows": [
  {"name": "run in development", "form": "npm run dev", "what": "Runs the service in watch mode in this terminal, restarting on each code change."},
  {"name": "start in production mode", "form": "npm start", "what": "Starts the service in production mode in this terminal."},
  {"name": "restart the installed service", "form": "systemctl --user restart codebot.service", "what": "Restarts the installed service once active Bots and recordings have finished."},
  {"name": "stop the installed service", "form": "systemctl --user stop codebot.service", "what": "Stops the service, interrupts Bot turns and finishes recordings."},
  {"name": "force-stop the installed service", "form": "systemctl --user kill --kill-whom=all --signal=SIGKILL codebot.service", "what": "Force-kills the service, which can lose recordings still being written."},
  {"name": "read the service log", "form": "journalctl --user -u codebot.service -n 80 --no-pager", "what": "Prints the last 80 log lines of the installed service."},
  {"name": "health check", "form": "curl http://127.0.0.1:3505/api/session", "what": "Reads whether the service answers on its port."},
  {"name": "host diagnostics", "form": "/api/diagnostics/host in the signed-in web app", "what": "Shows the host's counters and lifecycle state, with no provider tokens."},
  {"name": "deploy after a change", "form": "sh ops/deploy.sh", "what": "Builds, pushes and restarts the installed service, after waiting for active Bots to finish."},
  {"name": "private settings", "form": "~/.config/codebot/service.env", "what": "Opens the private settings the service reads at start (mode 0600)."},
  {"name": "example settings", "form": "ops/environment.example", "what": "Opens the example settings, with every variable and what it does."},
  {"name": "service unit", "form": "ops/codebot.service", "what": "Opens the systemd unit that runs the service, installed under ~/.config/systemd/user."},
  {"name": "terminal broker", "form": "screen: service › terminal broker", "what": "Opens the terminal broker screen: the separate per-user process that holds the shell."},
  {"name": "service source", "form": "apps/service/src/", "what": "Opens the service code: Bots, providers, terminal, avatars and storage."},
  {"name": "web app source", "form": "apps/web/src/", "what": "Opens the web app code that phones and desktops show."},
  {"name": "shared schemas", "form": "packages/contracts/src/", "what": "Opens the schemas the service and client share, so a bad payload is refused early."}
 ]},
 {"path": ["service", "terminal broker"], "sentence": "The terminal broker: a per-user process that holds the owner's shell, separate from the web service. It is off until enabled.", "rows": [
  {"name": "enable and start the broker", "form": "systemctl --user enable --now codebot-terminal-broker.service", "what": "Enables and starts the broker, which keeps running when the web service restarts."},
  {"name": "broker status", "form": "systemctl --user status codebot-terminal-broker.service --no-pager", "what": "Prints whether the broker is running, with its recent output."},
  {"name": "linger check", "form": "loginctl show-user $USER -p Linger", "what": "Prints whether the broker keeps running without a desktop login."},
  {"name": "broker unit", "form": "ops/codebot-terminal-broker.service", "what": "Opens the systemd unit that runs the broker."},
  {"name": "broker program", "form": "ops/terminal-broker.ts", "what": "Opens the broker program, the process that holds the terminal."}
 ]},
 {"path": ["devices"], "sentence": "How a phone, tablet or desktop reaches this host and gets its notifications.", "rows": [
  {"name": "web app on the private address", "form": "https://liel.tail18e69e.ts.net/", "what": "Opens the web app on the private Tailscale address."},
  {"name": "entrance key", "form": "~/.local/share/codebot/owner-key", "what": "Prints the key a new device needs to sign in. Keep it private."},
  {"name": "Tailscale mapping", "form": "tailscale serve status --json", "what": "Prints the private mapping, which must send the root address to port 3505."},
  {"name": "app install manifest", "form": "apps/web/public/manifest.webmanifest", "what": "Opens the manifest that gives the installed app its name, icon and standalone display."},
  {"name": "offline page", "form": "apps/web/public/offline.html", "what": "Opens the page shown when the host cannot be reached."},
  {"name": "device notifications", "form": "web app: Bot settings › Enable this device", "what": "Enables alerts on this device, once the browser allows notifications."},
  {"name": "test notification", "form": "web app: Bot settings › Send test", "what": "Sends a test notification to the selected device, separate from the Bot's switch."},
  {"name": "notification diagnostics", "form": "/api/notifications/diagnostics in the signed-in web app", "what": "Reads the notification queue, its timer and the active sends."}
 ]},
 {"path": ["guests"], "sentence": "The guest CodeBot and the family CodeBots: second hosts on this machine, each run by its own Linux user.", "rows": [
  {"name": "guest", "form": "screen: guests › guest", "what": "Opens the guest screen: the guest CodeBot, run as its own Linux user."},
  {"name": "family", "form": "screen: guests › family", "what": "Opens the family screen: the family CodeBots at the home Wi-Fi address."}
 ]},
 {"path": ["guests", "guest"], "sentence": "The guest CodeBot: a second host that runs as the codebot-guest Linux user on port 10000.", "rows": [
  {"name": "guest status", "form": "systemctl status codebot-guest", "what": "Prints whether the guest CodeBot is running."},
  {"name": "guest log", "form": "journalctl -u codebot-guest", "what": "Prints the guest CodeBot's log."},
  {"name": "guest address", "form": "https://liel.tail18e69e.ts.net:10000", "what": "Opens the guest's own web app on port 10000."},
  {"name": "set up the guest", "form": "sudo ops/guest-install.sh", "what": "Creates the guest user, service, settings and sudo rules. Run once."},
  {"name": "update the guest", "form": "ops/guest-update.sh", "what": "Builds the guest copy, replaces /opt/codebot-guest and restarts it. No password needed."},
  {"name": "make an invite", "form": "sudo -u codebot-guest /opt/codebot-guest/invite", "what": "Prints a one-use Google invite link, valid for ten minutes."},
  {"name": "guest program", "form": "/opt/codebot-guest", "what": "Opens the packaged copy the guest runs."},
  {"name": "guest service unit", "form": "ops/codebot-guest.service", "what": "Opens the systemd unit that runs the guest service."}
 ]},
 {"path": ["guests", "family"], "sentence": "The family CodeBots: one per family Google account, behind a front door at the home Wi-Fi address, up to six.", "rows": [
  {"name": "family status", "form": "systemctl status codebot-family-lobby 'codebot-family@*'", "what": "Prints whether the front door and each family CodeBot are running."},
  {"name": "family logs", "form": "journalctl -u codebot-family-lobby -u 'codebot-family@*'", "what": "Prints the logs of the front door and each family CodeBot."},
  {"name": "family helper status", "form": "sudo codebot-family status", "what": "Prints each family CodeBot, whether it runs and whether its Gmail can connect."},
  {"name": "add a family CodeBot", "form": "sudo codebot-family add N", "what": "Creates family CodeBot N, the N-th of up to six slots."},
  {"name": "remove a family CodeBot", "form": "sudo codebot-family remove N", "what": "Deletes family CodeBot N and frees its number. Its Google account stays linked."},
  {"name": "stop or start every family CodeBot", "form": "sudo codebot-family stop-all, or start-all", "what": "Stops or starts every family CodeBot at once."},
  {"name": "set up the family", "form": "sudo ops/family-install.sh", "what": "Sets up the front door user, helper, services, sudo rules and nginx. Run once."},
  {"name": "update the family", "form": "ops/family-update.sh", "what": "Builds the family program, replaces /opt/codebot-family and restarts every family CodeBot."},
  {"name": "family address", "form": "https://family.codebot.lielbenor.com", "what": "Opens the family sign-in page at the home Wi-Fi address."},
  {"name": "family helper", "form": "/usr/local/sbin/codebot-family", "what": "Opens the root helper that adds, removes and restarts family CodeBots."},
  {"name": "family settings", "form": "/etc/codebot-family.conf", "what": "Opens the settings the family helper reads."}
 ]},
 {"path": ["accounts"], "sentence": "Google sign-in, Gmail and the central account service that every host shares.", "rows": [
  {"name": "gmail", "form": "screen: accounts › gmail", "what": "Opens the Gmail screen: how Bots reach the owner's Gmail."},
  {"name": "sign-in page", "form": "https://liel.tail18e69e.ts.net/onboarding", "what": "Opens the sign-in page that new people start from."},
  {"name": "account service project", "form": "Supabase project wbgrjvqbupgdclaztuou", "what": "Opens the Supabase project the account service runs in."},
  {"name": "deploy host-access", "form": "npx supabase functions deploy host-access --project-ref wbgrjvqbupgdclaztuou", "what": "Deploys the host-access function with the Supabase token file. Run again when a contract it parses changes."},
  {"name": "account service functions", "form": "supabase/functions/", "what": "Opens the account functions: gmail-relay and host-access."},
  {"name": "account service migrations", "form": "supabase/migrations/", "what": "Opens the database migrations for the account service."},
  {"name": "control service source", "form": "apps/control/src/", "what": "Opens the trusted control service that signs host proofs."},
  {"name": "account setup", "form": "npm run setup-account", "what": "Runs the account setup script for this computer (ops/setup-account.ts)."}
 ]},
 {"path": ["accounts", "gmail"], "sentence": "Gmail for Bots: the Google app, its settings and the checks behind it.", "rows": [
  {"name": "supervisor guide", "form": "docs/automation/gmail.md", "what": "Opens the supervisor guide for Gmail for Bots, including the Google sign-in relay."},
  {"name": "Gmail reference", "form": "docs/automation/gmail-reference.md", "what": "Opens the generated reference for Gmail for Bots."},
  {"name": "regenerate the Gmail reference", "form": "npm run docs:gmail", "what": "Regenerates the Gmail reference from the code."},
  {"name": "review Gmail", "form": "npm run review:gmail", "what": "Runs the Gmail review script (ops/review/gmail-review.mjs)."},
  {"name": "Google app settings", "form": "~/.config/codebot/service.env (CODEBOT_GOOGLE_CLIENT_ID, CODEBOT_GOOGLE_CLIENT_SECRET)", "what": "Opens the Google app settings Gmail sign-in needs. The secret never goes in a VITE_ variable."}
 ]},
 {"path": ["data"], "sentence": "The host's data folder, its backups, its restores and its resets.", "rows": [
  {"name": "data folder", "form": "~/.local/share/codebot", "what": "Opens the owner's data folder, which is kept outside the checkout."},
  {"name": "database", "form": "~/.local/share/codebot/codebot.sqlite", "what": "Opens the SQLite database that holds Bots, transcripts and state. Do not write to it while the service runs."},
  {"name": "backup folder", "form": "~/.local/share/codebot-backups/", "what": "Opens the folder where backups are written, with mode 0700."},
  {"name": "back up", "form": "ops/OPERATIONS.md › Back up a consistent installation", "what": "Opens the steps to stop the service and copy its data, config and unit."},
  {"name": "restore", "form": "ops/OPERATIONS.md › Restore into a separate directory first", "what": "Opens the steps to restore a backup into a separate directory and check it before promotion."},
  {"name": "reset onboarding", "form": "ops/OPERATIONS.md › Reset someone's onboarding", "what": "Opens the steps to replay the first-use tour or restart onboarding with a fresh CodeBot."},
  {"name": "emergency stop", "form": "ops/OPERATIONS.md › Emergency stop and rollback", "what": "Opens the steps to stop the service at once and roll back to a retained copy."},
  {"name": "recovery hold", "form": "CODEBOT_RECOVERY_HOLD in ~/.config/codebot/service.env", "what": "Sets the switch that pauses automatic sends and schedules while you inspect the data."}
 ]},
 {"path": ["check"], "sentence": "The commands that compile, build and test the project, and the workflows that run them.", "rows": [
  {"name": "typecheck", "form": "npm run typecheck", "what": "Runs tsc --noEmit: compiles the code and runs no tests."},
  {"name": "build", "form": "npm run build", "what": "Typechecks, then builds the release into dist/releases and swaps the served link."},
  {"name": "test", "form": "npm test", "what": "Runs the Gmail automation tests against a fake Google server. It says little about Bot behavior."},
  {"name": "check", "form": "npm run check", "what": "Typechecks and runs the same tests in one command."},
  {"name": "build for QA", "form": "npm run build:integration", "what": "Typechecks, then builds the integration copy for the QA instance on port 3506."},
  {"name": "schedules review", "form": "npm run review:schedules", "what": "Runs the schedules review script (ops/review/schedules-review.mjs)."},
  {"name": "playground", "form": "npm run playground", "what": "Starts Vite and opens the Gmail playground page on 127.0.0.1."},
  {"name": "regenerate AGENTS.md", "form": "npm run sync:agents", "what": "Regenerates AGENTS.md from CLAUDE.md. Edit CLAUDE.md, never AGENTS.md."},
  {"name": "service tests", "form": "apps/service/test/", "what": "Opens the service tests, including the approved-files and deploy-guard checks."},
  {"name": "intents and features", "form": ".idd/modules/ and .bdd/features/", "what": "Opens the module intents and the behavior feature files the tests check."},
  {"name": "CI workflow", "form": ".github/workflows/check.yml", "what": "Opens the CI workflow that runs the checks."},
  {"name": "Supabase keep-alive workflow", "form": ".github/workflows/supabase-keepalive.yml", "what": "Opens the workflow that keeps the Supabase project awake."}
 ]},
 {"path": ["docs"], "sentence": "The written guides, runbooks, plans and records of the project.", "rows": [
  {"name": "README", "form": "README.md", "what": "Opens the project overview: what Codebot is and how to run the service."},
  {"name": "rules", "form": "CLAUDE.md", "what": "Opens the rules every task assumes: addresses, screens and deploys."},
  {"name": "architecture", "form": "ARCHITECTURE.md", "what": "Opens how the system is built: its boundaries, providers and persistence."},
  {"name": "product spec", "form": "PRODUCT-SPEC.md", "what": "Opens the behavior contract for the product."},
  {"name": "operations runbook", "form": "ops/OPERATIONS.md", "what": "Opens the full runbook: install, update, recover, notifications and address changes."},
  {"name": "open work", "form": "DEFERRED-WORK.md", "what": "Opens the open-work list and the safe restart state."},
  {"name": "implementation status", "form": "IMPLEMENTATION-STATUS.md", "what": "Opens what has been built and where the paused beta stopped."},
  {"name": "design method", "form": "docs/design-method.md", "what": "Opens the method for designing any screen."},
  {"name": "design rulings", "form": "docs/design-taste.md", "what": "Opens the owner's design rulings and what they rejected."},
  {"name": "plans", "form": "docs/plans/", "what": "Opens the plan documents, one per piece of work."},
  {"name": "objectives", "form": "docs/objectives/", "what": "Opens the objectives for chat, Gmail, schedules and terminal tabs."},
  {"name": "verification records", "form": "docs/verification/", "what": "Opens the recorded evidence that features were verified."},
  {"name": "task records", "form": "docs/tasks/", "what": "Opens the task records and the self-hosted session evidence."},
  {"name": "onboarding and self-hosting notes", "form": "docs/onboarding-*.md, docs/self-hosting-practices.md, docs/host-account-exchange.md", "what": "Opens the onboarding notes, recorded proof and self-hosting practices."},
  {"name": "design images", "form": "design/", "what": "Opens the design screenshots and annotated references."},
  {"name": "housekeeping skill", "form": "skills/codebot-housekeeping/SKILL.md", "what": "Opens the housekeeping skill."}
 ]}
],
"questions": [
 "The docs screen has 15 rows. Split it into 'guides' (README, rules, architecture, product spec, runbook, open work, status) and 'records' (design, plans, objectives, verification, tasks, onboarding notes)? Recommendation: yes, so the top-level docs entry stays short.",
 "The service screen has 14 rows, three of them source folders. Move the source folders into a new top-level group 'code', so service stays about running the host? Recommendation: yes. That makes eight top groups, still a short list.",
 "Confirm the group names you will type: service, devices, guests, accounts, data, check, docs. I used 'check' to match the npm script name, not 'checks'.",
 "Keep the family CodeBots on this map? They serve family members rather than the owner, but the owner operates them from this machine. Recommendation: keep them, because the map is for the owner's operations.",
 "The README contains a fragment that mentions cli/codebot.py, which is not in the tree. Is that a removed file, a planned one, or a stray line to delete? I left it off the map until you say.",
 "Confirm the files I could not see in the listing (PRODUCT-SPEC.md, DEFERRED-WORK.md, IMPLEMENTATION-STATUS.md, ops/deploy.sh, ops/terminal-broker.ts, ops/setup-account.ts, the guest and family scripts). I included them because the docs cite them."
]}
```

workstation (CLI)

The approved map (ground truth)
Agentsworkstation help AgentsWho the agents are, what they know how to do, and how they work as a team.
Browsersworkstation help BrowsersDriving Chrome from a terminal or an agent, and checking pages in it.
Claude Code and Codexworkstation help Claude Code and CodexHow Claude Code, Codex and OpenCode run here: panes, hooks, sessions, limits and settings.
Codeworkstation help CodeThe git and shell setup every repo and terminal on this machine uses.
Dashboardsworkstation help DashboardsPages and screens that show what waits for you, every project, and what the agents are doing.
Decisions and recordsworkstation help Decisions and recordsWhat agents asked you, decided alone and found, and the work queued for them.
Docs and designworkstation help Docs and designThe plans, flows, designs, research and notes behind the work.
Personalworkstation help PersonalYour CVs and the job-search agent.
READMEworkstation help READMEHow this README is laid out, and the dated log of machine-level changes.
Rulesworkstation help RulesWhat every agent must follow, and the global instruction files that point to it.
Utilitiesworkstation help UtilitiesFixes and small services for this Linux machine and its devices.
Windowsworkstation help WindowsSetting up the Windows machine and keeping it in sync.
Agents
Who the agents are, what they know how to do, and how they work as a team.
[Agent records and sandbox](agent-framework/README.md)[agent-framework/](agent-framework/)Check every agent record; question, compare and test agents
[How team members talk](#agent-system)[~/projects/my-skills/coordinated-agentic-session/](~/projects/my-skills/coordinated-agentic-session/)Hand over, ask, report and wait, the same way in Claude and Codex
[Personas](#agent-system)[~/.claude/agents/](~/.claude/agents/)<br>[~/projects/my-skills/agents/](~/projects/my-skills/agents/)Who each agent is: worker, supervisor, admin, researcher, QA agent. Claude Code agents; OpenCode agents and typed records with saved tests
[Playbooks](#agent-system)[docs/playbooks/](docs/playbooks/)What a main session follows, step by step
[Role cards and drafts](docs/roles/drafts-2026-10-23/README.md)[docs/roles/](docs/roles/)The QA agent's role card; proposed stronger role skills, not applied yet
[Skill backups](#where-things-land)[claude/skills/](claude/skills/)Copies of skills; copy in the ones you want installed
[Skills](#agent-system)[~/projects/my-skills/](~/projects/my-skills/)What agents know how to do; linked into Claude Code, Codex and OpenCode
[Team park](claude/team-park/README.md)[claude/team-park/](claude/team-park/)Close team members that ran out of work, and resume them
[Teams](#agent-system)[~/projects/my-skills/spawn-team/](~/projects/my-skills/spawn-team/)Start a worker pair or a research team, always with an admin
Browsers
Driving Chrome from a terminal or an agent, and checking pages in it.
[Behavioral browser smoke QA](#behavioral-browser-smoke-qa)[jev-browser-test/](jev-browser-test/)Run a goal in a browser and check its text and URL assertions
[Browser CLI](#browser-cli)[browser/](browser/)Drive one Chrome window that stays open, from a terminal; record proof of a feature
[Codex browser tools](#ai-assistant-setup)[codex/browser/](codex/browser/)<br>[codex/chrome-bridge/](codex/chrome-bridge/)<br>[codex/playwright-mcp/](codex/playwright-mcp/)Codex driving Chrome directly; repair of its Chrome connection; the retired Playwright server
[Starting Chrome](chrome/README.md)[chrome/](chrome/)The one way Chrome starts here, and why
Claude Code and Codex
How Claude Code, Codex and OpenCode run here: panes, hooks, sessions, limits and settings.
[Changelog pane](claude/mods/changelog-pane/README.md)[claude/mods/changelog-pane/](claude/mods/changelog-pane/)What a session did while you were away; opens by itself after 30 minutes
[Claude Code and Codex settings](#ai-assistant-setup)[claude/settings.json](claude/settings.json)<br>[codex/config.toml](codex/config.toml)Settings deployed to Windows (this machine's stay local)
[Hooks](#where-things-land)[claude/hooks/](claude/hooks/)Checks and records on Claude Code tool calls: no local servers, proof reminders, team activity, machine history
[OpenCode profiles](#shell-and-git-linux)[opencode-profiles/](opencode-profiles/)<br>[zsh.d/opencode-profiles.zsh](zsh.d/opencode-profiles.zsh)Which OpenCode and Claude Code setup `opencode` runs with; `opencode help`
[Review pane](claude/mods/review-pane/README.md)[claude/mods/review-pane/](claude/mods/review-pane/)A file an agent opens for you shows beside the chat, editable as drawn
[Scratchpad playground](#system-wide-changes)[claude/mods/scratchpad-playground/](claude/mods/scratchpad-playground/)A trial pane where questions to you could live instead of the question tool
[Session types](#where-things-land)[claude/session-types/](claude/session-types/)`claude --main`: a main session that records itself; `-c` resumes the last, `-r` picks one
[Team Overview pane](#system-wide-changes)[claude/mods/team-board/](claude/mods/team-board/)The running team, its members and what each one reads or edits, in every session
[Usage guard](claude/usage-guard/README.md)[claude/usage-guard/](claude/usage-guard/)The `claude` command stops foreground use at 80% of the five-hour limit
Code
The git and shell setup every repo and terminal on this machine uses.
[Git config](#shell-and-git-linux)[.gitconfig](.gitconfig)Git identity, LFS, credential helper, and the hooks folder for every repo
[Git hooks and gates](#shell-and-git-linux)[git-hooks/](git-hooks/)Lefthook shims in every repo; the push gate (supervisor approval, nothing to main where pull requests are the policy) and the commit and proof gates
[Shell helpers](#shell-and-git-linux)[zsh.d/](zsh.d/)Docker, Postgres, nginx, VPN, terminal and `fix-*` helpers; a `git checkout` that asks first; paths starting with `-` that work
[The workstation command](#shell-and-git-linux)[workstation-cli/](workstation-cli/)`workstation help` (also `setup`, `ws`): this table; links that open files on a terminal
Dashboards
Pages and screens that show what waits for you, every project, and what the agents are doing.
[Dashboard](dashboard/README.md)[dashboard/](dashboard/)What waits for you, the running team, and everything the agent system holds, on one page
[Dashboard, concepts version](dashboard-concepts/README.md)[dashboard-concepts/](dashboard-concepts/)A second dashboard, one cell per project, to compare with the first
[Projects menu](docs/plans/2026-10-26-workstation-projects/plan.md)[workstation-cli/projects.py](workstation-cli/projects.py)`workstation projects`: every project by org, newest work first, Enter opens its help; `workstation projects timeline` and `workstation <project> timeline`: main sessions on their days
Decisions and records
What agents asked you, decided alone and found, and the work queued for them.
[Answer sync](#agent-system)[~/projects/data/bin/](~/projects/data/bin/)<br>[~/projects/data/systemd/](~/projects/data/systemd/)Pulls and syncs the data repo every 5 minutes
[Archive](#agent-system)[~/archive/](~/archive/)Files moved out of projects, each with where it came from; agents' test evidence
[Cases and decisions](#agent-system)[~/projects/data/](~/projects/data/)Questions to you, calls decided alone, rule proposals, verdicts, troubleshooting notes
[Supervision backlog](#agent-system)[~/projects/betec/workboard/docs/supervision-backlog.md](~/projects/betec/workboard/docs/supervision-backlog.md)Open work on how agents are supervised
[Work items](#agent-system)[docs/items/](docs/items/)Features to build, by how many products proved them: urgent, work, planned
Docs and design
The plans, flows, designs, research and notes behind the work.
[Case studies](#case-studies)[case-studies/](case-studies/)Archived experiments, one folder each
[Design passes](#system-wide-changes)[docs/design/](docs/design/)<br>[docs/design-references/](docs/design-references/)Pitches, mockups and references behind each page's look
[Flows](#system-wide-changes)[docs/flows/](docs/flows/)Flow cards, data models and screens of the agent system's pages, by date
[Functional research](#system-wide-changes)[docs/functional-research/](docs/functional-research/)What leading products do, as features to adopt
[Notes and drafts](#ai-assistant-setup)[claude/skills-shortlist.md](claude/skills-shortlist.md)<br>[claude/communication-framework.md](claude/communication-framework.md)Skills researched on skills.sh (none installed); a communication framework draft, not enforced
[Patch notes](#i-want-to)[docs/changelog/](docs/changelog/)One file per patch of the agent system; the dashboard lists them
[Plans](#system-wide-changes)[docs/plans/](docs/plans/)<br>[docs/superpowers/](docs/superpowers/)Plans written before building, one per change
Personal
Your CVs and the job-search agent.
[CVs](cv/README.md)[cv/](cv/)The CVs, their editable sources, and factual notes
[Hermes](hermes/README.md)[hermes/](hermes/)The Hermes agent install: example settings and the restore runbook (its secrets stay in `~/.hermes`)
README
How this README is laid out, and the dated log of machine-level changes.
[Conventions and gotchas](#conventions-and-gotchas)[README.md](README.md)How new things are added here, and what to watch for
[I want to...](#i-want-to)[README.md](README.md)Find where to go for a task
[Repository map](#repository-map)[README.md](README.md)Every folder and file of this repo, one line each
[System-wide changes](#system-wide-changes)[README.md](README.md)Dated log of machine-level fixes and how things work since
[Where things land](#where-things-land)[README.md](README.md)Where each file here is copied to on the machine
Rules
What every agent must follow, and the global instruction files that point to it.
[Global instructions](#where-things-land)[claude/linux-global/](claude/linux-global/)<br>[claude/windows-global/](claude/windows-global/)<br>[claude/CLAUDE.md](claude/CLAUDE.md)<br>[claude/AGENTS.md](claude/AGENTS.md)Copies of each machine's global `CLAUDE.md` and `AGENTS.md`; the Windows ones are deployed by `init-windows`
[Instruction backups](#ai-assistant-setup)[claude/backups/](claude/backups/)Earlier global instruction sets, to restore by hand
[Rules and policies](#agent-system)[workboard/](workboard/)<br>[zsh.d/rules.zsh](zsh.d/rules.zsh)Every rule and policy agents follow (escalation, git, proof, when to ask), in one list; `rules` prints the ones for a folder, `rules edit` opens the list in VS Code; the user's words and why, kept apart
Utilities
Fixes and small services for this Linux machine and its devices.
[API keys](#system-wide-changes)[zsh.d/api-keys.zsh](zsh.d/api-keys.zsh)<br>[~/.config/api-keys/env](~/.config/api-keys/env)General-use API keys, kept out of Git and exported in every shell; `api-keys-edit` opens them
[Incident records](reference/README.md)[reference/](reference/)Dated machine failures and repairs, so a false diagnosis is not repeated
[Lan Mouse (retired)](lan-mouse/README.md)[lan-mouse/](lan-mouse/)The setup Deskflow replaced on 2026-10-05, kept for rollback and its incident history
[Machine utilities (Linux)](#machine-utilities-linux)[cpu-min-power.sh](cpu-min-power.sh)<br>[cpu-normal-power.sh](cpu-normal-power.sh)<br>[fix_old_monitor_hdmi.sh](fix_old_monitor_hdmi.sh)<br>[linux-internet-recovery.sh](linux-internet-recovery.sh)<br>[recover-tailscale-remote-terminal.sh](recover-tailscale-remote-terminal.sh)<br>[laptop-utilities/](laptop-utilities/)Power, monitor, internet, remote access and lid fixes
[Mouse and keyboard sharing](deskflow/)[deskflow/](deskflow/)Deskflow: the laptop's trackpad and keyboard on Windows, admin prompts included; recovery and privacy checks
[Supabase keepalive](supabase-keepalive/)[supabase-keepalive/](supabase-keepalive/)A daily request to each free Supabase project so it does not pause
Windows
Setting up the Windows machine and keeping it in sync.
[Cloning the work repos](#cloning-the-work-repos)[repos/](repos/)Clone every work repo that is missing locally
[Windows bootstrap](#windows-bootstrap)[init-windows/](init-windows/)Rebuild a Windows dev machine from reviewable lists, and deploy its agent files
[Windows skill sync](skills-sync-windows/README.md)[skills-sync-windows/](skills-sync-windows/)A push to `my-skills` updates the Windows machine's skills through a runner there

Home

AgentsWho the agents are, what they know how to do, and how they work as a team.
›
BrowsersDriving Chrome from a terminal or an agent, and checking pages in it.
›
Claude Code and CodexHow Claude Code, Codex and OpenCode run here: panes, hooks, sessions, limits and settings.
›
CodeThe git and shell setup every repo and terminal on this machine uses.
›
DashboardsPages and screens that show what waits for you, every project, and what the agents are doing.
›
Decisions and recordsWhat agents asked you, decided alone and found, and the work queued for them.
›
Docs and designThe plans, flows, designs, research and notes behind the work.
›
PersonalYour CVs and the job-search agent.
›
READMEHow this README is laid out, and the dated log of machine-level changes.
›
RulesWhat every agent must follow, and the global instruction files that point to it.
›
UtilitiesFixes and small services for this Linux machine and its devices.
›
WindowsSetting up the Windows machine and keeping it in sync.
›
‹ Home

Agents

Who the agents are, what they know how to do, and how they work as a team.

[Agent records and sandbox](agent-framework/README.md)Check every agent record; question, compare and test agents
›
[How team members talk](#agent-system)Hand over, ask, report and wait, the same way in Claude and Codex
›
[Personas](#agent-system)Who each agent is: worker, supervisor, admin, researcher, QA agent. Claude Code agents; OpenCode agents and typed records with saved tests
›
[Playbooks](#agent-system)What a main session follows, step by step
›
[Role cards and drafts](docs/roles/drafts-2026-10-23/README.md)The QA agent's role card; proposed stronger role skills, not applied yet
›
[Skill backups](#where-things-land)Copies of skills; copy in the ones you want installed
›
[Skills](#agent-system)What agents know how to do; linked into Claude Code, Codex and OpenCode
›
[Team park](claude/team-park/README.md)Close team members that ran out of work, and resume them
›
[Teams](#agent-system)Start a worker pair or a research team, always with an admin
›
‹ Home

Browsers

Driving Chrome from a terminal or an agent, and checking pages in it.

[Behavioral browser smoke QA](#behavioral-browser-smoke-qa)Run a goal in a browser and check its text and URL assertions
›
[Browser CLI](#browser-cli)Drive one Chrome window that stays open, from a terminal; record proof of a feature
›
[Codex browser tools](#ai-assistant-setup)Codex driving Chrome directly; repair of its Chrome connection; the retired Playwright server
›
[Starting Chrome](chrome/README.md)The one way Chrome starts here, and why
›
‹ Home

Claude Code and Codex

How Claude Code, Codex and OpenCode run here: panes, hooks, sessions, limits and settings.

[Changelog pane](claude/mods/changelog-pane/README.md)What a session did while you were away; opens by itself after 30 minutes
›
[Claude Code and Codex settings](#ai-assistant-setup)Settings deployed to Windows (this machine's stay local)
›
[Hooks](#where-things-land)Checks and records on Claude Code tool calls: no local servers, proof reminders, team activity, machine history
›
[OpenCode profiles](#shell-and-git-linux)Which OpenCode and Claude Code setup `opencode` runs with; `opencode help`
›
[Review pane](claude/mods/review-pane/README.md)A file an agent opens for you shows beside the chat, editable as drawn
›
[Scratchpad playground](#system-wide-changes)A trial pane where questions to you could live instead of the question tool
›
[Session types](#where-things-land)`claude --main`: a main session that records itself; `-c` resumes the last, `-r` picks one
›
[Team Overview pane](#system-wide-changes)The running team, its members and what each one reads or edits, in every session
›
[Usage guard](claude/usage-guard/README.md)The `claude` command stops foreground use at 80% of the five-hour limit
›
‹ Home

Code

The git and shell setup every repo and terminal on this machine uses.

[Git config](#shell-and-git-linux)Git identity, LFS, credential helper, and the hooks folder for every repo
›
[Git hooks and gates](#shell-and-git-linux)Lefthook shims in every repo; the push gate (supervisor approval, nothing to main where pull requests are the policy) and the commit and proof gates
›
[Shell helpers](#shell-and-git-linux)Docker, Postgres, nginx, VPN, terminal and `fix-*` helpers; a `git checkout` that asks first; paths starting with `-` that work
›
[The workstation command](#shell-and-git-linux)`workstation help` (also `setup`, `ws`): this table; links that open files on a terminal
›
‹ Home

Dashboards

Pages and screens that show what waits for you, every project, and what the agents are doing.

[Dashboard](dashboard/README.md)What waits for you, the running team, and everything the agent system holds, on one page
›
[Dashboard, concepts version](dashboard-concepts/README.md)A second dashboard, one cell per project, to compare with the first
›
[Projects menu](docs/plans/2026-10-26-workstation-projects/plan.md)`workstation projects`: every project by org, newest work first, Enter opens its help; `workstation projects timeline` and `workstation <project> timeline`: main sessions on their days
›
‹ Home

Decisions and records

What agents asked you, decided alone and found, and the work queued for them.

[Answer sync](#agent-system)Pulls and syncs the data repo every 5 minutes
›
[Archive](#agent-system)Files moved out of projects, each with where it came from; agents' test evidence
›
[Cases and decisions](#agent-system)Questions to you, calls decided alone, rule proposals, verdicts, troubleshooting notes
›
[Supervision backlog](#agent-system)Open work on how agents are supervised
›
[Work items](#agent-system)Features to build, by how many products proved them: urgent, work, planned
›
‹ Home

Docs and design

The plans, flows, designs, research and notes behind the work.

[Case studies](#case-studies)Archived experiments, one folder each
›
[Design passes](#system-wide-changes)Pitches, mockups and references behind each page's look
›
[Flows](#system-wide-changes)Flow cards, data models and screens of the agent system's pages, by date
›
[Functional research](#system-wide-changes)What leading products do, as features to adopt
›
[Notes and drafts](#ai-assistant-setup)Skills researched on skills.sh (none installed); a communication framework draft, not enforced
›
[Patch notes](#i-want-to)One file per patch of the agent system; the dashboard lists them
›
[Plans](#system-wide-changes)Plans written before building, one per change
›
‹ Home

Personal

Your CVs and the job-search agent.

[CVs](cv/README.md)The CVs, their editable sources, and factual notes
›
[Hermes](hermes/README.md)The Hermes agent install: example settings and the restore runbook (its secrets stay in `~/.hermes`)
›
‹ Home

README

How this README is laid out, and the dated log of machine-level changes.

[Conventions and gotchas](#conventions-and-gotchas)How new things are added here, and what to watch for
›
[I want to...](#i-want-to)Find where to go for a task
›
[Repository map](#repository-map)Every folder and file of this repo, one line each
›
[System-wide changes](#system-wide-changes)Dated log of machine-level fixes and how things work since
›
[Where things land](#where-things-land)Where each file here is copied to on the machine
›
‹ Home

Rules

What every agent must follow, and the global instruction files that point to it.

[Global instructions](#where-things-land)Copies of each machine's global `CLAUDE.md` and `AGENTS.md`; the Windows ones are deployed by `init-windows`
›
[Instruction backups](#ai-assistant-setup)Earlier global instruction sets, to restore by hand
›
[Rules and policies](#agent-system)Every rule and policy agents follow (escalation, git, proof, when to ask), in one list; `rules` prints the ones for a folder, `rules edit` opens the list in VS Code; the user's words and why, kept apart
›
‹ Home

Utilities

Fixes and small services for this Linux machine and its devices.

[API keys](#system-wide-changes)General-use API keys, kept out of Git and exported in every shell; `api-keys-edit` opens them
›
[Incident records](reference/README.md)Dated machine failures and repairs, so a false diagnosis is not repeated
›
[Lan Mouse (retired)](lan-mouse/README.md)The setup Deskflow replaced on 2026-10-05, kept for rollback and its incident history
›
[Machine utilities (Linux)](#machine-utilities-linux)Power, monitor, internet, remote access and lid fixes
›
[Mouse and keyboard sharing](deskflow/)Deskflow: the laptop's trackpad and keyboard on Windows, admin prompts included; recovery and privacy checks
›
[Supabase keepalive](supabase-keepalive/)A daily request to each free Supabase project so it does not pause
›
‹ Home

Windows

Setting up the Windows machine and keeping it in sync.

[Cloning the work repos](#cloning-the-work-repos)Clone every work repo that is missing locally
›
[Windows bootstrap](#windows-bootstrap)Rebuild a Windows dev machine from reviewable lists, and deploy its agent files
›
[Windows skill sync](skills-sync-windows/README.md)A push to `my-skills` updates the Windows machine's skills through a runner there
›
Show:
No skill
Today's skills
screen-decomposition, first draft
screen-decomposition, final

No skill · run 1 exit=0 seconds=130 · prompt

P1 Recall: 0.686P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.527P5 Short top: 9P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.316
As terminal help
Everything this kit does for its owner, grouped by what it is for. Typed as `workstation`, or its short forms `ws` and `setup`, followed by a noun. Given no noun, this screen.
dashboardscreen: dashboardThe at-a-glance screen: what is waiting for you, and the running team
browserscreen: browserPersistent Chrome automation and proof recording
chromescreen: chromeThe one way to start Chrome on this machine
rulesscreen: rulesThe rules every agent follows
machinescreen: machinePower, network, displays, shared keyboard and mouse, lid, audio, clipboard, git, keys
assistantsscreen: assistantsAgents, skills, sessions, Claude and Codex, OpenCode, Hermes, Jev, reviews
windowsscreen: windowsSet up, check, repair and sync the Windows PC (run on Windows)
cvscreen: cvCV sources, builds and dated versions
referencescreen: referenceIncident records, case studies, plans, recovery notes
dashboard
One screen for the owner. Opens on Waiting; Overview holds the counts and the running team. Desktop only, at 1440 by 900.
Waiting tabhttp://127.0.0.1:8780#waitingDefault tab: cases asked, rule changes proposed, calls agents made alone
Overview tabhttp://127.0.0.1:8780 (Overview tab)Counts of cases and proposed rule changes, and the running team's lanes
Start the serverpython3 ~/projects/workstation/dashboard/server.py [port]Runs the dashboard; nothing starts it for you
Answer a casecomment posted on its GitHub issueSends your answer back to the asking agent
Accept or reject a rule changestatus line in a file under ~/projects/data/global/rule-proposals/Decides a proposed rule change; the data timer commits it
Review a call decided alonereview: line in the case fileMarks it justified, should have asked, or wrong, with a note
Run its checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard199 checks against the real data and a real server
Concepts versionhttp://127.0.0.1:8781 (python3 ~/projects/workstation/dashboard-concepts/server.py)Second layout for comparison; see questions
browser
One Chrome window that stays open between commands, driven by the browser command.
Run stepsbrowser '<json-array-of-steps>' or browser path/to/steps.jsonRuns steps in order on the one persistent page
Statusbrowser statusShows whether the background server is up
Closebrowser closeCloses Chrome and stops the server
Record proofsteps recordStart and recordStopThe only supported way to record a feature
Still imagestep screenshot with a pathA still picture of the page
Installcd browser && npm install && npm linkOnce per machine
Behavioral smoke checkjev-browser-test (see its README)Runs a goal and reports only your text and URL checks
chrome
Chrome is started only through one launcher, so recording can start without a prompt.
Install the launcher~/projects/workstation/chrome/install.shLinks google-chrome and rewrites the menu entry; restart Chrome after
Start Chromegoogle-chromeStarts Chrome with the flags; do not start the real binary by hand
Flagschrome/flagsThe one list of launch flags; edit it only here
Check the running flagpgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'Confirms the running Chrome has the flag
Why it is this waychrome/README.mdExplains the recording flag and its limits
rules
The rules every agent follows. Changed only by you or by an accepted rule proposal.
Print the rulesrules [folder]Prints the rules for everything, or for one folder
Rules sourceworkboard/rules.yamlThe rules themselves
Rule metadataworkboard/rules-meta.yamlDetails kept beside the rules
Generated copy~/.claude/references/rules.mdGenerated from rules.yaml; do not edit by hand
Propose a changedashboard, Accept or reject a rule changeA proposed rule change becomes a rule only when accepted
machine
What keeps this Linux machine working: power, network, displays, the shared keyboard and mouse, lid, audio, clipboard, git, keys and shell helpers.
powerscreen: machine powerPower profiles for the CPU
networkscreen: machine networkInternet and remote-terminal recovery
fixscreen: machine fixRepair helpers for keyboard, mouse, disk, WhatsApp
displayscreen: machine displaySet the external monitor's mode
kvmscreen: machine kvmShared mouse and keyboard with Windows (Deskflow)
lidscreen: machine lidKeep running with the lid closed, or restore the default
audioscreen: machine audioSend Linux audio to the Windows machine
clipboardscreen: machine clipboardClipboard history on Linux and Windows
gitscreen: machine gitCheckout guard, git settings, commit and push gates
keysscreen: machine keysGeneral-use API keys, kept outside git
shellscreen: machine shellSmall terminal helpers
machine › power
CPU power profiles. Intel P-state only; both ask for sudo.
Power savercpu-min-power.shpower-saver profile, turbo off, CPU capped at 8% of max
Balancedcpu-normal-power.shbalanced profile, turbo on, cap back to 100%
machine › network
Recovery for internet and the remote terminal. Both change system networking.
Internet recoverylinux-internet-recovery.shResolver fix, restart NetworkManager, flush DNS, cycle networking; re-runs with sudo
Remote terminal recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, starts the remote-terminal service, checks port 3500; the hostname is hardcoded to this machine
machine › fix
Repair helpers, each a zsh function; their steps are in zsh.d/utils.zsh.
Keyboardfix-keyboardRepairs the keyboard
Mousefix-mouseRepairs the mouse
Diskfix-diskDisk repair helper
WhatsAppfix-whatsappWhatsApp repair helper
machine › display
Sets the mode and refresh rate of the external HDMI or DisplayPort output.
Set the external modefix_old_monitor_hdmi.sh [--output NAME] [--mode 1920x1080] [--rate 59.88] [--quiet]Uses xrandr; picks the first external output if none is given
machine › kvm
Deskflow shares the laptop's trackpad and keyboard with Windows. Lan Mouse is retired and not listed.
Resume sharingresume-kvmStarts Deskflow again and asks GNOME for input capture
Deskflow service~/.config/systemd/user/deskflow.serviceStarts with the graphical session; click Allow on GNOME's prompt or it stops
USB mouse sharingdeskflow-usb-mouse.service (disabled)Off since 2026-10-20; see deskflow/usb-mouse/README.md to turn it back on
Deskflow notesdeskflow/README.mdEveryday use, recovery, and what is not tested
machine › lid
Lid behavior. Both changes apply after a reboot.
Keep running with the lid closedlaptop-utilities/keep-running-with-lid-closed.shWrites a logind drop-in so closing the lid does nothing; keep the laptop ventilated
Restore the defaultlaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in
The closed-lid testreference/incidents/2026-10-01-codebot-lid-closed.mdThe 1 minute 46 second test that passed
machine › audio
Sends all Linux audio to the Windows machine over Tailscale, and restores the speakers on pause.
Startaudio-start (or audio-share on)Makes the Windows machine the default output
Pauseaudio-pause (or audio-share off)Restores the speakers
Statusaudio-share statusShows the current state
Test toneaudio-share tonePlays a test tone
Streamtcp port 4953The raw PCM stream; the Windows ffplay reconnect loop is run by the windows-audio-share agent
machine › clipboard
Clipboard history, Linux side and Windows side.
Install the Linux sideclipstack/install.shSets up the Linux parts
Pickerclipstack/picker.pyPick an item from the history
Background servicesclipstack/units/clipstack-server.service and clipstack-watcher.serviceThe history server and the clipboard watcher
Windows installclipstack/windows/install.ps1Installs the AutoHotkey script clipstack.ahk on Windows
Windows check and removalclipstack/windows/verify.ps1 and uninstall.ps1Checks or removes the Windows side
machine › git
Git safeguards on this machine.
Checkout guardgit checkout (zsh wrapper, zsh.d/git-safety.zsh)Lists the files and asks [y/N] before discarding unstaged changes
Git settings~/.gitconfig (from .gitconfig)Identity, LFS, credential store, hooks path
Commit and push gates~/.git-hooks/ (commit-msg, pre-push)Block commits and pushes to main in marked repos; need lefthook on PATH
Repointing an old clonegit remote set-url origin https://github.com/Lebnor/workstation.gitThe repo was renamed from scripts
machine › keys
General-use API keys. They live outside git.
Edit the keysapi-keys-editOpens ~/.config/api-keys/env
Load the keyszsh.d/api-keys.zshExports the keys in every new shell
machine › shell
Small terminal helpers.
Set the titleset-titleSets the terminal title
Kill a portkillportStops whatever holds a port
assistants
The AI assistants on this machine and how they are set up.
agentsscreen: assistants agentsCheck, list, test and start agents
skillsscreen: assistants skillsGlobal skills and backed-up copies
sessionsscreen: assistants sessionsContinue, resume and park sessions
claudescreen: assistants claudeClaude Code and Codex setup, hooks, plugins, usage guard
opencodescreen: assistants opencodeOpenCode profiles
hermesscreen: assistants hermesThe Hermes agent on this machine
jevscreen: assistants jevAsk Jev to decide between options
reviewsscreen: assistants reviewsReview helper and review and changelog panes
assistants › agents
The agent framework. Agents are typed records; the sandbox page runs them as real sessions.
Check the records~/projects/workstation/agent-framework/agent checkRefuses broken records (exit 1)
List agents~/projects/workstation/agent-framework/agent listAgents, tier, model, number of tests
Sandbox page~/projects/workstation/agent-framework/agent serve, then http://127.0.0.1:8790Pick an agent, change its setup, send a message, check the reaction
Agent record~/projects/my-skills/agents/<id>/agent.yamlThe typed agent; its tests are in evals/
Results and memory~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/Where test results and agent memory are kept
Start a team/spawn-team <team> (Claude) or $spawn-team <team> (Codex)Starts a team from spawn-team/teams/ (worker-pair, research-team)
assistants › skills
Where skills come from and which copies are kept here.
Global skills~/projects/my-skills/<skill>/SKILL.mdThe source; install.sh links it into the agents' skill folders
Backed-up skillsclaude/skills/Copies kept here; copy the ones you want installed
Skill shortlistclaude/skills-shortlist.mdSkills researched on skills.sh
Mentor modeclaude/skills/mentor-mode/scripts/serve_mentor.pyRuns the mentor teaching page
Resume a projectskill resume-project (scripts/resume_project.py)Picks up a project where it stopped
Resume after rebootskill reboot-resumeKeeps work going across a reboot or Claude Code restart
Create a skillskill tank--skill-creatorMakes a new skill
assistants › sessions
Starting, continuing and parking Claude sessions.
Continue the main sessionclaude --main -cContinues the main session (main-sessions.py)
Resume a main sessionclaude --main -rPicks a main session to resume
Session types~/.claude/hooks/session-types.sh (SessionStart hook)Picks the session type at start
Park a teamteam-park (~/.local/bin/team-park)Parks a team; details in claude/team-park/README.md
assistants › claude
Claude Code and Codex on this machine: the command, the rules, the settings, the plugins, and the usage guard.
Start Claudeclaude (~/bin/claude, ahead of ~/.local/bin/claude)The usage-guard wrapper runs first
Usage guard installclaude/usage-guard/install.sh (Linux) or Install-Windows.cmd (Windows)Installs the usage guard
Global rulesclaude/CLAUDE.md (Windows: %USERPROFILE%/.claude/CLAUDE.md)Browser automation, communication, research, presenting work
Settingsclaude/settings.jsonClaude Code settings; the Linux copy stays machine-local
Linux instruction mirrorclaude/linux-global/Copy of the installed Linux instruction files
Hooksclaude/hooks/Core rules, machine history, proof reminder, local server guard, team activity
Pluginsclaude/mods/ (changelog-pane, review-pane, scratchpad-playground, team-board)Plugins with their own hooks
Codex configcodex/config.toml (Windows: %USERPROFILE%/.codex/config.toml)Codex CLI config; multi-agent tools on
Chrome bridgecodex/chrome-bridge/install.sh (Linux) or Install-CodexChromeBridge.cmd (Windows)Keeps the Chrome plugin's latest link and the file: patch in place
Desktop backupclaude/backups/desktop-v2-2026/Portable snapshot; not loaded automatically
assistants › opencode
OpenCode runs with a named profile. Each profile loads its own files.
Runopencode or ocRuns with the current profile
Current profileopencode-profileNames the current profile
All profilesopencode-profilesShows what each profile loads
Switchopencode-switch <name>New runs in every shell use this profile
Sign in Claude Codeopencode-login <profile>Signs a profile's Claude Code in
Filesopencode-filesLists the current profile's files
Edit a fileopencode-edit <file>Opens one of the profile's files
Helpopencode help (also oc help, opencode-help, oc-help)Table of every profile's files and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it
Profile definitionsopencode-profiles/profiles.py and the private profile folder
assistants › hermes
The Hermes agent, installed from source. Its state and secrets stay out of git.
Launcherhermes (~/.local/bin/hermes)Runs Hermes
Manage its Python toolshermes pmInstalls extras such as telegram; not raw pip
State and secrets~/.hermesNot in git; mode-600 credential files
Restorehermes/RESTORE.mdHow to restore it
Example settingshermes/default.config.example.yaml and jobs.config.example.yamlSecret-free examples
Current configurationhermes/README.md (Current configuration)What is configured now, and the laptop must stay awake
assistants › jev
Jev is the decision helper. Its choices are guidance, not proof.
Ask Jevjev '<context>' -c '<question>' option_one,option_two,other_none -jMultiple-choice question; -j uses confidence of 0.85 or more as approval for that decision
Browser smoke checkjev-browser-testRuns a goal in a browser and checks text and URL
Install itjev-browser-test/install.shInstalls at a pinned upstream revision
Its secrets~/.config/jev-browser-test/env (mode 600)Keys for the model; never in git
assistants › reviews
Review helpers and the review and changelog panes.
Open a reviewreview-open (~/.local/bin/review-open)Opens a review; also works from bash and agents
Review paneclaude/mods/review-pane/The review pane plugin; its design is in docs/design/2026-10-18-review-pane
Changelog paneclaude/mods/changelog-pane/The changelog pane plugin
windows
Set up, check, repair and sync the Windows PC. Run these on Windows, not from this Linux shell.
Install the kitinit-windows/Start-Install.cmd (double-click, approve the admin prompt)Rebuilds the dev environment from manifests
Smoke testinit-windows/Smoke-Test-Windows.ps1Checks that the install worked
Verifyinit-windows/Verify-Windows.ps1Second check of the install
Roll backinit-windows/Remove-WindowsPack.ps1Removes what the install added
Capture current stateinit-windows/Export-Windows.ps1Captures the Windows state into the manifests; read its header first
What was captured and sign-ins to redoinit-windows/inventory.md and secrets-checklist.mdInventory, and the sign-ins to do by hand
Repair scripts%USERPROFILE%/Scripts/ (from init-windows/user-scripts/)Touchpad fixes, hibernate, Mongo restore
Clone work reposrepos/Clone-BetecRepos.ps1Clones missing work repos; safe to re-run
Skill syncskills-sync-windows/Sync-Skills.ps1 (runs from the GitHub runner on push to master)Updates the skill links; last success in C:/ProgramData/MySkillsSync/state/last-success.json
Check skill syncskills-sync-windows/Test-Sync.ps1 and Test-Account.ps1Tests the sync and the runner account
Codex Chrome bridgecodex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls the scheduled task that repairs the bridge
Usage guardclaude/usage-guard/Install-Windows.cmdInstalls the Windows usage guard
Clipboardclipstack/windows/install.ps1, verify.ps1, uninstall.ps1Windows clipboard history
Deskflow serviceWindows service, AutomaticWindows side of the shared mouse and keyboard
cv
The three CVs: sources here, PDFs built from them, dated copies in versions/.
Build the full-stack CVpdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex (in cv/)Builds the Full Stack Developer CV
Build the AI full-stack CVpdflatex -interaction=nonstopmode -halt-on-error cv-ai-full-stack.tex (in cv/)Builds the AI Full Stack Engineer CV
Build the AI integrations CVpdflatex -interaction=nonstopmode -halt-on-error cv-ai-integrations.tex (in cv/)Builds the AI Integrations CV
Full textcv/text/build-full.shBuilds the plain-text versions
Design buildcv/design/build-design.pyBuilds the design HTML and PDF
Dated versionscv/versions/2026-10-04/ and cv/versions/2026-10-04-v2/PDF, text and variables for each date
Factual inputcv/experience-notes.md and cv/cv-master.mdSource facts and the readable master
Workflowcv/WORKFLOW.mdHow an update moves through the CVs
reference
Recovery notes, incident records, case studies, plans and the changelog.
Incidentsreference/incidents/Machine failures and verified working states; index in reference/README.md
Case studiescase-studies/conceptual-modeling/2026-09-15-codebot-return/ and case-studies/blume-astryx/2026-09-16-signal-garden/Archived, reviewed experiments
Kernel browser results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdCloud browser tests; lives outside this repo
Plansdocs/plans/<date>-<slug>/plan.mdDated plans
Changelogdocs/changelog/Dated patch notes
Restore runbookshermes/RESTORE.md and init-windows/secrets-checklist.mdHow to recover the machines
Where files landREADME.md#where-things-landWhich repo file is copied to which place on the machine
Questions
  • Source gap: the README describes workstation-cli/workstation.py, workstation-cli/terminal_links.py, zsh.d/workstation.zsh, zsh.d/audio-share.zsh and audio-share/, and none of them is in the dump. The map uses the README's names. Recommendation: send those files so the subcommands, the ws and setup aliases, and the audio command names can be checked before the help is written.
  • Aliases: should the top screen name ws and setup as aliases of workstation, or show only workstation? Recommendation: show workstation as the name and mention ws and setup once, in the top sentence.
  • Windows commands: should they sit in the same tree or on a separate screen? Recommendation: keep the windows screen in the same tree, with each row marked as run on Windows, because a Linux shell cannot run them and people look for them in one place.
  • rules as a top-level noun: agents read it too. Recommendation: keep it top-level, since you run it directly.
  • Dashboard concepts (port 8781): should it appear? Recommendation: no, until the comparison is decided. Keep it as one line under dashboard, not a screen.
  • Credential helpers: git_pull_with_creds (infra.zsh) and update-gitlab-token (utils.zsh) embed a credential in git URLs. Recommendation: keep both out of the help, and rotate the credential first, as init-windows/secrets-checklist.md already advises.
  • Retired items: Lan Mouse, codex/playwright-mcp, the legacy Codex recorders in codex/browser/, and the usage-guard resolutions are left out. Recommendation: keep them out, so the help lists only what is current.
  • Missing detail: the dashboard's third tab name and the Overview tab's link fragment are cut off in the dump, and the arguments for killport and the fix-* helpers are not shown. Recommendation: name the tab Overview, leave out its fragment, and leave out argument lists until the source is supplied.
As phone screens

Home

Everything this kit does for its owner, grouped by what it is for. Typed as `workstation`, or its short forms `ws` and `setup`, followed by a noun. Given no noun, this screen.

dashboardThe at-a-glance screen: what is waiting for you, and the running team
›
browserPersistent Chrome automation and proof recording
›
chromeThe one way to start Chrome on this machine
›
rulesThe rules every agent follows
›
machinePower, network, displays, shared keyboard and mouse, lid, audio, clipboard, git, keys
›
assistantsAgents, skills, sessions, Claude and Codex, OpenCode, Hermes, Jev, reviews
›
windowsSet up, check, repair and sync the Windows PC (run on Windows)
›
cvCV sources, builds and dated versions
›
referenceIncident records, case studies, plans, recovery notes
›
‹ Home

dashboard

One screen for the owner. Opens on Waiting; Overview holds the counts and the running team. Desktop only, at 1440 by 900.

Waiting tabDefault tab: cases asked, rule changes proposed, calls agents made alone
›
Overview tabCounts of cases and proposed rule changes, and the running team's lanes
›
Start the serverRuns the dashboard; nothing starts it for you
›
Answer a caseSends your answer back to the asking agent
›
Accept or reject a rule changeDecides a proposed rule change; the data timer commits it
›
Review a call decided aloneMarks it justified, should have asked, or wrong, with a note
›
Run its checks199 checks against the real data and a real server
›
Concepts versionSecond layout for comparison; see questions
›
‹ Home

browser

One Chrome window that stays open between commands, driven by the browser command.

Run stepsRuns steps in order on the one persistent page
›
StatusShows whether the background server is up
›
CloseCloses Chrome and stops the server
›
Record proofThe only supported way to record a feature
›
Still imageA still picture of the page
›
InstallOnce per machine
›
Behavioral smoke checkRuns a goal and reports only your text and URL checks
›
‹ Home

chrome

Chrome is started only through one launcher, so recording can start without a prompt.

Install the launcherLinks google-chrome and rewrites the menu entry; restart Chrome after
›
Start ChromeStarts Chrome with the flags; do not start the real binary by hand
›
FlagsThe one list of launch flags; edit it only here
›
Check the running flagConfirms the running Chrome has the flag
›
Why it is this wayExplains the recording flag and its limits
›
‹ Home

rules

The rules every agent follows. Changed only by you or by an accepted rule proposal.

Print the rulesPrints the rules for everything, or for one folder
›
Rules sourceThe rules themselves
›
Rule metadataDetails kept beside the rules
›
Generated copyGenerated from rules.yaml; do not edit by hand
›
Propose a changeA proposed rule change becomes a rule only when accepted
›
‹ Home

machine

What keeps this Linux machine working: power, network, displays, the shared keyboard and mouse, lid, audio, clipboard, git, keys and shell helpers.

powerPower profiles for the CPU
›
networkInternet and remote-terminal recovery
›
fixRepair helpers for keyboard, mouse, disk, WhatsApp
›
displaySet the external monitor's mode
›
kvmShared mouse and keyboard with Windows (Deskflow)
›
lidKeep running with the lid closed, or restore the default
›
audioSend Linux audio to the Windows machine
›
clipboardClipboard history on Linux and Windows
›
gitCheckout guard, git settings, commit and push gates
›
keysGeneral-use API keys, kept outside git
›
shellSmall terminal helpers
›
‹ machine

power

CPU power profiles. Intel P-state only; both ask for sudo.

Power saverpower-saver profile, turbo off, CPU capped at 8% of max
›
Balancedbalanced profile, turbo on, cap back to 100%
›
‹ machine

network

Recovery for internet and the remote terminal. Both change system networking.

Internet recoveryResolver fix, restart NetworkManager, flush DNS, cycle networking; re-runs with sudo
›
Remote terminal recoveryRepairs DNS, restarts tailscaled, starts the remote-terminal service, checks port 3500; the hostname is hardcoded to this machine
›
‹ machine

fix

Repair helpers, each a zsh function; their steps are in zsh.d/utils.zsh.

KeyboardRepairs the keyboard
›
MouseRepairs the mouse
›
DiskDisk repair helper
›
WhatsAppWhatsApp repair helper
›
‹ machine

display

Sets the mode and refresh rate of the external HDMI or DisplayPort output.

Set the external modeUses xrandr; picks the first external output if none is given
›
‹ machine

kvm

Deskflow shares the laptop's trackpad and keyboard with Windows. Lan Mouse is retired and not listed.

Resume sharingStarts Deskflow again and asks GNOME for input capture
›
Deskflow serviceStarts with the graphical session; click Allow on GNOME's prompt or it stops
›
USB mouse sharingOff since 2026-10-20; see deskflow/usb-mouse/README.md to turn it back on
›
Deskflow notesEveryday use, recovery, and what is not tested
›
‹ machine

lid

Lid behavior. Both changes apply after a reboot.

Keep running with the lid closedWrites a logind drop-in so closing the lid does nothing; keep the laptop ventilated
›
Restore the defaultRemoves that drop-in
›
The closed-lid testThe 1 minute 46 second test that passed
›
‹ machine

audio

Sends all Linux audio to the Windows machine over Tailscale, and restores the speakers on pause.

StartMakes the Windows machine the default output
›
PauseRestores the speakers
›
StatusShows the current state
›
Test tonePlays a test tone
›
StreamThe raw PCM stream; the Windows ffplay reconnect loop is run by the windows-audio-share agent
›
‹ machine

clipboard

Clipboard history, Linux side and Windows side.

Install the Linux sideSets up the Linux parts
›
PickerPick an item from the history
›
Background servicesThe history server and the clipboard watcher
›
Windows installInstalls the AutoHotkey script clipstack.ahk on Windows
›
Windows check and removalChecks or removes the Windows side
›
‹ machine

git

Git safeguards on this machine.

Checkout guardLists the files and asks [y/N] before discarding unstaged changes
›
Git settingsIdentity, LFS, credential store, hooks path
›
Commit and push gatesBlock commits and pushes to main in marked repos; need lefthook on PATH
›
Repointing an old cloneThe repo was renamed from scripts
›
‹ machine

keys

General-use API keys. They live outside git.

Edit the keysOpens ~/.config/api-keys/env
›
Load the keysExports the keys in every new shell
›
‹ machine

shell

Small terminal helpers.

Set the titleSets the terminal title
›
Kill a portStops whatever holds a port
›
‹ Home

assistants

The AI assistants on this machine and how they are set up.

agentsCheck, list, test and start agents
›
skillsGlobal skills and backed-up copies
›
sessionsContinue, resume and park sessions
›
claudeClaude Code and Codex setup, hooks, plugins, usage guard
›
opencodeOpenCode profiles
›
hermesThe Hermes agent on this machine
›
jevAsk Jev to decide between options
›
reviewsReview helper and review and changelog panes
›
‹ assistants

agents

The agent framework. Agents are typed records; the sandbox page runs them as real sessions.

Check the recordsRefuses broken records (exit 1)
›
List agentsAgents, tier, model, number of tests
›
Sandbox pagePick an agent, change its setup, send a message, check the reaction
›
Agent recordThe typed agent; its tests are in evals/
›
Results and memoryWhere test results and agent memory are kept
›
Start a teamStarts a team from spawn-team/teams/ (worker-pair, research-team)
›
‹ assistants

skills

Where skills come from and which copies are kept here.

Global skillsThe source; install.sh links it into the agents' skill folders
›
Backed-up skillsCopies kept here; copy the ones you want installed
›
Skill shortlistSkills researched on skills.sh
›
Mentor modeRuns the mentor teaching page
›
Resume a projectPicks up a project where it stopped
›
Resume after rebootKeeps work going across a reboot or Claude Code restart
›
Create a skillMakes a new skill
›
‹ assistants

sessions

Starting, continuing and parking Claude sessions.

Continue the main sessionContinues the main session (main-sessions.py)
›
Resume a main sessionPicks a main session to resume
›
Session typesPicks the session type at start
›
Park a teamParks a team; details in claude/team-park/README.md
›
‹ assistants

claude

Claude Code and Codex on this machine: the command, the rules, the settings, the plugins, and the usage guard.

Start ClaudeThe usage-guard wrapper runs first
›
Usage guard installInstalls the usage guard
›
Global rulesBrowser automation, communication, research, presenting work
›
SettingsClaude Code settings; the Linux copy stays machine-local
›
Linux instruction mirrorCopy of the installed Linux instruction files
›
HooksCore rules, machine history, proof reminder, local server guard, team activity
›
PluginsPlugins with their own hooks
›
Codex configCodex CLI config; multi-agent tools on
›
Chrome bridgeKeeps the Chrome plugin's latest link and the file: patch in place
›
Desktop backupPortable snapshot; not loaded automatically
›
‹ assistants

opencode

OpenCode runs with a named profile. Each profile loads its own files.

RunRuns with the current profile
›
Current profileNames the current profile
›
All profilesShows what each profile loads
›
SwitchNew runs in every shell use this profile
›
Sign in Claude CodeSigns a profile's Claude Code in
›
FilesLists the current profile's files
›
Edit a fileOpens one of the profile's files
›
HelpTable of every profile's files and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it
›
Profile definitionsprofiles.py and the private profile folder
›
‹ assistants

hermes

The Hermes agent, installed from source. Its state and secrets stay out of git.

LauncherRuns Hermes
›
Manage its Python toolsInstalls extras such as telegram; not raw pip
›
State and secretsNot in git; mode-600 credential files
›
RestoreHow to restore it
›
Example settingsSecret-free examples
›
Current configurationWhat is configured now, and the laptop must stay awake
›
‹ assistants

jev

Jev is the decision helper. Its choices are guidance, not proof.

Ask JevMultiple-choice question; -j uses confidence of 0.85 or more as approval for that decision
›
Browser smoke checkRuns a goal in a browser and checks text and URL
›
Install itInstalls at a pinned upstream revision
›
Its secretsKeys for the model; never in git
›
‹ assistants

reviews

Review helpers and the review and changelog panes.

Open a reviewOpens a review; also works from bash and agents
›
Review paneThe review pane plugin; its design is in docs/design/2026-10-18-review-pane
›
Changelog paneThe changelog pane plugin
›
‹ Home

windows

Set up, check, repair and sync the Windows PC. Run these on Windows, not from this Linux shell.

Install the kitRebuilds the dev environment from manifests
›
Smoke testChecks that the install worked
›
VerifySecond check of the install
›
Roll backRemoves what the install added
›
Capture current stateCaptures the Windows state into the manifests; read its header first
›
What was captured and sign-ins to redoInventory, and the sign-ins to do by hand
›
Repair scriptsTouchpad fixes, hibernate, Mongo restore
›
Clone work reposClones missing work repos; safe to re-run
›
Skill syncUpdates the skill links; last success in C:/ProgramData/MySkillsSync/state/last-success.json
›
Check skill syncTests the sync and the runner account
›
Codex Chrome bridgeInstalls the scheduled task that repairs the bridge
›
Usage guardInstalls the Windows usage guard
›
ClipboardWindows clipboard history
›
Deskflow serviceWindows side of the shared mouse and keyboard
›
‹ Home

cv

The three CVs: sources here, PDFs built from them, dated copies in versions/.

Build the full-stack CVBuilds the Full Stack Developer CV
›
Build the AI full-stack CVBuilds the AI Full Stack Engineer CV
›
Build the AI integrations CVBuilds the AI Integrations CV
›
Full textBuilds the plain-text versions
›
Design buildBuilds the design HTML and PDF
›
Dated versionsPDF, text and variables for each date
›
Factual inputSource facts and the readable master
›
WorkflowHow an update moves through the CVs
›
‹ Home

reference

Recovery notes, incident records, case studies, plans and the changelog.

IncidentsMachine failures and verified working states; index in reference/README.md
›
Case studiesArchived, reviewed experiments
›
Kernel browser resultsCloud browser tests; lives outside this repo
›
PlansDated plans
›
ChangelogDated patch notes
›
Restore runbooksHow to recover the machines
›
Where files landWhich repo file is copied to which place on the machine
›
Raw answer
The map below is planning only, nothing is built. It is built from the README and the file tree. Several files the README describes are not in the dump: `workstation-cli/`, `zsh.d/workstation.zsh`, `zsh.d/audio-share.zsh`, and `audio-share/`. Their subcommand names come from the README alone, so they should be checked before the help is written. Internal material is left out on purpose: git hook internals, `claude/hooks` scripts, tests, design and research folders, backups, the archive, and `.bdd/` and `.idd/`. Retired tools are left out too. The questions at the end have my recommendations.

```json
{"screens": [
{"path": [], "sentence": "Everything this kit does for its owner, grouped by what it is for. Typed as `workstation`, or its short forms `ws` and `setup`, followed by a noun. Given no noun, this screen.", "rows": [
{"name": "dashboard", "form": "screen: dashboard", "what": "The at-a-glance screen: what is waiting for you, and the running team"},
{"name": "browser", "form": "screen: browser", "what": "Persistent Chrome automation and proof recording"},
{"name": "chrome", "form": "screen: chrome", "what": "The one way to start Chrome on this machine"},
{"name": "rules", "form": "screen: rules", "what": "The rules every agent follows"},
{"name": "machine", "form": "screen: machine", "what": "Power, network, displays, shared keyboard and mouse, lid, audio, clipboard, git, keys"},
{"name": "assistants", "form": "screen: assistants", "what": "Agents, skills, sessions, Claude and Codex, OpenCode, Hermes, Jev, reviews"},
{"name": "windows", "form": "screen: windows", "what": "Set up, check, repair and sync the Windows PC (run on Windows)"},
{"name": "cv", "form": "screen: cv", "what": "CV sources, builds and dated versions"},
{"name": "reference", "form": "screen: reference", "what": "Incident records, case studies, plans, recovery notes"}
]},

{"path": ["dashboard"], "sentence": "One screen for the owner. Opens on Waiting; Overview holds the counts and the running team. Desktop only, at 1440 by 900.", "rows": [
{"name": "Waiting tab", "form": "http://127.0.0.1:8780#waiting", "what": "Default tab: cases asked, rule changes proposed, calls agents made alone"},
{"name": "Overview tab", "form": "http://127.0.0.1:8780 (Overview tab)", "what": "Counts of cases and proposed rule changes, and the running team's lanes"},
{"name": "Start the server", "form": "python3 ~/projects/workstation/dashboard/server.py [port]", "what": "Runs the dashboard; nothing starts it for you"},
{"name": "Answer a case", "form": "comment posted on its GitHub issue", "what": "Sends your answer back to the asking agent"},
{"name": "Accept or reject a rule change", "form": "status line in a file under ~/projects/data/global/rule-proposals/", "what": "Decides a proposed rule change; the data timer commits it"},
{"name": "Review a call decided alone", "form": "review: line in the case file", "what": "Marks it justified, should have asked, or wrong, with a note"},
{"name": "Run its checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "199 checks against the real data and a real server"},
{"name": "Concepts version", "form": "http://127.0.0.1:8781 (python3 ~/projects/workstation/dashboard-concepts/server.py)", "what": "Second layout for comparison; see questions"}
]},

{"path": ["browser"], "sentence": "One Chrome window that stays open between commands, driven by the browser command.", "rows": [
{"name": "Run steps", "form": "browser '<json-array-of-steps>'  or  browser path/to/steps.json", "what": "Runs steps in order on the one persistent page"},
{"name": "Status", "form": "browser status", "what": "Shows whether the background server is up"},
{"name": "Close", "form": "browser close", "what": "Closes Chrome and stops the server"},
{"name": "Record proof", "form": "steps recordStart and recordStop", "what": "The only supported way to record a feature"},
{"name": "Still image", "form": "step screenshot with a path", "what": "A still picture of the page"},
{"name": "Install", "form": "cd browser && npm install && npm link", "what": "Once per machine"},
{"name": "Behavioral smoke check", "form": "jev-browser-test (see its README)", "what": "Runs a goal and reports only your text and URL checks"}
]},

{"path": ["chrome"], "sentence": "Chrome is started only through one launcher, so recording can start without a prompt.", "rows": [
{"name": "Install the launcher", "form": "~/projects/workstation/chrome/install.sh", "what": "Links google-chrome and rewrites the menu entry; restart Chrome after"},
{"name": "Start Chrome", "form": "google-chrome", "what": "Starts Chrome with the flags; do not start the real binary by hand"},
{"name": "Flags", "form": "chrome/flags", "what": "The one list of launch flags; edit it only here"},
{"name": "Check the running flag", "form": "pgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'", "what": "Confirms the running Chrome has the flag"},
{"name": "Why it is this way", "form": "chrome/README.md", "what": "Explains the recording flag and its limits"}
]},

{"path": ["rules"], "sentence": "The rules every agent follows. Changed only by you or by an accepted rule proposal.", "rows": [
{"name": "Print the rules", "form": "rules [folder]", "what": "Prints the rules for everything, or for one folder"},
{"name": "Rules source", "form": "workboard/rules.yaml", "what": "The rules themselves"},
{"name": "Rule metadata", "form": "workboard/rules-meta.yaml", "what": "Details kept beside the rules"},
{"name": "Generated copy", "form": "~/.claude/references/rules.md", "what": "Generated from rules.yaml; do not edit by hand"},
{"name": "Propose a change", "form": "dashboard, Accept or reject a rule change", "what": "A proposed rule change becomes a rule only when accepted"}
]},

{"path": ["machine"], "sentence": "What keeps this Linux machine working: power, network, displays, the shared keyboard and mouse, lid, audio, clipboard, git, keys and shell helpers.", "rows": [
{"name": "power", "form": "screen: machine power", "what": "Power profiles for the CPU"},
{"name": "network", "form": "screen: machine network", "what": "Internet and remote-terminal recovery"},
{"name": "fix", "form": "screen: machine fix", "what": "Repair helpers for keyboard, mouse, disk, WhatsApp"},
{"name": "display", "form": "screen: machine display", "what": "Set the external monitor's mode"},
{"name": "kvm", "form": "screen: machine kvm", "what": "Shared mouse and keyboard with Windows (Deskflow)"},
{"name": "lid", "form": "screen: machine lid", "what": "Keep running with the lid closed, or restore the default"},
{"name": "audio", "form": "screen: machine audio", "what": "Send Linux audio to the Windows machine"},
{"name": "clipboard", "form": "screen: machine clipboard", "what": "Clipboard history on Linux and Windows"},
{"name": "git", "form": "screen: machine git", "what": "Checkout guard, git settings, commit and push gates"},
{"name": "keys", "form": "screen: machine keys", "what": "General-use API keys, kept outside git"},
{"name": "shell", "form": "screen: machine shell", "what": "Small terminal helpers"}
]},

{"path": ["machine", "power"], "sentence": "CPU power profiles. Intel P-state only; both ask for sudo.", "rows": [
{"name": "Power saver", "form": "cpu-min-power.sh", "what": "power-saver profile, turbo off, CPU capped at 8% of max"},
{"name": "Balanced", "form": "cpu-normal-power.sh", "what": "balanced profile, turbo on, cap back to 100%"}
]},

{"path": ["machine", "network"], "sentence": "Recovery for internet and the remote terminal. Both change system networking.", "rows": [
{"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "Resolver fix, restart NetworkManager, flush DNS, cycle networking; re-runs with sudo"},
{"name": "Remote terminal recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, starts the remote-terminal service, checks port 3500; the hostname is hardcoded to this machine"}
]},

{"path": ["machine", "fix"], "sentence": "Repair helpers, each a zsh function; their steps are in zsh.d/utils.zsh.", "rows": [
{"name": "Keyboard", "form": "fix-keyboard", "what": "Repairs the keyboard"},
{"name": "Mouse", "form": "fix-mouse", "what": "Repairs the mouse"},
{"name": "Disk", "form": "fix-disk", "what": "Disk repair helper"},
{"name": "WhatsApp", "form": "fix-whatsapp", "what": "WhatsApp repair helper"}
]},

{"path": ["machine", "display"], "sentence": "Sets the mode and refresh rate of the external HDMI or DisplayPort output.", "rows": [
{"name": "Set the external mode", "form": "fix_old_monitor_hdmi.sh [--output NAME] [--mode 1920x1080] [--rate 59.88] [--quiet]", "what": "Uses xrandr; picks the first external output if none is given"}
]},

{"path": ["machine", "kvm"], "sentence": "Deskflow shares the laptop's trackpad and keyboard with Windows. Lan Mouse is retired and not listed.", "rows": [
{"name": "Resume sharing", "form": "resume-kvm", "what": "Starts Deskflow again and asks GNOME for input capture"},
{"name": "Deskflow service", "form": "~/.config/systemd/user/deskflow.service", "what": "Starts with the graphical session; click Allow on GNOME's prompt or it stops"},
{"name": "USB mouse sharing", "form": "deskflow-usb-mouse.service (disabled)", "what": "Off since 2026-10-20; see deskflow/usb-mouse/README.md to turn it back on"},
{"name": "Deskflow notes", "form": "deskflow/README.md", "what": "Everyday use, recovery, and what is not tested"}
]},

{"path": ["machine", "lid"], "sentence": "Lid behavior. Both changes apply after a reboot.", "rows": [
{"name": "Keep running with the lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind drop-in so closing the lid does nothing; keep the laptop ventilated"},
{"name": "Restore the default", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in"},
{"name": "The closed-lid test", "form": "reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "The 1 minute 46 second test that passed"}
]},

{"path": ["machine", "audio"], "sentence": "Sends all Linux audio to the Windows machine over Tailscale, and restores the speakers on pause.", "rows": [
{"name": "Start", "form": "audio-start  (or audio-share on)", "what": "Makes the Windows machine the default output"},
{"name": "Pause", "form": "audio-pause  (or audio-share off)", "what": "Restores the speakers"},
{"name": "Status", "form": "audio-share status", "what": "Shows the current state"},
{"name": "Test tone", "form": "audio-share tone", "what": "Plays a test tone"},
{"name": "Stream", "form": "tcp port 4953", "what": "The raw PCM stream; the Windows ffplay reconnect loop is run by the windows-audio-share agent"}
]},

{"path": ["machine", "clipboard"], "sentence": "Clipboard history, Linux side and Windows side.", "rows": [
{"name": "Install the Linux side", "form": "clipstack/install.sh", "what": "Sets up the Linux parts"},
{"name": "Picker", "form": "clipstack/picker.py", "what": "Pick an item from the history"},
{"name": "Background services", "form": "clipstack/units/clipstack-server.service and clipstack-watcher.service", "what": "The history server and the clipboard watcher"},
{"name": "Windows install", "form": "clipstack/windows/install.ps1", "what": "Installs the AutoHotkey script clipstack.ahk on Windows"},
{"name": "Windows check and removal", "form": "clipstack/windows/verify.ps1 and uninstall.ps1", "what": "Checks or removes the Windows side"}
]},

{"path": ["machine", "git"], "sentence": "Git safeguards on this machine.", "rows": [
{"name": "Checkout guard", "form": "git checkout (zsh wrapper, zsh.d/git-safety.zsh)", "what": "Lists the files and asks [y/N] before discarding unstaged changes"},
{"name": "Git settings", "form": "~/.gitconfig (from .gitconfig)", "what": "Identity, LFS, credential store, hooks path"},
{"name": "Commit and push gates", "form": "~/.git-hooks/ (commit-msg, pre-push)", "what": "Block commits and pushes to main in marked repos; need lefthook on PATH"},
{"name": "Repointing an old clone", "form": "git remote set-url origin https://github.com/Lebnor/workstation.git", "what": "The repo was renamed from scripts"}
]},

{"path": ["machine", "keys"], "sentence": "General-use API keys. They live outside git.", "rows": [
{"name": "Edit the keys", "form": "api-keys-edit", "what": "Opens ~/.config/api-keys/env"},
{"name": "Load the keys", "form": "zsh.d/api-keys.zsh", "what": "Exports the keys in every new shell"}
]},

{"path": ["machine", "shell"], "sentence": "Small terminal helpers.", "rows": [
{"name": "Set the title", "form": "set-title", "what": "Sets the terminal title"},
{"name": "Kill a port", "form": "killport", "what": "Stops whatever holds a port"}
]},

{"path": ["assistants"], "sentence": "The AI assistants on this machine and how they are set up.", "rows": [
{"name": "agents", "form": "screen: assistants agents", "what": "Check, list, test and start agents"},
{"name": "skills", "form": "screen: assistants skills", "what": "Global skills and backed-up copies"},
{"name": "sessions", "form": "screen: assistants sessions", "what": "Continue, resume and park sessions"},
{"name": "claude", "form": "screen: assistants claude", "what": "Claude Code and Codex setup, hooks, plugins, usage guard"},
{"name": "opencode", "form": "screen: assistants opencode", "what": "OpenCode profiles"},
{"name": "hermes", "form": "screen: assistants hermes", "what": "The Hermes agent on this machine"},
{"name": "jev", "form": "screen: assistants jev", "what": "Ask Jev to decide between options"},
{"name": "reviews", "form": "screen: assistants reviews", "what": "Review helper and review and changelog panes"}
]},

{"path": ["assistants", "agents"], "sentence": "The agent framework. Agents are typed records; the sandbox page runs them as real sessions.", "rows": [
{"name": "Check the records", "form": "~/projects/workstation/agent-framework/agent check", "what": "Refuses broken records (exit 1)"},
{"name": "List agents", "form": "~/projects/workstation/agent-framework/agent list", "what": "Agents, tier, model, number of tests"},
{"name": "Sandbox page", "form": "~/projects/workstation/agent-framework/agent serve, then http://127.0.0.1:8790", "what": "Pick an agent, change its setup, send a message, check the reaction"},
{"name": "Agent record", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "The typed agent; its tests are in evals/"},
{"name": "Results and memory", "form": "~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/", "what": "Where test results and agent memory are kept"},
{"name": "Start a team", "form": "/spawn-team <team> (Claude) or $spawn-team <team> (Codex)", "what": "Starts a team from spawn-team/teams/ (worker-pair, research-team)"}
]},

{"path": ["assistants", "skills"], "sentence": "Where skills come from and which copies are kept here.", "rows": [
{"name": "Global skills", "form": "~/projects/my-skills/<skill>/SKILL.md", "what": "The source; install.sh links it into the agents' skill folders"},
{"name": "Backed-up skills", "form": "claude/skills/", "what": "Copies kept here; copy the ones you want installed"},
{"name": "Skill shortlist", "form": "claude/skills-shortlist.md", "what": "Skills researched on skills.sh"},
{"name": "Mentor mode", "form": "claude/skills/mentor-mode/scripts/serve_mentor.py", "what": "Runs the mentor teaching page"},
{"name": "Resume a project", "form": "skill resume-project (scripts/resume_project.py)", "what": "Picks up a project where it stopped"},
{"name": "Resume after reboot", "form": "skill reboot-resume", "what": "Keeps work going across a reboot or Claude Code restart"},
{"name": "Create a skill", "form": "skill tank--skill-creator", "what": "Makes a new skill"}
]},

{"path": ["assistants", "sessions"], "sentence": "Starting, continuing and parking Claude sessions.", "rows": [
{"name": "Continue the main session", "form": "claude --main -c", "what": "Continues the main session (main-sessions.py)"},
{"name": "Resume a main session", "form": "claude --main -r", "what": "Picks a main session to resume"},
{"name": "Session types", "form": "~/.claude/hooks/session-types.sh (SessionStart hook)", "what": "Picks the session type at start"},
{"name": "Park a team", "form": "team-park (~/.local/bin/team-park)", "what": "Parks a team; details in claude/team-park/README.md"}
]},

{"path": ["assistants", "claude"], "sentence": "Claude Code and Codex on this machine: the command, the rules, the settings, the plugins, and the usage guard.", "rows": [
{"name": "Start Claude", "form": "claude (~/bin/claude, ahead of ~/.local/bin/claude)", "what": "The usage-guard wrapper runs first"},
{"name": "Usage guard install", "form": "claude/usage-guard/install.sh (Linux) or Install-Windows.cmd (Windows)", "what": "Installs the usage guard"},
{"name": "Global rules", "form": "claude/CLAUDE.md (Windows: %USERPROFILE%/.claude/CLAUDE.md)", "what": "Browser automation, communication, research, presenting work"},
{"name": "Settings", "form": "claude/settings.json", "what": "Claude Code settings; the Linux copy stays machine-local"},
{"name": "Linux instruction mirror", "form": "claude/linux-global/", "what": "Copy of the installed Linux instruction files"},
{"name": "Hooks", "form": "claude/hooks/", "what": "Core rules, machine history, proof reminder, local server guard, team activity"},
{"name": "Plugins", "form": "claude/mods/ (changelog-pane, review-pane, scratchpad-playground, team-board)", "what": "Plugins with their own hooks"},
{"name": "Codex config", "form": "codex/config.toml (Windows: %USERPROFILE%/.codex/config.toml)", "what": "Codex CLI config; multi-agent tools on"},
{"name": "Chrome bridge", "form": "codex/chrome-bridge/install.sh (Linux) or Install-CodexChromeBridge.cmd (Windows)", "what": "Keeps the Chrome plugin's latest link and the file: patch in place"},
{"name": "Desktop backup", "form": "claude/backups/desktop-v2-2026/", "what": "Portable snapshot; not loaded automatically"}
]},

{"path": ["assistants", "opencode"], "sentence": "OpenCode runs with a named profile. Each profile loads its own files.", "rows": [
{"name": "Run", "form": "opencode  or  oc", "what": "Runs with the current profile"},
{"name": "Current profile", "form": "opencode-profile", "what": "Names the current profile"},
{"name": "All profiles", "form": "opencode-profiles", "what": "Shows what each profile loads"},
{"name": "Switch", "form": "opencode-switch <name>", "what": "New runs in every shell use this profile"},
{"name": "Sign in Claude Code", "form": "opencode-login <profile>", "what": "Signs a profile's Claude Code in"},
{"name": "Files", "form": "opencode-files", "what": "Lists the current profile's files"},
{"name": "Edit a file", "form": "opencode-edit <file>", "what": "Opens one of the profile's files"},
{"name": "Help", "form": "opencode help  (also oc help, opencode-help, oc-help)", "what": "Table of every profile's files and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it"},
{"name": "Profile definitions", "form": "opencode-profiles/", "what": "profiles.py and the private profile folder"}
]},

{"path": ["assistants", "hermes"], "sentence": "The Hermes agent, installed from source. Its state and secrets stay out of git.", "rows": [
{"name": "Launcher", "form": "hermes  (~/.local/bin/hermes)", "what": "Runs Hermes"},
{"name": "Manage its Python tools", "form": "hermes pm", "what": "Installs extras such as telegram; not raw pip"},
{"name": "State and secrets", "form": "~/.hermes", "what": "Not in git; mode-600 credential files"},
{"name": "Restore", "form": "hermes/RESTORE.md", "what": "How to restore it"},
{"name": "Example settings", "form": "hermes/default.config.example.yaml and jobs.config.example.yaml", "what": "Secret-free examples"},
{"name": "Current configuration", "form": "hermes/README.md (Current configuration)", "what": "What is configured now, and the laptop must stay awake"}
]},

{"path": ["assistants", "jev"], "sentence": "Jev is the decision helper. Its choices are guidance, not proof.", "rows": [
{"name": "Ask Jev", "form": "jev '<context>' -c '<question>' option_one,option_two,other_none -j", "what": "Multiple-choice question; -j uses confidence of 0.85 or more as approval for that decision"},
{"name": "Browser smoke check", "form": "jev-browser-test", "what": "Runs a goal in a browser and checks text and URL"},
{"name": "Install it", "form": "jev-browser-test/install.sh", "what": "Installs at a pinned upstream revision"},
{"name": "Its secrets", "form": "~/.config/jev-browser-test/env (mode 600)", "what": "Keys for the model; never in git"}
]},

{"path": ["assistants", "reviews"], "sentence": "Review helpers and the review and changelog panes.", "rows": [
{"name": "Open a review", "form": "review-open  (~/.local/bin/review-open)", "what": "Opens a review; also works from bash and agents"},
{"name": "Review pane", "form": "claude/mods/review-pane/", "what": "The review pane plugin; its design is in docs/design/2026-10-18-review-pane"},
{"name": "Changelog pane", "form": "claude/mods/changelog-pane/", "what": "The changelog pane plugin"}
]},

{"path": ["windows"], "sentence": "Set up, check, repair and sync the Windows PC. Run these on Windows, not from this Linux shell.", "rows": [
{"name": "Install the kit", "form": "init-windows/Start-Install.cmd (double-click, approve the admin prompt)", "what": "Rebuilds the dev environment from manifests"},
{"name": "Smoke test", "form": "init-windows/Smoke-Test-Windows.ps1", "what": "Checks that the install worked"},
{"name": "Verify", "form": "init-windows/Verify-Windows.ps1", "what": "Second check of the install"},
{"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes what the install added"},
{"name": "Capture current state", "form": "init-windows/Export-Windows.ps1", "what": "Captures the Windows state into the manifests; read its header first"},
{"name": "What was captured and sign-ins to redo", "form": "init-windows/inventory.md and secrets-checklist.md", "what": "Inventory, and the sign-ins to do by hand"},
{"name": "Repair scripts", "form": "%USERPROFILE%/Scripts/ (from init-windows/user-scripts/)", "what": "Touchpad fixes, hibernate, Mongo restore"},
{"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones missing work repos; safe to re-run"},
{"name": "Skill sync", "form": "skills-sync-windows/Sync-Skills.ps1 (runs from the GitHub runner on push to master)", "what": "Updates the skill links; last success in C:/ProgramData/MySkillsSync/state/last-success.json"},
{"name": "Check skill sync", "form": "skills-sync-windows/Test-Sync.ps1 and Test-Account.ps1", "what": "Tests the sync and the runner account"},
{"name": "Codex Chrome bridge", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs the scheduled task that repairs the bridge"},
{"name": "Usage guard", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the Windows usage guard"},
{"name": "Clipboard", "form": "clipstack/windows/install.ps1, verify.ps1, uninstall.ps1", "what": "Windows clipboard history"},
{"name": "Deskflow service", "form": "Windows service, Automatic", "what": "Windows side of the shared mouse and keyboard"}
]},

{"path": ["cv"], "sentence": "The three CVs: sources here, PDFs built from them, dated copies in versions/.", "rows": [
{"name": "Build the full-stack CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex (in cv/)", "what": "Builds the Full Stack Developer CV"},
{"name": "Build the AI full-stack CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-ai-full-stack.tex (in cv/)", "what": "Builds the AI Full Stack Engineer CV"},
{"name": "Build the AI integrations CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-ai-integrations.tex (in cv/)", "what": "Builds the AI Integrations CV"},
{"name": "Full text", "form": "cv/text/build-full.sh", "what": "Builds the plain-text versions"},
{"name": "Design build", "form": "cv/design/build-design.py", "what": "Builds the design HTML and PDF"},
{"name": "Dated versions", "form": "cv/versions/2026-10-04/ and cv/versions/2026-10-04-v2/", "what": "PDF, text and variables for each date"},
{"name": "Factual input", "form": "cv/experience-notes.md and cv/cv-master.md", "what": "Source facts and the readable master"},
{"name": "Workflow", "form": "cv/WORKFLOW.md", "what": "How an update moves through the CVs"}
]},

{"path": ["reference"], "sentence": "Recovery notes, incident records, case studies, plans and the changelog.", "rows": [
{"name": "Incidents", "form": "reference/incidents/", "what": "Machine failures and verified working states; index in reference/README.md"},
{"name": "Case studies", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/ and case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "Archived, reviewed experiments"},
{"name": "Kernel browser results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Cloud browser tests; lives outside this repo"},
{"name": "Plans", "form": "docs/plans/<date>-<slug>/plan.md", "what": "Dated plans"},
{"name": "Changelog", "form": "docs/changelog/", "what": "Dated patch notes"},
{"name": "Restore runbooks", "form": "hermes/RESTORE.md and init-windows/secrets-checklist.md", "what": "How to recover the machines"},
{"name": "Where files land", "form": "README.md#where-things-land", "what": "Which repo file is copied to which place on the machine"}
]}
],
"questions": [
"Source gap: the README describes workstation-cli/workstation.py, workstation-cli/terminal_links.py, zsh.d/workstation.zsh, zsh.d/audio-share.zsh and audio-share/, and none of them is in the dump. The map uses the README's names. Recommendation: send those files so the subcommands, the ws and setup aliases, and the audio command names can be checked before the help is written.",
"Aliases: should the top screen name ws and setup as aliases of workstation, or show only workstation? Recommendation: show workstation as the name and mention ws and setup once, in the top sentence.",
"Windows commands: should they sit in the same tree or on a separate screen? Recommendation: keep the windows screen in the same tree, with each row marked as run on Windows, because a Linux shell cannot run them and people look for them in one place.",
"rules as a top-level noun: agents read it too. Recommendation: keep it top-level, since you run it directly.",
"Dashboard concepts (port 8781): should it appear? Recommendation: no, until the comparison is decided. Keep it as one line under dashboard, not a screen.",
"Credential helpers: git_pull_with_creds (infra.zsh) and update-gitlab-token (utils.zsh) embed a credential in git URLs. Recommendation: keep both out of the help, and rotate the credential first, as init-windows/secrets-checklist.md already advises.",
"Retired items: Lan Mouse, codex/playwright-mcp, the legacy Codex recorders in codex/browser/, and the usage-guard resolutions are left out. Recommendation: keep them out, so the help lists only what is current.",
"Missing detail: the dashboard's third tab name and the Overview tab's link fragment are cut off in the dump, and the arguments for killport and the fix-* helpers are not shown. Recommendation: name the tab Overview, leave out its fragment, and leave out argument lists until the source is supplied."
]}
```

Today's skills · run 1 exit=0 seconds=181 · prompt

P1 Recall: 0.829P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 11P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.372
As terminal help
The workstation: the areas of this machine and its projects, one screen each. Pick one to see what it holds.
shellworkstation shellPrints the shell screen: the helper files in ~/.zsh.d, the git setup, and the commands that open files and keys.
machineworkstation machinePrints the machine screen: the Linux power, display, network and laptop-lid scripts, the repair helpers, and the services that run here.
devicesworkstation devicesPrints the devices screen: the mouse and keyboard shared with the Windows PC, and the audio sent to it.
windowsworkstation windowsPrints the windows screen: the Windows PC's install kit, its skill sync, and its repo cloning script.
claudeworkstation claudePrints the claude screen: Claude Code's global files, its hooks, its usage guard, and its main session.
agentsworkstation agentsPrints the agents screen: the rules, agent records, roles and teams, skills, the Agent Sandbox, Hermes and Codex.
opencodeworkstation opencodePrints the opencode screen: the OpenCode commands for profiles, their help, and their files.
browserworkstation browserPrints the browser screen: the browser command, the Chrome launcher, and the Jev browser check.
dashboardworkstation dashboardPrints the dashboard screen: the two local dashboards, their addresses, and their checks.
clipboardworkstation clipboardPrints the clipboard screen: the clipstack history, its services, and its Windows side.
documentsworkstation documentsPrints the documents screen: CVs, plans, research, designs, case studies, changelog, and incident records.
shell
The shell helpers in ~/.zsh.d, one file per topic, and the git setup that goes with them.
git-safetyzsh.d/git-safety.zshOpens the file that wraps git checkout to list the files and ask before discarding unstaged changes.
infrazsh.d/infra.zshOpens the file with the Docker and Compose shortcuts, Prisma and Postgres helpers, and nginx and VPN commands.
utilszsh.d/utils.zshOpens the file with the terminal helpers, IP aliases, lazy node tools, Android, Java and Bun setup, and the repair helpers.
api-keyszsh.d/api-keys.zshOpens the file that exports the general-use API keys from ~/.config/api-keys/env.
api-keys-editcommand api-keys-editOpens ~/.config/api-keys/env, the general-use API keys file that is never in Git.
review-opencommand review-open (zsh.d/review-open.zsh, ~/.local/bin/review-open)Opens a file for review, from the shell or from an agent.
dash-path-warnzsh.d/dash-path-warn.zshOpens the file behind the dash-path-warn helper; read it to confirm what it warns about.
gitconfig.gitconfigOpens the git settings: author identity, Git LFS, the credential store, and the shared hooks folder.
git-hooksgit-hooks/Opens the Lefthook hooks that run in every repo, including the push and commit gates.
machine
This Linux machine: its power, display, network and laptop-lid scripts, its repair helpers, and its background services.
cpu-min-powercpu-min-power.shRuns the power-saver profile: turbo off, CPU capped at 8 percent of its maximum (Intel only, asks for sudo).
cpu-normal-powercpu-normal-power.shRuns the balanced profile: turbo on, CPU cap back to 100 percent.
hdmi-fixfix_old_monitor_hdmi.shRuns xrandr to set the mode and refresh rate on the external monitor (default 1920x1080 at 59.88).
internet-recoverylinux-internet-recovery.shRuns the network repair: systemd-resolved, DNS, a NetworkManager restart, and a networking cycle.
tailscale-recoveryrecover-tailscale-remote-terminal.shRuns the Tailscale repair: DNS, a tailscaled restart, a wait of up to 30 seconds, then starts the remote terminal and checks port 3500.
lid-keep-runninglaptop-utilities/keep-running-with-lid-closed.shRuns the change so that closing the lid does nothing; it applies after a reboot.
lid-restore-defaultlaptop-utilities/restore-default-lid-behavior.shRuns the removal of that change; it applies after a reboot.
fix-keyboard, fix-mouse, fix-disk, fix-whatsappcommands defined in zsh.d/utils.zshRuns the repair for that part: keyboard, mouse, disk, or WhatsApp.
supabase-keepalivesupabase-keepalive/ (supabase-keepalive.timer)Runs on a timer to keep the Supabase project active.
remote-terminaluser service remote-terminal (defined outside this repo)Runs the remote terminal on port 3500, reached over Tailscale.
devices
The mouse and keyboard shared with the Windows PC over Tailscale, and the audio that goes to it.
deskflow-guidedeskflow/README.mdOpens the guide: everyday use, crossing the screen edges, and recovery.
deskflow-service~/.config/systemd/user/deskflow.serviceRuns the Deskflow server with the graphical session; GNOME asks each start to allow input capture.
resume-kvmcommand resume-kvmStarts Deskflow again and asks GNOME for input capture again after a cancel.
deskflow-linux-config~/.config/Deskflow/Deskflow.conf (from deskflow/linux.conf)Opens the Linux Deskflow settings.
deskflow-windows-configdeskflow/windows.confOpens the Windows Deskflow client settings.
deskflow-network-auditdeskflow/NETWORK-AUDIT.mdOpens the audit of what Deskflow connects to.
deskflow-firewalldeskflow/deskflow-lockdown.nftOpens the firewall rules that lock down Deskflow's network use.
usb-mouse-guidedeskflow/usb-mouse/README.mdOpens the notes on forwarding the Windows USB mouse, which has been off since 2026-10-20.
usb-mouse-servicedeskflow-usb-mouse.service (disabled)Starts forwarding the Windows USB mouse to the laptop when it is enabled again.
lan-mouse-retiredlan-mouse/README.mdOpens the retired Lan Mouse guide; do not run it alongside Deskflow.
audio-startcommand audio-start (also audio-share on)Starts sending all Linux audio to the Windows PC over Tailscale.
audio-pausecommand audio-pause (also audio-share off)Pauses the audio sent to Windows and restores the speakers.
audio-statuscommand audio-share statusPrints whether audio goes to Windows.
audio-tonecommand audio-share tonePlays a test tone to the Windows PC.
windows
The Windows PC: its install kit, the skill sync that keeps its skills current, and the repo cloning script.
installinit-windows/Start-Install.cmdRuns the one-command install: programs, Node, VS Code, Git settings, user scripts, then opens the Chrome sign-in.
install-guideinit-windows/README.mdOpens the install guide and its prerequisites.
smoke-testinit-windows/Smoke-Test-Windows.ps1Runs the smoke test that checks the install.
verifyinit-windows/Verify-Windows.ps1Runs the verification of the installed setup.
rollbackinit-windows/Remove-WindowsPack.ps1Runs the rollback of the install, using the install journal.
exportinit-windows/Export-Windows.ps1Runs the export that captures this PC's setup into the manifests (name-based; read it to confirm).
manifestsinit-windows/manifests/Opens the pinned lists: programs, Node versions, VS Code extensions, and managed files.
inventoryinit-windows/inventory.mdOpens the list of what was captured.
secrets-checklistinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand.
skill-sync-guideskills-sync-windows/README.mdOpens the guide to the Windows skill sync.
sync-nowskills-sync-windows/Sync-Skills.ps1Runs a sync now: fast-forwards the skills checkout and fixes the links.
sync-testskills-sync-windows/Test-Sync.ps1Runs the sync test.
sync-account-checkskills-sync-windows/Test-Account.ps1Runs the check of the sync account (name-based; read it to confirm).
last-syncC:\ProgramData\MySkillsSync\state\last-success.jsonOpens the record of the last successful sync.
sync-runnerservice actions.runner.Lebnor-my-skills.my-skills-liel-windowsRuns the GitHub runner that starts a sync on each push to master.
clone-reposrepos/Clone-BetecRepos.ps1Runs the clone of every missing Betec repo; existing folders are left alone.
claude
Claude Code on this machine: its global files, its hooks, the usage guard that wraps it, and the main session.
global-linux-mirrorclaude/linux-global/Opens the mirror of this machine's global instructions and their four docs.
machine-settings~/.claude/settings.jsonOpens this machine's Claude settings; the file is not in Git.
windows-global-mirrorclaude/windows-global/Opens the mirror of the Windows PC's global instructions and docs.
global-rulesclaude/CLAUDE.mdOpens the global rules deployed to the Windows PC.
agent-notesclaude/AGENTS.mdOpens the shorter global agent notes deployed to the Windows PC.
settings-repoclaude/settings.jsonOpens the Claude settings deployed to the Windows PC.
communication-draftclaude/communication-framework.mdOpens a draft of communication design notes; nothing enforces it yet.
hooksclaude/hooks/Opens the hooks wired into settings.json: core rules, local server guard, machine history, proof reminder, team activity.
session-types-hookclaude/session-types/session-types.shRuns at each session start to set up the session type.
main-sessioncommand claude --mainStarts the main Claude session; -c continues the last one and -r resumes one.
session-type-testsclaude/session-types/tests/run.shRuns the session type tests.
claude-wrappercommand claude (~/bin/claude, from claude/usage-guard/claude)Runs Claude Code through the usage guard, ahead of the native binary.
usage-guard-installclaude/usage-guard/install.shRuns the Linux install of the wrapper and the native Claude Code.
usage-guard-install-windowsclaude/usage-guard/Install-Windows.cmdRuns the Windows install of the usage guard.
usage-guard-guideclaude/usage-guard/README.mdOpens the usage guard guide.
team-parkcommand team-park (~/.local/bin/team-park)Runs team_park.py; its README says what it parks.
pluginsclaude/mods/Opens the four plugins: changelog-pane, review-pane, scratchpad-playground, team-board.
desktop-backupsclaude/backups/Opens the portable snapshots of the Windows desktop's instructions and two skills.
agents
The agent system: the rules every agent follows, agent records and teams, roles and skills, the Agent Sandbox, and the agents' own runtimes.
rulescommand rules [folder] (zsh.d/rules.zsh)Prints the rules that apply to every org; a folder argument prints that folder's rules.
rules-fileworkboard/rules.yaml (metadata in rules-meta.yaml)Opens the rules, changed only by the user or an accepted rule proposal.
rules-reminderdocs/plans/2026-10-24-rules-per-role/reminder/Runs on a timer to remind each role of its rules.
agent-checkcommand agent-framework/agent checkChecks every agent record and refuses the broken ones (exit 1).
agent-listcommand agent-framework/agent listPrints the agents with their tier, model and number of tests.
agent-servecommand agent-framework/agent serveStarts the Agent Sandbox page at http://127.0.0.1:8790.
sandbox-pagehttp://127.0.0.1:8790Opens the Agent Sandbox in a browser, once agent serve is running.
agent-framework-guideagent-framework/README.mdOpens the Agent Sandbox guide: setup, tests, and replies.
agent-framework-intent.idd/modules/agent-framework/INTENT.mdOpens the agent framework's intent and rules.
agent-records~/projects/my-skills/agents/Opens the agent records, one folder per agent with its tests and role skill.
roles~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.mdOpens the role instructions each team member starts from.
teams~/projects/my-skills/spawn-team/teams/Opens the team files, such as worker-pair and research-team.
spawn-teamcommand /spawn-team <team> (Claude) and $spawn-team <team> (Codex)Starts a team of agents from its team file.
skill-backupsclaude/skills/Opens the skill backups kept in this repo.
skill-shortlistclaude/skills-shortlist.mdOpens the skills researched on skills.sh and which ones are installed.
global-skills~/projects/my-skills/Opens the global skills repo, which is linked into the Claude, Codex and OpenCode skill folders.
skill-link~/projects/my-skills/install.shRuns the link step that puts the global skills and agent personas in place.
data-repo~/projects/data/Opens the private data repo: cases, rule proposals, verdicts, and troubleshooting.
data-pull~/projects/data/bin/sync (timer data-pull)Runs every 5 minutes to pull answers into the data repo.
supervision-backlog~/projects/betec/workboard/docs/supervision-backlog.mdOpens the supervision backlog.
hermes-runcommand hermes (~/.local/bin/hermes)Runs the Hermes agent.
hermes-guidehermes/README.mdOpens the Hermes install and configuration notes.
hermes-restorehermes/RESTORE.mdOpens the Hermes restore runbook.
hermes-state~/.hermesOpens Hermes's state and secrets folder; it is never in Git.
codex-configcodex/config.tomlOpens the Codex CLI settings (deployed to Windows; machine-local on Linux).
opencode
OpenCode with a set of files per profile: run it, switch the profile, and see or edit what each one loads.
opencode-runcommand opencode (also oc)Runs OpenCode with the current profile's files.
opencode-profilecommand opencode-profilePrints the name of the current profile.
opencode-profilescommand opencode-profilesPrints what each profile loads.
opencode-switchcommand opencode-switch <name>Switches the profile that every shell's new runs use.
opencode-logincommand opencode-loginSigns a profile's Claude Code in.
opencode-filescommand opencode-filesLists the current profile's files.
opencode-editcommand opencode-edit <file>Opens one of the current profile's files in the editor.
opencode-helpcommand opencode help (also oc help, opencode-help, oc-help)Prints the table of every profile's files, one column per profile; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
profiles-folderopencode-profiles/Opens the profile folder: profiles.py, its tests, and the experimental profile.
profiles-shellzsh.d/opencode-profiles.zshOpens the shell wiring for these commands; ~/.bashrc sources it too.
experimental-profileopencode-profiles/private-leb-experimental/Opens the experimental profile's CLAUDE.md, settings, and opencode.json.
browser
Chrome automation: the browser command that drives one persistent Chrome window, the Chrome launcher, and the Jev browser check.
browser-runcommand browser '<steps>'Runs the listed steps in the one persistent Chrome window, starting the background server if needed.
browser-statuscommand browser statusPrints whether the background server and its Chrome are running.
browser-closecommand browser closeCloses Chrome and stops the background server.
record-startbrowser with a recordStart stepStarts recording the tab as proof of a feature.
record-stopbrowser with a recordStop stepStops the recording.
browser-guidebrowser/README.mdOpens the browser command guide, including recording proof.
chrome-runcommand google-chrome (also google-chrome-stable)Starts Chrome through chrome.sh, with the recording flag.
chrome-launcherchrome/chrome.shOpens the one Chrome launcher, which adds the flags and starts Chrome.
chrome-installchrome/install.shRuns once per machine: links the Chrome commands and menu entry to chrome.sh.
chrome-flagschrome/flagsOpens the one list of Chrome flags.
chrome-guidechrome/README.mdOpens the Chrome guide: why it starts this way and its limits.
codex-bridge-timercodex/chrome-bridge/ (codex-chrome-bridge.timer)Runs on a timer to repair the Codex Chrome plugin link and its local navigation patch.
codex-bridge-installcodex/chrome-bridge/install.shRuns once on Linux: installs the bridge watcher and timer.
codex-browser-notescodex/browser/README.mdOpens the notes on Codex's direct Chrome path and its live checks.
jev-runcommand jev-browser-testRuns a goal in a browser and reports the text and URL it was asked to check.
jev-installjev-browser-test/install.shRuns once: installs the pinned jev-ultrafast checkout and the CLI.
jev-guidejev-browser-test/README.mdOpens the Jev guide: privacy boundary, exit codes, and the shared Chrome profile.
jev-instructionsjev-browser-test/instructions.mdOpens the Jev instructions.
jev-env~/.config/jev-browser-test/envOpens the private keys file for Jev (mode 600).
jev-decidecommand jevAsks Jev to choose one of the options you give, with a confidence score.
dashboard
Two local dashboards on this machine, one to read at a glance and one to compare it with, plus their checks.
dashboard-runcommand python3 ~/projects/workstation/dashboard/server.pyStarts the dashboard at http://127.0.0.1:8780.
dashboard-pagehttp://127.0.0.1:8780Opens the dashboard in a browser, once it is running.
concepts-runcommand python3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts dashboard at http://127.0.0.1:8781.
concepts-pagehttp://127.0.0.1:8781Opens the concepts dashboard in a browser, once it is running.
dashboard-testscommand python3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the 199 dashboard checks against the real data and a real server.
concepts-testscommand python3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the 17 concepts checks against the real data and a real server.
dashboard-guidedashboard/README.mdOpens the dashboard guide: its tabs, what it writes, and hot reload.
dashboard-intent.idd/modules/dashboard/INTENT.mdOpens the dashboard's intent and rules.
concepts-guidedashboard-concepts/README.mdOpens the concepts guide and what differs from the main dashboard.
snapshotdashboard/snapshot.pyRuns the snapshot script; its file says what it captures.
clipboard
The shared clipboard history, clipstack: its picker, its server and watcher as services, and its Windows side.
pickerclipstack/picker.pyRuns the picker to choose an earlier clip.
clipstack-serverclipstack/server.py (service clipstack-server.service)Runs the clipstack server as a user service.
clipstack-watcherclipstack/watcher.py (service clipstack-watcher.service)Runs the watcher as a user service that records what is copied.
clipstack-unitsclipstack/units/Opens the two systemd service files.
clipstack-installclipstack/install.shRuns the Linux install of the clipstack services.
clipstack-windowsclipstack/windows/clipstack.ahkRuns on Windows: the AutoHotkey script that is the Windows side of the history.
clipstack-windows-installclipstack/windows/install.ps1Runs on Windows: installs the Windows side.
clipstack-windows-verifyclipstack/windows/verify.ps1Runs the check of the Windows side.
clipstack-windows-intentclipstack/windows/INTENT.mdOpens the Windows side's intent and its feature file.
clipstack-testsclipstack/test_server.pyOpens the server tests.
documents
The written work: CVs, plans, research, designs, flows, items, case studies, changelog, incident records, and the archive.
cv-foldercv/Opens the CV folder: the sources, the PDFs, and how they are built.
cv-full-stackcv/cv-full-stack.pdfOpens the Full Stack Developer CV.
cv-ai-full-stackcv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
cv-ai-integrationscv/cv-ai-integrations.pdfOpens the AI Integrations CV.
cv-buildpdflatex -interaction=nonstopmode -halt-on-error <name>.tex (in cv/)Rebuilds a CV PDF from its .tex source.
cv-experience-notescv/experience-notes.mdOpens the factual notes every CV draws on.
cv-mastercv/cv-master.mdOpens the readable master CV.
cv-versionscv/versions/Opens the dated CV versions, 2026-10-04 and its v2.
cv-workflowcv/WORKFLOW.mdOpens the CV workflow.
cv-text-buildcv/text/build-full.shRuns the build of the plain-text CVs from the sources.
plansdocs/plans/Opens the dated plans, one folder each.
researchdocs/research/Opens the dated research folders, phase checks included.
functional-researchdocs/functional-research/Opens the functional research on agent frameworks and tools.
designsdocs/design/Opens the design pitches and recommendations, the dashboard and agent sandbox among them.
flowsdocs/flows/Opens the flow cards and data models.
itemsdocs/items/Opens the planned, urgent and work item lists.
changelogdocs/changelog/Opens the dated changelog entries.
playbookdocs/playbooks/talk-while-team-builds.mdOpens the playbook for talking while a team builds.
case-studiescase-studies/Opens the archived, reviewed experiments: the CodeBot return and Signal Garden.
incidentsreference/incidents/Opens the dated incident records, starting with the closed-lid CodeBot test.
ai-lab-results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the Kernel cloud browser results, tested 2026-10-08.
workstation-readmeREADME.mdOpens the main guide: where things land, conventions, and the system-wide changes log.
archive~/archive/Opens the archive of files moved out of projects; it is not backed up.
copy-screenshotscopy/Opens the three dashboard screenshots kept for copy.
Questions
  • The file list does not contain workstation-cli/ (workstation.py, terminal_links.py), zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, or init-windows/Start-Install.cmd, though the READMEs describe them. Are they untracked, elsewhere, or not yet written? Recommendation: confirm before building, because the facade's own file decides how the help is wired.
  • Several rows are named from the file name or a README only: dash-path-warn, machine-history.sh, session-types.sh, team_park.py, picker.py, watcher.py, clipstack server.py, snapshot.py, Export-Windows.ps1, Test-Account.ps1, and rules-reminder. Recommendation: paste the first lines of each so the what column says what the file does, not what its name suggests.
  • The agents screen (about 30 rows) and the documents screen (about 24 rows) are long. Recommendation: split documents into a documents cv screen and keep the rest flat, and split agents into an agents skills screen (skill backups, global skills, roles, teams) and the agents screen (rules, records, sandbox, data, runtimes). Your call: yes or no, and which split.
  • The alias setup is generic and easy to clash with other tools. Recommendation: keep workstation and ws, and drop setup unless whence -a setup shows nothing else on PATH. Do you want setup kept?
  • The infra.zsh and utils.zsh files embed a token in git URLs (a known issue in the README). Recommendation: the shell screen marks those two rows with a warning that the file holds a token to rotate, so the map does not hide it. Do you want that marking?
  • The README says opencode-profile names the profile. Recommendation: treat it as printing the current name, not setting it, and check the file before the row goes live. Is that the intent, or does it also set the profile?
As phone screens

Home

The workstation: the areas of this machine and its projects, one screen each. Pick one to see what it holds.

shellPrints the shell screen: the helper files in ~/.zsh.d, the git setup, and the commands that open files and keys.
›
machinePrints the machine screen: the Linux power, display, network and laptop-lid scripts, the repair helpers, and the services that run here.
›
devicesPrints the devices screen: the mouse and keyboard shared with the Windows PC, and the audio sent to it.
›
windowsPrints the windows screen: the Windows PC's install kit, its skill sync, and its repo cloning script.
›
claudePrints the claude screen: Claude Code's global files, its hooks, its usage guard, and its main session.
›
agentsPrints the agents screen: the rules, agent records, roles and teams, skills, the Agent Sandbox, Hermes and Codex.
›
opencodePrints the opencode screen: the OpenCode commands for profiles, their help, and their files.
›
browserPrints the browser screen: the browser command, the Chrome launcher, and the Jev browser check.
›
dashboardPrints the dashboard screen: the two local dashboards, their addresses, and their checks.
›
clipboardPrints the clipboard screen: the clipstack history, its services, and its Windows side.
›
documentsPrints the documents screen: CVs, plans, research, designs, case studies, changelog, and incident records.
›
‹ Home

shell

The shell helpers in ~/.zsh.d, one file per topic, and the git setup that goes with them.

git-safetyOpens the file that wraps git checkout to list the files and ask before discarding unstaged changes.
›
infraOpens the file with the Docker and Compose shortcuts, Prisma and Postgres helpers, and nginx and VPN commands.
›
utilsOpens the file with the terminal helpers, IP aliases, lazy node tools, Android, Java and Bun setup, and the repair helpers.
›
api-keysOpens the file that exports the general-use API keys from ~/.config/api-keys/env.
›
api-keys-editOpens ~/.config/api-keys/env, the general-use API keys file that is never in Git.
›
review-openOpens a file for review, from the shell or from an agent.
›
dash-path-warnOpens the file behind the dash-path-warn helper; read it to confirm what it warns about.
›
gitconfigOpens the git settings: author identity, Git LFS, the credential store, and the shared hooks folder.
›
git-hooksOpens the Lefthook hooks that run in every repo, including the push and commit gates.
›
‹ Home

machine

This Linux machine: its power, display, network and laptop-lid scripts, its repair helpers, and its background services.

cpu-min-powerRuns the power-saver profile: turbo off, CPU capped at 8 percent of its maximum (Intel only, asks for sudo).
›
cpu-normal-powerRuns the balanced profile: turbo on, CPU cap back to 100 percent.
›
hdmi-fixRuns xrandr to set the mode and refresh rate on the external monitor (default 1920x1080 at 59.88).
›
internet-recoveryRuns the network repair: systemd-resolved, DNS, a NetworkManager restart, and a networking cycle.
›
tailscale-recoveryRuns the Tailscale repair: DNS, a tailscaled restart, a wait of up to 30 seconds, then starts the remote terminal and checks port 3500.
›
lid-keep-runningRuns the change so that closing the lid does nothing; it applies after a reboot.
›
lid-restore-defaultRuns the removal of that change; it applies after a reboot.
›
fix-keyboard, fix-mouse, fix-disk, fix-whatsappRuns the repair for that part: keyboard, mouse, disk, or WhatsApp.
›
supabase-keepaliveRuns on a timer to keep the Supabase project active.
›
remote-terminalRuns the remote terminal on port 3500, reached over Tailscale.
›
‹ Home

devices

The mouse and keyboard shared with the Windows PC over Tailscale, and the audio that goes to it.

deskflow-guideOpens the guide: everyday use, crossing the screen edges, and recovery.
›
deskflow-serviceRuns the Deskflow server with the graphical session; GNOME asks each start to allow input capture.
›
resume-kvmStarts Deskflow again and asks GNOME for input capture again after a cancel.
›
deskflow-linux-configOpens the Linux Deskflow settings.
›
deskflow-windows-configOpens the Windows Deskflow client settings.
›
deskflow-network-auditOpens the audit of what Deskflow connects to.
›
deskflow-firewallOpens the firewall rules that lock down Deskflow's network use.
›
usb-mouse-guideOpens the notes on forwarding the Windows USB mouse, which has been off since 2026-10-20.
›
usb-mouse-serviceStarts forwarding the Windows USB mouse to the laptop when it is enabled again.
›
lan-mouse-retiredOpens the retired Lan Mouse guide; do not run it alongside Deskflow.
›
audio-startStarts sending all Linux audio to the Windows PC over Tailscale.
›
audio-pausePauses the audio sent to Windows and restores the speakers.
›
audio-statusPrints whether audio goes to Windows.
›
audio-tonePlays a test tone to the Windows PC.
›
‹ Home

windows

The Windows PC: its install kit, the skill sync that keeps its skills current, and the repo cloning script.

installRuns the one-command install: programs, Node, VS Code, Git settings, user scripts, then opens the Chrome sign-in.
›
install-guideOpens the install guide and its prerequisites.
›
smoke-testRuns the smoke test that checks the install.
›
verifyRuns the verification of the installed setup.
›
rollbackRuns the rollback of the install, using the install journal.
›
exportRuns the export that captures this PC's setup into the manifests (name-based; read it to confirm).
›
manifestsOpens the pinned lists: programs, Node versions, VS Code extensions, and managed files.
›
inventoryOpens the list of what was captured.
›
secrets-checklistOpens the sign-ins to redo by hand.
›
skill-sync-guideOpens the guide to the Windows skill sync.
›
sync-nowRuns a sync now: fast-forwards the skills checkout and fixes the links.
›
sync-testRuns the sync test.
›
sync-account-checkRuns the check of the sync account (name-based; read it to confirm).
›
last-syncOpens the record of the last successful sync.
›
sync-runnerRuns the GitHub runner that starts a sync on each push to master.
›
clone-reposRuns the clone of every missing Betec repo; existing folders are left alone.
›
‹ Home

claude

Claude Code on this machine: its global files, its hooks, the usage guard that wraps it, and the main session.

global-linux-mirrorOpens the mirror of this machine's global instructions and their four docs.
›
machine-settingsOpens this machine's Claude settings; the file is not in Git.
›
windows-global-mirrorOpens the mirror of the Windows PC's global instructions and docs.
›
global-rulesOpens the global rules deployed to the Windows PC.
›
agent-notesOpens the shorter global agent notes deployed to the Windows PC.
›
settings-repoOpens the Claude settings deployed to the Windows PC.
›
communication-draftOpens a draft of communication design notes; nothing enforces it yet.
›
hooksOpens the hooks wired into settings.json: core rules, local server guard, machine history, proof reminder, team activity.
›
session-types-hookRuns at each session start to set up the session type.
›
main-sessionStarts the main Claude session; -c continues the last one and -r resumes one.
›
session-type-testsRuns the session type tests.
›
claude-wrapperRuns Claude Code through the usage guard, ahead of the native binary.
›
usage-guard-installRuns the Linux install of the wrapper and the native Claude Code.
›
usage-guard-install-windowsRuns the Windows install of the usage guard.
›
usage-guard-guideOpens the usage guard guide.
›
team-parkRuns team_park.py; its README says what it parks.
›
pluginsOpens the four plugins: changelog-pane, review-pane, scratchpad-playground, team-board.
›
desktop-backupsOpens the portable snapshots of the Windows desktop's instructions and two skills.
›
‹ Home

agents

The agent system: the rules every agent follows, agent records and teams, roles and skills, the Agent Sandbox, and the agents' own runtimes.

rulesPrints the rules that apply to every org; a folder argument prints that folder's rules.
›
rules-fileOpens the rules, changed only by the user or an accepted rule proposal.
›
rules-reminderRuns on a timer to remind each role of its rules.
›
agent-checkChecks every agent record and refuses the broken ones (exit 1).
›
agent-listPrints the agents with their tier, model and number of tests.
›
agent-serveStarts the Agent Sandbox page at http://127.0.0.1:8790.
›
sandbox-pageOpens the Agent Sandbox in a browser, once agent serve is running.
›
agent-framework-guideOpens the Agent Sandbox guide: setup, tests, and replies.
›
agent-framework-intentOpens the agent framework's intent and rules.
›
agent-recordsOpens the agent records, one folder per agent with its tests and role skill.
›
rolesOpens the role instructions each team member starts from.
›
teamsOpens the team files, such as worker-pair and research-team.
›
spawn-teamStarts a team of agents from its team file.
›
skill-backupsOpens the skill backups kept in this repo.
›
skill-shortlistOpens the skills researched on skills.sh and which ones are installed.
›
global-skillsOpens the global skills repo, which is linked into the Claude, Codex and OpenCode skill folders.
›
skill-linkRuns the link step that puts the global skills and agent personas in place.
›
data-repoOpens the private data repo: cases, rule proposals, verdicts, and troubleshooting.
›
data-pullRuns every 5 minutes to pull answers into the data repo.
›
supervision-backlogOpens the supervision backlog.
›
hermes-runRuns the Hermes agent.
›
hermes-guideOpens the Hermes install and configuration notes.
›
hermes-restoreOpens the Hermes restore runbook.
›
hermes-stateOpens Hermes's state and secrets folder; it is never in Git.
›
codex-configOpens the Codex CLI settings (deployed to Windows; machine-local on Linux).
›
‹ Home

opencode

OpenCode with a set of files per profile: run it, switch the profile, and see or edit what each one loads.

opencode-runRuns OpenCode with the current profile's files.
›
opencode-profilePrints the name of the current profile.
›
opencode-profilesPrints what each profile loads.
›
opencode-switchSwitches the profile that every shell's new runs use.
›
opencode-loginSigns a profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editOpens one of the current profile's files in the editor.
›
opencode-helpPrints the table of every profile's files, one column per profile; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
›
profiles-folderOpens the profile folder: profiles.py, its tests, and the experimental profile.
›
profiles-shellOpens the shell wiring for these commands; ~/.bashrc sources it too.
›
experimental-profileOpens the experimental profile's CLAUDE.md, settings, and opencode.json.
›
‹ Home

browser

Chrome automation: the browser command that drives one persistent Chrome window, the Chrome launcher, and the Jev browser check.

browser-runRuns the listed steps in the one persistent Chrome window, starting the background server if needed.
›
browser-statusPrints whether the background server and its Chrome are running.
›
browser-closeCloses Chrome and stops the background server.
›
record-startStarts recording the tab as proof of a feature.
›
record-stopStops the recording.
›
browser-guideOpens the browser command guide, including recording proof.
›
chrome-runStarts Chrome through chrome.sh, with the recording flag.
›
chrome-launcherOpens the one Chrome launcher, which adds the flags and starts Chrome.
›
chrome-installRuns once per machine: links the Chrome commands and menu entry to chrome.sh.
›
chrome-flagsOpens the one list of Chrome flags.
›
chrome-guideOpens the Chrome guide: why it starts this way and its limits.
›
codex-bridge-timerRuns on a timer to repair the Codex Chrome plugin link and its local navigation patch.
›
codex-bridge-installRuns once on Linux: installs the bridge watcher and timer.
›
codex-browser-notesOpens the notes on Codex's direct Chrome path and its live checks.
›
jev-runRuns a goal in a browser and reports the text and URL it was asked to check.
›
jev-installRuns once: installs the pinned jev-ultrafast checkout and the CLI.
›
jev-guideOpens the Jev guide: privacy boundary, exit codes, and the shared Chrome profile.
›
jev-instructionsOpens the Jev instructions.
›
jev-envOpens the private keys file for Jev (mode 600).
›
jev-decideAsks Jev to choose one of the options you give, with a confidence score.
›
‹ Home

dashboard

Two local dashboards on this machine, one to read at a glance and one to compare it with, plus their checks.

dashboard-runStarts the dashboard at http://127.0.0.1:8780.
›
dashboard-pageOpens the dashboard in a browser, once it is running.
›
concepts-runStarts the concepts dashboard at http://127.0.0.1:8781.
›
concepts-pageOpens the concepts dashboard in a browser, once it is running.
›
dashboard-testsRuns the 199 dashboard checks against the real data and a real server.
›
concepts-testsRuns the 17 concepts checks against the real data and a real server.
›
dashboard-guideOpens the dashboard guide: its tabs, what it writes, and hot reload.
›
dashboard-intentOpens the dashboard's intent and rules.
›
concepts-guideOpens the concepts guide and what differs from the main dashboard.
›
snapshotRuns the snapshot script; its file says what it captures.
›
‹ Home

clipboard

The shared clipboard history, clipstack: its picker, its server and watcher as services, and its Windows side.

pickerRuns the picker to choose an earlier clip.
›
clipstack-serverRuns the clipstack server as a user service.
›
clipstack-watcherRuns the watcher as a user service that records what is copied.
›
clipstack-unitsOpens the two systemd service files.
›
clipstack-installRuns the Linux install of the clipstack services.
›
clipstack-windowsRuns on Windows: the AutoHotkey script that is the Windows side of the history.
›
clipstack-windows-installRuns on Windows: installs the Windows side.
›
clipstack-windows-verifyRuns the check of the Windows side.
›
clipstack-windows-intentOpens the Windows side's intent and its feature file.
›
clipstack-testsOpens the server tests.
›
‹ Home

documents

The written work: CVs, plans, research, designs, flows, items, case studies, changelog, incident records, and the archive.

cv-folderOpens the CV folder: the sources, the PDFs, and how they are built.
›
cv-full-stackOpens the Full Stack Developer CV.
›
cv-ai-full-stackOpens the AI Full Stack Engineer CV.
›
cv-ai-integrationsOpens the AI Integrations CV.
›
cv-buildRebuilds a CV PDF from its .tex source.
›
cv-experience-notesOpens the factual notes every CV draws on.
›
cv-masterOpens the readable master CV.
›
cv-versionsOpens the dated CV versions, 2026-10-04 and its v2.
›
cv-workflowOpens the CV workflow.
›
cv-text-buildRuns the build of the plain-text CVs from the sources.
›
plansOpens the dated plans, one folder each.
›
researchOpens the dated research folders, phase checks included.
›
functional-researchOpens the functional research on agent frameworks and tools.
›
designsOpens the design pitches and recommendations, the dashboard and agent sandbox among them.
›
flowsOpens the flow cards and data models.
›
itemsOpens the planned, urgent and work item lists.
›
changelogOpens the dated changelog entries.
›
playbookOpens the playbook for talking while a team builds.
›
case-studiesOpens the archived, reviewed experiments: the CodeBot return and Signal Garden.
›
incidentsOpens the dated incident records, starting with the closed-lid CodeBot test.
›
ai-lab-resultsOpens the Kernel cloud browser results, tested 2026-10-08.
›
workstation-readmeOpens the main guide: where things land, conventions, and the system-wide changes log.
›
archiveOpens the archive of files moved out of projects; it is not backed up.
›
copy-screenshotsOpens the three dashboard screenshots kept for copy.
›
Raw answer
The map has 11 top-level areas and 12 screens. Paths are relative to `~/projects/workstation` unless they start with `~`, `/`, or a scheme. Several facade files named in the READMEs (`workstation-cli/`, `zsh.d/workstation.zsh`, `audio-share/`) are missing from the file list, so those rows come from the READMEs and are unverified. The questions at the end cover that and the other open calls.

Judgment calls:
- `opencode` is its own top-level area because `opencode help` is already its own facade.
- Screens are flat for now. Splitting `agents` and `documents` is a question, not a decision I made.
- Depth-1 screens print the same table for the bare noun and for `help`.
- Retired items (Lan Mouse controller, the Playwright MCP setup) appear only as pointers to their notes.
- Rows whose purpose is only inferred from a name are marked, and question 2 asks for the file contents.

```json
{"screens": [
 {"path": [], "sentence": "The workstation: the areas of this machine and its projects, one screen each. Pick one to see what it holds.", "rows": [
  {"name": "shell", "form": "workstation shell", "what": "Prints the shell screen: the helper files in ~/.zsh.d, the git setup, and the commands that open files and keys."},
  {"name": "machine", "form": "workstation machine", "what": "Prints the machine screen: the Linux power, display, network and laptop-lid scripts, the repair helpers, and the services that run here."},
  {"name": "devices", "form": "workstation devices", "what": "Prints the devices screen: the mouse and keyboard shared with the Windows PC, and the audio sent to it."},
  {"name": "windows", "form": "workstation windows", "what": "Prints the windows screen: the Windows PC's install kit, its skill sync, and its repo cloning script."},
  {"name": "claude", "form": "workstation claude", "what": "Prints the claude screen: Claude Code's global files, its hooks, its usage guard, and its main session."},
  {"name": "agents", "form": "workstation agents", "what": "Prints the agents screen: the rules, agent records, roles and teams, skills, the Agent Sandbox, Hermes and Codex."},
  {"name": "opencode", "form": "workstation opencode", "what": "Prints the opencode screen: the OpenCode commands for profiles, their help, and their files."},
  {"name": "browser", "form": "workstation browser", "what": "Prints the browser screen: the browser command, the Chrome launcher, and the Jev browser check."},
  {"name": "dashboard", "form": "workstation dashboard", "what": "Prints the dashboard screen: the two local dashboards, their addresses, and their checks."},
  {"name": "clipboard", "form": "workstation clipboard", "what": "Prints the clipboard screen: the clipstack history, its services, and its Windows side."},
  {"name": "documents", "form": "workstation documents", "what": "Prints the documents screen: CVs, plans, research, designs, case studies, changelog, and incident records."}
 ]},
 {"path": ["shell"], "sentence": "The shell helpers in ~/.zsh.d, one file per topic, and the git setup that goes with them.", "rows": [
  {"name": "git-safety", "form": "zsh.d/git-safety.zsh", "what": "Opens the file that wraps git checkout to list the files and ask before discarding unstaged changes."},
  {"name": "infra", "form": "zsh.d/infra.zsh", "what": "Opens the file with the Docker and Compose shortcuts, Prisma and Postgres helpers, and nginx and VPN commands."},
  {"name": "utils", "form": "zsh.d/utils.zsh", "what": "Opens the file with the terminal helpers, IP aliases, lazy node tools, Android, Java and Bun setup, and the repair helpers."},
  {"name": "api-keys", "form": "zsh.d/api-keys.zsh", "what": "Opens the file that exports the general-use API keys from ~/.config/api-keys/env."},
  {"name": "api-keys-edit", "form": "command api-keys-edit", "what": "Opens ~/.config/api-keys/env, the general-use API keys file that is never in Git."},
  {"name": "review-open", "form": "command review-open (zsh.d/review-open.zsh, ~/.local/bin/review-open)", "what": "Opens a file for review, from the shell or from an agent."},
  {"name": "dash-path-warn", "form": "zsh.d/dash-path-warn.zsh", "what": "Opens the file behind the dash-path-warn helper; read it to confirm what it warns about."},
  {"name": "gitconfig", "form": ".gitconfig", "what": "Opens the git settings: author identity, Git LFS, the credential store, and the shared hooks folder."},
  {"name": "git-hooks", "form": "git-hooks/", "what": "Opens the Lefthook hooks that run in every repo, including the push and commit gates."}
 ]},
 {"path": ["machine"], "sentence": "This Linux machine: its power, display, network and laptop-lid scripts, its repair helpers, and its background services.", "rows": [
  {"name": "cpu-min-power", "form": "cpu-min-power.sh", "what": "Runs the power-saver profile: turbo off, CPU capped at 8 percent of its maximum (Intel only, asks for sudo)."},
  {"name": "cpu-normal-power", "form": "cpu-normal-power.sh", "what": "Runs the balanced profile: turbo on, CPU cap back to 100 percent."},
  {"name": "hdmi-fix", "form": "fix_old_monitor_hdmi.sh", "what": "Runs xrandr to set the mode and refresh rate on the external monitor (default 1920x1080 at 59.88)."},
  {"name": "internet-recovery", "form": "linux-internet-recovery.sh", "what": "Runs the network repair: systemd-resolved, DNS, a NetworkManager restart, and a networking cycle."},
  {"name": "tailscale-recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Runs the Tailscale repair: DNS, a tailscaled restart, a wait of up to 30 seconds, then starts the remote terminal and checks port 3500."},
  {"name": "lid-keep-running", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Runs the change so that closing the lid does nothing; it applies after a reboot."},
  {"name": "lid-restore-default", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Runs the removal of that change; it applies after a reboot."},
  {"name": "fix-keyboard, fix-mouse, fix-disk, fix-whatsapp", "form": "commands defined in zsh.d/utils.zsh", "what": "Runs the repair for that part: keyboard, mouse, disk, or WhatsApp."},
  {"name": "supabase-keepalive", "form": "supabase-keepalive/ (supabase-keepalive.timer)", "what": "Runs on a timer to keep the Supabase project active."},
  {"name": "remote-terminal", "form": "user service remote-terminal (defined outside this repo)", "what": "Runs the remote terminal on port 3500, reached over Tailscale."}
 ]},
 {"path": ["devices"], "sentence": "The mouse and keyboard shared with the Windows PC over Tailscale, and the audio that goes to it.", "rows": [
  {"name": "deskflow-guide", "form": "deskflow/README.md", "what": "Opens the guide: everyday use, crossing the screen edges, and recovery."},
  {"name": "deskflow-service", "form": "~/.config/systemd/user/deskflow.service", "what": "Runs the Deskflow server with the graphical session; GNOME asks each start to allow input capture."},
  {"name": "resume-kvm", "form": "command resume-kvm", "what": "Starts Deskflow again and asks GNOME for input capture again after a cancel."},
  {"name": "deskflow-linux-config", "form": "~/.config/Deskflow/Deskflow.conf (from deskflow/linux.conf)", "what": "Opens the Linux Deskflow settings."},
  {"name": "deskflow-windows-config", "form": "deskflow/windows.conf", "what": "Opens the Windows Deskflow client settings."},
  {"name": "deskflow-network-audit", "form": "deskflow/NETWORK-AUDIT.md", "what": "Opens the audit of what Deskflow connects to."},
  {"name": "deskflow-firewall", "form": "deskflow/deskflow-lockdown.nft", "what": "Opens the firewall rules that lock down Deskflow's network use."},
  {"name": "usb-mouse-guide", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes on forwarding the Windows USB mouse, which has been off since 2026-10-20."},
  {"name": "usb-mouse-service", "form": "deskflow-usb-mouse.service (disabled)", "what": "Starts forwarding the Windows USB mouse to the laptop when it is enabled again."},
  {"name": "lan-mouse-retired", "form": "lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide; do not run it alongside Deskflow."},
  {"name": "audio-start", "form": "command audio-start (also audio-share on)", "what": "Starts sending all Linux audio to the Windows PC over Tailscale."},
  {"name": "audio-pause", "form": "command audio-pause (also audio-share off)", "what": "Pauses the audio sent to Windows and restores the speakers."},
  {"name": "audio-status", "form": "command audio-share status", "what": "Prints whether audio goes to Windows."},
  {"name": "audio-tone", "form": "command audio-share tone", "what": "Plays a test tone to the Windows PC."}
 ]},
 {"path": ["windows"], "sentence": "The Windows PC: its install kit, the skill sync that keeps its skills current, and the repo cloning script.", "rows": [
  {"name": "install", "form": "init-windows/Start-Install.cmd", "what": "Runs the one-command install: programs, Node, VS Code, Git settings, user scripts, then opens the Chrome sign-in."},
  {"name": "install-guide", "form": "init-windows/README.md", "what": "Opens the install guide and its prerequisites."},
  {"name": "smoke-test", "form": "init-windows/Smoke-Test-Windows.ps1", "what": "Runs the smoke test that checks the install."},
  {"name": "verify", "form": "init-windows/Verify-Windows.ps1", "what": "Runs the verification of the installed setup."},
  {"name": "rollback", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Runs the rollback of the install, using the install journal."},
  {"name": "export", "form": "init-windows/Export-Windows.ps1", "what": "Runs the export that captures this PC's setup into the manifests (name-based; read it to confirm)."},
  {"name": "manifests", "form": "init-windows/manifests/", "what": "Opens the pinned lists: programs, Node versions, VS Code extensions, and managed files."},
  {"name": "inventory", "form": "init-windows/inventory.md", "what": "Opens the list of what was captured."},
  {"name": "secrets-checklist", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand."},
  {"name": "skill-sync-guide", "form": "skills-sync-windows/README.md", "what": "Opens the guide to the Windows skill sync."},
  {"name": "sync-now", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Runs a sync now: fast-forwards the skills checkout and fixes the links."},
  {"name": "sync-test", "form": "skills-sync-windows/Test-Sync.ps1", "what": "Runs the sync test."},
  {"name": "sync-account-check", "form": "skills-sync-windows/Test-Account.ps1", "what": "Runs the check of the sync account (name-based; read it to confirm)."},
  {"name": "last-sync", "form": "C:\\ProgramData\\MySkillsSync\\state\\last-success.json", "what": "Opens the record of the last successful sync."},
  {"name": "sync-runner", "form": "service actions.runner.Lebnor-my-skills.my-skills-liel-windows", "what": "Runs the GitHub runner that starts a sync on each push to master."},
  {"name": "clone-repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Runs the clone of every missing Betec repo; existing folders are left alone."}
 ]},
 {"path": ["claude"], "sentence": "Claude Code on this machine: its global files, its hooks, the usage guard that wraps it, and the main session.", "rows": [
  {"name": "global-linux-mirror", "form": "claude/linux-global/", "what": "Opens the mirror of this machine's global instructions and their four docs."},
  {"name": "machine-settings", "form": "~/.claude/settings.json", "what": "Opens this machine's Claude settings; the file is not in Git."},
  {"name": "windows-global-mirror", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows PC's global instructions and docs."},
  {"name": "global-rules", "form": "claude/CLAUDE.md", "what": "Opens the global rules deployed to the Windows PC."},
  {"name": "agent-notes", "form": "claude/AGENTS.md", "what": "Opens the shorter global agent notes deployed to the Windows PC."},
  {"name": "settings-repo", "form": "claude/settings.json", "what": "Opens the Claude settings deployed to the Windows PC."},
  {"name": "communication-draft", "form": "claude/communication-framework.md", "what": "Opens a draft of communication design notes; nothing enforces it yet."},
  {"name": "hooks", "form": "claude/hooks/", "what": "Opens the hooks wired into settings.json: core rules, local server guard, machine history, proof reminder, team activity."},
  {"name": "session-types-hook", "form": "claude/session-types/session-types.sh", "what": "Runs at each session start to set up the session type."},
  {"name": "main-session", "form": "command claude --main", "what": "Starts the main Claude session; -c continues the last one and -r resumes one."},
  {"name": "session-type-tests", "form": "claude/session-types/tests/run.sh", "what": "Runs the session type tests."},
  {"name": "claude-wrapper", "form": "command claude (~/bin/claude, from claude/usage-guard/claude)", "what": "Runs Claude Code through the usage guard, ahead of the native binary."},
  {"name": "usage-guard-install", "form": "claude/usage-guard/install.sh", "what": "Runs the Linux install of the wrapper and the native Claude Code."},
  {"name": "usage-guard-install-windows", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Runs the Windows install of the usage guard."},
  {"name": "usage-guard-guide", "form": "claude/usage-guard/README.md", "what": "Opens the usage guard guide."},
  {"name": "team-park", "form": "command team-park (~/.local/bin/team-park)", "what": "Runs team_park.py; its README says what it parks."},
  {"name": "plugins", "form": "claude/mods/", "what": "Opens the four plugins: changelog-pane, review-pane, scratchpad-playground, team-board."},
  {"name": "desktop-backups", "form": "claude/backups/", "what": "Opens the portable snapshots of the Windows desktop's instructions and two skills."}
 ]},
 {"path": ["agents"], "sentence": "The agent system: the rules every agent follows, agent records and teams, roles and skills, the Agent Sandbox, and the agents' own runtimes.", "rows": [
  {"name": "rules", "form": "command rules [folder] (zsh.d/rules.zsh)", "what": "Prints the rules that apply to every org; a folder argument prints that folder's rules."},
  {"name": "rules-file", "form": "workboard/rules.yaml (metadata in rules-meta.yaml)", "what": "Opens the rules, changed only by the user or an accepted rule proposal."},
  {"name": "rules-reminder", "form": "docs/plans/2026-10-24-rules-per-role/reminder/", "what": "Runs on a timer to remind each role of its rules."},
  {"name": "agent-check", "form": "command agent-framework/agent check", "what": "Checks every agent record and refuses the broken ones (exit 1)."},
  {"name": "agent-list", "form": "command agent-framework/agent list", "what": "Prints the agents with their tier, model and number of tests."},
  {"name": "agent-serve", "form": "command agent-framework/agent serve", "what": "Starts the Agent Sandbox page at http://127.0.0.1:8790."},
  {"name": "sandbox-page", "form": "http://127.0.0.1:8790", "what": "Opens the Agent Sandbox in a browser, once agent serve is running."},
  {"name": "agent-framework-guide", "form": "agent-framework/README.md", "what": "Opens the Agent Sandbox guide: setup, tests, and replies."},
  {"name": "agent-framework-intent", "form": ".idd/modules/agent-framework/INTENT.md", "what": "Opens the agent framework's intent and rules."},
  {"name": "agent-records", "form": "~/projects/my-skills/agents/", "what": "Opens the agent records, one folder per agent with its tests and role skill."},
  {"name": "roles", "form": "~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.md", "what": "Opens the role instructions each team member starts from."},
  {"name": "teams", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files, such as worker-pair and research-team."},
  {"name": "spawn-team", "form": "command /spawn-team <team> (Claude) and $spawn-team <team> (Codex)", "what": "Starts a team of agents from its team file."},
  {"name": "skill-backups", "form": "claude/skills/", "what": "Opens the skill backups kept in this repo."},
  {"name": "skill-shortlist", "form": "claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and which ones are installed."},
  {"name": "global-skills", "form": "~/projects/my-skills/", "what": "Opens the global skills repo, which is linked into the Claude, Codex and OpenCode skill folders."},
  {"name": "skill-link", "form": "~/projects/my-skills/install.sh", "what": "Runs the link step that puts the global skills and agent personas in place."},
  {"name": "data-repo", "form": "~/projects/data/", "what": "Opens the private data repo: cases, rule proposals, verdicts, and troubleshooting."},
  {"name": "data-pull", "form": "~/projects/data/bin/sync (timer data-pull)", "what": "Runs every 5 minutes to pull answers into the data repo."},
  {"name": "supervision-backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "Opens the supervision backlog."},
  {"name": "hermes-run", "form": "command hermes (~/.local/bin/hermes)", "what": "Runs the Hermes agent."},
  {"name": "hermes-guide", "form": "hermes/README.md", "what": "Opens the Hermes install and configuration notes."},
  {"name": "hermes-restore", "form": "hermes/RESTORE.md", "what": "Opens the Hermes restore runbook."},
  {"name": "hermes-state", "form": "~/.hermes", "what": "Opens Hermes's state and secrets folder; it is never in Git."},
  {"name": "codex-config", "form": "codex/config.toml", "what": "Opens the Codex CLI settings (deployed to Windows; machine-local on Linux)."}
 ]},
 {"path": ["opencode"], "sentence": "OpenCode with a set of files per profile: run it, switch the profile, and see or edit what each one loads.", "rows": [
  {"name": "opencode-run", "form": "command opencode (also oc)", "what": "Runs OpenCode with the current profile's files."},
  {"name": "opencode-profile", "form": "command opencode-profile", "what": "Prints the name of the current profile."},
  {"name": "opencode-profiles", "form": "command opencode-profiles", "what": "Prints what each profile loads."},
  {"name": "opencode-switch", "form": "command opencode-switch <name>", "what": "Switches the profile that every shell's new runs use."},
  {"name": "opencode-login", "form": "command opencode-login", "what": "Signs a profile's Claude Code in."},
  {"name": "opencode-files", "form": "command opencode-files", "what": "Lists the current profile's files."},
  {"name": "opencode-edit", "form": "command opencode-edit <file>", "what": "Opens one of the current profile's files in the editor."},
  {"name": "opencode-help", "form": "command opencode help (also oc help, opencode-help, oc-help)", "what": "Prints the table of every profile's files, one column per profile; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it."},
  {"name": "profiles-folder", "form": "opencode-profiles/", "what": "Opens the profile folder: profiles.py, its tests, and the experimental profile."},
  {"name": "profiles-shell", "form": "zsh.d/opencode-profiles.zsh", "what": "Opens the shell wiring for these commands; ~/.bashrc sources it too."},
  {"name": "experimental-profile", "form": "opencode-profiles/private-leb-experimental/", "what": "Opens the experimental profile's CLAUDE.md, settings, and opencode.json."}
 ]},
 {"path": ["browser"], "sentence": "Chrome automation: the browser command that drives one persistent Chrome window, the Chrome launcher, and the Jev browser check.", "rows": [
  {"name": "browser-run", "form": "command browser '<steps>'", "what": "Runs the listed steps in the one persistent Chrome window, starting the background server if needed."},
  {"name": "browser-status", "form": "command browser status", "what": "Prints whether the background server and its Chrome are running."},
  {"name": "browser-close", "form": "command browser close", "what": "Closes Chrome and stops the background server."},
  {"name": "record-start", "form": "browser with a recordStart step", "what": "Starts recording the tab as proof of a feature."},
  {"name": "record-stop", "form": "browser with a recordStop step", "what": "Stops the recording."},
  {"name": "browser-guide", "form": "browser/README.md", "what": "Opens the browser command guide, including recording proof."},
  {"name": "chrome-run", "form": "command google-chrome (also google-chrome-stable)", "what": "Starts Chrome through chrome.sh, with the recording flag."},
  {"name": "chrome-launcher", "form": "chrome/chrome.sh", "what": "Opens the one Chrome launcher, which adds the flags and starts Chrome."},
  {"name": "chrome-install", "form": "chrome/install.sh", "what": "Runs once per machine: links the Chrome commands and menu entry to chrome.sh."},
  {"name": "chrome-flags", "form": "chrome/flags", "what": "Opens the one list of Chrome flags."},
  {"name": "chrome-guide", "form": "chrome/README.md", "what": "Opens the Chrome guide: why it starts this way and its limits."},
  {"name": "codex-bridge-timer", "form": "codex/chrome-bridge/ (codex-chrome-bridge.timer)", "what": "Runs on a timer to repair the Codex Chrome plugin link and its local navigation patch."},
  {"name": "codex-bridge-install", "form": "codex/chrome-bridge/install.sh", "what": "Runs once on Linux: installs the bridge watcher and timer."},
  {"name": "codex-browser-notes", "form": "codex/browser/README.md", "what": "Opens the notes on Codex's direct Chrome path and its live checks."},
  {"name": "jev-run", "form": "command jev-browser-test", "what": "Runs a goal in a browser and reports the text and URL it was asked to check."},
  {"name": "jev-install", "form": "jev-browser-test/install.sh", "what": "Runs once: installs the pinned jev-ultrafast checkout and the CLI."},
  {"name": "jev-guide", "form": "jev-browser-test/README.md", "what": "Opens the Jev guide: privacy boundary, exit codes, and the shared Chrome profile."},
  {"name": "jev-instructions", "form": "jev-browser-test/instructions.md", "what": "Opens the Jev instructions."},
  {"name": "jev-env", "form": "~/.config/jev-browser-test/env", "what": "Opens the private keys file for Jev (mode 600)."},
  {"name": "jev-decide", "form": "command jev", "what": "Asks Jev to choose one of the options you give, with a confidence score."}
 ]},
 {"path": ["dashboard"], "sentence": "Two local dashboards on this machine, one to read at a glance and one to compare it with, plus their checks.", "rows": [
  {"name": "dashboard-run", "form": "command python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard at http://127.0.0.1:8780."},
  {"name": "dashboard-page", "form": "http://127.0.0.1:8780", "what": "Opens the dashboard in a browser, once it is running."},
  {"name": "concepts-run", "form": "command python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts dashboard at http://127.0.0.1:8781."},
  {"name": "concepts-page", "form": "http://127.0.0.1:8781", "what": "Opens the concepts dashboard in a browser, once it is running."},
  {"name": "dashboard-tests", "form": "command python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the 199 dashboard checks against the real data and a real server."},
  {"name": "concepts-tests", "form": "command python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the 17 concepts checks against the real data and a real server."},
  {"name": "dashboard-guide", "form": "dashboard/README.md", "what": "Opens the dashboard guide: its tabs, what it writes, and hot reload."},
  {"name": "dashboard-intent", "form": ".idd/modules/dashboard/INTENT.md", "what": "Opens the dashboard's intent and rules."},
  {"name": "concepts-guide", "form": "dashboard-concepts/README.md", "what": "Opens the concepts guide and what differs from the main dashboard."},
  {"name": "snapshot", "form": "dashboard/snapshot.py", "what": "Runs the snapshot script; its file says what it captures."}
 ]},
 {"path": ["clipboard"], "sentence": "The shared clipboard history, clipstack: its picker, its server and watcher as services, and its Windows side.", "rows": [
  {"name": "picker", "form": "clipstack/picker.py", "what": "Runs the picker to choose an earlier clip."},
  {"name": "clipstack-server", "form": "clipstack/server.py (service clipstack-server.service)", "what": "Runs the clipstack server as a user service."},
  {"name": "clipstack-watcher", "form": "clipstack/watcher.py (service clipstack-watcher.service)", "what": "Runs the watcher as a user service that records what is copied."},
  {"name": "clipstack-units", "form": "clipstack/units/", "what": "Opens the two systemd service files."},
  {"name": "clipstack-install", "form": "clipstack/install.sh", "what": "Runs the Linux install of the clipstack services."},
  {"name": "clipstack-windows", "form": "clipstack/windows/clipstack.ahk", "what": "Runs on Windows: the AutoHotkey script that is the Windows side of the history."},
  {"name": "clipstack-windows-install", "form": "clipstack/windows/install.ps1", "what": "Runs on Windows: installs the Windows side."},
  {"name": "clipstack-windows-verify", "form": "clipstack/windows/verify.ps1", "what": "Runs the check of the Windows side."},
  {"name": "clipstack-windows-intent", "form": "clipstack/windows/INTENT.md", "what": "Opens the Windows side's intent and its feature file."},
  {"name": "clipstack-tests", "form": "clipstack/test_server.py", "what": "Opens the server tests."}
 ]},
 {"path": ["documents"], "sentence": "The written work: CVs, plans, research, designs, flows, items, case studies, changelog, incident records, and the archive.", "rows": [
  {"name": "cv-folder", "form": "cv/", "what": "Opens the CV folder: the sources, the PDFs, and how they are built."},
  {"name": "cv-full-stack", "form": "cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
  {"name": "cv-ai-full-stack", "form": "cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
  {"name": "cv-ai-integrations", "form": "cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
  {"name": "cv-build", "form": "pdflatex -interaction=nonstopmode -halt-on-error <name>.tex (in cv/)", "what": "Rebuilds a CV PDF from its .tex source."},
  {"name": "cv-experience-notes", "form": "cv/experience-notes.md", "what": "Opens the factual notes every CV draws on."},
  {"name": "cv-master", "form": "cv/cv-master.md", "what": "Opens the readable master CV."},
  {"name": "cv-versions", "form": "cv/versions/", "what": "Opens the dated CV versions, 2026-10-04 and its v2."},
  {"name": "cv-workflow", "form": "cv/WORKFLOW.md", "what": "Opens the CV workflow."},
  {"name": "cv-text-build", "form": "cv/text/build-full.sh", "what": "Runs the build of the plain-text CVs from the sources."},
  {"name": "plans", "form": "docs/plans/", "what": "Opens the dated plans, one folder each."},
  {"name": "research", "form": "docs/research/", "what": "Opens the dated research folders, phase checks included."},
  {"name": "functional-research", "form": "docs/functional-research/", "what": "Opens the functional research on agent frameworks and tools."},
  {"name": "designs", "form": "docs/design/", "what": "Opens the design pitches and recommendations, the dashboard and agent sandbox among them."},
  {"name": "flows", "form": "docs/flows/", "what": "Opens the flow cards and data models."},
  {"name": "items", "form": "docs/items/", "what": "Opens the planned, urgent and work item lists."},
  {"name": "changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
  {"name": "playbook", "form": "docs/playbooks/talk-while-team-builds.md", "what": "Opens the playbook for talking while a team builds."},
  {"name": "case-studies", "form": "case-studies/", "what": "Opens the archived, reviewed experiments: the CodeBot return and Signal Garden."},
  {"name": "incidents", "form": "reference/incidents/", "what": "Opens the dated incident records, starting with the closed-lid CodeBot test."},
  {"name": "ai-lab-results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the Kernel cloud browser results, tested 2026-10-08."},
  {"name": "workstation-readme", "form": "README.md", "what": "Opens the main guide: where things land, conventions, and the system-wide changes log."},
  {"name": "archive", "form": "~/archive/", "what": "Opens the archive of files moved out of projects; it is not backed up."},
  {"name": "copy-screenshots", "form": "copy/", "what": "Opens the three dashboard screenshots kept for copy."}
 ]}
],
"questions": [
 "The file list does not contain workstation-cli/ (workstation.py, terminal_links.py), zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, or init-windows/Start-Install.cmd, though the READMEs describe them. Are they untracked, elsewhere, or not yet written? Recommendation: confirm before building, because the facade's own file decides how the help is wired.",
 "Several rows are named from the file name or a README only: dash-path-warn, machine-history.sh, session-types.sh, team_park.py, picker.py, watcher.py, clipstack server.py, snapshot.py, Export-Windows.ps1, Test-Account.ps1, and rules-reminder. Recommendation: paste the first lines of each so the what column says what the file does, not what its name suggests.",
 "The agents screen (about 30 rows) and the documents screen (about 24 rows) are long. Recommendation: split documents into a documents cv screen and keep the rest flat, and split agents into an agents skills screen (skill backups, global skills, roles, teams) and the agents screen (rules, records, sandbox, data, runtimes). Your call: yes or no, and which split.",
 "The alias setup is generic and easy to clash with other tools. Recommendation: keep workstation and ws, and drop setup unless whence -a setup shows nothing else on PATH. Do you want setup kept?",
 "The infra.zsh and utils.zsh files embed a token in git URLs (a known issue in the README). Recommendation: the shell screen marks those two rows with a warning that the file holds a token to rotate, so the map does not hide it. Do you want that marking?",
 "The README says opencode-profile names the profile. Recommendation: treat it as printing the current name, not setting it, and check the file before the row goes live. Is that the intent, or does it also set the profile?"
]}
```

screen-decomposition, first draft · run 1 exit=0 seconds=156 · prompt

P1 Recall: 0.743P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.293
As terminal help
The workstation's map: the areas of one developer's documents, config, scripts, agent setup and small tools on this Linux machine.
assistantsworkstation assistantsOpens the assistants screen: Claude, Codex, OpenCode and Hermes, with the rules, skills and records they share.
browserworkstation browserOpens the browser screen: the browser command, the Chrome launcher and the jev browser check.
machineworkstation machineOpens the machine screen: power, repairs, Deskflow and audio sharing for this Linux machine.
shellworkstation shellOpens the shell screen: the zsh helpers, Git settings and hooks, and API keys that every terminal gets.
serversworkstation serversOpens the servers screen: the dashboards, the Agent Sandbox, clipstack, the Supabase keepalive and the Hermes gateway.
documentsworkstation documentsOpens the documents screen: plans, designs, research, items, CVs, case studies, incidents, specs and the archive.
windowsworkstation windowsOpens the Windows screen: the install, checks, skills sync and mirrored instruction files that run on the Windows PC.
assistants
The AI assistants on this machine, and the rules, skills and records they share.
rulesrules [folder]Prints the rules that apply everywhere, or to one folder, from workboard/rules.yaml.
agentagent-framework/agentRuns the agent records: agent check refuses broken ones, agent list lists them, agent serve starts the Agent Sandbox.
team-park~/.local/bin/team-park (claude/team-park/team_park.py)Runs team-park; its README in claude/team-park says what it does.
my-skills~/projects/my-skillsOpens the skills and agent records repo, whose skills are linked into the assistants' folders.
backed-up skillsclaude/skills/Opens the copies of skills kept in this repo; copy the ones you want into ~/.claude/skills.
agent notesclaude/AGENTS.mdOpens the shorter global agent notes, next to claude/CLAUDE.md.
data~/projects/dataOpens the private data repo: cases, rule proposals, verdicts and team reviews that agents write.
supervision backlog~/projects/betec/workboard/docs/supervision-backlog.mdOpens the supervision backlog, which lives in the betec workboard, not in this repo.
claudeworkstation assistants claudeOpens the Claude screen: its wrapper, session types, rules, hooks and plugin mods.
codexworkstation assistants codexOpens the Codex screen: its config, the Chrome bridge that keeps its plugin working, and its browser notes.
opencodeworkstation assistants opencodeOpens the OpenCode screen: the commands that run it with the current profile, and the files each profile loads.
hermesworkstation assistants hermesOpens the Hermes screen: its launcher, example settings and restore runbook.
assistants › claude
Claude Code: how it is started, which session it resumes, and the rules and hooks it runs with.
claude~/bin/claudeRuns Claude Code through the usage guard, ahead of the native ~/.local/bin/claude.
usage guardclaude/usage-guard/Opens the usage guard folder: install.sh, the plugin and the request-budget tests.
session typesclaude --main -c and claude --main -rRuns claude --main -c or -r, which resume the main session through main-sessions.py.
global rulesclaude/CLAUDE.mdOpens the global rules every Claude session reads: browser automation, communication style, research, and presenting work.
settingsclaude/settings.jsonOpens the Claude Code settings this kit keeps; the machine's own ~/.claude/settings.json is separate.
hooksclaude/hooks/Opens the hook scripts wired into ~/.claude/settings.json: core rules, machine history, team activity, local server guard and proof reminder.
plugin modsclaude/mods/Opens the Claude plugin mods: changelog pane, review pane, scratchpad playground and team board.
linux globalclaude/linux-global/Opens the mirror of this machine's global CLAUDE.md, AGENTS.md and four docs.
assistants › codex
Codex: its config, the Chrome bridge that keeps its plugin working, and its browser notes.
codex configcodex/config.tomlOpens the Codex CLI config this kit keeps; ~/.codex/config.toml on this machine is machine-local.
chrome bridge installcodex/chrome-bridge/install.shInstalls the systemd watcher and timer that keep the Chrome plugin's latest link working.
chrome bridgecodex/chrome-bridge/Opens the Chrome bridge folder and its README: restart rules and the repair script.
browser notescodex/browser/Opens the notes on Codex's direct Chrome command path and its live verification.
assistants › opencode
OpenCode: the commands that run it with the current profile, and the files each profile loads.
opencodeopencode (also oc)Runs opencode with the current profile; oc is the same command.
opencode helpopencode help (also oc help, opencode-help, oc-help)Prints every profile's files, one column per profile, and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
opencode-profileopencode-profilePrints the current profile's name; the README only says it names the profile, so check the source.
opencode-profilesopencode-profilesLists what each profile loads.
opencode-switchopencode-switch <name>Switches every shell's new runs to the named profile.
opencode-loginopencode-loginSigns a profile's Claude Code in.
opencode-filesopencode-filesLists the current profile's files.
opencode-editopencode-edit <file>Opens one of the current profile's files.
profile filesopencode-profiles/Opens the profile folder: profiles.py and each profile's CLAUDE.md, settings and opencode.json.
assistants › hermes
Hermes: its launcher, the source it was installed from, its example settings and its restore runbook.
hermeshermes (~/.local/bin/hermes)Runs Hermes, the agent installed from source.
checkout~/projects/hermes-agentOpens the Hermes source checkout, the code the launcher runs.
restore runbookhermes/RESTORE.mdOpens the restore runbook: how to bring Hermes back.
example settingshermes/default.config.example.yaml and hermes/jobs.config.example.yamlOpens the secret-free example settings for the default and jobs profiles.
PATH lineshermes/zprofile-path.zshOpens the PATH lines the installer added to ~/.zprofile.
backup notehermes/BACKUP-2026-10-02.mdOpens the backup note from 2026-10-02.
browser
The browser: the browser command, Chrome, and the jev browser check.
browserbrowser '<json steps>'Runs a JSON list of browser steps on one Chrome window that stays open between calls.
browser statusbrowser statusPrints whether the background server and its browser are up.
browser closebrowser closeCloses the browser and stops the background server.
recordingbrowser/README.md#recording-proofRecords the current tab as proof of a feature, between a recordStart step and a recordStop step.
browser guidebrowser/README.mdOpens the browser guide: every action, viewport preset, network capture and login gotcha.
chromegoogle-chrome (runs chrome/chrome.sh)Starts Chrome with the flags in chrome/flags; this is the only way Chrome is started here.
chrome installchrome/install.shInstalls the launcher links and menu entry that point Chrome at chrome.sh; run once per machine and again after a Chrome update.
chrome flagschrome/flagsOpens the flags file: the one list that chrome.sh and the browser recorder both read.
jev browser testjev-browser-testRuns a goal against a browser and reports only the text and URL assertions it was given.
jev installjev-browser-test/install.shInstalls the pinned jev-ultrafast checkout and the jev-browser-test command in ~/.local/bin.
machine
This Linux machine: power, repairs, Deskflow and audio sharing.
powerworkstation machine powerOpens the power screen: CPU profiles, the external monitor mode and the lid settings.
repairworkstation machine repairOpens the repair screen: network, remote access, keyboard, mouse, disk and WhatsApp fixes, and the port helper.
deskflowworkstation machine deskflowOpens the Deskflow screen: the shared mouse and laptop keyboard that replaced Lan Mouse.
audio-shareaudio-start, audio-pause, audio-share on|off|status|toneSends all Linux audio to the Windows PC over Tailscale; audio-pause restores the speakers.
machine › power
Power and display on this machine: CPU profiles, the external monitor mode, and the lid.
cpu-min-powercpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8% of max; asks for sudo and works only on Intel P-state.
cpu-normal-powercpu-normal-power.shSets the balanced profile, turns turbo on and lifts the CPU cap back to 100%.
hdmi monitorfix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output with xrandr; the default is 1920x1080 at 59.88.
lid keep awakelaptop-utilities/keep-running-with-lid-closed.shWrites the logind drop-in so closing the lid does nothing; it applies after a reboot.
lid restorelaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in so closing the lid works as before; it applies after a reboot.
machine › repair
Repairs for this machine: network, remote access, keyboard, mouse, disk, WhatsApp and ports.
internet recoverylinux-internet-recovery.shRepairs DNS through systemd-resolved, restarts NetworkManager and cycles networking; it reruns itself with sudo.
tailscale recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, waits up to 30 s for reconnect, then starts remote-terminal and checks port 3500.
fix-keyboardfix-keyboard (zsh.d/utils.zsh)Runs the keyboard repair helper; utils.zsh has the exact steps.
fix-mousefix-mouse (zsh.d/utils.zsh)Runs the mouse repair helper; utils.zsh has the exact steps.
fix-diskfix-disk (zsh.d/utils.zsh)Runs the disk repair helper; utils.zsh has the exact steps.
fix-whatsappfix-whatsapp (zsh.d/utils.zsh)Runs the WhatsApp repair helper; utils.zsh has the exact steps.
killportkillport (zsh.d/utils.zsh)Runs killport, the terminal helper for a port; utils.zsh has the exact steps.
machine › deskflow
Deskflow: sharing the laptop's keyboard and trackpad with the Windows PC, and the USB mouse.
deskflow guidedeskflow/README.mdOpens the Deskflow guide: everyday use, the Windows admin terminal, and recovery.
usb mouse notesdeskflow/usb-mouse/README.mdOpens the USB mouse notes: how the keyboard follows the mouse, and how to turn USB sharing back on.
resume-kvmresume-kvmStarts Deskflow again and asks for input access; use it after a canceled prompt.
deskflow service~/.config/systemd/user/deskflow.serviceRuns the Deskflow server when the graphical session starts; a canceled input prompt stops it.
servers
Things that run as a server or page on this machine, and where to open them.
dashboardhttp://127.0.0.1:8780 (run: python3 ~/projects/workstation/dashboard/server.py)Runs the dashboard server; its page at 127.0.0.1:8780 shows what waits for you.
dashboard conceptshttp://127.0.0.1:8781 (run: python3 ~/projects/workstation/dashboard-concepts/server.py)Runs the concepts version of the dashboard, with the Projects panel, at 127.0.0.1:8781.
Agent Sandboxhttp://127.0.0.1:8790 (run: agent serve)Runs the Agent Sandbox page, where you pick an agent, change its setup and send it a message.
clipstackclipstack/units/ (clipstack-server.service, clipstack-watcher.service)Runs the clipstack server and watcher services that share the clipboard.
supabase keepalivesupabase-keepalive/install.shInstalls the timer that runs supabase-keepalive.sh on a schedule.
Hermes gatewayhermes (gateway)Runs the Hermes gateway that serves both Telegram bots; the laptop must stay awake and online.
documents
Documents: plans, designs, research, items, CVs, case studies, incidents, specs and the archive.
plansdocs/plans/Opens the plans folder: one dated plan.md per piece of work.
designdocs/design/ and docs/flows/Opens the design pitches, recommendations and flow cards, one dated folder each.
researchdocs/research/ and docs/functional-research/Opens the research notes behind the designs and plans.
itemsdocs/items/Opens the planned, urgent and work item lists.
changelogdocs/changelog/Opens the dated changelog entries.
specs.idd/ and .bdd/Opens the intents and Gherkin features that specify each module, and the QA findings.
CVscv/Opens the CVs: the three PDFs, their LaTeX sources, and the steps to rebuild them in cv/README.md.
case studiescase-studies/Opens the human-reviewed experiments, one folder each.
incidentsreference/Opens the dated incident records for machine-level failures and repairs.
rolesdocs/roles/Opens the draft role skills: admin, qa-agent, supervisor and worker.
archive~/archive/Opens the archive: files moved out of projects, each folder with an ARCHIVE.md; it is not backed up.
shell
The shell: the zsh helpers, Git settings and hooks, and API keys that every terminal and bash session gets.
workstation commandzsh.d/workstation.zshDefines the workstation command, with the ws and setup aliases and the help screens.
review-openreview-open (~/.local/bin/review-open; zsh.d/review-open.zsh)Opens a file for review, from zsh, bash or an agent.
git checkout guardzsh.d/git-safety.zshLists the files and asks [y/N] before a git checkout would discard unstaged changes.
infrazsh.d/infra.zshDefines the Docker and Compose shortcuts, the Prisma and Postgres helpers, and the nginx and VPN commands.
utilszsh.d/utils.zshDefines the terminal helpers, IP aliases, lazy nvm and node, Android, Java and Bun setup, and the repair helpers.
opencode commandszsh.d/opencode-profiles.zshDefines the opencode and oc commands; they are listed under assistants, opencode.
api keysapi-keys-edit (opens ~/.config/api-keys/env)Opens the API keys file, which is never in Git.
dash-path checkzsh.d/dash-path-warn.zshDefines the dash-path warning; its file says what it checks.
git hooksgit-hooks/ (installed at ~/.git-hooks)Opens the global git hooks: Lefthook shims that run in every repo and need lefthook on PATH.
gitconfig.gitconfig (installed at ~/.gitconfig)Opens the Git config: author identity, LFS, the credential store and the hooks path.
windows
The Windows PC: the install and checks, the skills sync, and the mirrored instruction files. These run on Windows, not in this shell.
installinit-windows/Start-Install.cmdRuns the install that rebuilds the Windows dev environment from the manifests; approve the admin prompt.
checksinit-windows/Smoke-Test-Windows.ps1 and init-windows/Verify-Windows.ps1Runs the checks that the install worked.
roll backinit-windows/Remove-WindowsPack.ps1Rolls the install back from its journal.
sign-insinit-windows/secrets-checklist.mdOpens the list of sign-ins to redo by hand.
inventoryinit-windows/inventory.mdOpens the inventory of what the install captured.
skills syncskills-sync-windows/README.mdOpens the skills sync, where a runner updates the skills on each trusted push to master.
repo clonerepos/Clone-BetecRepos.ps1Clones the missing Betec repos into the standard workspace layout; safe to run again.
windows instructionsclaude/windows-global/Opens the mirror of the Windows desktop's CLAUDE.md and four docs.
desktop backupclaude/backups/desktop-v2-2026/Opens the portable snapshot of the Windows desktop's instructions; nothing loads it automatically.
usage guard installclaude/usage-guard/Install-Windows.cmdRuns the Windows install of the usage guard.
clipstack installclipstack/windows/install.ps1Runs install.ps1, which sets up the Windows clipstack from clipstack.ahk.
codex bridge taskcodex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls the Scheduled Task that keeps the Codex Chrome bridge patched.
Questions
  • Facade names: the README gives workstation, ws and setup. Recommend keeping workstation and ws, and dropping setup, which reads as an install command. Which do you want?
  • Split the assistants screen? It has 12 rows. Recommend moving the data repo, the supervision backlog and the agent records behind a records screen, since agents write those and you don't edit them. Yes or no?
  • Windows items run on Windows, not in this shell. Should workstation windows <item> print the PowerShell command for you to run there, or only show the file? Recommend printing only.
  • Do these exist here? workstation.zsh, workstation-cli/, resume-kvm, init-windows/inventory.md and audio-share are named in the README but are not in the file list. Anything missing gets dropped from the map.
As phone screens

Home

The workstation's map: the areas of one developer's documents, config, scripts, agent setup and small tools on this Linux machine.

assistantsOpens the assistants screen: Claude, Codex, OpenCode and Hermes, with the rules, skills and records they share.
›
browserOpens the browser screen: the browser command, the Chrome launcher and the jev browser check.
›
machineOpens the machine screen: power, repairs, Deskflow and audio sharing for this Linux machine.
›
shellOpens the shell screen: the zsh helpers, Git settings and hooks, and API keys that every terminal gets.
›
serversOpens the servers screen: the dashboards, the Agent Sandbox, clipstack, the Supabase keepalive and the Hermes gateway.
›
documentsOpens the documents screen: plans, designs, research, items, CVs, case studies, incidents, specs and the archive.
›
windowsOpens the Windows screen: the install, checks, skills sync and mirrored instruction files that run on the Windows PC.
›
‹ Home

assistants

The AI assistants on this machine, and the rules, skills and records they share.

rulesPrints the rules that apply everywhere, or to one folder, from workboard/rules.yaml.
›
agentRuns the agent records: agent check refuses broken ones, agent list lists them, agent serve starts the Agent Sandbox.
›
team-parkRuns team-park; its README in claude/team-park says what it does.
›
my-skillsOpens the skills and agent records repo, whose skills are linked into the assistants' folders.
›
backed-up skillsOpens the copies of skills kept in this repo; copy the ones you want into ~/.claude/skills.
›
agent notesOpens the shorter global agent notes, next to claude/CLAUDE.md.
›
dataOpens the private data repo: cases, rule proposals, verdicts and team reviews that agents write.
›
supervision backlogOpens the supervision backlog, which lives in the betec workboard, not in this repo.
›
claudeOpens the Claude screen: its wrapper, session types, rules, hooks and plugin mods.
›
codexOpens the Codex screen: its config, the Chrome bridge that keeps its plugin working, and its browser notes.
›
opencodeOpens the OpenCode screen: the commands that run it with the current profile, and the files each profile loads.
›
hermesOpens the Hermes screen: its launcher, example settings and restore runbook.
›
‹ assistants

claude

Claude Code: how it is started, which session it resumes, and the rules and hooks it runs with.

claudeRuns Claude Code through the usage guard, ahead of the native ~/.local/bin/claude.
›
usage guardOpens the usage guard folder: install.sh, the plugin and the request-budget tests.
›
session typesRuns claude --main -c or -r, which resume the main session through main-sessions.py.
›
global rulesOpens the global rules every Claude session reads: browser automation, communication style, research, and presenting work.
›
settingsOpens the Claude Code settings this kit keeps; the machine's own ~/.claude/settings.json is separate.
›
hooksOpens the hook scripts wired into ~/.claude/settings.json: core rules, machine history, team activity, local server guard and proof reminder.
›
plugin modsOpens the Claude plugin mods: changelog pane, review pane, scratchpad playground and team board.
›
linux globalOpens the mirror of this machine's global CLAUDE.md, AGENTS.md and four docs.
›
‹ assistants

codex

Codex: its config, the Chrome bridge that keeps its plugin working, and its browser notes.

codex configOpens the Codex CLI config this kit keeps; ~/.codex/config.toml on this machine is machine-local.
›
chrome bridge installInstalls the systemd watcher and timer that keep the Chrome plugin's latest link working.
›
chrome bridgeOpens the Chrome bridge folder and its README: restart rules and the repair script.
›
browser notesOpens the notes on Codex's direct Chrome command path and its live verification.
›
‹ assistants

opencode

OpenCode: the commands that run it with the current profile, and the files each profile loads.

opencodeRuns opencode with the current profile; oc is the same command.
›
opencode helpPrints every profile's files, one column per profile, and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
›
opencode-profilePrints the current profile's name; the README only says it names the profile, so check the source.
›
opencode-profilesLists what each profile loads.
›
opencode-switchSwitches every shell's new runs to the named profile.
›
opencode-loginSigns a profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editOpens one of the current profile's files.
›
profile filesOpens the profile folder: profiles.py and each profile's CLAUDE.md, settings and opencode.json.
›
‹ assistants

hermes

Hermes: its launcher, the source it was installed from, its example settings and its restore runbook.

hermesRuns Hermes, the agent installed from source.
›
checkoutOpens the Hermes source checkout, the code the launcher runs.
›
restore runbookOpens the restore runbook: how to bring Hermes back.
›
example settingsOpens the secret-free example settings for the default and jobs profiles.
›
PATH linesOpens the PATH lines the installer added to ~/.zprofile.
›
backup noteOpens the backup note from 2026-10-02.
›
‹ Home

browser

The browser: the browser command, Chrome, and the jev browser check.

browserRuns a JSON list of browser steps on one Chrome window that stays open between calls.
›
browser statusPrints whether the background server and its browser are up.
›
browser closeCloses the browser and stops the background server.
›
recordingRecords the current tab as proof of a feature, between a recordStart step and a recordStop step.
›
browser guideOpens the browser guide: every action, viewport preset, network capture and login gotcha.
›
chromeStarts Chrome with the flags in chrome/flags; this is the only way Chrome is started here.
›
chrome installInstalls the launcher links and menu entry that point Chrome at chrome.sh; run once per machine and again after a Chrome update.
›
chrome flagsOpens the flags file: the one list that chrome.sh and the browser recorder both read.
›
jev browser testRuns a goal against a browser and reports only the text and URL assertions it was given.
›
jev installInstalls the pinned jev-ultrafast checkout and the jev-browser-test command in ~/.local/bin.
›
‹ Home

machine

This Linux machine: power, repairs, Deskflow and audio sharing.

powerOpens the power screen: CPU profiles, the external monitor mode and the lid settings.
›
repairOpens the repair screen: network, remote access, keyboard, mouse, disk and WhatsApp fixes, and the port helper.
›
deskflowOpens the Deskflow screen: the shared mouse and laptop keyboard that replaced Lan Mouse.
›
audio-shareSends all Linux audio to the Windows PC over Tailscale; audio-pause restores the speakers.
›
‹ machine

power

Power and display on this machine: CPU profiles, the external monitor mode, and the lid.

cpu-min-powerSets the power-saver profile, turns turbo off and caps the CPU at 8% of max; asks for sudo and works only on Intel P-state.
›
cpu-normal-powerSets the balanced profile, turns turbo on and lifts the CPU cap back to 100%.
›
hdmi monitorSets the mode and refresh rate of the external HDMI or DP output with xrandr; the default is 1920x1080 at 59.88.
›
lid keep awakeWrites the logind drop-in so closing the lid does nothing; it applies after a reboot.
›
lid restoreRemoves that drop-in so closing the lid works as before; it applies after a reboot.
›
‹ machine

repair

Repairs for this machine: network, remote access, keyboard, mouse, disk, WhatsApp and ports.

internet recoveryRepairs DNS through systemd-resolved, restarts NetworkManager and cycles networking; it reruns itself with sudo.
›
tailscale recoveryRepairs DNS, restarts tailscaled, waits up to 30 s for reconnect, then starts remote-terminal and checks port 3500.
›
fix-keyboardRuns the keyboard repair helper; utils.zsh has the exact steps.
›
fix-mouseRuns the mouse repair helper; utils.zsh has the exact steps.
›
fix-diskRuns the disk repair helper; utils.zsh has the exact steps.
›
fix-whatsappRuns the WhatsApp repair helper; utils.zsh has the exact steps.
›
killportRuns killport, the terminal helper for a port; utils.zsh has the exact steps.
›
‹ machine

deskflow

Deskflow: sharing the laptop's keyboard and trackpad with the Windows PC, and the USB mouse.

deskflow guideOpens the Deskflow guide: everyday use, the Windows admin terminal, and recovery.
›
usb mouse notesOpens the USB mouse notes: how the keyboard follows the mouse, and how to turn USB sharing back on.
›
resume-kvmStarts Deskflow again and asks for input access; use it after a canceled prompt.
›
deskflow serviceRuns the Deskflow server when the graphical session starts; a canceled input prompt stops it.
›
‹ Home

servers

Things that run as a server or page on this machine, and where to open them.

dashboardRuns the dashboard server; its page at 127.0.0.1:8780 shows what waits for you.
›
dashboard conceptsRuns the concepts version of the dashboard, with the Projects panel, at 127.0.0.1:8781.
›
Agent SandboxRuns the Agent Sandbox page, where you pick an agent, change its setup and send it a message.
›
clipstackRuns the clipstack server and watcher services that share the clipboard.
›
supabase keepaliveInstalls the timer that runs supabase-keepalive.sh on a schedule.
›
Hermes gatewayRuns the Hermes gateway that serves both Telegram bots; the laptop must stay awake and online.
›
‹ Home

documents

Documents: plans, designs, research, items, CVs, case studies, incidents, specs and the archive.

plansOpens the plans folder: one dated plan.md per piece of work.
›
designOpens the design pitches, recommendations and flow cards, one dated folder each.
›
researchOpens the research notes behind the designs and plans.
›
itemsOpens the planned, urgent and work item lists.
›
changelogOpens the dated changelog entries.
›
specsOpens the intents and Gherkin features that specify each module, and the QA findings.
›
CVsOpens the CVs: the three PDFs, their LaTeX sources, and the steps to rebuild them in cv/README.md.
›
case studiesOpens the human-reviewed experiments, one folder each.
›
incidentsOpens the dated incident records for machine-level failures and repairs.
›
rolesOpens the draft role skills: admin, qa-agent, supervisor and worker.
›
archiveOpens the archive: files moved out of projects, each folder with an ARCHIVE.md; it is not backed up.
›
‹ Home

shell

The shell: the zsh helpers, Git settings and hooks, and API keys that every terminal and bash session gets.

workstation commandDefines the workstation command, with the ws and setup aliases and the help screens.
›
review-openOpens a file for review, from zsh, bash or an agent.
›
git checkout guardLists the files and asks [y/N] before a git checkout would discard unstaged changes.
›
infraDefines the Docker and Compose shortcuts, the Prisma and Postgres helpers, and the nginx and VPN commands.
›
utilsDefines the terminal helpers, IP aliases, lazy nvm and node, Android, Java and Bun setup, and the repair helpers.
›
opencode commandsDefines the opencode and oc commands; they are listed under assistants, opencode.
›
api keysOpens the API keys file, which is never in Git.
›
dash-path checkDefines the dash-path warning; its file says what it checks.
›
git hooksOpens the global git hooks: Lefthook shims that run in every repo and need lefthook on PATH.
›
gitconfigOpens the Git config: author identity, LFS, the credential store and the hooks path.
›
‹ Home

windows

The Windows PC: the install and checks, the skills sync, and the mirrored instruction files. These run on Windows, not in this shell.

installRuns the install that rebuilds the Windows dev environment from the manifests; approve the admin prompt.
›
checksRuns the checks that the install worked.
›
roll backRolls the install back from its journal.
›
sign-insOpens the list of sign-ins to redo by hand.
›
inventoryOpens the inventory of what the install captured.
›
skills syncOpens the skills sync, where a runner updates the skills on each trusted push to master.
›
repo cloneClones the missing Betec repos into the standard workspace layout; safe to run again.
›
windows instructionsOpens the mirror of the Windows desktop's CLAUDE.md and four docs.
›
desktop backupOpens the portable snapshot of the Windows desktop's instructions; nothing loads it automatically.
›
usage guard installRuns the Windows install of the usage guard.
›
clipstack installRuns install.ps1, which sets up the Windows clipstack from clipstack.ahk.
›
codex bridge taskInstalls the Scheduled Task that keeps the Codex Chrome bridge patched.
›
Raw answer
## Map for `workstation`

**Scenario (reasoning from the README, not observed use):** the owner sits at a terminal and asks "where is X", "how do I start Y", or "how do I fix Z". They need to tell apart the many helpers, background servers, and Windows-only pieces. Each screen answers one of those questions.

**Judgment calls:**
- The top screen has seven groups, grouped by job, not by folder.
- I named the AI group `assistants` rather than `agents`, because `agent` is already a command.
- Retired items (Lan Mouse, playwright-mcp) are left out.
- The credentials embedded in `zsh.d/infra.zsh` and `zsh.d/utils.zsh` are not printed. The help points at those files without showing the URLs.
- I could not open any file. Forms come from the README and the file list. Where the README gives no purpose for a thing (`team-park`, `dash-path-warn`, the `fix-*` helpers, `killport`, `opencode-profile`), the line says so and points at the source.

**Questions for you:**
1. **Facade names.** The README gives `workstation`, `ws` and `setup`. I recommend keeping `workstation` and `ws`, and dropping `setup` because it reads as an install command. Your call.
2. **Split `assistants`?** It has 12 rows. I recommend moving the data repo, the supervision backlog and the agent records behind a `records` screen, since agents write those and you don't edit them. The map below is not split yet, pending your answer.
3. **Windows items.** These run on Windows, not here. Should `workstation windows <item>` print the PowerShell command for you to run there? I recommend printing only, not running.
4. **Files named but not in the listing.** `workstation.zsh`, `workstation-cli/`, `resume-kvm`, `init-windows/inventory.md`, and `audio-share` appear in the README but not in the file list. Do they exist? Anything missing gets dropped from the map.

```json
{"screens": [
{"path": [], "sentence": "The workstation's map: the areas of one developer's documents, config, scripts, agent setup and small tools on this Linux machine.", "rows": [
{"name": "assistants", "form": "workstation assistants", "what": "Opens the assistants screen: Claude, Codex, OpenCode and Hermes, with the rules, skills and records they share."},
{"name": "browser", "form": "workstation browser", "what": "Opens the browser screen: the browser command, the Chrome launcher and the jev browser check."},
{"name": "machine", "form": "workstation machine", "what": "Opens the machine screen: power, repairs, Deskflow and audio sharing for this Linux machine."},
{"name": "shell", "form": "workstation shell", "what": "Opens the shell screen: the zsh helpers, Git settings and hooks, and API keys that every terminal gets."},
{"name": "servers", "form": "workstation servers", "what": "Opens the servers screen: the dashboards, the Agent Sandbox, clipstack, the Supabase keepalive and the Hermes gateway."},
{"name": "documents", "form": "workstation documents", "what": "Opens the documents screen: plans, designs, research, items, CVs, case studies, incidents, specs and the archive."},
{"name": "windows", "form": "workstation windows", "what": "Opens the Windows screen: the install, checks, skills sync and mirrored instruction files that run on the Windows PC."}
]},
{"path": ["assistants"], "sentence": "The AI assistants on this machine, and the rules, skills and records they share.", "rows": [
{"name": "rules", "form": "rules [folder]", "what": "Prints the rules that apply everywhere, or to one folder, from workboard/rules.yaml."},
{"name": "agent", "form": "agent-framework/agent", "what": "Runs the agent records: agent check refuses broken ones, agent list lists them, agent serve starts the Agent Sandbox."},
{"name": "team-park", "form": "~/.local/bin/team-park (claude/team-park/team_park.py)", "what": "Runs team-park; its README in claude/team-park says what it does."},
{"name": "my-skills", "form": "~/projects/my-skills", "what": "Opens the skills and agent records repo, whose skills are linked into the assistants' folders."},
{"name": "backed-up skills", "form": "claude/skills/", "what": "Opens the copies of skills kept in this repo; copy the ones you want into ~/.claude/skills."},
{"name": "agent notes", "form": "claude/AGENTS.md", "what": "Opens the shorter global agent notes, next to claude/CLAUDE.md."},
{"name": "data", "form": "~/projects/data", "what": "Opens the private data repo: cases, rule proposals, verdicts and team reviews that agents write."},
{"name": "supervision backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "Opens the supervision backlog, which lives in the betec workboard, not in this repo."},
{"name": "claude", "form": "workstation assistants claude", "what": "Opens the Claude screen: its wrapper, session types, rules, hooks and plugin mods."},
{"name": "codex", "form": "workstation assistants codex", "what": "Opens the Codex screen: its config, the Chrome bridge that keeps its plugin working, and its browser notes."},
{"name": "opencode", "form": "workstation assistants opencode", "what": "Opens the OpenCode screen: the commands that run it with the current profile, and the files each profile loads."},
{"name": "hermes", "form": "workstation assistants hermes", "what": "Opens the Hermes screen: its launcher, example settings and restore runbook."}
]},
{"path": ["assistants", "claude"], "sentence": "Claude Code: how it is started, which session it resumes, and the rules and hooks it runs with.", "rows": [
{"name": "claude", "form": "~/bin/claude", "what": "Runs Claude Code through the usage guard, ahead of the native ~/.local/bin/claude."},
{"name": "usage guard", "form": "claude/usage-guard/", "what": "Opens the usage guard folder: install.sh, the plugin and the request-budget tests."},
{"name": "session types", "form": "claude --main -c and claude --main -r", "what": "Runs claude --main -c or -r, which resume the main session through main-sessions.py."},
{"name": "global rules", "form": "claude/CLAUDE.md", "what": "Opens the global rules every Claude session reads: browser automation, communication style, research, and presenting work."},
{"name": "settings", "form": "claude/settings.json", "what": "Opens the Claude Code settings this kit keeps; the machine's own ~/.claude/settings.json is separate."},
{"name": "hooks", "form": "claude/hooks/", "what": "Opens the hook scripts wired into ~/.claude/settings.json: core rules, machine history, team activity, local server guard and proof reminder."},
{"name": "plugin mods", "form": "claude/mods/", "what": "Opens the Claude plugin mods: changelog pane, review pane, scratchpad playground and team board."},
{"name": "linux global", "form": "claude/linux-global/", "what": "Opens the mirror of this machine's global CLAUDE.md, AGENTS.md and four docs."}
]},
{"path": ["assistants", "codex"], "sentence": "Codex: its config, the Chrome bridge that keeps its plugin working, and its browser notes.", "rows": [
{"name": "codex config", "form": "codex/config.toml", "what": "Opens the Codex CLI config this kit keeps; ~/.codex/config.toml on this machine is machine-local."},
{"name": "chrome bridge install", "form": "codex/chrome-bridge/install.sh", "what": "Installs the systemd watcher and timer that keep the Chrome plugin's latest link working."},
{"name": "chrome bridge", "form": "codex/chrome-bridge/", "what": "Opens the Chrome bridge folder and its README: restart rules and the repair script."},
{"name": "browser notes", "form": "codex/browser/", "what": "Opens the notes on Codex's direct Chrome command path and its live verification."}
]},
{"path": ["assistants", "opencode"], "sentence": "OpenCode: the commands that run it with the current profile, and the files each profile loads.", "rows": [
{"name": "opencode", "form": "opencode (also oc)", "what": "Runs opencode with the current profile; oc is the same command."},
{"name": "opencode help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints every profile's files, one column per profile, and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it."},
{"name": "opencode-profile", "form": "opencode-profile", "what": "Prints the current profile's name; the README only says it names the profile, so check the source."},
{"name": "opencode-profiles", "form": "opencode-profiles", "what": "Lists what each profile loads."},
{"name": "opencode-switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "opencode-login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "opencode-files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "opencode-edit", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files."},
{"name": "profile files", "form": "opencode-profiles/", "what": "Opens the profile folder: profiles.py and each profile's CLAUDE.md, settings and opencode.json."}
]},
{"path": ["assistants", "hermes"], "sentence": "Hermes: its launcher, the source it was installed from, its example settings and its restore runbook.", "rows": [
{"name": "hermes", "form": "hermes (~/.local/bin/hermes)", "what": "Runs Hermes, the agent installed from source."},
{"name": "checkout", "form": "~/projects/hermes-agent", "what": "Opens the Hermes source checkout, the code the launcher runs."},
{"name": "restore runbook", "form": "hermes/RESTORE.md", "what": "Opens the restore runbook: how to bring Hermes back."},
{"name": "example settings", "form": "hermes/default.config.example.yaml and hermes/jobs.config.example.yaml", "what": "Opens the secret-free example settings for the default and jobs profiles."},
{"name": "PATH lines", "form": "hermes/zprofile-path.zsh", "what": "Opens the PATH lines the installer added to ~/.zprofile."},
{"name": "backup note", "form": "hermes/BACKUP-2026-10-02.md", "what": "Opens the backup note from 2026-10-02."}
]},
{"path": ["browser"], "sentence": "The browser: the browser command, Chrome, and the jev browser check.", "rows": [
{"name": "browser", "form": "browser '<json steps>'", "what": "Runs a JSON list of browser steps on one Chrome window that stays open between calls."},
{"name": "browser status", "form": "browser status", "what": "Prints whether the background server and its browser are up."},
{"name": "browser close", "form": "browser close", "what": "Closes the browser and stops the background server."},
{"name": "recording", "form": "browser/README.md#recording-proof", "what": "Records the current tab as proof of a feature, between a recordStart step and a recordStop step."},
{"name": "browser guide", "form": "browser/README.md", "what": "Opens the browser guide: every action, viewport preset, network capture and login gotcha."},
{"name": "chrome", "form": "google-chrome (runs chrome/chrome.sh)", "what": "Starts Chrome with the flags in chrome/flags; this is the only way Chrome is started here."},
{"name": "chrome install", "form": "chrome/install.sh", "what": "Installs the launcher links and menu entry that point Chrome at chrome.sh; run once per machine and again after a Chrome update."},
{"name": "chrome flags", "form": "chrome/flags", "what": "Opens the flags file: the one list that chrome.sh and the browser recorder both read."},
{"name": "jev browser test", "form": "jev-browser-test", "what": "Runs a goal against a browser and reports only the text and URL assertions it was given."},
{"name": "jev install", "form": "jev-browser-test/install.sh", "what": "Installs the pinned jev-ultrafast checkout and the jev-browser-test command in ~/.local/bin."}
]},
{"path": ["machine"], "sentence": "This Linux machine: power, repairs, Deskflow and audio sharing.", "rows": [
{"name": "power", "form": "workstation machine power", "what": "Opens the power screen: CPU profiles, the external monitor mode and the lid settings."},
{"name": "repair", "form": "workstation machine repair", "what": "Opens the repair screen: network, remote access, keyboard, mouse, disk and WhatsApp fixes, and the port helper."},
{"name": "deskflow", "form": "workstation machine deskflow", "what": "Opens the Deskflow screen: the shared mouse and laptop keyboard that replaced Lan Mouse."},
{"name": "audio-share", "form": "audio-start, audio-pause, audio-share on|off|status|tone", "what": "Sends all Linux audio to the Windows PC over Tailscale; audio-pause restores the speakers."}
]},
{"path": ["machine", "power"], "sentence": "Power and display on this machine: CPU profiles, the external monitor mode, and the lid.", "rows": [
{"name": "cpu-min-power", "form": "cpu-min-power.sh", "what": "Sets the power-saver profile, turns turbo off and caps the CPU at 8% of max; asks for sudo and works only on Intel P-state."},
{"name": "cpu-normal-power", "form": "cpu-normal-power.sh", "what": "Sets the balanced profile, turns turbo on and lifts the CPU cap back to 100%."},
{"name": "hdmi monitor", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output with xrandr; the default is 1920x1080 at 59.88."},
{"name": "lid keep awake", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes the logind drop-in so closing the lid does nothing; it applies after a reboot."},
{"name": "lid restore", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in so closing the lid works as before; it applies after a reboot."}
]},
{"path": ["machine", "repair"], "sentence": "Repairs for this machine: network, remote access, keyboard, mouse, disk, WhatsApp and ports.", "rows": [
{"name": "internet recovery", "form": "linux-internet-recovery.sh", "what": "Repairs DNS through systemd-resolved, restarts NetworkManager and cycles networking; it reruns itself with sudo."},
{"name": "tailscale recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, waits up to 30 s for reconnect, then starts remote-terminal and checks port 3500."},
{"name": "fix-keyboard", "form": "fix-keyboard (zsh.d/utils.zsh)", "what": "Runs the keyboard repair helper; utils.zsh has the exact steps."},
{"name": "fix-mouse", "form": "fix-mouse (zsh.d/utils.zsh)", "what": "Runs the mouse repair helper; utils.zsh has the exact steps."},
{"name": "fix-disk", "form": "fix-disk (zsh.d/utils.zsh)", "what": "Runs the disk repair helper; utils.zsh has the exact steps."},
{"name": "fix-whatsapp", "form": "fix-whatsapp (zsh.d/utils.zsh)", "what": "Runs the WhatsApp repair helper; utils.zsh has the exact steps."},
{"name": "killport", "form": "killport (zsh.d/utils.zsh)", "what": "Runs killport, the terminal helper for a port; utils.zsh has the exact steps."}
]},
{"path": ["machine", "deskflow"], "sentence": "Deskflow: sharing the laptop's keyboard and trackpad with the Windows PC, and the USB mouse.", "rows": [
{"name": "deskflow guide", "form": "deskflow/README.md", "what": "Opens the Deskflow guide: everyday use, the Windows admin terminal, and recovery."},
{"name": "usb mouse notes", "form": "deskflow/usb-mouse/README.md", "what": "Opens the USB mouse notes: how the keyboard follows the mouse, and how to turn USB sharing back on."},
{"name": "resume-kvm", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input access; use it after a canceled prompt."},
{"name": "deskflow service", "form": "~/.config/systemd/user/deskflow.service", "what": "Runs the Deskflow server when the graphical session starts; a canceled input prompt stops it."}
]},
{"path": ["servers"], "sentence": "Things that run as a server or page on this machine, and where to open them.", "rows": [
{"name": "dashboard", "form": "http://127.0.0.1:8780 (run: python3 ~/projects/workstation/dashboard/server.py)", "what": "Runs the dashboard server; its page at 127.0.0.1:8780 shows what waits for you."},
{"name": "dashboard concepts", "form": "http://127.0.0.1:8781 (run: python3 ~/projects/workstation/dashboard-concepts/server.py)", "what": "Runs the concepts version of the dashboard, with the Projects panel, at 127.0.0.1:8781."},
{"name": "Agent Sandbox", "form": "http://127.0.0.1:8790 (run: agent serve)", "what": "Runs the Agent Sandbox page, where you pick an agent, change its setup and send it a message."},
{"name": "clipstack", "form": "clipstack/units/ (clipstack-server.service, clipstack-watcher.service)", "what": "Runs the clipstack server and watcher services that share the clipboard."},
{"name": "supabase keepalive", "form": "supabase-keepalive/install.sh", "what": "Installs the timer that runs supabase-keepalive.sh on a schedule."},
{"name": "Hermes gateway", "form": "hermes (gateway)", "what": "Runs the Hermes gateway that serves both Telegram bots; the laptop must stay awake and online."}
]},
{"path": ["documents"], "sentence": "Documents: plans, designs, research, items, CVs, case studies, incidents, specs and the archive.", "rows": [
{"name": "plans", "form": "docs/plans/", "what": "Opens the plans folder: one dated plan.md per piece of work."},
{"name": "design", "form": "docs/design/ and docs/flows/", "what": "Opens the design pitches, recommendations and flow cards, one dated folder each."},
{"name": "research", "form": "docs/research/ and docs/functional-research/", "what": "Opens the research notes behind the designs and plans."},
{"name": "items", "form": "docs/items/", "what": "Opens the planned, urgent and work item lists."},
{"name": "changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "specs", "form": ".idd/ and .bdd/", "what": "Opens the intents and Gherkin features that specify each module, and the QA findings."},
{"name": "CVs", "form": "cv/", "what": "Opens the CVs: the three PDFs, their LaTeX sources, and the steps to rebuild them in cv/README.md."},
{"name": "case studies", "form": "case-studies/", "what": "Opens the human-reviewed experiments, one folder each."},
{"name": "incidents", "form": "reference/", "what": "Opens the dated incident records for machine-level failures and repairs."},
{"name": "roles", "form": "docs/roles/", "what": "Opens the draft role skills: admin, qa-agent, supervisor and worker."},
{"name": "archive", "form": "~/archive/", "what": "Opens the archive: files moved out of projects, each folder with an ARCHIVE.md; it is not backed up."}
]},
{"path": ["shell"], "sentence": "The shell: the zsh helpers, Git settings and hooks, and API keys that every terminal and bash session gets.", "rows": [
{"name": "workstation command", "form": "zsh.d/workstation.zsh", "what": "Defines the workstation command, with the ws and setup aliases and the help screens."},
{"name": "review-open", "form": "review-open (~/.local/bin/review-open; zsh.d/review-open.zsh)", "what": "Opens a file for review, from zsh, bash or an agent."},
{"name": "git checkout guard", "form": "zsh.d/git-safety.zsh", "what": "Lists the files and asks [y/N] before a git checkout would discard unstaged changes."},
{"name": "infra", "form": "zsh.d/infra.zsh", "what": "Defines the Docker and Compose shortcuts, the Prisma and Postgres helpers, and the nginx and VPN commands."},
{"name": "utils", "form": "zsh.d/utils.zsh", "what": "Defines the terminal helpers, IP aliases, lazy nvm and node, Android, Java and Bun setup, and the repair helpers."},
{"name": "opencode commands", "form": "zsh.d/opencode-profiles.zsh", "what": "Defines the opencode and oc commands; they are listed under assistants, opencode."},
{"name": "api keys", "form": "api-keys-edit (opens ~/.config/api-keys/env)", "what": "Opens the API keys file, which is never in Git."},
{"name": "dash-path check", "form": "zsh.d/dash-path-warn.zsh", "what": "Defines the dash-path warning; its file says what it checks."},
{"name": "git hooks", "form": "git-hooks/ (installed at ~/.git-hooks)", "what": "Opens the global git hooks: Lefthook shims that run in every repo and need lefthook on PATH."},
{"name": "gitconfig", "form": ".gitconfig (installed at ~/.gitconfig)", "what": "Opens the Git config: author identity, LFS, the credential store and the hooks path."}
]},
{"path": ["windows"], "sentence": "The Windows PC: the install and checks, the skills sync, and the mirrored instruction files. These run on Windows, not in this shell.", "rows": [
{"name": "install", "form": "init-windows/Start-Install.cmd", "what": "Runs the install that rebuilds the Windows dev environment from the manifests; approve the admin prompt."},
{"name": "checks", "form": "init-windows/Smoke-Test-Windows.ps1 and init-windows/Verify-Windows.ps1", "what": "Runs the checks that the install worked."},
{"name": "roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Rolls the install back from its journal."},
{"name": "sign-ins", "form": "init-windows/secrets-checklist.md", "what": "Opens the list of sign-ins to redo by hand."},
{"name": "inventory", "form": "init-windows/inventory.md", "what": "Opens the inventory of what the install captured."},
{"name": "skills sync", "form": "skills-sync-windows/README.md", "what": "Opens the skills sync, where a runner updates the skills on each trusted push to master."},
{"name": "repo clone", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing Betec repos into the standard workspace layout; safe to run again."},
{"name": "windows instructions", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows desktop's CLAUDE.md and four docs."},
{"name": "desktop backup", "form": "claude/backups/desktop-v2-2026/", "what": "Opens the portable snapshot of the Windows desktop's instructions; nothing loads it automatically."},
{"name": "usage guard install", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Runs the Windows install of the usage guard."},
{"name": "clipstack install", "form": "clipstack/windows/install.ps1", "what": "Runs install.ps1, which sets up the Windows clipstack from clipstack.ahk."},
{"name": "codex bridge task", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs the Scheduled Task that keeps the Codex Chrome bridge patched."}
]}
],
"questions": [
"Facade names: the README gives workstation, ws and setup. Recommend keeping workstation and ws, and dropping setup, which reads as an install command. Which do you want?",
"Split the assistants screen? It has 12 rows. Recommend moving the data repo, the supervision backlog and the agent records behind a records screen, since agents write those and you don't edit them. Yes or no?",
"Windows items run on Windows, not in this shell. Should workstation windows <item> print the PowerShell command for you to run there, or only show the file? Recommend printing only.",
"Do these exist here? workstation.zsh, workstation-cli/, resume-kvm, init-windows/inventory.md and audio-share are named in the README but are not in the file list. Anything missing gets dropped from the map."
]}
```

screen-decomposition, final · run 1 exit=0 seconds=193 · prompt

P1 Recall: 0.771P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 9P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.272
As terminal help
Everything this workstation has, grouped by what you do with it.
shell and gitworkstation shell-and-gitPrints the shell and git screen: the zsh helpers, opencode profiles and git setup this machine loads.
machine utilitiesworkstation machine-utilitiesPrints the machine utilities screen: the Linux power, display, network and laptop scripts and the fix commands.
AI assistant setupworkstation ai-assistant-setupPrints the AI assistant setup screen: the Claude and Codex rules and settings, the skills, and the agent system.
browserworkstation browserPrints the browser screen: the browser command, Chrome's launcher, and the browser smoke QA.
toolsworkstation toolsPrints the tools screen: the dashboards, Deskflow, Hermes, clipboard, audio and the Supabase keepalive.
windowsworkstation windowsPrints the windows screen: the Windows bootstrap, the skill sync and the repo clone.
CVsworkstation cvPrints the CVs screen: the three CV versions, their sources and the build commands.
docsworkstation docsPrints the docs screen: the plans, designs, research, flows, changelog, items, roles and intent folders.
case studiesworkstation case-studiesPrints the case studies screen: the archived experiments and the dated machine incidents.
shell-and-git
The zsh helpers, the opencode profile commands and the git setup.
zsh helpersworkstation shell-and-git zsh-helpersPrints the zsh helpers screen: the files in ~/.zsh.d/ and what each adds to the shell.
opencode profilesworkstation shell-and-git opencode-profilesPrints the opencode profiles screen: opencode and oc, and the commands that choose a profile.
gitworkstation shell-and-git gitPrints the git screen: the author and credential settings, the hooks and the hook scripts.
shell-and-git › zsh-helpers
The helper files this shell sources from ~/.zsh.d/.
git safety~/.zsh.d/git-safety.zshWraps git checkout: lists the files it would discard and asks [y/N] first.
infra~/.zsh.d/infra.zshSets up Docker and Compose shortcuts, Prisma and Postgres helpers, and nginx and VPN commands.
utils~/.zsh.d/utils.zshSets up terminal helpers (set-title, killport), IP aliases, lazy-loaded nvm and node, Android, Java and Bun.
api keys~/.zsh.d/api-keys.zshExports the general-use API keys kept in ~/.config/api-keys/env; api-keys-edit opens that file.
dash path warn~/.zsh.d/dash-path-warn.zshRuns the dash path check; the README does not say what it checks.
rulesrules, from ~/.zsh.d/rules.zshPrints the rules, or the rules of one folder with rules [folder].
review openreview-open, from ~/.zsh.d/review-open.zshOpens a file for review; ~/.local/bin/review-open does the same for bash and agents.
opencode profiles file~/.zsh.d/opencode-profiles.zshRuns opencode and oc with the current profile; ~/.bashrc sources it too.
shell-and-git › opencode-profiles
The opencode and oc commands and the profile commands that run with the current profile.
opencode and ocopencode (also oc)Runs opencode with the current profile.
opencode-profileopencode-profileSets which profile is current.
opencode-profilesopencode-profilesLists what each profile loads.
opencode-switchopencode-switch <name>Switches every shell's new runs to the named profile.
opencode-loginopencode-loginSigns a profile's Claude Code in.
opencode-filesopencode-filesLists the current profile's files.
opencode-editopencode-edit <file>Opens one of the current profile's files for editing.
opencode helpopencode help (also oc help, opencode-help, oc-help)Prints every profile's files, one column per profile; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
profile definitionsopencode-profiles/Opens the profile definitions, one folder per profile, including private-leb-experimental.
shell-and-git › git
The git settings, the hooks and the hook scripts.
git settings~/.gitconfig (from .gitconfig)Opens the git settings: author, Git LFS, the credential helper and the hooks path.
git hooks~/.git-hooks/ (from git-hooks/)Opens the Lefthook shims that run in every repo; they need lefthook on the PATH.
scenario gategit-hooks/scenario-gate.pyRuns the scenario gate from the hooks; the README does not describe its check.
machine-utilities
The Linux scripts for power, display, network and the laptop lid, and the fix commands.
power savecpu-min-power.shSets the power-saver profile, turbo off, CPU capped at 8% of max; asks for sudo.
power normalcpu-normal-power.shSets the balanced profile, turbo on, and the cap back to 100%.
external monitorfix_old_monitor_hdmi.shSets a mode and refresh rate on the external HDMI or DP output with xrandr.
internet recoverylinux-internet-recovery.shRepairs the network: enables systemd-resolved, repoints DNS and cycles networking; re-runs itself with sudo.
tailscale remote terminalrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, waits for reconnect, and checks the remote terminal on port 3500.
keep running lid closedlaptop-utilities/keep-running-with-lid-closed.shWrites a logind drop-in so closing the lid does nothing; applies after a reboot.
restore lid behaviorlaptop-utilities/restore-default-lid-behavior.shRemoves that logind drop-in; applies after a reboot.
fix keyboardfix-keyboardRepairs the keyboard.
fix mousefix-mouseRepairs the mouse.
fix diskfix-diskRepairs the disk.
fix whatsappfix-whatsappRepairs WhatsApp.
ai-assistant-setup
The global rules, settings and skills for Claude, Codex and the agent system.
global rulesclaude/CLAUDE.mdOpens the global rules: browser automation, communication style, research, and how to present work.
agent notesclaude/AGENTS.mdOpens the shorter global agent notes.
claude settingsclaude/settings.jsonOpens the Claude Code settings that init-windows deploys to Windows.
codex configcodex/config.tomlOpens the Codex CLI config that init-windows deploys to Windows.
communication draftclaude/communication-framework.mdOpens the communication design draft; nothing enforces it yet.
skills shortlistclaude/skills-shortlist.mdOpens the skills researched on skills.sh and which of them are installed.
linux instructionsclaude/linux-global/Opens the mirror of the Linux machine's installed global instructions.
windows instructionsclaude/windows-global/Opens the mirror of the Windows desktop's installed CLAUDE.md and its docs.
desktop v2 snapshotclaude/backups/desktop-v2-2026/Opens the portable snapshot of the Windows desktop's instructions and two skills; it does not load itself.
skill backupsworkstation ai-assistant-setup skill-backupsPrints the skill backups screen: the skills kept here, to copy into ~/.claude/skills/.
global skillsworkstation ai-assistant-setup global-skillsPrints the global skills screen: the skills that live in Lebnor/my-skills.
agent systemworkstation ai-assistant-setup agent-systemPrints the agent system screen: the rules, agent records, hooks and plugins.
ai-assistant-setup › skill-backups
The skills kept here as backups in claude/skills/; copy the ones you want into ~/.claude/skills/.
tech-ledgerclaude/skills/tech-ledger/Opens the backup of the skill that reads and writes the betec Tech Ledger.
api-key-creationclaude/skills/api-key-creation/Opens the backup of the skill for getting a missing API key with browser tools.
clone-websiteclaude/skills/clone-website/Opens the backup of the website cloning skill.
contextual-value-product-thinkingclaude/skills/contextual-value-product-thinking/Opens the backup of the skill that analyzes products through contextual human values.
web research assistantclaude/skills/elad12390--web-research-assistant/Opens the backup of the web research MCP skill; its setup is in SETUP-NOTES.md.
epic-fanout-planningclaude/skills/epic-fanout-planning/Opens the backup of the 10-step pattern for QA-gap epics with parallel fan-out.
impeccableclaude/skills/impeccable/Opens the backup of the frontend design skill: shape, critique, audit, polish.
iterative-action-reviewclaude/skills/iterative-action-review/Opens the backup of the review of one completed real-world action in a series.
lab-experimentclaude/skills/lab-experiment/Opens the backup of how to run an experiment in ai-lab.
mentor-modeclaude/skills/mentor-mode/Opens the backup of the mentor mode skill with its runtime and scripts.
post-feature-cleanupclaude/skills/post-feature-cleanup/Opens the backup of the pass after writing code: UI defects, leftovers and repo hygiene.
powershell-launchingclaude/skills/powershell-launching/Opens the backup of the skill for launching PowerShell or a new terminal on Windows.
reboot-resumeclaude/skills/reboot-resume/Opens the backup of the skill for preserving work across a reboot or restart.
resume-projectclaude/skills/resume-project/Opens the backup of the resume-project skill and its script.
solaraai-content-calendarclaude/skills/solaraai-content-calendar/Opens the backup of the SolaraAI content calendar skill.
solaraai-deploymentclaude/skills/solaraai-deployment/Opens the backup of the SolaraAI deploy flow skill.
solaraai-designclaude/skills/solaraai-design/Opens the backup of the SolaraAI design system skill.
solaraai-formsclaude/skills/solaraai-forms/Opens the backup of the SolaraAI form behavior skill.
supabaseclaude/skills/supabase/Opens the backup of Supabase's own skill: Auth, RLS, migrations, CLI and debugging.
supabase-postgres-best-practicesclaude/skills/supabase-postgres-best-practices/Opens the backup of Supabase's Postgres performance rules.
tank--communication-engineeringclaude/skills/tank--communication-engineering/Opens the backup of the discipline for what an agent says and how much.
tank--skill-creatorclaude/skills/tank--skill-creator/Opens the backup of the skill for creating new skills.
tech-cv-writerclaude/skills/tech-cv-writer/Opens the backup of the CV writer skill with its ATS and template references.
ai-assistant-setup › global-skills
The skills that live in Lebnor/my-skills and that install.sh links into the agent skill folders.
supabase/home/liel/projects/my-skills/supabase/SKILL.mdOpens the source of Supabase's skill for Auth, RLS and migrations.
supabase-postgres-best-practices/home/liel/projects/my-skills/supabase-postgres-best-practices/SKILL.mdOpens the source of Supabase's Postgres performance rules.
clone-website/home/liel/projects/my-skills/clone-website/SKILL.mdOpens the source of the website cloning skill with its builder agents.
lab-experiment/home/liel/projects/my-skills/lab-experiment/SKILL.mdOpens the source of how to run an experiment in /home/liel/projects/ai-lab.
coding-guidelines/home/liel/projects/my-skills/coding-guidelines/SKILL.mdOpens the source of the house coding rules: lean code, reuse before writing, component file order.
volatility-based-decomposition/home/liel/projects/my-skills/volatility-based-decomposition/SKILL.mdOpens the source of the decomposition skill for architect-tier work.
working-with-windows/home/liel/projects/my-skills/working-with-windows/SKILL.mdOpens the source of the Windows gotchas for Node MCP servers that call PowerShell.
solaraai-content-calendar/home/liel/projects/my-skills/solaraai-content-calendar/SKILL.mdOpens the source of the SolaraAI content calendar skill.
solaraai-deployment/home/liel/projects/my-skills/solaraai-deployment/SKILL.mdOpens the source of the SolaraAI deploy flow skill.
solaraai-design/home/liel/projects/my-skills/solaraai-design/SKILL.mdOpens the source of the SolaraAI design system skill.
solaraai-forms/home/liel/projects/my-skills/solaraai-forms/SKILL.mdOpens the source of the SolaraAI form behavior skill.
ai-assistant-setup › agent-system
Where the rules, agent records, hooks and plugins live.
rulesworkboard/rules.yamlOpens the rules every org follows; only the user or an accepted proposal changes them.
rules metadataworkboard/rules-meta.yamlOpens the metadata kept for each rule.
rules testsworkboard/test_rules.pyTests the rules file.
agent checkagent-framework/agent checkChecks every agent record and refuses broken ones (exit 1).
agent listagent-framework/agent listLists the agents with their tier, model and number of tests.
agent sandboxagent-framework/agent serve (http://127.0.0.1:8790)Serves the Agent Sandbox page where you pick an agent and run it.
hooksworkstation ai-assistant-setup agent-system hooksPrints the hooks screen: the Claude Code hook scripts wired in ~/.claude/settings.json.
pluginsclaude/mods/Opens the Claude Code plugins: changelog pane, review pane, scratchpad playground and team board.
usage guardclaude/usage-guard/Wraps the claude command with the usage guard; ~/bin/claude runs ahead of the native one.
session typesclaude/session-types/session-types.shRuns at SessionStart; main-sessions.py serves claude --main -c and -r.
team parkclaude/team-park/team_park.pyRuns the team park tool, installed as ~/.local/bin/team-park.
ai-assistant-setup › agent-system › hooks
The Claude Code hook scripts in claude/hooks/, wired in ~/.claude/settings.json.
core rulesclaude/hooks/core-rules.shRuns at SessionStart and before each Bash call with the rules.
local server guardclaude/hooks/local-server-guard.pyRuns before each Bash call to guard the local server.
machine historyclaude/hooks/machine-history.shRuns as a hook wired in settings.json; the README gives no more detail.
proof reminderclaude/hooks/proof-reminder.shRuns after Edit, MultiEdit, Write and Bash to remind you to prove the change.
team activityclaude/hooks/team-activity.shRuns as a hook wired in settings.json; the README gives no more detail.
hook testsclaude/hooks/test_core_rules.shTests the core rules hook.
browser
The browser command, Chrome's launcher, the Codex Chrome path, and the browser smoke QA.
browserbrowser/browser.sh (~/.local/bin/browser)Runs browser steps in one Chrome window that stays open across calls.
browser statusbrowser statusPrints whether the background server and its Chrome are up.
browser closebrowser closeCloses Chrome and stops the background server.
recording proofbrowser/README.md (Recording proof)Opens the recording steps: recordStart and recordStop.
chromechrome/chrome.shStarts Chrome with the flags in chrome/flags; the only way Chrome starts here.
chrome flagschrome/flagsOpens the launch flags that chrome.sh and the recorder both read.
chrome installchrome/install.shLinks the Chrome launchers and menu entries to chrome.sh; run it once per machine.
codex browsercodex/browser/Opens Codex's direct Chrome command path and its live verification.
chrome bridgecodex/chrome-bridge/install.shMaintains the Chrome plugin's latest link and reapplies the local navigation patch.
smoke QAjev-browser-testRuns a goal against a browser and reports only the text and URL you assert.
jev installjev-browser-test/install.shInstalls the pinned jev-ultrafast checkout and the CLI into ~/.local/bin.
jev settings~/.config/jev-browser-test/envEdits the model keys and settings for the smoke QA; keep it out of Git.
tools
The small tools this machine runs: dashboards, Deskflow, Hermes, clipboard, audio and the Supabase keepalive.
dashboardhttp://127.0.0.1:8780 (dashboard/server.py)Starts the dashboard on port 8780, with the waiting list and the overview.
dashboard conceptshttp://127.0.0.1:8781 (dashboard-concepts/server.py)Starts the concepts version of the dashboard on port 8781, to compare with the first.
dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardTests the dashboard: 199 checks against the real data and a real server.
deskflowdeskflow/README.mdShares the laptop trackpad and keyboard with the Windows PC; shows everyday use and recovery.
deskflow USB mousedeskflow/usb-mouse/README.mdOpens the notes for turning back on the forwarded Windows USB mouse, off since 2026-10-20.
hermes~/.local/bin/hermes (source in ~/projects/hermes-agent)Runs the Hermes agent installed from source; its state lives in ~/.hermes.
hermes restorehermes/RESTORE.mdOpens the Hermes restore runbook.
clipboardclipstack/ (units in clipstack/units/)Runs the shared clipboard: server, watcher and picker, as systemd units.
clipboard on Windowsclipstack/windows/install.ps1Installs the Windows clipboard hotkey (clipstack.ahk); verify.ps1 checks it.
audio shareaudio-share/ (audio-start, audio-pause)Sends all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers.
supabase keepalivesupabase-keepalive/install.shRuns the Supabase keepalive on a timer; install.sh sets it up.
windows
The Windows bootstrap, the skill sync, and the cloning of the work repos.
init windowsinit-windows/Start-Install.cmdRebuilds the Windows dev environment from the manifests; approve the administrator prompt.
init checkinit-windows/Smoke-Test-Windows.ps1 (and Verify-Windows.ps1)Checks the install against the manifests.
init rollbackinit-windows/Remove-WindowsPack.ps1Removes the installed pack; close Node, npm, Git and VS Code first.
init manifestsinit-windows/manifests/Opens the exact program, Node and extension lists the install reads.
init inventoryinit-windows/inventory.mdOpens what the bootstrap captured.
init secretsinit-windows/secrets-checklist.mdOpens the sign-ins you redo by hand after the install.
skill syncskills-sync-windows/Sync-Skills.ps1Syncs the Windows skill links from my-skills after each trusted push.
skill sync testskills-sync-windows/Test-Sync.ps1Tests the skill sync.
skill sync accountskills-sync-windows/Test-Account.ps1Tests the runner account the sync uses.
clone reposrepos/Clone-BetecRepos.ps1Clones each missing Betec repo into the workspace; leaves existing folders alone.
cv
The three CV versions, their sources, the build commands and the dated versions.
Full Stack Developercv/cv-full-stack.pdf (source cv-full-stack.tex)Opens the PDF of the Full Stack Developer CV.
AI Full Stack Engineercv/cv-ai-full-stack.pdf (source cv-ai-full-stack.tex)Opens the PDF of the AI Full Stack Engineer CV.
AI Integrationscv/cv-ai-integrations.pdf (source cv-ai-integrations.tex)Opens the PDF of the AI Integrations CV.
buildcv/README.md (Update)Rebuilds the three PDFs with pdflatex from this folder.
text buildcv/text/build-full.shBuilds the full text of the CVs from their variables.
design buildcv/design/build-design.pyBuilds the HTML and PDF design of the AI Full Stack CV.
readable mastercv/cv-master.mdOpens the readable master of the CV content.
experience notescv/experience-notes.mdOpens the factual input for every CV; the README names it, the file list does not show it.
drafting decisionscv/cv-material-draft.mdOpens the record of the CV drafting decisions.
versionscv/versions/Opens the dated CV versions: 2026-10-04 and 2026-10-04-v2.
CV workflowcv/WORKFLOW.mdOpens the CV workflow.
docs
The working documents: plans, designs, research, flows, changelog, items, roles, playbooks and intent.
plansdocs/plans/Opens the dated plans, one folder per piece of work.
superpowers plansdocs/superpowers/plans/Opens the older plans folder, including the claude usage guard plan.
designdocs/design/Opens the dated design pitches and recommendations.
design referencesdocs/design-references/Opens the 2026-10-13 design mock-ups.
researchdocs/research/Opens the dated research and the phase checks.
functional researchdocs/functional-research/Opens the 2026-10-21 research into other agent tools.
flowsdocs/flows/Opens the flow cards and data models, dated by day.
changelogdocs/changelog/Opens the dated changelog entries.
itemsdocs/items/Opens the planned, urgent and work item lists.
rolesdocs/roles/Opens the role skills for admin, worker, supervisor and qa-agent, with the drafts.
playbooksdocs/playbooks/Opens the playbooks, such as talk-while-team-builds.
intent.idd/project.intent.md and .idd/modules/Opens the project intent and each module's INTENT.md.
features.bdd/features/Opens the Gherkin features, one folder per module.
qa findings.bdd/qa/findings/Opens the QA findings from the say-the-thing runs.
case-studies
The archived, human-reviewed experiments and the dated machine incident records.
codebot returncase-studies/conceptual-modeling/2026-09-15-codebot-return/Opens the same design request run with and without the conceptual-modeling skill.
signal gardencase-studies/blume-astryx/2026-09-16-signal-garden/Opens the documentation exhibit that separates Blume's explanation from Astryx's live interface.
kernel use cases/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the Kernel cloud browser results tested on 2026-10-08; the file is outside this repo.
referencereference/README.mdOpens the index of dated machine incidents and repairs.
codebot lid incidentreference/incidents/2026-10-01-codebot-lid-closed.mdOpens the closed-lid test record: the test passed for 1 minute 46 seconds with CodeBot healthy.
Questions
  • Should setup stay as a facade alias? It is generic and likely to clash. Recommendation: keep workstation and ws, and drop setup from the map.
  • tools has ten items. Should it split now, for example into dashboards and the rest? Recommendation: wait until it grows.
  • Should docs list only its folders, or also the individual pitches and recommendations? Recommendation: folders only.
  • skill backups has 23 flat rows. Should the Supabase and SolaraAI skills move to their own screens? Recommendation: yes.
  • Should the Claude backups desktop-v1-2026 and linux-v1-2026-10-03 be on the map? Recommendation: no, since the README points only to v2.
  • machine utilities has eleven rows. Should it split into power, network and laptop? Recommendation: leave it until it grows.
  • What do dash-path-warn.zsh, scenario-gate.py and deskflow-lockdown.nft do? Their lines say not described until you say.
As phone screens

Home

Everything this workstation has, grouped by what you do with it.

shell and gitPrints the shell and git screen: the zsh helpers, opencode profiles and git setup this machine loads.
›
machine utilitiesPrints the machine utilities screen: the Linux power, display, network and laptop scripts and the fix commands.
›
AI assistant setupPrints the AI assistant setup screen: the Claude and Codex rules and settings, the skills, and the agent system.
›
browserPrints the browser screen: the browser command, Chrome's launcher, and the browser smoke QA.
›
toolsPrints the tools screen: the dashboards, Deskflow, Hermes, clipboard, audio and the Supabase keepalive.
›
windowsPrints the windows screen: the Windows bootstrap, the skill sync and the repo clone.
›
CVsPrints the CVs screen: the three CV versions, their sources and the build commands.
›
docsPrints the docs screen: the plans, designs, research, flows, changelog, items, roles and intent folders.
›
case studiesPrints the case studies screen: the archived experiments and the dated machine incidents.
›
‹ Home

shell-and-git

The zsh helpers, the opencode profile commands and the git setup.

zsh helpersPrints the zsh helpers screen: the files in ~/.zsh.d/ and what each adds to the shell.
›
opencode profilesPrints the opencode profiles screen: opencode and oc, and the commands that choose a profile.
›
gitPrints the git screen: the author and credential settings, the hooks and the hook scripts.
›
‹ shell-and-git

zsh-helpers

The helper files this shell sources from ~/.zsh.d/.

git safetyWraps git checkout: lists the files it would discard and asks [y/N] first.
›
infraSets up Docker and Compose shortcuts, Prisma and Postgres helpers, and nginx and VPN commands.
›
utilsSets up terminal helpers (set-title, killport), IP aliases, lazy-loaded nvm and node, Android, Java and Bun.
›
api keysExports the general-use API keys kept in ~/.config/api-keys/env; api-keys-edit opens that file.
›
dash path warnRuns the dash path check; the README does not say what it checks.
›
rulesPrints the rules, or the rules of one folder with rules [folder].
›
review openOpens a file for review; ~/.local/bin/review-open does the same for bash and agents.
›
opencode profiles fileRuns opencode and oc with the current profile; ~/.bashrc sources it too.
›
‹ shell-and-git

opencode-profiles

The opencode and oc commands and the profile commands that run with the current profile.

opencode and ocRuns opencode with the current profile.
›
opencode-profileSets which profile is current.
›
opencode-profilesLists what each profile loads.
›
opencode-switchSwitches every shell's new runs to the named profile.
›
opencode-loginSigns a profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editOpens one of the current profile's files for editing.
›
opencode helpPrints every profile's files, one column per profile; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
›
profile definitionsOpens the profile definitions, one folder per profile, including private-leb-experimental.
›
‹ shell-and-git

git

The git settings, the hooks and the hook scripts.

git settingsOpens the git settings: author, Git LFS, the credential helper and the hooks path.
›
git hooksOpens the Lefthook shims that run in every repo; they need lefthook on the PATH.
›
scenario gateRuns the scenario gate from the hooks; the README does not describe its check.
›
‹ Home

machine-utilities

The Linux scripts for power, display, network and the laptop lid, and the fix commands.

power saveSets the power-saver profile, turbo off, CPU capped at 8% of max; asks for sudo.
›
power normalSets the balanced profile, turbo on, and the cap back to 100%.
›
external monitorSets a mode and refresh rate on the external HDMI or DP output with xrandr.
›
internet recoveryRepairs the network: enables systemd-resolved, repoints DNS and cycles networking; re-runs itself with sudo.
›
tailscale remote terminalRepairs DNS, restarts tailscaled, waits for reconnect, and checks the remote terminal on port 3500.
›
keep running lid closedWrites a logind drop-in so closing the lid does nothing; applies after a reboot.
›
restore lid behaviorRemoves that logind drop-in; applies after a reboot.
›
fix keyboardRepairs the keyboard.
›
fix mouseRepairs the mouse.
›
fix diskRepairs the disk.
›
fix whatsappRepairs WhatsApp.
›
‹ Home

ai-assistant-setup

The global rules, settings and skills for Claude, Codex and the agent system.

global rulesOpens the global rules: browser automation, communication style, research, and how to present work.
›
agent notesOpens the shorter global agent notes.
›
claude settingsOpens the Claude Code settings that init-windows deploys to Windows.
›
codex configOpens the Codex CLI config that init-windows deploys to Windows.
›
communication draftOpens the communication design draft; nothing enforces it yet.
›
skills shortlistOpens the skills researched on skills.sh and which of them are installed.
›
linux instructionsOpens the mirror of the Linux machine's installed global instructions.
›
windows instructionsOpens the mirror of the Windows desktop's installed CLAUDE.md and its docs.
›
desktop v2 snapshotOpens the portable snapshot of the Windows desktop's instructions and two skills; it does not load itself.
›
skill backupsPrints the skill backups screen: the skills kept here, to copy into ~/.claude/skills/.
›
global skillsPrints the global skills screen: the skills that live in Lebnor/my-skills.
›
agent systemPrints the agent system screen: the rules, agent records, hooks and plugins.
›
‹ ai-assistant-setup

skill-backups

The skills kept here as backups in claude/skills/; copy the ones you want into ~/.claude/skills/.

tech-ledgerOpens the backup of the skill that reads and writes the betec Tech Ledger.
›
api-key-creationOpens the backup of the skill for getting a missing API key with browser tools.
›
clone-websiteOpens the backup of the website cloning skill.
›
contextual-value-product-thinkingOpens the backup of the skill that analyzes products through contextual human values.
›
web research assistantOpens the backup of the web research MCP skill; its setup is in SETUP-NOTES.md.
›
epic-fanout-planningOpens the backup of the 10-step pattern for QA-gap epics with parallel fan-out.
›
impeccableOpens the backup of the frontend design skill: shape, critique, audit, polish.
›
iterative-action-reviewOpens the backup of the review of one completed real-world action in a series.
›
lab-experimentOpens the backup of how to run an experiment in ai-lab.
›
mentor-modeOpens the backup of the mentor mode skill with its runtime and scripts.
›
post-feature-cleanupOpens the backup of the pass after writing code: UI defects, leftovers and repo hygiene.
›
powershell-launchingOpens the backup of the skill for launching PowerShell or a new terminal on Windows.
›
reboot-resumeOpens the backup of the skill for preserving work across a reboot or restart.
›
resume-projectOpens the backup of the resume-project skill and its script.
›
solaraai-content-calendarOpens the backup of the SolaraAI content calendar skill.
›
solaraai-deploymentOpens the backup of the SolaraAI deploy flow skill.
›
solaraai-designOpens the backup of the SolaraAI design system skill.
›
solaraai-formsOpens the backup of the SolaraAI form behavior skill.
›
supabaseOpens the backup of Supabase's own skill: Auth, RLS, migrations, CLI and debugging.
›
supabase-postgres-best-practicesOpens the backup of Supabase's Postgres performance rules.
›
tank--communication-engineeringOpens the backup of the discipline for what an agent says and how much.
›
tank--skill-creatorOpens the backup of the skill for creating new skills.
›
tech-cv-writerOpens the backup of the CV writer skill with its ATS and template references.
›
‹ ai-assistant-setup

global-skills

The skills that live in Lebnor/my-skills and that install.sh links into the agent skill folders.

supabaseOpens the source of Supabase's skill for Auth, RLS and migrations.
›
supabase-postgres-best-practicesOpens the source of Supabase's Postgres performance rules.
›
clone-websiteOpens the source of the website cloning skill with its builder agents.
›
lab-experimentOpens the source of how to run an experiment in /home/liel/projects/ai-lab.
›
coding-guidelinesOpens the source of the house coding rules: lean code, reuse before writing, component file order.
›
volatility-based-decompositionOpens the source of the decomposition skill for architect-tier work.
›
working-with-windowsOpens the source of the Windows gotchas for Node MCP servers that call PowerShell.
›
solaraai-content-calendarOpens the source of the SolaraAI content calendar skill.
›
solaraai-deploymentOpens the source of the SolaraAI deploy flow skill.
›
solaraai-designOpens the source of the SolaraAI design system skill.
›
solaraai-formsOpens the source of the SolaraAI form behavior skill.
›
‹ ai-assistant-setup

agent-system

Where the rules, agent records, hooks and plugins live.

rulesOpens the rules every org follows; only the user or an accepted proposal changes them.
›
rules metadataOpens the metadata kept for each rule.
›
rules testsTests the rules file.
›
agent checkChecks every agent record and refuses broken ones (exit 1).
›
agent listLists the agents with their tier, model and number of tests.
›
agent sandboxServes the Agent Sandbox page where you pick an agent and run it.
›
hooksPrints the hooks screen: the Claude Code hook scripts wired in ~/.claude/settings.json.
›
pluginsOpens the Claude Code plugins: changelog pane, review pane, scratchpad playground and team board.
›
usage guardWraps the claude command with the usage guard; ~/bin/claude runs ahead of the native one.
›
session typesRuns at SessionStart; main-sessions.py serves claude --main -c and -r.
›
team parkRuns the team park tool, installed as ~/.local/bin/team-park.
›
‹ agent-system

hooks

The Claude Code hook scripts in claude/hooks/, wired in ~/.claude/settings.json.

core rulesRuns at SessionStart and before each Bash call with the rules.
›
local server guardRuns before each Bash call to guard the local server.
›
machine historyRuns as a hook wired in settings.json; the README gives no more detail.
›
proof reminderRuns after Edit, MultiEdit, Write and Bash to remind you to prove the change.
›
team activityRuns as a hook wired in settings.json; the README gives no more detail.
›
hook testsTests the core rules hook.
›
‹ Home

browser

The browser command, Chrome's launcher, the Codex Chrome path, and the browser smoke QA.

browserRuns browser steps in one Chrome window that stays open across calls.
›
browser statusPrints whether the background server and its Chrome are up.
›
browser closeCloses Chrome and stops the background server.
›
recording proofOpens the recording steps: recordStart and recordStop.
›
chromeStarts Chrome with the flags in chrome/flags; the only way Chrome starts here.
›
chrome flagsOpens the launch flags that chrome.sh and the recorder both read.
›
chrome installLinks the Chrome launchers and menu entries to chrome.sh; run it once per machine.
›
codex browserOpens Codex's direct Chrome command path and its live verification.
›
chrome bridgeMaintains the Chrome plugin's latest link and reapplies the local navigation patch.
›
smoke QARuns a goal against a browser and reports only the text and URL you assert.
›
jev installInstalls the pinned jev-ultrafast checkout and the CLI into ~/.local/bin.
›
jev settingsEdits the model keys and settings for the smoke QA; keep it out of Git.
›
‹ Home

tools

The small tools this machine runs: dashboards, Deskflow, Hermes, clipboard, audio and the Supabase keepalive.

dashboardStarts the dashboard on port 8780, with the waiting list and the overview.
›
dashboard conceptsStarts the concepts version of the dashboard on port 8781, to compare with the first.
›
dashboard checksTests the dashboard: 199 checks against the real data and a real server.
›
deskflowShares the laptop trackpad and keyboard with the Windows PC; shows everyday use and recovery.
›
deskflow USB mouseOpens the notes for turning back on the forwarded Windows USB mouse, off since 2026-10-20.
›
hermesRuns the Hermes agent installed from source; its state lives in ~/.hermes.
›
hermes restoreOpens the Hermes restore runbook.
›
clipboardRuns the shared clipboard: server, watcher and picker, as systemd units.
›
clipboard on WindowsInstalls the Windows clipboard hotkey (clipstack.ahk); verify.ps1 checks it.
›
audio shareSends all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers.
›
supabase keepaliveRuns the Supabase keepalive on a timer; install.sh sets it up.
›
‹ Home

windows

The Windows bootstrap, the skill sync, and the cloning of the work repos.

init windowsRebuilds the Windows dev environment from the manifests; approve the administrator prompt.
›
init checkChecks the install against the manifests.
›
init rollbackRemoves the installed pack; close Node, npm, Git and VS Code first.
›
init manifestsOpens the exact program, Node and extension lists the install reads.
›
init inventoryOpens what the bootstrap captured.
›
init secretsOpens the sign-ins you redo by hand after the install.
›
skill syncSyncs the Windows skill links from my-skills after each trusted push.
›
skill sync testTests the skill sync.
›
skill sync accountTests the runner account the sync uses.
›
clone reposClones each missing Betec repo into the workspace; leaves existing folders alone.
›
‹ Home

cv

The three CV versions, their sources, the build commands and the dated versions.

Full Stack DeveloperOpens the PDF of the Full Stack Developer CV.
›
AI Full Stack EngineerOpens the PDF of the AI Full Stack Engineer CV.
›
AI IntegrationsOpens the PDF of the AI Integrations CV.
›
buildRebuilds the three PDFs with pdflatex from this folder.
›
text buildBuilds the full text of the CVs from their variables.
›
design buildBuilds the HTML and PDF design of the AI Full Stack CV.
›
readable masterOpens the readable master of the CV content.
›
experience notesOpens the factual input for every CV; the README names it, the file list does not show it.
›
drafting decisionsOpens the record of the CV drafting decisions.
›
versionsOpens the dated CV versions: 2026-10-04 and 2026-10-04-v2.
›
CV workflowOpens the CV workflow.
›
‹ Home

docs

The working documents: plans, designs, research, flows, changelog, items, roles, playbooks and intent.

plansOpens the dated plans, one folder per piece of work.
›
superpowers plansOpens the older plans folder, including the claude usage guard plan.
›
designOpens the dated design pitches and recommendations.
›
design referencesOpens the 2026-10-13 design mock-ups.
›
researchOpens the dated research and the phase checks.
›
functional researchOpens the 2026-10-21 research into other agent tools.
›
flowsOpens the flow cards and data models, dated by day.
›
changelogOpens the dated changelog entries.
›
itemsOpens the planned, urgent and work item lists.
›
rolesOpens the role skills for admin, worker, supervisor and qa-agent, with the drafts.
›
playbooksOpens the playbooks, such as talk-while-team-builds.
›
intentOpens the project intent and each module's INTENT.md.
›
featuresOpens the Gherkin features, one folder per module.
›
qa findingsOpens the QA findings from the say-the-thing runs.
›
‹ Home

case-studies

The archived, human-reviewed experiments and the dated machine incident records.

codebot returnOpens the same design request run with and without the conceptual-modeling skill.
›
signal gardenOpens the documentation exhibit that separates Blume's explanation from Astryx's live interface.
›
kernel use casesOpens the Kernel cloud browser results tested on 2026-10-08; the file is outside this repo.
›
referenceOpens the index of dated machine incidents and repairs.
›
codebot lid incidentOpens the closed-lid test record: the test passed for 1 minute 46 seconds with CodeBot healthy.
›
Raw answer
**Scenario (reasoning from the README, not observed use):** the owner of this workstation reaches for a tool, command, or record when they need to run something, repair something, or find a file, such as "which command fixes the keyboard" or "where is the CV PDF". They can be on a terminal or in a file browser, and may be in a hurry.

I worked from the file list and the README excerpts in the dump only. Several READMEs were cut at 2500 characters, so items that appear only in the cut parts are not on the map.

**Judgment calls**

- **Groups use the README's own headings.** "Case studies" and "Reference" are merged under `case-studies` so the top screen stays at nine groups.
- **Off the map, because the owner retired them:** `lan-mouse` ("Retired on 2026-10-05. The active setup is Deskflow") and `codex/playwright-mcp` ("is retired; it does not install a browser server anymore").
- **Repair commands sit under `machine-utilities`**, because the job is repair. The `utils.zsh` row lists only its other helpers.
- **Deskflow's USB forwarding is off but stays on the map,** since the owner's notes say how to turn it back on.
- **The credential issue in `zsh.d/` is not on the map.** It is a fix to make, not a destination.
- **Not on the map, because nothing describes them:** `copy/` (images), `deskflow-lockdown.nft`, and the purpose of `dash-path-warn.zsh` and `scenario-gate.py`. Their lines say "not described" and are asked about below.
- **Files the READMEs name but the file list does not show:** `workstation-cli/`, `zsh.d/workstation.zsh`, `audio-share/`, `zsh.d/audio-share.zsh`, three CV notes, `init-windows/inventory.md`, `secrets-checklist.md`, and `Verify-Windows.ps1`. They are mapped as written. Each must exist before anything is built.
- **Commands are the forms.** A screen's form is the `workstation …` command that draws it. Commands like `opencode-switch` are rows with their own verbs.
- **Each file has one screen.** `zsh.d/opencode-profiles.zsh` is a file row under `zsh-helpers`. The commands it defines are on the `opencode-profiles` screen.

**Questions for you**

1. Should `setup` stay as a facade alias? It is generic and likely to clash. My recommendation is to keep `workstation` and `ws` and drop `setup` from the map.
2. `tools` has ten items. Should it split now, for example into dashboards and the rest? My recommendation is to wait until it grows.
3. Should `docs` list only its folders, as drafted, or also the individual pitches and recommendations? My recommendation is folders only.
4. `skill-backups` has 23 flat rows. Should the Supabase and SolaraAI skills move to their own screens? My recommendation is yes.
5. Should the Claude backups `desktop-v1-2026` and `linux-v1-2026-10-03` be on the map? My recommendation is no, since the README points only to v2.
6. `machine-utilities` has eleven rows. Should it split into power, network and laptop? My recommendation is to leave it until it grows.
7. What do `dash-path-warn.zsh`, `scenario-gate.py` and `deskflow-lockdown.nft` do? Their lines will say "not described" until you say.

```json
{"screens": [
{"path": [], "sentence": "Everything this workstation has, grouped by what you do with it.", "rows": [
{"name": "shell and git", "form": "workstation shell-and-git", "what": "Prints the shell and git screen: the zsh helpers, opencode profiles and git setup this machine loads."},
{"name": "machine utilities", "form": "workstation machine-utilities", "what": "Prints the machine utilities screen: the Linux power, display, network and laptop scripts and the fix commands."},
{"name": "AI assistant setup", "form": "workstation ai-assistant-setup", "what": "Prints the AI assistant setup screen: the Claude and Codex rules and settings, the skills, and the agent system."},
{"name": "browser", "form": "workstation browser", "what": "Prints the browser screen: the browser command, Chrome's launcher, and the browser smoke QA."},
{"name": "tools", "form": "workstation tools", "what": "Prints the tools screen: the dashboards, Deskflow, Hermes, clipboard, audio and the Supabase keepalive."},
{"name": "windows", "form": "workstation windows", "what": "Prints the windows screen: the Windows bootstrap, the skill sync and the repo clone."},
{"name": "CVs", "form": "workstation cv", "what": "Prints the CVs screen: the three CV versions, their sources and the build commands."},
{"name": "docs", "form": "workstation docs", "what": "Prints the docs screen: the plans, designs, research, flows, changelog, items, roles and intent folders."},
{"name": "case studies", "form": "workstation case-studies", "what": "Prints the case studies screen: the archived experiments and the dated machine incidents."}
]},

{"path": ["shell-and-git"], "sentence": "The zsh helpers, the opencode profile commands and the git setup.", "rows": [
{"name": "zsh helpers", "form": "workstation shell-and-git zsh-helpers", "what": "Prints the zsh helpers screen: the files in ~/.zsh.d/ and what each adds to the shell."},
{"name": "opencode profiles", "form": "workstation shell-and-git opencode-profiles", "what": "Prints the opencode profiles screen: opencode and oc, and the commands that choose a profile."},
{"name": "git", "form": "workstation shell-and-git git", "what": "Prints the git screen: the author and credential settings, the hooks and the hook scripts."}
]},

{"path": ["shell-and-git", "zsh-helpers"], "sentence": "The helper files this shell sources from ~/.zsh.d/.", "rows": [
{"name": "git safety", "form": "~/.zsh.d/git-safety.zsh", "what": "Wraps git checkout: lists the files it would discard and asks [y/N] first."},
{"name": "infra", "form": "~/.zsh.d/infra.zsh", "what": "Sets up Docker and Compose shortcuts, Prisma and Postgres helpers, and nginx and VPN commands."},
{"name": "utils", "form": "~/.zsh.d/utils.zsh", "what": "Sets up terminal helpers (set-title, killport), IP aliases, lazy-loaded nvm and node, Android, Java and Bun."},
{"name": "api keys", "form": "~/.zsh.d/api-keys.zsh", "what": "Exports the general-use API keys kept in ~/.config/api-keys/env; api-keys-edit opens that file."},
{"name": "dash path warn", "form": "~/.zsh.d/dash-path-warn.zsh", "what": "Runs the dash path check; the README does not say what it checks."},
{"name": "rules", "form": "rules, from ~/.zsh.d/rules.zsh", "what": "Prints the rules, or the rules of one folder with rules [folder]."},
{"name": "review open", "form": "review-open, from ~/.zsh.d/review-open.zsh", "what": "Opens a file for review; ~/.local/bin/review-open does the same for bash and agents."},
{"name": "opencode profiles file", "form": "~/.zsh.d/opencode-profiles.zsh", "what": "Runs opencode and oc with the current profile; ~/.bashrc sources it too."}
]},

{"path": ["shell-and-git", "opencode-profiles"], "sentence": "The opencode and oc commands and the profile commands that run with the current profile.", "rows": [
{"name": "opencode and oc", "form": "opencode (also oc)", "what": "Runs opencode with the current profile."},
{"name": "opencode-profile", "form": "opencode-profile", "what": "Sets which profile is current."},
{"name": "opencode-profiles", "form": "opencode-profiles", "what": "Lists what each profile loads."},
{"name": "opencode-switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "opencode-login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "opencode-files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "opencode-edit", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files for editing."},
{"name": "opencode help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints every profile's files, one column per profile; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it."},
{"name": "profile definitions", "form": "opencode-profiles/", "what": "Opens the profile definitions, one folder per profile, including private-leb-experimental."}
]},

{"path": ["shell-and-git", "git"], "sentence": "The git settings, the hooks and the hook scripts.", "rows": [
{"name": "git settings", "form": "~/.gitconfig (from .gitconfig)", "what": "Opens the git settings: author, Git LFS, the credential helper and the hooks path."},
{"name": "git hooks", "form": "~/.git-hooks/ (from git-hooks/)", "what": "Opens the Lefthook shims that run in every repo; they need lefthook on the PATH."},
{"name": "scenario gate", "form": "git-hooks/scenario-gate.py", "what": "Runs the scenario gate from the hooks; the README does not describe its check."}
]},

{"path": ["machine-utilities"], "sentence": "The Linux scripts for power, display, network and the laptop lid, and the fix commands.", "rows": [
{"name": "power save", "form": "cpu-min-power.sh", "what": "Sets the power-saver profile, turbo off, CPU capped at 8% of max; asks for sudo."},
{"name": "power normal", "form": "cpu-normal-power.sh", "what": "Sets the balanced profile, turbo on, and the cap back to 100%."},
{"name": "external monitor", "form": "fix_old_monitor_hdmi.sh", "what": "Sets a mode and refresh rate on the external HDMI or DP output with xrandr."},
{"name": "internet recovery", "form": "linux-internet-recovery.sh", "what": "Repairs the network: enables systemd-resolved, repoints DNS and cycles networking; re-runs itself with sudo."},
{"name": "tailscale remote terminal", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, waits for reconnect, and checks the remote terminal on port 3500."},
{"name": "keep running lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind drop-in so closing the lid does nothing; applies after a reboot."},
{"name": "restore lid behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that logind drop-in; applies after a reboot."},
{"name": "fix keyboard", "form": "fix-keyboard", "what": "Repairs the keyboard."},
{"name": "fix mouse", "form": "fix-mouse", "what": "Repairs the mouse."},
{"name": "fix disk", "form": "fix-disk", "what": "Repairs the disk."},
{"name": "fix whatsapp", "form": "fix-whatsapp", "what": "Repairs WhatsApp."}
]},

{"path": ["ai-assistant-setup"], "sentence": "The global rules, settings and skills for Claude, Codex and the agent system.", "rows": [
{"name": "global rules", "form": "claude/CLAUDE.md", "what": "Opens the global rules: browser automation, communication style, research, and how to present work."},
{"name": "agent notes", "form": "claude/AGENTS.md", "what": "Opens the shorter global agent notes."},
{"name": "claude settings", "form": "claude/settings.json", "what": "Opens the Claude Code settings that init-windows deploys to Windows."},
{"name": "codex config", "form": "codex/config.toml", "what": "Opens the Codex CLI config that init-windows deploys to Windows."},
{"name": "communication draft", "form": "claude/communication-framework.md", "what": "Opens the communication design draft; nothing enforces it yet."},
{"name": "skills shortlist", "form": "claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and which of them are installed."},
{"name": "linux instructions", "form": "claude/linux-global/", "what": "Opens the mirror of the Linux machine's installed global instructions."},
{"name": "windows instructions", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows desktop's installed CLAUDE.md and its docs."},
{"name": "desktop v2 snapshot", "form": "claude/backups/desktop-v2-2026/", "what": "Opens the portable snapshot of the Windows desktop's instructions and two skills; it does not load itself."},
{"name": "skill backups", "form": "workstation ai-assistant-setup skill-backups", "what": "Prints the skill backups screen: the skills kept here, to copy into ~/.claude/skills/."},
{"name": "global skills", "form": "workstation ai-assistant-setup global-skills", "what": "Prints the global skills screen: the skills that live in Lebnor/my-skills."},
{"name": "agent system", "form": "workstation ai-assistant-setup agent-system", "what": "Prints the agent system screen: the rules, agent records, hooks and plugins."}
]},

{"path": ["ai-assistant-setup", "skill-backups"], "sentence": "The skills kept here as backups in claude/skills/; copy the ones you want into ~/.claude/skills/.", "rows": [
{"name": "tech-ledger", "form": "claude/skills/tech-ledger/", "what": "Opens the backup of the skill that reads and writes the betec Tech Ledger."},
{"name": "api-key-creation", "form": "claude/skills/api-key-creation/", "what": "Opens the backup of the skill for getting a missing API key with browser tools."},
{"name": "clone-website", "form": "claude/skills/clone-website/", "what": "Opens the backup of the website cloning skill."},
{"name": "contextual-value-product-thinking", "form": "claude/skills/contextual-value-product-thinking/", "what": "Opens the backup of the skill that analyzes products through contextual human values."},
{"name": "web research assistant", "form": "claude/skills/elad12390--web-research-assistant/", "what": "Opens the backup of the web research MCP skill; its setup is in SETUP-NOTES.md."},
{"name": "epic-fanout-planning", "form": "claude/skills/epic-fanout-planning/", "what": "Opens the backup of the 10-step pattern for QA-gap epics with parallel fan-out."},
{"name": "impeccable", "form": "claude/skills/impeccable/", "what": "Opens the backup of the frontend design skill: shape, critique, audit, polish."},
{"name": "iterative-action-review", "form": "claude/skills/iterative-action-review/", "what": "Opens the backup of the review of one completed real-world action in a series."},
{"name": "lab-experiment", "form": "claude/skills/lab-experiment/", "what": "Opens the backup of how to run an experiment in ai-lab."},
{"name": "mentor-mode", "form": "claude/skills/mentor-mode/", "what": "Opens the backup of the mentor mode skill with its runtime and scripts."},
{"name": "post-feature-cleanup", "form": "claude/skills/post-feature-cleanup/", "what": "Opens the backup of the pass after writing code: UI defects, leftovers and repo hygiene."},
{"name": "powershell-launching", "form": "claude/skills/powershell-launching/", "what": "Opens the backup of the skill for launching PowerShell or a new terminal on Windows."},
{"name": "reboot-resume", "form": "claude/skills/reboot-resume/", "what": "Opens the backup of the skill for preserving work across a reboot or restart."},
{"name": "resume-project", "form": "claude/skills/resume-project/", "what": "Opens the backup of the resume-project skill and its script."},
{"name": "solaraai-content-calendar", "form": "claude/skills/solaraai-content-calendar/", "what": "Opens the backup of the SolaraAI content calendar skill."},
{"name": "solaraai-deployment", "form": "claude/skills/solaraai-deployment/", "what": "Opens the backup of the SolaraAI deploy flow skill."},
{"name": "solaraai-design", "form": "claude/skills/solaraai-design/", "what": "Opens the backup of the SolaraAI design system skill."},
{"name": "solaraai-forms", "form": "claude/skills/solaraai-forms/", "what": "Opens the backup of the SolaraAI form behavior skill."},
{"name": "supabase", "form": "claude/skills/supabase/", "what": "Opens the backup of Supabase's own skill: Auth, RLS, migrations, CLI and debugging."},
{"name": "supabase-postgres-best-practices", "form": "claude/skills/supabase-postgres-best-practices/", "what": "Opens the backup of Supabase's Postgres performance rules."},
{"name": "tank--communication-engineering", "form": "claude/skills/tank--communication-engineering/", "what": "Opens the backup of the discipline for what an agent says and how much."},
{"name": "tank--skill-creator", "form": "claude/skills/tank--skill-creator/", "what": "Opens the backup of the skill for creating new skills."},
{"name": "tech-cv-writer", "form": "claude/skills/tech-cv-writer/", "what": "Opens the backup of the CV writer skill with its ATS and template references."}
]},

{"path": ["ai-assistant-setup", "global-skills"], "sentence": "The skills that live in Lebnor/my-skills and that install.sh links into the agent skill folders.", "rows": [
{"name": "supabase", "form": "/home/liel/projects/my-skills/supabase/SKILL.md", "what": "Opens the source of Supabase's skill for Auth, RLS and migrations."},
{"name": "supabase-postgres-best-practices", "form": "/home/liel/projects/my-skills/supabase-postgres-best-practices/SKILL.md", "what": "Opens the source of Supabase's Postgres performance rules."},
{"name": "clone-website", "form": "/home/liel/projects/my-skills/clone-website/SKILL.md", "what": "Opens the source of the website cloning skill with its builder agents."},
{"name": "lab-experiment", "form": "/home/liel/projects/my-skills/lab-experiment/SKILL.md", "what": "Opens the source of how to run an experiment in /home/liel/projects/ai-lab."},
{"name": "coding-guidelines", "form": "/home/liel/projects/my-skills/coding-guidelines/SKILL.md", "what": "Opens the source of the house coding rules: lean code, reuse before writing, component file order."},
{"name": "volatility-based-decomposition", "form": "/home/liel/projects/my-skills/volatility-based-decomposition/SKILL.md", "what": "Opens the source of the decomposition skill for architect-tier work."},
{"name": "working-with-windows", "form": "/home/liel/projects/my-skills/working-with-windows/SKILL.md", "what": "Opens the source of the Windows gotchas for Node MCP servers that call PowerShell."},
{"name": "solaraai-content-calendar", "form": "/home/liel/projects/my-skills/solaraai-content-calendar/SKILL.md", "what": "Opens the source of the SolaraAI content calendar skill."},
{"name": "solaraai-deployment", "form": "/home/liel/projects/my-skills/solaraai-deployment/SKILL.md", "what": "Opens the source of the SolaraAI deploy flow skill."},
{"name": "solaraai-design", "form": "/home/liel/projects/my-skills/solaraai-design/SKILL.md", "what": "Opens the source of the SolaraAI design system skill."},
{"name": "solaraai-forms", "form": "/home/liel/projects/my-skills/solaraai-forms/SKILL.md", "what": "Opens the source of the SolaraAI form behavior skill."}
]},

{"path": ["ai-assistant-setup", "agent-system"], "sentence": "Where the rules, agent records, hooks and plugins live.", "rows": [
{"name": "rules", "form": "workboard/rules.yaml", "what": "Opens the rules every org follows; only the user or an accepted proposal changes them."},
{"name": "rules metadata", "form": "workboard/rules-meta.yaml", "what": "Opens the metadata kept for each rule."},
{"name": "rules tests", "form": "workboard/test_rules.py", "what": "Tests the rules file."},
{"name": "agent check", "form": "agent-framework/agent check", "what": "Checks every agent record and refuses broken ones (exit 1)."},
{"name": "agent list", "form": "agent-framework/agent list", "what": "Lists the agents with their tier, model and number of tests."},
{"name": "agent sandbox", "form": "agent-framework/agent serve (http://127.0.0.1:8790)", "what": "Serves the Agent Sandbox page where you pick an agent and run it."},
{"name": "hooks", "form": "workstation ai-assistant-setup agent-system hooks", "what": "Prints the hooks screen: the Claude Code hook scripts wired in ~/.claude/settings.json."},
{"name": "plugins", "form": "claude/mods/", "what": "Opens the Claude Code plugins: changelog pane, review pane, scratchpad playground and team board."},
{"name": "usage guard", "form": "claude/usage-guard/", "what": "Wraps the claude command with the usage guard; ~/bin/claude runs ahead of the native one."},
{"name": "session types", "form": "claude/session-types/session-types.sh", "what": "Runs at SessionStart; main-sessions.py serves claude --main -c and -r."},
{"name": "team park", "form": "claude/team-park/team_park.py", "what": "Runs the team park tool, installed as ~/.local/bin/team-park."}
]},

{"path": ["ai-assistant-setup", "agent-system", "hooks"], "sentence": "The Claude Code hook scripts in claude/hooks/, wired in ~/.claude/settings.json.", "rows": [
{"name": "core rules", "form": "claude/hooks/core-rules.sh", "what": "Runs at SessionStart and before each Bash call with the rules."},
{"name": "local server guard", "form": "claude/hooks/local-server-guard.py", "what": "Runs before each Bash call to guard the local server."},
{"name": "machine history", "form": "claude/hooks/machine-history.sh", "what": "Runs as a hook wired in settings.json; the README gives no more detail."},
{"name": "proof reminder", "form": "claude/hooks/proof-reminder.sh", "what": "Runs after Edit, MultiEdit, Write and Bash to remind you to prove the change."},
{"name": "team activity", "form": "claude/hooks/team-activity.sh", "what": "Runs as a hook wired in settings.json; the README gives no more detail."},
{"name": "hook tests", "form": "claude/hooks/test_core_rules.sh", "what": "Tests the core rules hook."}
]},

{"path": ["browser"], "sentence": "The browser command, Chrome's launcher, the Codex Chrome path, and the browser smoke QA.", "rows": [
{"name": "browser", "form": "browser/browser.sh (~/.local/bin/browser)", "what": "Runs browser steps in one Chrome window that stays open across calls."},
{"name": "browser status", "form": "browser status", "what": "Prints whether the background server and its Chrome are up."},
{"name": "browser close", "form": "browser close", "what": "Closes Chrome and stops the background server."},
{"name": "recording proof", "form": "browser/README.md (Recording proof)", "what": "Opens the recording steps: recordStart and recordStop."},
{"name": "chrome", "form": "chrome/chrome.sh", "what": "Starts Chrome with the flags in chrome/flags; the only way Chrome starts here."},
{"name": "chrome flags", "form": "chrome/flags", "what": "Opens the launch flags that chrome.sh and the recorder both read."},
{"name": "chrome install", "form": "chrome/install.sh", "what": "Links the Chrome launchers and menu entries to chrome.sh; run it once per machine."},
{"name": "codex browser", "form": "codex/browser/", "what": "Opens Codex's direct Chrome command path and its live verification."},
{"name": "chrome bridge", "form": "codex/chrome-bridge/install.sh", "what": "Maintains the Chrome plugin's latest link and reapplies the local navigation patch."},
{"name": "smoke QA", "form": "jev-browser-test", "what": "Runs a goal against a browser and reports only the text and URL you assert."},
{"name": "jev install", "form": "jev-browser-test/install.sh", "what": "Installs the pinned jev-ultrafast checkout and the CLI into ~/.local/bin."},
{"name": "jev settings", "form": "~/.config/jev-browser-test/env", "what": "Edits the model keys and settings for the smoke QA; keep it out of Git."}
]},

{"path": ["tools"], "sentence": "The small tools this machine runs: dashboards, Deskflow, Hermes, clipboard, audio and the Supabase keepalive.", "rows": [
{"name": "dashboard", "form": "http://127.0.0.1:8780 (dashboard/server.py)", "what": "Starts the dashboard on port 8780, with the waiting list and the overview."},
{"name": "dashboard concepts", "form": "http://127.0.0.1:8781 (dashboard-concepts/server.py)", "what": "Starts the concepts version of the dashboard on port 8781, to compare with the first."},
{"name": "dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Tests the dashboard: 199 checks against the real data and a real server."},
{"name": "deskflow", "form": "deskflow/README.md", "what": "Shares the laptop trackpad and keyboard with the Windows PC; shows everyday use and recovery."},
{"name": "deskflow USB mouse", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes for turning back on the forwarded Windows USB mouse, off since 2026-10-20."},
{"name": "hermes", "form": "~/.local/bin/hermes (source in ~/projects/hermes-agent)", "what": "Runs the Hermes agent installed from source; its state lives in ~/.hermes."},
{"name": "hermes restore", "form": "hermes/RESTORE.md", "what": "Opens the Hermes restore runbook."},
{"name": "clipboard", "form": "clipstack/ (units in clipstack/units/)", "what": "Runs the shared clipboard: server, watcher and picker, as systemd units."},
{"name": "clipboard on Windows", "form": "clipstack/windows/install.ps1", "what": "Installs the Windows clipboard hotkey (clipstack.ahk); verify.ps1 checks it."},
{"name": "audio share", "form": "audio-share/ (audio-start, audio-pause)", "what": "Sends all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers."},
{"name": "supabase keepalive", "form": "supabase-keepalive/install.sh", "what": "Runs the Supabase keepalive on a timer; install.sh sets it up."}
]},

{"path": ["windows"], "sentence": "The Windows bootstrap, the skill sync, and the cloning of the work repos.", "rows": [
{"name": "init windows", "form": "init-windows/Start-Install.cmd", "what": "Rebuilds the Windows dev environment from the manifests; approve the administrator prompt."},
{"name": "init check", "form": "init-windows/Smoke-Test-Windows.ps1 (and Verify-Windows.ps1)", "what": "Checks the install against the manifests."},
{"name": "init rollback", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes the installed pack; close Node, npm, Git and VS Code first."},
{"name": "init manifests", "form": "init-windows/manifests/", "what": "Opens the exact program, Node and extension lists the install reads."},
{"name": "init inventory", "form": "init-windows/inventory.md", "what": "Opens what the bootstrap captured."},
{"name": "init secrets", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins you redo by hand after the install."},
{"name": "skill sync", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Syncs the Windows skill links from my-skills after each trusted push."},
{"name": "skill sync test", "form": "skills-sync-windows/Test-Sync.ps1", "what": "Tests the skill sync."},
{"name": "skill sync account", "form": "skills-sync-windows/Test-Account.ps1", "what": "Tests the runner account the sync uses."},
{"name": "clone repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones each missing Betec repo into the workspace; leaves existing folders alone."}
]},

{"path": ["cv"], "sentence": "The three CV versions, their sources, the build commands and the dated versions.", "rows": [
{"name": "Full Stack Developer", "form": "cv/cv-full-stack.pdf (source cv-full-stack.tex)", "what": "Opens the PDF of the Full Stack Developer CV."},
{"name": "AI Full Stack Engineer", "form": "cv/cv-ai-full-stack.pdf (source cv-ai-full-stack.tex)", "what": "Opens the PDF of the AI Full Stack Engineer CV."},
{"name": "AI Integrations", "form": "cv/cv-ai-integrations.pdf (source cv-ai-integrations.tex)", "what": "Opens the PDF of the AI Integrations CV."},
{"name": "build", "form": "cv/README.md (Update)", "what": "Rebuilds the three PDFs with pdflatex from this folder."},
{"name": "text build", "form": "cv/text/build-full.sh", "what": "Builds the full text of the CVs from their variables."},
{"name": "design build", "form": "cv/design/build-design.py", "what": "Builds the HTML and PDF design of the AI Full Stack CV."},
{"name": "readable master", "form": "cv/cv-master.md", "what": "Opens the readable master of the CV content."},
{"name": "experience notes", "form": "cv/experience-notes.md", "what": "Opens the factual input for every CV; the README names it, the file list does not show it."},
{"name": "drafting decisions", "form": "cv/cv-material-draft.md", "what": "Opens the record of the CV drafting decisions."},
{"name": "versions", "form": "cv/versions/", "what": "Opens the dated CV versions: 2026-10-04 and 2026-10-04-v2."},
{"name": "CV workflow", "form": "cv/WORKFLOW.md", "what": "Opens the CV workflow."}
]},

{"path": ["docs"], "sentence": "The working documents: plans, designs, research, flows, changelog, items, roles, playbooks and intent.", "rows": [
{"name": "plans", "form": "docs/plans/", "what": "Opens the dated plans, one folder per piece of work."},
{"name": "superpowers plans", "form": "docs/superpowers/plans/", "what": "Opens the older plans folder, including the claude usage guard plan."},
{"name": "design", "form": "docs/design/", "what": "Opens the dated design pitches and recommendations."},
{"name": "design references", "form": "docs/design-references/", "what": "Opens the 2026-10-13 design mock-ups."},
{"name": "research", "form": "docs/research/", "what": "Opens the dated research and the phase checks."},
{"name": "functional research", "form": "docs/functional-research/", "what": "Opens the 2026-10-21 research into other agent tools."},
{"name": "flows", "form": "docs/flows/", "what": "Opens the flow cards and data models, dated by day."},
{"name": "changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "items", "form": "docs/items/", "what": "Opens the planned, urgent and work item lists."},
{"name": "roles", "form": "docs/roles/", "what": "Opens the role skills for admin, worker, supervisor and qa-agent, with the drafts."},
{"name": "playbooks", "form": "docs/playbooks/", "what": "Opens the playbooks, such as talk-while-team-builds."},
{"name": "intent", "form": ".idd/project.intent.md and .idd/modules/", "what": "Opens the project intent and each module's INTENT.md."},
{"name": "features", "form": ".bdd/features/", "what": "Opens the Gherkin features, one folder per module."},
{"name": "qa findings", "form": ".bdd/qa/findings/", "what": "Opens the QA findings from the say-the-thing runs."}
]},

{"path": ["case-studies"], "sentence": "The archived, human-reviewed experiments and the dated machine incident records.", "rows": [
{"name": "codebot return", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "Opens the same design request run with and without the conceptual-modeling skill."},
{"name": "signal garden", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "Opens the documentation exhibit that separates Blume's explanation from Astryx's live interface."},
{"name": "kernel use cases", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the Kernel cloud browser results tested on 2026-10-08; the file is outside this repo."},
{"name": "reference", "form": "reference/README.md", "what": "Opens the index of dated machine incidents and repairs."},
{"name": "codebot lid incident", "form": "reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "Opens the closed-lid test record: the test passed for 1 minute 46 seconds with CodeBot healthy."}
]}
],
"questions": [
"Should setup stay as a facade alias? It is generic and likely to clash. Recommendation: keep workstation and ws, and drop setup from the map.",
"tools has ten items. Should it split now, for example into dashboards and the rest? Recommendation: wait until it grows.",
"Should docs list only its folders, or also the individual pitches and recommendations? Recommendation: folders only.",
"skill backups has 23 flat rows. Should the Supabase and SolaraAI skills move to their own screens? Recommendation: yes.",
"Should the Claude backups desktop-v1-2026 and linux-v1-2026-10-03 be on the map? Recommendation: no, since the README points only to v2.",
"machine utilities has eleven rows. Should it split into power, network and laptop? Recommendation: leave it until it grows.",
"What do dash-path-warn.zsh, scenario-gate.py and deskflow-lockdown.nft do? Their lines say not described until you say."
]}
```

No skill · run 2 exit=0 seconds=129 · prompt

P1 Recall: 0.714P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.463P5 Short top: 16P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.287
As terminal help
The workstation help: one line per area you can reach on this machine. Run workstation followed by an area name (also ws or setup) to open that area's screen.
shellworkstation shellHelper commands from ~/.zsh.d: git safety, infra, terminal helpers, repairs, API key editing, review-open.
gitworkstation gitGit config, the lefthook hooks, and the push and commit gates.
keysworkstation keysWhere API keys and tokens are kept, outside Git, and how to edit them.
rulesworkstation rulesThe org rules every session follows, printed from workboard/rules.yaml.
assistantsworkstation assistantsClaude, Codex, Hermes, Jev, the usage guard and the Claude plugins: how each is set up and started.
opencodeworkstation opencodeOpenCode profiles: which one is current, what each loads, how to switch.
agentsworkstation agentsAgent records, their checks, and the Agent Sandbox page.
browserworkstation browserThe browser command, its one Chrome window, recording proof, and how Chrome is started.
dashboardsworkstation dashboardsThe local dashboard pages on localhost and the command that starts each.
machineworkstation machinePower, display, network, lid, audio sharing and keepalive on this Linux laptop.
deskflowworkstation deskflowThe shared mouse and keyboard between the laptop and the Windows PC.
clipboardworkstation clipboardClipboard history (clipstack) on Linux and Windows.
windowsworkstation windowsWindows-side scripts for setup, checks, repo clones and skill sync. Run them on Windows, not in this shell.
skillsworkstation skillsGlobal skills, where they come from, and how they reach each assistant.
cvworkstation cvThe three CV versions, their sources, and how to rebuild the PDFs.
workworkstation workItems, plans, changelog, cases, the archive, and the dated incident and case-study records.
shell
Helper commands that the shell loads from ~/.zsh.d, grouped by topic.
git safetygit checkout (wrapper from zsh.d/git-safety.zsh)Lists the files a checkout would discard and asks [y/N] first.
infra helperscommand names defined in zsh.d/infra.zshDocker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands.
terminal helpersset-title, killport (zsh.d/utils.zsh)Set the terminal title, free a port, and use the IP aliases and lazy-loaded nvm, node, npm and npx.
runtime setupzsh.d/utils.zsh (Android, Java, Bun)Environment setup for Android, Java and Bun.
fix-keyboardfix-keyboardOne-shot repair for the keyboard.
fix-mousefix-mouseOne-shot repair for the mouse.
fix-diskfix-diskOne-shot repair for the disk.
fix-whatsappfix-whatsappOne-shot repair for WhatsApp.
API key editorapi-keys-editOpens ~/.config/api-keys/env, the general-use keys that zsh.d/api-keys.zsh loads.
review-openreview-open (also ~/.local/bin/review-open)Opens a review from the shell; the wrapper lets bash and agents call it too.
rules commandrules [folder]Prints the rules. See the rules screen.
git
Git config, the hooks that run in every repo, and the gates they enforce.
Git config.gitconfig, copied to ~/.gitconfigAuthor identity, Git LFS, the store credential helper, a large http.postBuffer, and core.hooksPath.
Git hooksgit-hooks/, copied to ~/.git-hooks/Lefthook shims that run in every repo. They need lefthook on PATH.
Push and commit gatesgit-hooks/pre-push and git-hooks/commit-msgRefuse pushes to main in repos marked team.gitpolicy pull-request, and refuse commits on main in marked repos. They sit above LEFTHOOK=0, so that variable cannot skip them.
Reinstall hookslefthook install, then re-add the gates by handA plain lefthook install overwrites the hand-added gates.
Repoint an old clonegit remote set-url origin https://github.com/Lebnor/workstation.gitFor clones made before the rename from scripts.
keys
Where secrets live. None of these are in Git.
General API keysapi-keys-edit opens ~/.config/api-keys/envKeys for general use, exported by zsh.d/api-keys.zsh.
Jev browser-test keys~/.config/jev-browser-test/env (mode 600)The Jev key and the Gemini text model key for jev-browser-test.
Hermes credentials~/.hermes (auth.json files)Hermes ChatGPT logins and provider keys. Not backed up in this repo.
Known issue: embedded credentialzsh.d/infra.zsh and zsh.d/utils.zshA credential sits inside git URLs there. Rotate it and move to a credential manager. Help shows names only, never values.
Sign-ins to redoinit-windows/secrets-checklist.mdWhat to sign in to again on a fresh Windows install.
rules
The org rules every session follows.
Print the rulesrules [folder]Prints every rule, or the ones for one folder. Each session runs it at start.
Rule sourceworkboard/rules.yamlThe rules. Changed only by you or by an accepted rule proposal (R43).
Rule metadataworkboard/rules-meta.yamlDetails kept beside the rules.
Rule proposals~/projects/data/global/rule-proposals/Proposed rule changes. Accept or Reject them on the dashboard.
Generated rules file~/.claude/references/rules.mdGenerated from rules.yaml. Do not edit it by hand.
opencode
OpenCode profiles: which one runs, what each loads, and how to switch.
Run OpenCodeopencode, or ocRuns OpenCode with the current profile.
Current profileopencode-profileNames the profile in use.
Profilesopencode-profilesLists each profile and what it loads.
Switch profileopencode-switch <name>Switches every shell's new runs to that profile.
Sign Claude Code inopencode-loginSigns the current profile's Claude Code in.
Profile filesopencode-filesLists the current profile's files.
Edit a profile fileopencode-edit <file>Opens one of those files.
Full help pageopencode help (also oc help, opencode-help, oc-help)Every profile's files, one column per profile. With more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
Profile sourcesopencode-profiles/ (profiles.py, private-leb-experimental/)Where the profiles are defined.
assistants
The AI assistants on this machine, how each is started, and where its setup lives.
Claude wrapperclaude (~/bin/claude, ahead of ~/.local/bin/claude)Starts Claude Code through the usage guard.
Main sessionsclaude --main -c, or claude --main -rContinues or resumes a main session through the session-types hook.
Team parkteam-park (~/.local/bin/team-park)The team-park tool. Its usage is in claude/team-park/README.md.
Global Claude filesclaude/CLAUDE.md, claude/AGENTS.md, claude/settings.jsonGlobal rules and settings. init-windows deploys them to Windows.
Linux global mirrorclaude/linux-global/A mirror of the installed Linux CLAUDE.md and its docs.
Windows global mirrorclaude/windows-global/A mirror of the Windows CLAUDE.md and its docs.
Usage guardclaude/usage-guard/ (install.sh; Install-Windows.cmd on Windows)Tracks Claude usage and the request budget.
Claude pluginsclaude/mods/ (review-pane, changelog-pane, team-board, scratchpad-playground)Panes and boards inside Claude Code. The review pane opens through review-open.
Codex configcodex/config.toml (deployed to the Windows .codex folder)Codex CLI config.
Codex Chrome bridgecodex/chrome-bridge/install.sh on Linux; Install-CodexChromeBridge.cmd on WindowsKeeps the Chrome plugin's latest link and the file: navigation patch working.
Hermeshermes (~/.local/bin/hermes); source in ~/projects/hermes-agentThe Hermes agent, with default and jobs profiles. hermes/RESTORE.md covers recovery.
Jev consultjev CONTEXT -c QUESTION OPTIONS -jAsks Jev a multi-choice decision. A Jev choice is guidance, not proof of anything.
Jev browser smoke testjev-browser-test (installed by jev-browser-test/install.sh)Runs a goal in a browser and checks the text and URL you supply.
agents
Agent records, their checks, and the Agent Sandbox page.
Check records~/projects/workstation/agent-framework/agent checkRefuses broken agent records. Exits 1 on failure.
List agents~/projects/workstation/agent-framework/agent listLists agents with their tier, model and number of tests.
Agent Sandboxagent serve, then http://127.0.0.1:8790The page where you pick an agent, change its setup, and ask it things.
Agent records~/projects/my-skills/agents/<id>/agent.yamlEach agent's record, its saved tests, and its role skill.
Results and memory~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/Test results and each agent's memory.
Start a team/spawn-team <team> in Claude, or $spawn-team <team> in CodexStarts a team from a team file in spawn-team/teams/.
Sandbox designdocs/plans/2026-10-22-agent-sandbox/prd.htmlThe PRD and mockups for the sandbox page.
browser
The browser command: one Chrome window that stays open between calls.
Run stepsbrowser '<json array of steps>', or browser with a steps fileRuns the steps in order on one persistent page and prints the results as JSON.
Statusbrowser statusShows whether the background server and Chrome are up.
Closebrowser closeCloses Chrome and stops the server.
Record proofrecordStart and recordStop stepsRecords a tab as proof that a feature works. The only supported way to record.
Screenshotscreenshot step with a pathA still image of the page.
Local serverhttp://127.0.0.1:8848 (/health, /run, /close)The server the browser command talks to.
Installcd browser && npm install && npm linkRun once per machine.
Start Chromechrome/chrome.sh (flags in chrome/flags); install once with chrome/install.shThe only way to start Chrome here. It adds the recording flag. Quit and reopen Chrome after install.
Browser READMEbrowser/README.mdActions, viewport presets, network capture, and login gotchas.
dashboards
Pages served on localhost. Each runs only when you start it.
Dashboardhttp://127.0.0.1:8780, started by python3 ~/projects/workstation/dashboard/server.pyThe Waiting, Overview and reader views. Desktop only.
Waiting tabhttp://127.0.0.1:8780/#waitingCases asked, rule changes, and calls decided alone. The default tab.
Dashboard conceptshttp://127.0.0.1:8781, started by python3 ~/projects/workstation/dashboard-concepts/server.pyA second dashboard version to compare against, with the Projects panel and machine buttons.
Agent Sandbox pagehttp://127.0.0.1:8790 (agent serve)The same page as the agents screen, listed because it is a localhost page.
Dashboard testspython3 -I -m unittest discover -s ~/projects/workstation/dashboardChecks against the real data and a real server.
Dashboard designdocs/design/2026-10-17-dashboard/The design rounds that chose the current look.
machine
Power, display, network, lid, audio and keepalive on this Linux laptop. Most scripts ask for sudo.
Low powercpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8%. Intel P-state only.
Normal powercpu-normal-power.shSets the balanced profile, turns turbo on and removes the cap.
External monitorfix_old_monitor_hdmi.sh [--output] [--mode] [--rate] [--quiet]Sets mode and refresh rate on the HDMI or DP output with xrandr. Defaults to 1920x1080 at 59.88.
Internet recoverylinux-internet-recovery.shEnables systemd-resolved, fixes resolv.conf, restarts networking. Re-runs itself with sudo.
Tailscale remote terminal recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, starts the remote-terminal service and checks port 3500. Run as your normal user.
Keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shWrites a logind drop-in so closing the lid does nothing. Applies after reboot.
Restore lid behaviourlaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in. Applies after reboot.
Closed-lid test recordreference/incidents/2026-10-01-codebot-lid-closed.mdThe test that showed CodeBot stays up with the lid closed.
Audio to Windowsaudio-start, audio-pause, audio-share on|off|status|toneSends Linux audio to the Windows PC over Tailscale. Pausing restores the speakers. The Windows player is run by the windows-audio-share agent.
Supabase keepalivesupabase-keepalive/install.sh (systemd timer)Timer that keeps the Supabase project active.
deskflow
One mouse and keyboard shared between the laptop and the Windows PC.
Everyday usedeskflow/README.md, section Everyday useMove past the laptop's right edge to control Windows, and past Windows' left edge to come back.
Restart and re-ask for inputresume-kvmStarts Deskflow again after a cancelled GNOME input prompt, and asks again.
Server service~/.config/systemd/user/deskflow.serviceRuns the Linux Deskflow server with the graphical session.
Settings~/.config/Deskflow/Deskflow.conf and server.confLinux server settings, copied from deskflow/linux.conf and deskflow/server.conf.
Keyboard follows the mousedeskflow/usb-mouse/README.md, section Keyboard follows the mouseWhich mouse the keyboard follows, and how to stop it.
USB mouse forwardingdeskflow-usb-mouse.service (disabled)Forwards the Windows USB mouse. Off since 2026-10-20.
Network audit and firewalldeskflow/NETWORK-AUDIT.md and deskflow/deskflow-lockdown.nftWhat the server opens on the network, and the lockdown rules.
Retired: Lan Mouselan-mouse/README.md (service disabled)The old KVM, retired 2026-10-05. Rollback only. Never run it beside Deskflow.
clipboard
Clipboard history across Linux and Windows.
History serverclipstack-server.service (clipstack/server.py)Serves the clipboard history.
Watcherclipstack-watcher.service (clipstack/watcher.py)Watches the clipboard and records changes.
Pickerclipstack/picker.pyChooses an item from the history.
Install on Linuxclipstack/install.shSets up the Linux services.
Windows sideclipstack/windows/install.ps1, uninstall.ps1, verify.ps1, clipstack.ahkWindows install, removal, checks, and the AutoHotkey script.
Shared clipboard plandocs/plans/2026-10-26-shared-clipboard/plan.mdThe plan for sharing the clipboard across machines.
windows
Scripts you run on the Windows PC, from PowerShell or Explorer. They are not run from this shell.
Set up the Windows environmentinit-windows/Start-Install.cmdRebuilds the dev environment from the manifests. Approve the admin prompt.
Check the installinit-windows/Verify-Windows.ps1, init-windows/Smoke-Test-Windows.ps1Checks the environment after install.
Roll backinit-windows/Remove-WindowsPack.ps1Removes what the pack installed, using its install journal.
Capture the environmentinit-windows/Export-Windows.ps1Exports the current machine's state for the manifests.
Install guideinit-windows/README.md, inventory.md, secrets-checklist.mdThe full guide, the inventory, and the sign-ins to redo.
Clone work reposrepos/Clone-BetecRepos.ps1Clones the missing Betec repos. Safe to re-run.
Skill syncskills-sync-windows/Sync-Skills.ps1 (runs on push through the GitHub runner)Fast-forwards the my-skills checkout and re-links the skills on Windows.
Skill sync checksskills-sync-windows/Test-Sync.ps1 and Test-Account.ps1; last-success.json in the ProgramData state folderChecks the sync, and records its last success.
Usage guard on Windowsclaude/usage-guard/Install-Windows.cmdInstalls the usage guard.
Codex Chrome bridge on Windowscodex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls the scheduled task that repairs the Chrome bridge.
skills
Global skills, where they come from, and how they reach each assistant.
Global skills~/projects/my-skills/<skill>/SKILL.md, linked into ~/.claude/skills, ~/.codex/skills, ~/.config/opencode/skillsThe source of the skills. install.sh links them.
Skill tableworkstation README, section AI assistant setupThe table of global skills and what each is for.
Backed-up skillsclaude/skills/Copies of the kept skills. Copy the ones you want into ~/.claude/skills.
Skill shortlistclaude/skills-shortlist.mdSkills researched on skills.sh.
Skill design rulevolatility-based-skill-designEvery new skill declares metadata.usage-tier, from junior to me.
Resume a projectresume-project skill: scripts/resume_project.py (see references/cli.md)Resumes a project's work from its saved state.
Create a skilltank--skill-creatorCreates new skills.
cv
The three CV versions, their sources, and how to rebuild them.
Full Stack Developer CVcv/cv-full-stack.pdf (source cv/cv-full-stack.tex)One of the three CV versions.
AI Full Stack Engineer CVcv/cv-ai-full-stack.pdf (source cv/cv-ai-full-stack.tex)One of the three CV versions.
AI Integrations CVcv/cv-ai-integrations.pdf (source cv/cv-ai-integrations.tex)One of the three CV versions.
Rebuild a CVpdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex, run in cv/Rebuilds the PDF. Commit the sources and PDFs together.
Plain-text versionscv/text/build-full.shBuilds the full text and variables files.
HTML design buildcv/design/build-design.pyBuilds the HTML design file.
Dated snapshotscv/versions/2026-10-04/ and cv/versions/2026-10-04-v2/Dated copies of the CVs, kept as they were.
Workflowcv/WORKFLOW.mdHow the CVs are updated.
Factual inputcv/experience-notes.md (readable master: cv/cv-master.md)The source facts that the CVs are built from.
work
Items, plans, changelog, cases, and the dated records.
Urgent itemsdocs/items/urgent.item.mdItems marked urgent.
Planned itemsdocs/items/planned.item.mdPlanned items.
Work itemsdocs/items/work.item.mdWork items.
Plansdocs/plans/<date>-<name>/plan.mdPlans for current work, one folder each.
Changelogdocs/changelog/Dated changes, for example 2026-10-17-patch-10.17.md.
Cases and decisions~/projects/data/ (private repo Lebnor/data)Questions asked, rule proposals, verdicts, and design and functional items.
Supervision backlog~/projects/betec/workboard/docs/supervision-backlog.mdThe supervision backlog.
Archive~/archive/ (layout in ~/archive/README.md)Files moved out of projects. Not a repo and not backed up.
Incidentsreference/incidents/ (index in reference/README.md)Dated machine-level failures and their repairs.
Case studiescase-studies/Archived, human-reviewed experiments, one folder each.
Design and researchdocs/design/, docs/research/, docs/functional-research/Pitches, recommendations, and research notes.
Questions
  • Should help screens only print commands, or also run them? Recommend: print only in the first version. Opening help then never starts a server, edits a file, or asks for sudo.
  • Should the Windows scripts appear in the Linux help? Recommend: yes, in their own windows screen marked run on Windows, so one place names every script you need.
  • How should retired items (Lan Mouse, the old Codex recorders, the retired Playwright MCP setup) be shown? Recommend: leave them off the top screen and keep one retired, rollback-only row where they belong, so they can be found but are not offered.
  • Is the command grammar workstation <area> right, with ws and setup as aliases? Recommend: yes, with workstation as the primary name. Check that setup does not clash with another command on PATH before keeping it.
  • Several source files are missing from the dump: workstation-cli/workstation.py, zsh.d/workstation.zsh, terminal_links.py, and the bodies of infra.zsh, utils.zsh and audio-share.zsh. The command names above come from the READMEs and are unverified. Recommend: send those files, or build each row from the script's own header before the help is written.
  • Should the known embedded credential in zsh.d get a visible warning on the keys screen? Recommend: yes, with the rotate-now note from secrets-checklist.md. The help should show only names, never values.
  • Should each localhost URL (8780, 8781, 8790) show its start command next to it? Recommend: yes, since the pages run only when started.
As phone screens

Home

The workstation help: one line per area you can reach on this machine. Run workstation followed by an area name (also ws or setup) to open that area's screen.

shellHelper commands from ~/.zsh.d: git safety, infra, terminal helpers, repairs, API key editing, review-open.
›
gitGit config, the lefthook hooks, and the push and commit gates.
›
keysWhere API keys and tokens are kept, outside Git, and how to edit them.
›
rulesThe org rules every session follows, printed from workboard/rules.yaml.
›
assistantsClaude, Codex, Hermes, Jev, the usage guard and the Claude plugins: how each is set up and started.
›
opencodeOpenCode profiles: which one is current, what each loads, how to switch.
›
agentsAgent records, their checks, and the Agent Sandbox page.
›
browserThe browser command, its one Chrome window, recording proof, and how Chrome is started.
›
dashboardsThe local dashboard pages on localhost and the command that starts each.
›
machinePower, display, network, lid, audio sharing and keepalive on this Linux laptop.
›
deskflowThe shared mouse and keyboard between the laptop and the Windows PC.
›
clipboardClipboard history (clipstack) on Linux and Windows.
›
windowsWindows-side scripts for setup, checks, repo clones and skill sync. Run them on Windows, not in this shell.
›
skillsGlobal skills, where they come from, and how they reach each assistant.
›
cvThe three CV versions, their sources, and how to rebuild the PDFs.
›
workItems, plans, changelog, cases, the archive, and the dated incident and case-study records.
›
‹ Home

shell

Helper commands that the shell loads from ~/.zsh.d, grouped by topic.

git safetyLists the files a checkout would discard and asks [y/N] first.
›
infra helpersDocker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands.
›
terminal helpersSet the terminal title, free a port, and use the IP aliases and lazy-loaded nvm, node, npm and npx.
›
runtime setupEnvironment setup for Android, Java and Bun.
›
fix-keyboardOne-shot repair for the keyboard.
›
fix-mouseOne-shot repair for the mouse.
›
fix-diskOne-shot repair for the disk.
›
fix-whatsappOne-shot repair for WhatsApp.
›
API key editorOpens ~/.config/api-keys/env, the general-use keys that zsh.d/api-keys.zsh loads.
›
review-openOpens a review from the shell; the wrapper lets bash and agents call it too.
›
rules commandPrints the rules. See the rules screen.
›
‹ Home

git

Git config, the hooks that run in every repo, and the gates they enforce.

Git configAuthor identity, Git LFS, the store credential helper, a large http.postBuffer, and core.hooksPath.
›
Git hooksLefthook shims that run in every repo. They need lefthook on PATH.
›
Push and commit gatesRefuse pushes to main in repos marked team.gitpolicy pull-request, and refuse commits on main in marked repos. They sit above LEFTHOOK=0, so that variable cannot skip them.
›
Reinstall hooksA plain lefthook install overwrites the hand-added gates.
›
Repoint an old cloneFor clones made before the rename from scripts.
›
‹ Home

keys

Where secrets live. None of these are in Git.

General API keysKeys for general use, exported by zsh.d/api-keys.zsh.
›
Jev browser-test keysThe Jev key and the Gemini text model key for jev-browser-test.
›
Hermes credentialsHermes ChatGPT logins and provider keys. Not backed up in this repo.
›
Known issue: embedded credentialA credential sits inside git URLs there. Rotate it and move to a credential manager. Help shows names only, never values.
›
Sign-ins to redoWhat to sign in to again on a fresh Windows install.
›
‹ Home

rules

The org rules every session follows.

Print the rulesPrints every rule, or the ones for one folder. Each session runs it at start.
›
Rule sourceThe rules. Changed only by you or by an accepted rule proposal (R43).
›
Rule metadataDetails kept beside the rules.
›
Rule proposalsProposed rule changes. Accept or Reject them on the dashboard.
›
Generated rules fileGenerated from rules.yaml. Do not edit it by hand.
›
‹ Home

opencode

OpenCode profiles: which one runs, what each loads, and how to switch.

Run OpenCodeRuns OpenCode with the current profile.
›
Current profileNames the profile in use.
›
ProfilesLists each profile and what it loads.
›
Switch profileSwitches every shell's new runs to that profile.
›
Sign Claude Code inSigns the current profile's Claude Code in.
›
Profile filesLists the current profile's files.
›
Edit a profile fileOpens one of those files.
›
Full help pageEvery profile's files, one column per profile. With more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
›
Profile sourcesWhere the profiles are defined.
›
‹ Home

assistants

The AI assistants on this machine, how each is started, and where its setup lives.

Claude wrapperStarts Claude Code through the usage guard.
›
Main sessionsContinues or resumes a main session through the session-types hook.
›
Team parkThe team-park tool. Its usage is in claude/team-park/README.md.
›
Global Claude filesGlobal rules and settings. init-windows deploys them to Windows.
›
Linux global mirrorA mirror of the installed Linux CLAUDE.md and its docs.
›
Windows global mirrorA mirror of the Windows CLAUDE.md and its docs.
›
Usage guardTracks Claude usage and the request budget.
›
Claude pluginsPanes and boards inside Claude Code. The review pane opens through review-open.
›
Codex configCodex CLI config.
›
Codex Chrome bridgeKeeps the Chrome plugin's latest link and the file: navigation patch working.
›
HermesThe Hermes agent, with default and jobs profiles. hermes/RESTORE.md covers recovery.
›
Jev consultAsks Jev a multi-choice decision. A Jev choice is guidance, not proof of anything.
›
Jev browser smoke testRuns a goal in a browser and checks the text and URL you supply.
›
‹ Home

agents

Agent records, their checks, and the Agent Sandbox page.

Check recordsRefuses broken agent records. Exits 1 on failure.
›
List agentsLists agents with their tier, model and number of tests.
›
Agent SandboxThe page where you pick an agent, change its setup, and ask it things.
›
Agent recordsEach agent's record, its saved tests, and its role skill.
›
Results and memoryTest results and each agent's memory.
›
Start a teamStarts a team from a team file in spawn-team/teams/.
›
Sandbox designThe PRD and mockups for the sandbox page.
›
‹ Home

browser

The browser command: one Chrome window that stays open between calls.

Run stepsRuns the steps in order on one persistent page and prints the results as JSON.
›
StatusShows whether the background server and Chrome are up.
›
CloseCloses Chrome and stops the server.
›
Record proofRecords a tab as proof that a feature works. The only supported way to record.
›
ScreenshotA still image of the page.
›
Local serverThe server the browser command talks to.
›
InstallRun once per machine.
›
Start ChromeThe only way to start Chrome here. It adds the recording flag. Quit and reopen Chrome after install.
›
Browser READMEActions, viewport presets, network capture, and login gotchas.
›
‹ Home

dashboards

Pages served on localhost. Each runs only when you start it.

DashboardThe Waiting, Overview and reader views. Desktop only.
›
Waiting tabCases asked, rule changes, and calls decided alone. The default tab.
›
Dashboard conceptsA second dashboard version to compare against, with the Projects panel and machine buttons.
›
Agent Sandbox pageThe same page as the agents screen, listed because it is a localhost page.
›
Dashboard testsChecks against the real data and a real server.
›
Dashboard designThe design rounds that chose the current look.
›
‹ Home

machine

Power, display, network, lid, audio and keepalive on this Linux laptop. Most scripts ask for sudo.

Low powerSets the power-saver profile, turns turbo off and caps the CPU at 8%. Intel P-state only.
›
Normal powerSets the balanced profile, turns turbo on and removes the cap.
›
External monitorSets mode and refresh rate on the HDMI or DP output with xrandr. Defaults to 1920x1080 at 59.88.
›
Internet recoveryEnables systemd-resolved, fixes resolv.conf, restarts networking. Re-runs itself with sudo.
›
Tailscale remote terminal recoveryRepairs DNS, restarts tailscaled, starts the remote-terminal service and checks port 3500. Run as your normal user.
›
Keep running with lid closedWrites a logind drop-in so closing the lid does nothing. Applies after reboot.
›
Restore lid behaviourRemoves that drop-in. Applies after reboot.
›
Closed-lid test recordThe test that showed CodeBot stays up with the lid closed.
›
Audio to WindowsSends Linux audio to the Windows PC over Tailscale. Pausing restores the speakers. The Windows player is run by the windows-audio-share agent.
›
Supabase keepaliveTimer that keeps the Supabase project active.
›
‹ Home

deskflow

One mouse and keyboard shared between the laptop and the Windows PC.

Everyday useMove past the laptop's right edge to control Windows, and past Windows' left edge to come back.
›
Restart and re-ask for inputStarts Deskflow again after a cancelled GNOME input prompt, and asks again.
›
Server serviceRuns the Linux Deskflow server with the graphical session.
›
SettingsLinux server settings, copied from deskflow/linux.conf and deskflow/server.conf.
›
Keyboard follows the mouseWhich mouse the keyboard follows, and how to stop it.
›
USB mouse forwardingForwards the Windows USB mouse. Off since 2026-10-20.
›
Network audit and firewallWhat the server opens on the network, and the lockdown rules.
›
Retired: Lan MouseThe old KVM, retired 2026-10-05. Rollback only. Never run it beside Deskflow.
›
‹ Home

clipboard

Clipboard history across Linux and Windows.

History serverServes the clipboard history.
›
WatcherWatches the clipboard and records changes.
›
PickerChooses an item from the history.
›
Install on LinuxSets up the Linux services.
›
Windows sideWindows install, removal, checks, and the AutoHotkey script.
›
Shared clipboard planThe plan for sharing the clipboard across machines.
›
‹ Home

windows

Scripts you run on the Windows PC, from PowerShell or Explorer. They are not run from this shell.

Set up the Windows environmentRebuilds the dev environment from the manifests. Approve the admin prompt.
›
Check the installChecks the environment after install.
›
Roll backRemoves what the pack installed, using its install journal.
›
Capture the environmentExports the current machine's state for the manifests.
›
Install guideThe full guide, the inventory, and the sign-ins to redo.
›
Clone work reposClones the missing Betec repos. Safe to re-run.
›
Skill syncFast-forwards the my-skills checkout and re-links the skills on Windows.
›
Skill sync checksChecks the sync, and records its last success.
›
Usage guard on WindowsInstalls the usage guard.
›
Codex Chrome bridge on WindowsInstalls the scheduled task that repairs the Chrome bridge.
›
‹ Home

skills

Global skills, where they come from, and how they reach each assistant.

Global skillsThe source of the skills. install.sh links them.
›
Skill tableThe table of global skills and what each is for.
›
Backed-up skillsCopies of the kept skills. Copy the ones you want into ~/.claude/skills.
›
Skill shortlistSkills researched on skills.sh.
›
Skill design ruleEvery new skill declares metadata.usage-tier, from junior to me.
›
Resume a projectResumes a project's work from its saved state.
›
Create a skillCreates new skills.
›
‹ Home

cv

The three CV versions, their sources, and how to rebuild them.

Full Stack Developer CVOne of the three CV versions.
›
AI Full Stack Engineer CVOne of the three CV versions.
›
AI Integrations CVOne of the three CV versions.
›
Rebuild a CVRebuilds the PDF. Commit the sources and PDFs together.
›
Plain-text versionsBuilds the full text and variables files.
›
HTML design buildBuilds the HTML design file.
›
Dated snapshotsDated copies of the CVs, kept as they were.
›
WorkflowHow the CVs are updated.
›
Factual inputThe source facts that the CVs are built from.
›
‹ Home

work

Items, plans, changelog, cases, and the dated records.

Urgent itemsItems marked urgent.
›
Planned itemsPlanned items.
›
Work itemsWork items.
›
PlansPlans for current work, one folder each.
›
ChangelogDated changes, for example 2026-10-17-patch-10.17.md.
›
Cases and decisionsQuestions asked, rule proposals, verdicts, and design and functional items.
›
Supervision backlogThe supervision backlog.
›
ArchiveFiles moved out of projects. Not a repo and not backed up.
›
IncidentsDated machine-level failures and their repairs.
›
Case studiesArchived, human-reviewed experiments, one folder each.
›
Design and researchPitches, recommendations, and research notes.
›
Raw answer
I built the map from the README files and the file list. Nothing was run, and the bodies of several scripts are missing from the dump, so the command names in the rows come from the docs. Each area below is one `workstation <area>` screen, which is an assumed command grammar (question 4).

```json
{"screens": [
{"path": [], "sentence": "The workstation help: one line per area you can reach on this machine. Run workstation followed by an area name (also ws or setup) to open that area's screen.", "rows": [
{"name": "shell", "form": "workstation shell", "what": "Helper commands from ~/.zsh.d: git safety, infra, terminal helpers, repairs, API key editing, review-open."},
{"name": "git", "form": "workstation git", "what": "Git config, the lefthook hooks, and the push and commit gates."},
{"name": "keys", "form": "workstation keys", "what": "Where API keys and tokens are kept, outside Git, and how to edit them."},
{"name": "rules", "form": "workstation rules", "what": "The org rules every session follows, printed from workboard/rules.yaml."},
{"name": "assistants", "form": "workstation assistants", "what": "Claude, Codex, Hermes, Jev, the usage guard and the Claude plugins: how each is set up and started."},
{"name": "opencode", "form": "workstation opencode", "what": "OpenCode profiles: which one is current, what each loads, how to switch."},
{"name": "agents", "form": "workstation agents", "what": "Agent records, their checks, and the Agent Sandbox page."},
{"name": "browser", "form": "workstation browser", "what": "The browser command, its one Chrome window, recording proof, and how Chrome is started."},
{"name": "dashboards", "form": "workstation dashboards", "what": "The local dashboard pages on localhost and the command that starts each."},
{"name": "machine", "form": "workstation machine", "what": "Power, display, network, lid, audio sharing and keepalive on this Linux laptop."},
{"name": "deskflow", "form": "workstation deskflow", "what": "The shared mouse and keyboard between the laptop and the Windows PC."},
{"name": "clipboard", "form": "workstation clipboard", "what": "Clipboard history (clipstack) on Linux and Windows."},
{"name": "windows", "form": "workstation windows", "what": "Windows-side scripts for setup, checks, repo clones and skill sync. Run them on Windows, not in this shell."},
{"name": "skills", "form": "workstation skills", "what": "Global skills, where they come from, and how they reach each assistant."},
{"name": "cv", "form": "workstation cv", "what": "The three CV versions, their sources, and how to rebuild the PDFs."},
{"name": "work", "form": "workstation work", "what": "Items, plans, changelog, cases, the archive, and the dated incident and case-study records."}
]},
{"path": ["shell"], "sentence": "Helper commands that the shell loads from ~/.zsh.d, grouped by topic.", "rows": [
{"name": "git safety", "form": "git checkout (wrapper from zsh.d/git-safety.zsh)", "what": "Lists the files a checkout would discard and asks [y/N] first."},
{"name": "infra helpers", "form": "command names defined in zsh.d/infra.zsh", "what": "Docker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands."},
{"name": "terminal helpers", "form": "set-title, killport (zsh.d/utils.zsh)", "what": "Set the terminal title, free a port, and use the IP aliases and lazy-loaded nvm, node, npm and npx."},
{"name": "runtime setup", "form": "zsh.d/utils.zsh (Android, Java, Bun)", "what": "Environment setup for Android, Java and Bun."},
{"name": "fix-keyboard", "form": "fix-keyboard", "what": "One-shot repair for the keyboard."},
{"name": "fix-mouse", "form": "fix-mouse", "what": "One-shot repair for the mouse."},
{"name": "fix-disk", "form": "fix-disk", "what": "One-shot repair for the disk."},
{"name": "fix-whatsapp", "form": "fix-whatsapp", "what": "One-shot repair for WhatsApp."},
{"name": "API key editor", "form": "api-keys-edit", "what": "Opens ~/.config/api-keys/env, the general-use keys that zsh.d/api-keys.zsh loads."},
{"name": "review-open", "form": "review-open (also ~/.local/bin/review-open)", "what": "Opens a review from the shell; the wrapper lets bash and agents call it too."},
{"name": "rules command", "form": "rules [folder]", "what": "Prints the rules. See the rules screen."}
]},
{"path": ["git"], "sentence": "Git config, the hooks that run in every repo, and the gates they enforce.", "rows": [
{"name": "Git config", "form": ".gitconfig, copied to ~/.gitconfig", "what": "Author identity, Git LFS, the store credential helper, a large http.postBuffer, and core.hooksPath."},
{"name": "Git hooks", "form": "git-hooks/, copied to ~/.git-hooks/", "what": "Lefthook shims that run in every repo. They need lefthook on PATH."},
{"name": "Push and commit gates", "form": "git-hooks/pre-push and git-hooks/commit-msg", "what": "Refuse pushes to main in repos marked team.gitpolicy pull-request, and refuse commits on main in marked repos. They sit above LEFTHOOK=0, so that variable cannot skip them."},
{"name": "Reinstall hooks", "form": "lefthook install, then re-add the gates by hand", "what": "A plain lefthook install overwrites the hand-added gates."},
{"name": "Repoint an old clone", "form": "git remote set-url origin https://github.com/Lebnor/workstation.git", "what": "For clones made before the rename from scripts."}
]},
{"path": ["keys"], "sentence": "Where secrets live. None of these are in Git.", "rows": [
{"name": "General API keys", "form": "api-keys-edit opens ~/.config/api-keys/env", "what": "Keys for general use, exported by zsh.d/api-keys.zsh."},
{"name": "Jev browser-test keys", "form": "~/.config/jev-browser-test/env (mode 600)", "what": "The Jev key and the Gemini text model key for jev-browser-test."},
{"name": "Hermes credentials", "form": "~/.hermes (auth.json files)", "what": "Hermes ChatGPT logins and provider keys. Not backed up in this repo."},
{"name": "Known issue: embedded credential", "form": "zsh.d/infra.zsh and zsh.d/utils.zsh", "what": "A credential sits inside git URLs there. Rotate it and move to a credential manager. Help shows names only, never values."},
{"name": "Sign-ins to redo", "form": "init-windows/secrets-checklist.md", "what": "What to sign in to again on a fresh Windows install."}
]},
{"path": ["rules"], "sentence": "The org rules every session follows.", "rows": [
{"name": "Print the rules", "form": "rules [folder]", "what": "Prints every rule, or the ones for one folder. Each session runs it at start."},
{"name": "Rule source", "form": "workboard/rules.yaml", "what": "The rules. Changed only by you or by an accepted rule proposal (R43)."},
{"name": "Rule metadata", "form": "workboard/rules-meta.yaml", "what": "Details kept beside the rules."},
{"name": "Rule proposals", "form": "~/projects/data/global/rule-proposals/", "what": "Proposed rule changes. Accept or Reject them on the dashboard."},
{"name": "Generated rules file", "form": "~/.claude/references/rules.md", "what": "Generated from rules.yaml. Do not edit it by hand."}
]},
{"path": ["opencode"], "sentence": "OpenCode profiles: which one runs, what each loads, and how to switch.", "rows": [
{"name": "Run OpenCode", "form": "opencode, or oc", "what": "Runs OpenCode with the current profile."},
{"name": "Current profile", "form": "opencode-profile", "what": "Names the profile in use."},
{"name": "Profiles", "form": "opencode-profiles", "what": "Lists each profile and what it loads."},
{"name": "Switch profile", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to that profile."},
{"name": "Sign Claude Code in", "form": "opencode-login", "what": "Signs the current profile's Claude Code in."},
{"name": "Profile files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "Edit a profile file", "form": "opencode-edit <file>", "what": "Opens one of those files."},
{"name": "Full help page", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Every profile's files, one column per profile. With more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it."},
{"name": "Profile sources", "form": "opencode-profiles/ (profiles.py, private-leb-experimental/)", "what": "Where the profiles are defined."}
]},
{"path": ["assistants"], "sentence": "The AI assistants on this machine, how each is started, and where its setup lives.", "rows": [
{"name": "Claude wrapper", "form": "claude (~/bin/claude, ahead of ~/.local/bin/claude)", "what": "Starts Claude Code through the usage guard."},
{"name": "Main sessions", "form": "claude --main -c, or claude --main -r", "what": "Continues or resumes a main session through the session-types hook."},
{"name": "Team park", "form": "team-park (~/.local/bin/team-park)", "what": "The team-park tool. Its usage is in claude/team-park/README.md."},
{"name": "Global Claude files", "form": "claude/CLAUDE.md, claude/AGENTS.md, claude/settings.json", "what": "Global rules and settings. init-windows deploys them to Windows."},
{"name": "Linux global mirror", "form": "claude/linux-global/", "what": "A mirror of the installed Linux CLAUDE.md and its docs."},
{"name": "Windows global mirror", "form": "claude/windows-global/", "what": "A mirror of the Windows CLAUDE.md and its docs."},
{"name": "Usage guard", "form": "claude/usage-guard/ (install.sh; Install-Windows.cmd on Windows)", "what": "Tracks Claude usage and the request budget."},
{"name": "Claude plugins", "form": "claude/mods/ (review-pane, changelog-pane, team-board, scratchpad-playground)", "what": "Panes and boards inside Claude Code. The review pane opens through review-open."},
{"name": "Codex config", "form": "codex/config.toml (deployed to the Windows .codex folder)", "what": "Codex CLI config."},
{"name": "Codex Chrome bridge", "form": "codex/chrome-bridge/install.sh on Linux; Install-CodexChromeBridge.cmd on Windows", "what": "Keeps the Chrome plugin's latest link and the file: navigation patch working."},
{"name": "Hermes", "form": "hermes (~/.local/bin/hermes); source in ~/projects/hermes-agent", "what": "The Hermes agent, with default and jobs profiles. hermes/RESTORE.md covers recovery."},
{"name": "Jev consult", "form": "jev CONTEXT -c QUESTION OPTIONS -j", "what": "Asks Jev a multi-choice decision. A Jev choice is guidance, not proof of anything."},
{"name": "Jev browser smoke test", "form": "jev-browser-test (installed by jev-browser-test/install.sh)", "what": "Runs a goal in a browser and checks the text and URL you supply."}
]},
{"path": ["agents"], "sentence": "Agent records, their checks, and the Agent Sandbox page.", "rows": [
{"name": "Check records", "form": "~/projects/workstation/agent-framework/agent check", "what": "Refuses broken agent records. Exits 1 on failure."},
{"name": "List agents", "form": "~/projects/workstation/agent-framework/agent list", "what": "Lists agents with their tier, model and number of tests."},
{"name": "Agent Sandbox", "form": "agent serve, then http://127.0.0.1:8790", "what": "The page where you pick an agent, change its setup, and ask it things."},
{"name": "Agent records", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "Each agent's record, its saved tests, and its role skill."},
{"name": "Results and memory", "form": "~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/", "what": "Test results and each agent's memory."},
{"name": "Start a team", "form": "/spawn-team <team> in Claude, or $spawn-team <team> in Codex", "what": "Starts a team from a team file in spawn-team/teams/."},
{"name": "Sandbox design", "form": "docs/plans/2026-10-22-agent-sandbox/prd.html", "what": "The PRD and mockups for the sandbox page."}
]},
{"path": ["browser"], "sentence": "The browser command: one Chrome window that stays open between calls.", "rows": [
{"name": "Run steps", "form": "browser '<json array of steps>', or browser with a steps file", "what": "Runs the steps in order on one persistent page and prints the results as JSON."},
{"name": "Status", "form": "browser status", "what": "Shows whether the background server and Chrome are up."},
{"name": "Close", "form": "browser close", "what": "Closes Chrome and stops the server."},
{"name": "Record proof", "form": "recordStart and recordStop steps", "what": "Records a tab as proof that a feature works. The only supported way to record."},
{"name": "Screenshot", "form": "screenshot step with a path", "what": "A still image of the page."},
{"name": "Local server", "form": "http://127.0.0.1:8848 (/health, /run, /close)", "what": "The server the browser command talks to."},
{"name": "Install", "form": "cd browser && npm install && npm link", "what": "Run once per machine."},
{"name": "Start Chrome", "form": "chrome/chrome.sh (flags in chrome/flags); install once with chrome/install.sh", "what": "The only way to start Chrome here. It adds the recording flag. Quit and reopen Chrome after install."},
{"name": "Browser README", "form": "browser/README.md", "what": "Actions, viewport presets, network capture, and login gotchas."}
]},
{"path": ["dashboards"], "sentence": "Pages served on localhost. Each runs only when you start it.", "rows": [
{"name": "Dashboard", "form": "http://127.0.0.1:8780, started by python3 ~/projects/workstation/dashboard/server.py", "what": "The Waiting, Overview and reader views. Desktop only."},
{"name": "Waiting tab", "form": "http://127.0.0.1:8780/#waiting", "what": "Cases asked, rule changes, and calls decided alone. The default tab."},
{"name": "Dashboard concepts", "form": "http://127.0.0.1:8781, started by python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "A second dashboard version to compare against, with the Projects panel and machine buttons."},
{"name": "Agent Sandbox page", "form": "http://127.0.0.1:8790 (agent serve)", "what": "The same page as the agents screen, listed because it is a localhost page."},
{"name": "Dashboard tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Checks against the real data and a real server."},
{"name": "Dashboard design", "form": "docs/design/2026-10-17-dashboard/", "what": "The design rounds that chose the current look."}
]},
{"path": ["machine"], "sentence": "Power, display, network, lid, audio and keepalive on this Linux laptop. Most scripts ask for sudo.", "rows": [
{"name": "Low power", "form": "cpu-min-power.sh", "what": "Sets the power-saver profile, turns turbo off and caps the CPU at 8%. Intel P-state only."},
{"name": "Normal power", "form": "cpu-normal-power.sh", "what": "Sets the balanced profile, turns turbo on and removes the cap."},
{"name": "External monitor", "form": "fix_old_monitor_hdmi.sh [--output] [--mode] [--rate] [--quiet]", "what": "Sets mode and refresh rate on the HDMI or DP output with xrandr. Defaults to 1920x1080 at 59.88."},
{"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "Enables systemd-resolved, fixes resolv.conf, restarts networking. Re-runs itself with sudo."},
{"name": "Tailscale remote terminal recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, starts the remote-terminal service and checks port 3500. Run as your normal user."},
{"name": "Keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind drop-in so closing the lid does nothing. Applies after reboot."},
{"name": "Restore lid behaviour", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in. Applies after reboot."},
{"name": "Closed-lid test record", "form": "reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "The test that showed CodeBot stays up with the lid closed."},
{"name": "Audio to Windows", "form": "audio-start, audio-pause, audio-share on|off|status|tone", "what": "Sends Linux audio to the Windows PC over Tailscale. Pausing restores the speakers. The Windows player is run by the windows-audio-share agent."},
{"name": "Supabase keepalive", "form": "supabase-keepalive/install.sh (systemd timer)", "what": "Timer that keeps the Supabase project active."}
]},
{"path": ["deskflow"], "sentence": "One mouse and keyboard shared between the laptop and the Windows PC.", "rows": [
{"name": "Everyday use", "form": "deskflow/README.md, section Everyday use", "what": "Move past the laptop's right edge to control Windows, and past Windows' left edge to come back."},
{"name": "Restart and re-ask for input", "form": "resume-kvm", "what": "Starts Deskflow again after a cancelled GNOME input prompt, and asks again."},
{"name": "Server service", "form": "~/.config/systemd/user/deskflow.service", "what": "Runs the Linux Deskflow server with the graphical session."},
{"name": "Settings", "form": "~/.config/Deskflow/Deskflow.conf and server.conf", "what": "Linux server settings, copied from deskflow/linux.conf and deskflow/server.conf."},
{"name": "Keyboard follows the mouse", "form": "deskflow/usb-mouse/README.md, section Keyboard follows the mouse", "what": "Which mouse the keyboard follows, and how to stop it."},
{"name": "USB mouse forwarding", "form": "deskflow-usb-mouse.service (disabled)", "what": "Forwards the Windows USB mouse. Off since 2026-10-20."},
{"name": "Network audit and firewall", "form": "deskflow/NETWORK-AUDIT.md and deskflow/deskflow-lockdown.nft", "what": "What the server opens on the network, and the lockdown rules."},
{"name": "Retired: Lan Mouse", "form": "lan-mouse/README.md (service disabled)", "what": "The old KVM, retired 2026-10-05. Rollback only. Never run it beside Deskflow."}
]},
{"path": ["clipboard"], "sentence": "Clipboard history across Linux and Windows.", "rows": [
{"name": "History server", "form": "clipstack-server.service (clipstack/server.py)", "what": "Serves the clipboard history."},
{"name": "Watcher", "form": "clipstack-watcher.service (clipstack/watcher.py)", "what": "Watches the clipboard and records changes."},
{"name": "Picker", "form": "clipstack/picker.py", "what": "Chooses an item from the history."},
{"name": "Install on Linux", "form": "clipstack/install.sh", "what": "Sets up the Linux services."},
{"name": "Windows side", "form": "clipstack/windows/install.ps1, uninstall.ps1, verify.ps1, clipstack.ahk", "what": "Windows install, removal, checks, and the AutoHotkey script."},
{"name": "Shared clipboard plan", "form": "docs/plans/2026-10-26-shared-clipboard/plan.md", "what": "The plan for sharing the clipboard across machines."}
]},
{"path": ["windows"], "sentence": "Scripts you run on the Windows PC, from PowerShell or Explorer. They are not run from this shell.", "rows": [
{"name": "Set up the Windows environment", "form": "init-windows/Start-Install.cmd", "what": "Rebuilds the dev environment from the manifests. Approve the admin prompt."},
{"name": "Check the install", "form": "init-windows/Verify-Windows.ps1, init-windows/Smoke-Test-Windows.ps1", "what": "Checks the environment after install."},
{"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes what the pack installed, using its install journal."},
{"name": "Capture the environment", "form": "init-windows/Export-Windows.ps1", "what": "Exports the current machine's state for the manifests."},
{"name": "Install guide", "form": "init-windows/README.md, inventory.md, secrets-checklist.md", "what": "The full guide, the inventory, and the sign-ins to redo."},
{"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing Betec repos. Safe to re-run."},
{"name": "Skill sync", "form": "skills-sync-windows/Sync-Skills.ps1 (runs on push through the GitHub runner)", "what": "Fast-forwards the my-skills checkout and re-links the skills on Windows."},
{"name": "Skill sync checks", "form": "skills-sync-windows/Test-Sync.ps1 and Test-Account.ps1; last-success.json in the ProgramData state folder", "what": "Checks the sync, and records its last success."},
{"name": "Usage guard on Windows", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the usage guard."},
{"name": "Codex Chrome bridge on Windows", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs the scheduled task that repairs the Chrome bridge."}
]},
{"path": ["skills"], "sentence": "Global skills, where they come from, and how they reach each assistant.", "rows": [
{"name": "Global skills", "form": "~/projects/my-skills/<skill>/SKILL.md, linked into ~/.claude/skills, ~/.codex/skills, ~/.config/opencode/skills", "what": "The source of the skills. install.sh links them."},
{"name": "Skill table", "form": "workstation README, section AI assistant setup", "what": "The table of global skills and what each is for."},
{"name": "Backed-up skills", "form": "claude/skills/", "what": "Copies of the kept skills. Copy the ones you want into ~/.claude/skills."},
{"name": "Skill shortlist", "form": "claude/skills-shortlist.md", "what": "Skills researched on skills.sh."},
{"name": "Skill design rule", "form": "volatility-based-skill-design", "what": "Every new skill declares metadata.usage-tier, from junior to me."},
{"name": "Resume a project", "form": "resume-project skill: scripts/resume_project.py (see references/cli.md)", "what": "Resumes a project's work from its saved state."},
{"name": "Create a skill", "form": "tank--skill-creator", "what": "Creates new skills."}
]},
{"path": ["cv"], "sentence": "The three CV versions, their sources, and how to rebuild them.", "rows": [
{"name": "Full Stack Developer CV", "form": "cv/cv-full-stack.pdf (source cv/cv-full-stack.tex)", "what": "One of the three CV versions."},
{"name": "AI Full Stack Engineer CV", "form": "cv/cv-ai-full-stack.pdf (source cv/cv-ai-full-stack.tex)", "what": "One of the three CV versions."},
{"name": "AI Integrations CV", "form": "cv/cv-ai-integrations.pdf (source cv/cv-ai-integrations.tex)", "what": "One of the three CV versions."},
{"name": "Rebuild a CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex, run in cv/", "what": "Rebuilds the PDF. Commit the sources and PDFs together."},
{"name": "Plain-text versions", "form": "cv/text/build-full.sh", "what": "Builds the full text and variables files."},
{"name": "HTML design build", "form": "cv/design/build-design.py", "what": "Builds the HTML design file."},
{"name": "Dated snapshots", "form": "cv/versions/2026-10-04/ and cv/versions/2026-10-04-v2/", "what": "Dated copies of the CVs, kept as they were."},
{"name": "Workflow", "form": "cv/WORKFLOW.md", "what": "How the CVs are updated."},
{"name": "Factual input", "form": "cv/experience-notes.md (readable master: cv/cv-master.md)", "what": "The source facts that the CVs are built from."}
]},
{"path": ["work"], "sentence": "Items, plans, changelog, cases, and the dated records.", "rows": [
{"name": "Urgent items", "form": "docs/items/urgent.item.md", "what": "Items marked urgent."},
{"name": "Planned items", "form": "docs/items/planned.item.md", "what": "Planned items."},
{"name": "Work items", "form": "docs/items/work.item.md", "what": "Work items."},
{"name": "Plans", "form": "docs/plans/<date>-<name>/plan.md", "what": "Plans for current work, one folder each."},
{"name": "Changelog", "form": "docs/changelog/", "what": "Dated changes, for example 2026-10-17-patch-10.17.md."},
{"name": "Cases and decisions", "form": "~/projects/data/ (private repo Lebnor/data)", "what": "Questions asked, rule proposals, verdicts, and design and functional items."},
{"name": "Supervision backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "The supervision backlog."},
{"name": "Archive", "form": "~/archive/ (layout in ~/archive/README.md)", "what": "Files moved out of projects. Not a repo and not backed up."},
{"name": "Incidents", "form": "reference/incidents/ (index in reference/README.md)", "what": "Dated machine-level failures and their repairs."},
{"name": "Case studies", "form": "case-studies/", "what": "Archived, human-reviewed experiments, one folder each."},
{"name": "Design and research", "form": "docs/design/, docs/research/, docs/functional-research/", "what": "Pitches, recommendations, and research notes."}
]}
],
"questions": [
"Should help screens only print commands, or also run them? Recommend: print only in the first version. Opening help then never starts a server, edits a file, or asks for sudo.",
"Should the Windows scripts appear in the Linux help? Recommend: yes, in their own windows screen marked run on Windows, so one place names every script you need.",
"How should retired items (Lan Mouse, the old Codex recorders, the retired Playwright MCP setup) be shown? Recommend: leave them off the top screen and keep one retired, rollback-only row where they belong, so they can be found but are not offered.",
"Is the command grammar workstation <area> right, with ws and setup as aliases? Recommend: yes, with workstation as the primary name. Check that setup does not clash with another command on PATH before keeping it.",
"Several source files are missing from the dump: workstation-cli/workstation.py, zsh.d/workstation.zsh, terminal_links.py, and the bodies of infra.zsh, utils.zsh and audio-share.zsh. The command names above come from the READMEs and are unverified. Recommend: send those files, or build each row from the script's own header before the help is written.",
"Should the known embedded credential in zsh.d get a visible warning on the keys screen? Recommend: yes, with the rotate-now note from secrets-checklist.md. The help should show only names, never values.",
"Should each localhost URL (8780, 8781, 8790) show its start command next to it? Recommend: yes, since the pages run only when started."
]}
```

Today's skills · run 2 exit=0 seconds=184 · prompt

P1 Recall: 0.714P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 10P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.313
As terminal help
The map of this workstation: pick a group to see what is inside it.
Machineworkstation machinePrints the machine screen: power, screen, network, repairs and background services of this Linux laptop.
Shellworkstation shellPrints the shell screen: the zsh helpers for git, infrastructure, keys, OpenCode and audio.
Agentsworkstation agentsPrints the agents screen: rules, skills, teams, sandbox, settings and sessions of the AI assistants.
Browserworkstation browserPrints the browser screen: the persistent Chrome window, its command and its smoke tests.
Dashboardworkstation dashboardPrints the dashboard screen: the two dashboard versions and their checks.
Inputworkstation inputPrints the input screen: the keyboard and mouse shared with the Windows PC.
Windowsworkstation windowsPrints the Windows screen: rebuilding the PC, keeping its skills in step, and cloning its work repos.
CVsworkstation cvPrints the CV screen: the three CVs, their sources and how to rebuild them.
Clipboardworkstation clipboardPrints the clipboard screen: the shared clipboard history server, watcher and picker.
Docsworkstation docsPrints the docs screen: plans, designs, research, flows, changelog, case studies, incidents and the archive.
machine
The Linux laptop's own fixes and background services.
Power and lidworkstation machine powerPrints the power and lid screen: the CPU power profiles and the lid settings.
Screen~/projects/workstation/fix_old_monitor_hdmi.shRuns the script that sets the mode and refresh rate of an external HDMI or DP screen.
Internet recovery~/projects/workstation/linux-internet-recovery.shRuns the script that resets DNS and restarts networking; it asks for sudo.
Tailscale remote terminal~/projects/workstation/recover-tailscale-remote-terminal.shRuns the script that repairs DNS, restarts Tailscale and checks the remote terminal on port 3500.
Repairsworkstation machine repairsPrints the repairs screen: keyboard, mouse, disk and WhatsApp fixes.
Servicesworkstation machine servicesPrints the services screen: the background services and timers that run here.
machine › power
The CPU power profiles and the laptop lid settings.
Power saver~/projects/workstation/cpu-min-power.shRuns the script that sets the power-saver profile, turbo off and the CPU capped at 8%; it asks for sudo.
Balanced~/projects/workstation/cpu-normal-power.shRuns the script that sets the balanced profile, turbo on and the CPU cap back to 100%.
Keep running with lid closed~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.shRuns the script that makes closing the lid do nothing; it applies after a reboot.
Restore default lid~/projects/workstation/laptop-utilities/restore-default-lid-behavior.shRuns the script that removes that lid setting; it applies after a reboot.
machine › repairs
The one-command repairs for keyboard, mouse, disk and WhatsApp.
Keyboardfix-keyboardRuns the keyboard repair defined in ~/projects/workstation/zsh.d/utils.zsh.
Mousefix-mouseRuns the mouse repair defined in ~/projects/workstation/zsh.d/utils.zsh.
Diskfix-diskRuns the disk repair defined in ~/projects/workstation/zsh.d/utils.zsh.
WhatsAppfix-whatsappRuns the WhatsApp repair defined in ~/projects/workstation/zsh.d/utils.zsh.
machine › services
The background services and timers that run on this machine.
Shared keyboard and mouse~/.config/systemd/user/deskflow.serviceStarts and stops the Deskflow server, which starts with the graphical session.
Clipboard server~/projects/workstation/clipstack/units/clipstack-server.serviceStarts and stops the clipboard history server.
Clipboard watcher~/projects/workstation/clipstack/units/clipstack-watcher.serviceStarts and stops the clipboard watcher.
Supabase keepalive~/projects/workstation/supabase-keepalive/supabase-keepalive.timerRuns the Supabase keepalive script on a timer.
Codex Chrome bridge~/projects/workstation/codex/chrome-bridge/codex-chrome-bridge.timerRuns the bridge repair on a timer, keeping Codex's Chrome link in place.
Rules reminder~/projects/workstation/docs/plans/2026-10-24-rules-per-role/reminder/rules-roles-reminder.timerRuns the rules reminder on a timer.
Answer sync~/.config/systemd/user/data-pull.timerRuns the answer sync from the data repo every 5 minutes.
Remote terminalsystemctl --user status remote-terminalStarts the remote terminal on port 3500.
All user timerssystemctl --user list-timersLists every user timer and when it next runs.
shell
The zsh helpers in ~/.zsh.d, one group per topic.
Gitworkstation shell gitPrints the git screen: the checkout guard, git config and the commit and push hooks.
Infra~/.zsh.d/infra.zshOpens the infra helpers: Docker and Compose, Prisma, Postgres, nginx and VPN commands.
Utilitiesworkstation shell utilsPrints the utilities screen: terminal title, port killing, IP aliases, lazy Node, and the Android, Java and Bun setup.
API keysapi-keys-editOpens the file of general-use API keys in the editor; keys are never in Git.
OpenCodeworkstation shell opencodePrints the OpenCode screen: profiles, switching, login, files and the OpenCode help.
Reviewreview-openOpens a file in the review pane.
Audio shareworkstation shell audioPrints the audio screen: start, pause and status of audio sent to the Windows PC.
Dash path check~/projects/workstation/zsh.d/dash-path-warn.zshOpens the dash path check; its purpose is not in the dump (see questions).
shell › git
The git guard, config and hooks that apply to every repo.
Checkout guard~/projects/workstation/zsh.d/git-safety.zshOpens the git checkout wrapper, which lists files and asks [y/N] before discarding unstaged changes.
Git config~/.gitconfigOpens the git config: author, LFS, credential helper and hooks path.
Git hooks~/.git-hooks/Opens the Lefthook shims that run in every repo on commit and push.
shell › utils
The terminal helpers in zsh.d/utils.zsh.
Set titleset-titleSets the title of the terminal window.
Kill portkillport <port>Stops the process listening on a port.
IP aliases~/projects/workstation/zsh.d/utils.zshOpens the IP aliases defined in this file.
Node and npmnvmLoads nvm, node, npm and npx on first use, not at shell start.
Android, Java and Bun~/projects/workstation/zsh.d/utils.zshOpens the Android, Java and Bun setup in this file.
shell › opencode
The OpenCode profile commands; OpenCode's own help is the full reference.
Current profileopencode-profilePrints the name of the profile OpenCode uses now.
Profilesopencode-profilesPrints each profile and what it loads.
Switch profileopencode-switch <name>Switches the profile every new shell run uses.
Sign inopencode-login <name>Signs a profile's Claude Code in.
Profile filesopencode-filesPrints the current profile's files.
Edit a fileopencode-edit <file>Opens one of the current profile's files in the editor.
Profile definitions~/projects/workstation/opencode-profiles/Opens the profile definitions kept in Git.
Full helpopencode helpPrints the full OpenCode help: every profile's files and the commands.
shell › audio
The controls for this machine's audio, sent to the Windows PC over Tailscale.
Startaudio-startStarts sending all Linux audio to the Windows PC.
Pauseaudio-pausePauses the audio share and restores the speakers.
Statusaudio-share statusPrints whether the audio share is on.
Toneaudio-share tonePlays the test tone to the Windows PC.
agents
The AI assistants on this machine: their rules, skills, teams, sandbox, settings and sessions.
RulesrulesPrints the rules every org follows, from workboard/rules.yaml.
Skillsworkstation agents skillsPrints the skills screen: the global skills and the copies kept here.
Roles and teamsworkstation agents teamsPrints the teams screen: role skills, personas, starting a team and team files.
Agent Sandboxworkstation agents sandboxPrints the sandbox screen: checking, listing and serving the agent records.
Configworkstation agents configPrints the config screen: Claude and Codex settings, instructions and hooks.
Sessions and usageworkstation agents sessionsPrints the sessions screen: the main session, the usage guard and team-park.
Hermes~/.local/bin/hermesRuns the Hermes agent, which serves its two Telegram bots.
Data repo~/projects/data/Opens the data repo of cases, rule proposals, verdicts and reviews.
agents › skills
The skills agents load, and where their copies are kept.
Global skills~/projects/my-skills/Opens the my-skills repo, the source of the global skills.
Skill links~/.claude/skills/Opens the folder where global skills are linked for Claude.
Install skills~/projects/my-skills/install.shRuns the install that links skills into the skill folders.
Kept hereworkstation agents skills keptPrints the kept screen: the twelve skill copies in this repo, which load only once copied in.
Shortlist~/projects/workstation/claude/skills-shortlist.mdOpens the skills researched on skills.sh and what is installed.
agents › skills › kept
The skill copies kept in this repo, one folder each.
contextual-value-product-thinking~/projects/workstation/claude/skills/contextual-value-product-thinking/Opens the skill that analyses products through contextual human values.
elad12390--web-research-assistant~/projects/workstation/claude/skills/elad12390--web-research-assistant/Opens the web research MCP skill: search, crawling, stealth scraping and package lookups.
epic-fanout-planning~/projects/workstation/claude/skills/epic-fanout-planning/Opens the 10-step pattern for QA-gap epics with parallel fan-out.
impeccable~/projects/workstation/claude/skills/impeccable/Opens the frontend design skill: shape, critique, audit and polish.
api-key-creation~/projects/workstation/claude/skills/api-key-creation/Opens the troubleshooting skill for getting a missing API key with browser tools.
iterative-action-review~/projects/workstation/claude/skills/iterative-action-review/Opens the skill for reviewing a completed action as one iteration in a series.
post-feature-cleanup~/projects/workstation/claude/skills/post-feature-cleanup/Opens the pass that catches UI defects, leftovers and repo hygiene after a feature.
powershell-launching~/projects/workstation/claude/skills/powershell-launching/Opens the skill for launching PowerShell or a new terminal on Windows.
reboot-resume~/projects/workstation/claude/skills/reboot-resume/Opens the skill that preserves and resumes work across a reboot.
tank--communication-engineering~/projects/workstation/claude/skills/tank--communication-engineering/Opens the skill that applies engineering discipline to what an agent says.
tank--skill-creator~/projects/workstation/claude/skills/tank--skill-creator/Opens the skill for creating new skills.
tech-ledger~/projects/workstation/claude/skills/tech-ledger/Opens the skill that reads and writes the Tech Ledger of evaluated tech.
agents › teams
The roles and teams that agents work in, and where their files are.
Worker role~/projects/my-skills/worker/SKILL.mdOpens the worker's role skill.
Supervisor role~/projects/my-skills/supervisor/SKILL.mdOpens the supervisor's role skill.
Admin role~/projects/my-skills/admin/SKILL.mdOpens the admin's role skill.
QA agent role~/projects/my-skills/qa-agent/SKILL.mdOpens the QA agent's role skill; no team starts it yet.
Claude personas~/projects/my-skills/agents/Opens the agents folder, one folder per agent with its Claude persona and OpenCode agent.
Start a team/spawn-team <team>Starts a team from a team file, such as worker-pair or research-team; Codex uses $spawn-team.
Team files~/projects/my-skills/spawn-team/teams/Opens the team files; a new team is a new file.
How team members talk~/projects/my-skills/coordinated-agentic-session/Opens the rules for how team members hand off work.
agents › sandbox
The Agent Sandbox: an agent's setup, run as a real session on a page.
Start the sandbox~/projects/workstation/agent-framework/agent serveStarts the Agent Sandbox server, which serves the page at 127.0.0.1:8790.
Open the pagehttp://127.0.0.1:8790Opens the Agent Sandbox page; it works only while the server runs.
Check the records~/projects/workstation/agent-framework/agent checkChecks every agent record and refuses broken ones; exits 1 when one fails.
List the agents~/projects/workstation/agent-framework/agent listLists each agent with its tier, model and number of tests.
Intent~/projects/workstation/.idd/modules/agent-framework/INTENT.mdOpens the intent and rules for the agent framework.
agents › config
The global instructions and settings for Claude and Codex, and the Claude hooks.
Claude instructions~/.claude/CLAUDE.mdOpens the global rules every Claude session reads on Linux.
Claude settings~/.claude/settings.jsonOpens Claude Code's settings, which stay on this machine.
Codex config~/.codex/config.tomlOpens Codex's config, where multi_agent_v2 is turned on.
Codex instructions~/.codex/AGENTS.mdOpens the global agent notes Codex reads.
Hooksworkstation agents config hooksPrints the hooks screen: the scripts wired into Claude's settings.
Windows copies~/projects/workstation/claude/Opens the repo copies that init-windows deploys to Windows.
agents › config › hooks
The Claude hook scripts wired into ~/.claude/settings.json.
Core rules~/projects/workstation/claude/hooks/core-rules.shOpens the hook that enforces the core rules at session start and before Bash calls.
Machine history~/projects/workstation/claude/hooks/machine-history.shOpens the machine-history hook.
Local server guard~/projects/workstation/claude/hooks/local-server-guard.pyOpens the guard hook that runs before each Bash call.
Proof reminder~/projects/workstation/claude/hooks/proof-reminder.shOpens the reminder hook that runs after edits and Bash calls.
Team activity~/projects/workstation/claude/hooks/team-activity.shOpens the team activity hook.
Session types~/projects/workstation/claude/session-types/session-types.shOpens the SessionStart hook that sets the session type.
Hook testssh ~/projects/workstation/claude/hooks/test_core_rules.shRuns the core rules hook tests.
agents › sessions
The Claude session tools: the main session, the usage guard and team-park.
Main sessionclaude --mainStarts the main Claude session; -c continues it and -r resumes one.
Usage guard~/bin/claudeOpens the claude wrapper that puts the usage guard in front of the native command.
Team parkteam-parkRuns team-park; its README in claude/team-park says what it parks.
browser
The Chrome this machine drives: one persistent window, the browser command and its checks.
Browser statusbrowser statusPrints whether the background browser server is up.
Close the browserbrowser closeStops the browser window and its server.
Browser guide~/projects/workstation/browser/README.mdOpens the browser command's guide, including how to record a feature as proof.
Start Chrome~/projects/workstation/chrome/chrome.shStarts Chrome with the flags in chrome/flags; the only way to start it here.
Chrome setup~/projects/workstation/chrome/install.shRuns the one-time setup that points Chrome's launchers at chrome.sh.
Chrome flags~/projects/workstation/chrome/flagsOpens the Chrome flag list, which every start reads.
Smoke QAjev-browser-testRuns a goal in a browser and reports only the text and URL you assert.
Codex browser path~/projects/workstation/codex/browser/Opens Codex's direct Chrome command path and its live verification.
dashboard
The screen that shows what waits for you, in two versions to compare.
Dashboard serverpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard at http://127.0.0.1:8780.
Concepts serverpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts version at http://127.0.0.1:8781, which differs only in its Projects panel.
Open the dashboardhttp://127.0.0.1:8780Opens the dashboard page; its server must be running.
Open the conceptshttp://127.0.0.1:8781Opens the concepts page; its server must be running.
Dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the dashboard's 199 checks against the real data and a real server.
Concepts checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the concepts version's 17 checks.
Design rounds~/projects/workstation/docs/design/2026-10-17-dashboard/Opens the design rounds that chose the look.
input
The keyboard and mouse shared between the laptop and the Windows PC.
Deskflow guide~/projects/workstation/deskflow/README.mdOpens the Deskflow guide: daily use, the permission prompt and recovery.
Restart Deskflowresume-kvmStarts Deskflow again and asks for input capture.
Deskflow config~/.config/Deskflow/Deskflow.confOpens the Deskflow settings on this laptop.
Keyboard follows the mouse~/projects/workstation/deskflow/usb-mouse/README.md#keyboard-follows-the-mouseOpens how the keyboard follows the mouse, and how to stop it.
USB mouse sharing~/projects/workstation/deskflow/usb-mouse/Opens the Windows USB mouse sharing files; forwarding has been off since 2026-10-20.
Network audit~/projects/workstation/deskflow/NETWORK-AUDIT.mdOpens the network audit for Deskflow.
Retired Lan Mouse~/projects/workstation/lan-mouse/README.mdOpens the retired Lan Mouse setup, kept for rollback only.
windows
The Windows PC: its rebuild, checks, skill sync and work repos.
Rebuild~/projects/workstation/init-windows/Start-Install.cmdRuns the install that rebuilds the dev environment from the manifests; it asks for admin approval.
Check the install~/projects/workstation/init-windows/Smoke-Test-Windows.ps1Runs the checks on the installed environment.
Roll back~/projects/workstation/init-windows/Remove-WindowsPack.ps1Runs the rollback that removes the installed pack.
Bootstrap guide~/projects/workstation/init-windows/README.mdOpens the bootstrap guide.
Inventory~/projects/workstation/init-windows/inventory.mdOpens what the install captured.
Sign-ins to redo~/projects/workstation/init-windows/secrets-checklist.mdOpens the sign-ins to redo by hand.
Skill sync guide~/projects/workstation/skills-sync-windows/README.mdOpens how Windows skills stay in step with my-skills.
Skill sync check~/projects/workstation/skills-sync-windows/Test-Sync.ps1Runs the skill sync test on Windows.
Clone work repos~/projects/workstation/repos/Clone-BetecRepos.ps1Runs the clone of every missing Betec repo; existing folders are left alone.
cv
The three CVs, their LaTeX sources and how their PDFs are rebuilt.
Full Stack Developer~/projects/workstation/cv/cv-full-stack.pdfOpens the Full Stack Developer CV.
AI Full Stack Engineer~/projects/workstation/cv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
AI Integrations~/projects/workstation/cv/cv-ai-integrations.pdfOpens the AI Integrations CV.
Sources~/projects/workstation/cv/Opens the CV folder with the LaTeX sources and shared parts.
Rebuild PDFspdflatex -interaction=nonstopmode -halt-on-error cv-ai-full-stack.texRuns pdflatex on each CV source, which rebuilds its PDF.
Plain-text versions~/projects/workstation/cv/text/build-full.shRuns the build of the plain-text CVs.
HTML design version~/projects/workstation/cv/design/build-design.pyRuns the build of the HTML design version.
Dated versions~/projects/workstation/cv/versions/Opens the dated copies of the CVs.
Experience notes~/projects/workstation/cv/experience-notes.mdOpens the factual notes the CVs are built from.
Workflow~/projects/workstation/cv/WORKFLOW.mdOpens the CV workflow.
clipboard
The shared clipboard history: its server, watcher, picker and Windows side.
Picker~/projects/workstation/clipstack/picker.pyRuns the picker, where you choose an earlier clip.
Server~/projects/workstation/clipstack/server.pyRuns the server that holds the history.
Watcher~/projects/workstation/clipstack/watcher.pyRuns the watcher that follows the clipboard.
Linux install~/projects/workstation/clipstack/install.shRuns the install that sets up the Linux server and watcher units.
Windows script~/projects/workstation/clipstack/windows/clipstack.ahkRuns the Windows clipboard script.
Windows install~/projects/workstation/clipstack/windows/install.ps1Runs the Windows install; uninstall.ps1 removes it.
Server tests~/projects/workstation/clipstack/test_server.pyRuns the server's tests.
docs
The written record: plans, designs, research, flows, changelog, case studies, incidents and the archive.
Plans~/projects/workstation/docs/plans/Opens the plans, one dated folder each.
Designs~/projects/workstation/docs/design/Opens the design rounds, one dated folder each.
Research~/projects/workstation/docs/research/Opens the research notes, one dated folder each.
Flows~/projects/workstation/docs/flows/Opens the flow cards and data models, by date.
Changelog~/projects/workstation/docs/changelog/Opens the dated changelog entries.
Work items~/projects/workstation/docs/items/Opens the planned, urgent and work item lists.
Case studies~/projects/workstation/case-studies/Opens the archived, human-reviewed experiments.
Incidents~/projects/workstation/reference/incidents/Opens the dated machine incident records.
Intent files~/projects/workstation/.idd/Opens the intent files that set each module's rules.
Behavior features~/projects/workstation/.bdd/features/Opens the behavior features, one folder per module.
Archive~/archive/Opens the archive of files moved out of projects; it is not backed up.
Questions
  • Aliases: the README already gives `workstation`, `ws` and `setup`. Keep `setup`? It is a common word and clashes easily. Recommendation: keep `workstation` and `ws`, and check `whence -a setup` before deciding.
  • Top groups: the map has ten groups. Recommendation: keep them as drawn. The alternative is to fold `input` into `machine`, since both are small Linux hardware groups.
  • Runnable or open-only: the power, lid, network, screen and repair rows say what they run. Should the thin commands run them (some ask for sudo) or only open the script? Recommendation: run the machine fixes through thin commands and open the rest.
  • Retired items: the map keeps one Lan Mouse row for rollback and leaves out the retired `codex/playwright-mcp` setup and the USB forwarding that is off. Recommendation: keep it this way.
  • Live state: should `machine services` show each unit's running state when printed, or only list the unit files? Recommendation: show the state, since it is the only live view of the machine.
  • Names to confirm: the README names `resume-kvm`, `workstation-cli/`, `zsh.d/workstation.zsh`, `audio-share/`, `init-windows/inventory.md` and `cv/cv-master.md`, but the file list does not show them. The purpose of `zsh.d/dash-path-warn.zsh` is also not in the dump. The map keeps all of them; please confirm they exist and what the dash path check does.
  • Credentials: the README says `infra.zsh` and `utils.zsh` embed credentials. The map lists the files and shows no values. Recommendation: do not add a row flagging them; the existing `secrets-checklist.md` already covers rotation.
As phone screens

Home

The map of this workstation: pick a group to see what is inside it.

MachinePrints the machine screen: power, screen, network, repairs and background services of this Linux laptop.
›
ShellPrints the shell screen: the zsh helpers for git, infrastructure, keys, OpenCode and audio.
›
AgentsPrints the agents screen: rules, skills, teams, sandbox, settings and sessions of the AI assistants.
›
BrowserPrints the browser screen: the persistent Chrome window, its command and its smoke tests.
›
DashboardPrints the dashboard screen: the two dashboard versions and their checks.
›
InputPrints the input screen: the keyboard and mouse shared with the Windows PC.
›
WindowsPrints the Windows screen: rebuilding the PC, keeping its skills in step, and cloning its work repos.
›
CVsPrints the CV screen: the three CVs, their sources and how to rebuild them.
›
ClipboardPrints the clipboard screen: the shared clipboard history server, watcher and picker.
›
DocsPrints the docs screen: plans, designs, research, flows, changelog, case studies, incidents and the archive.
›
‹ Home

machine

The Linux laptop's own fixes and background services.

Power and lidPrints the power and lid screen: the CPU power profiles and the lid settings.
›
ScreenRuns the script that sets the mode and refresh rate of an external HDMI or DP screen.
›
Internet recoveryRuns the script that resets DNS and restarts networking; it asks for sudo.
›
Tailscale remote terminalRuns the script that repairs DNS, restarts Tailscale and checks the remote terminal on port 3500.
›
RepairsPrints the repairs screen: keyboard, mouse, disk and WhatsApp fixes.
›
ServicesPrints the services screen: the background services and timers that run here.
›
‹ machine

power

The CPU power profiles and the laptop lid settings.

Power saverRuns the script that sets the power-saver profile, turbo off and the CPU capped at 8%; it asks for sudo.
›
BalancedRuns the script that sets the balanced profile, turbo on and the CPU cap back to 100%.
›
Keep running with lid closedRuns the script that makes closing the lid do nothing; it applies after a reboot.
›
Restore default lidRuns the script that removes that lid setting; it applies after a reboot.
›
‹ machine

repairs

The one-command repairs for keyboard, mouse, disk and WhatsApp.

KeyboardRuns the keyboard repair defined in ~/projects/workstation/zsh.d/utils.zsh.
›
MouseRuns the mouse repair defined in ~/projects/workstation/zsh.d/utils.zsh.
›
DiskRuns the disk repair defined in ~/projects/workstation/zsh.d/utils.zsh.
›
WhatsAppRuns the WhatsApp repair defined in ~/projects/workstation/zsh.d/utils.zsh.
›
‹ machine

services

The background services and timers that run on this machine.

Shared keyboard and mouseStarts and stops the Deskflow server, which starts with the graphical session.
›
Clipboard serverStarts and stops the clipboard history server.
›
Clipboard watcherStarts and stops the clipboard watcher.
›
Supabase keepaliveRuns the Supabase keepalive script on a timer.
›
Codex Chrome bridgeRuns the bridge repair on a timer, keeping Codex's Chrome link in place.
›
Rules reminderRuns the rules reminder on a timer.
›
Answer syncRuns the answer sync from the data repo every 5 minutes.
›
Remote terminalStarts the remote terminal on port 3500.
›
All user timersLists every user timer and when it next runs.
›
‹ Home

shell

The zsh helpers in ~/.zsh.d, one group per topic.

GitPrints the git screen: the checkout guard, git config and the commit and push hooks.
›
InfraOpens the infra helpers: Docker and Compose, Prisma, Postgres, nginx and VPN commands.
›
UtilitiesPrints the utilities screen: terminal title, port killing, IP aliases, lazy Node, and the Android, Java and Bun setup.
›
API keysOpens the file of general-use API keys in the editor; keys are never in Git.
›
OpenCodePrints the OpenCode screen: profiles, switching, login, files and the OpenCode help.
›
ReviewOpens a file in the review pane.
›
Audio sharePrints the audio screen: start, pause and status of audio sent to the Windows PC.
›
Dash path checkOpens the dash path check; its purpose is not in the dump (see questions).
›
‹ shell

git

The git guard, config and hooks that apply to every repo.

Checkout guardOpens the git checkout wrapper, which lists files and asks [y/N] before discarding unstaged changes.
›
Git configOpens the git config: author, LFS, credential helper and hooks path.
›
Git hooksOpens the Lefthook shims that run in every repo on commit and push.
›
‹ shell

utils

The terminal helpers in zsh.d/utils.zsh.

Set titleSets the title of the terminal window.
›
Kill portStops the process listening on a port.
›
IP aliasesOpens the IP aliases defined in this file.
›
Node and npmLoads nvm, node, npm and npx on first use, not at shell start.
›
Android, Java and BunOpens the Android, Java and Bun setup in this file.
›
‹ shell

opencode

The OpenCode profile commands; OpenCode's own help is the full reference.

Current profilePrints the name of the profile OpenCode uses now.
›
ProfilesPrints each profile and what it loads.
›
Switch profileSwitches the profile every new shell run uses.
›
Sign inSigns a profile's Claude Code in.
›
Profile filesPrints the current profile's files.
›
Edit a fileOpens one of the current profile's files in the editor.
›
Profile definitionsOpens the profile definitions kept in Git.
›
Full helpPrints the full OpenCode help: every profile's files and the commands.
›
‹ shell

audio

The controls for this machine's audio, sent to the Windows PC over Tailscale.

StartStarts sending all Linux audio to the Windows PC.
›
PausePauses the audio share and restores the speakers.
›
StatusPrints whether the audio share is on.
›
TonePlays the test tone to the Windows PC.
›
‹ Home

agents

The AI assistants on this machine: their rules, skills, teams, sandbox, settings and sessions.

RulesPrints the rules every org follows, from workboard/rules.yaml.
›
SkillsPrints the skills screen: the global skills and the copies kept here.
›
Roles and teamsPrints the teams screen: role skills, personas, starting a team and team files.
›
Agent SandboxPrints the sandbox screen: checking, listing and serving the agent records.
›
ConfigPrints the config screen: Claude and Codex settings, instructions and hooks.
›
Sessions and usagePrints the sessions screen: the main session, the usage guard and team-park.
›
HermesRuns the Hermes agent, which serves its two Telegram bots.
›
Data repoOpens the data repo of cases, rule proposals, verdicts and reviews.
›
‹ agents

skills

The skills agents load, and where their copies are kept.

Global skillsOpens the my-skills repo, the source of the global skills.
›
Skill linksOpens the folder where global skills are linked for Claude.
›
Install skillsRuns the install that links skills into the skill folders.
›
Kept herePrints the kept screen: the twelve skill copies in this repo, which load only once copied in.
›
ShortlistOpens the skills researched on skills.sh and what is installed.
›
‹ skills

kept

The skill copies kept in this repo, one folder each.

contextual-value-product-thinkingOpens the skill that analyses products through contextual human values.
›
elad12390--web-research-assistantOpens the web research MCP skill: search, crawling, stealth scraping and package lookups.
›
epic-fanout-planningOpens the 10-step pattern for QA-gap epics with parallel fan-out.
›
impeccableOpens the frontend design skill: shape, critique, audit and polish.
›
api-key-creationOpens the troubleshooting skill for getting a missing API key with browser tools.
›
iterative-action-reviewOpens the skill for reviewing a completed action as one iteration in a series.
›
post-feature-cleanupOpens the pass that catches UI defects, leftovers and repo hygiene after a feature.
›
powershell-launchingOpens the skill for launching PowerShell or a new terminal on Windows.
›
reboot-resumeOpens the skill that preserves and resumes work across a reboot.
›
tank--communication-engineeringOpens the skill that applies engineering discipline to what an agent says.
›
tank--skill-creatorOpens the skill for creating new skills.
›
tech-ledgerOpens the skill that reads and writes the Tech Ledger of evaluated tech.
›
‹ agents

teams

The roles and teams that agents work in, and where their files are.

Worker roleOpens the worker's role skill.
›
Supervisor roleOpens the supervisor's role skill.
›
Admin roleOpens the admin's role skill.
›
QA agent roleOpens the QA agent's role skill; no team starts it yet.
›
Claude personasOpens the agents folder, one folder per agent with its Claude persona and OpenCode agent.
›
Start a teamStarts a team from a team file, such as worker-pair or research-team; Codex uses $spawn-team.
›
Team filesOpens the team files; a new team is a new file.
›
How team members talkOpens the rules for how team members hand off work.
›
‹ agents

sandbox

The Agent Sandbox: an agent's setup, run as a real session on a page.

Start the sandboxStarts the Agent Sandbox server, which serves the page at 127.0.0.1:8790.
›
Open the pageOpens the Agent Sandbox page; it works only while the server runs.
›
Check the recordsChecks every agent record and refuses broken ones; exits 1 when one fails.
›
List the agentsLists each agent with its tier, model and number of tests.
›
IntentOpens the intent and rules for the agent framework.
›
‹ agents

config

The global instructions and settings for Claude and Codex, and the Claude hooks.

Claude instructionsOpens the global rules every Claude session reads on Linux.
›
Claude settingsOpens Claude Code's settings, which stay on this machine.
›
Codex configOpens Codex's config, where multi_agent_v2 is turned on.
›
Codex instructionsOpens the global agent notes Codex reads.
›
HooksPrints the hooks screen: the scripts wired into Claude's settings.
›
Windows copiesOpens the repo copies that init-windows deploys to Windows.
›
‹ config

hooks

The Claude hook scripts wired into ~/.claude/settings.json.

Core rulesOpens the hook that enforces the core rules at session start and before Bash calls.
›
Machine historyOpens the machine-history hook.
›
Local server guardOpens the guard hook that runs before each Bash call.
›
Proof reminderOpens the reminder hook that runs after edits and Bash calls.
›
Team activityOpens the team activity hook.
›
Session typesOpens the SessionStart hook that sets the session type.
›
Hook testsRuns the core rules hook tests.
›
‹ agents

sessions

The Claude session tools: the main session, the usage guard and team-park.

Main sessionStarts the main Claude session; -c continues it and -r resumes one.
›
Usage guardOpens the claude wrapper that puts the usage guard in front of the native command.
›
Team parkRuns team-park; its README in claude/team-park says what it parks.
›
‹ Home

browser

The Chrome this machine drives: one persistent window, the browser command and its checks.

Browser statusPrints whether the background browser server is up.
›
Close the browserStops the browser window and its server.
›
Browser guideOpens the browser command's guide, including how to record a feature as proof.
›
Start ChromeStarts Chrome with the flags in chrome/flags; the only way to start it here.
›
Chrome setupRuns the one-time setup that points Chrome's launchers at chrome.sh.
›
Chrome flagsOpens the Chrome flag list, which every start reads.
›
Smoke QARuns a goal in a browser and reports only the text and URL you assert.
›
Codex browser pathOpens Codex's direct Chrome command path and its live verification.
›
‹ Home

dashboard

The screen that shows what waits for you, in two versions to compare.

Dashboard serverStarts the dashboard at http://127.0.0.1:8780.
›
Concepts serverStarts the concepts version at http://127.0.0.1:8781, which differs only in its Projects panel.
›
Open the dashboardOpens the dashboard page; its server must be running.
›
Open the conceptsOpens the concepts page; its server must be running.
›
Dashboard checksRuns the dashboard's 199 checks against the real data and a real server.
›
Concepts checksRuns the concepts version's 17 checks.
›
Design roundsOpens the design rounds that chose the look.
›
‹ Home

input

The keyboard and mouse shared between the laptop and the Windows PC.

Deskflow guideOpens the Deskflow guide: daily use, the permission prompt and recovery.
›
Restart DeskflowStarts Deskflow again and asks for input capture.
›
Deskflow configOpens the Deskflow settings on this laptop.
›
Keyboard follows the mouseOpens how the keyboard follows the mouse, and how to stop it.
›
USB mouse sharingOpens the Windows USB mouse sharing files; forwarding has been off since 2026-10-20.
›
Network auditOpens the network audit for Deskflow.
›
Retired Lan MouseOpens the retired Lan Mouse setup, kept for rollback only.
›
‹ Home

windows

The Windows PC: its rebuild, checks, skill sync and work repos.

RebuildRuns the install that rebuilds the dev environment from the manifests; it asks for admin approval.
›
Check the installRuns the checks on the installed environment.
›
Roll backRuns the rollback that removes the installed pack.
›
Bootstrap guideOpens the bootstrap guide.
›
InventoryOpens what the install captured.
›
Sign-ins to redoOpens the sign-ins to redo by hand.
›
Skill sync guideOpens how Windows skills stay in step with my-skills.
›
Skill sync checkRuns the skill sync test on Windows.
›
Clone work reposRuns the clone of every missing Betec repo; existing folders are left alone.
›
‹ Home

cv

The three CVs, their LaTeX sources and how their PDFs are rebuilt.

Full Stack DeveloperOpens the Full Stack Developer CV.
›
AI Full Stack EngineerOpens the AI Full Stack Engineer CV.
›
AI IntegrationsOpens the AI Integrations CV.
›
SourcesOpens the CV folder with the LaTeX sources and shared parts.
›
Rebuild PDFsRuns pdflatex on each CV source, which rebuilds its PDF.
›
Plain-text versionsRuns the build of the plain-text CVs.
›
HTML design versionRuns the build of the HTML design version.
›
Dated versionsOpens the dated copies of the CVs.
›
Experience notesOpens the factual notes the CVs are built from.
›
WorkflowOpens the CV workflow.
›
‹ Home

clipboard

The shared clipboard history: its server, watcher, picker and Windows side.

PickerRuns the picker, where you choose an earlier clip.
›
ServerRuns the server that holds the history.
›
WatcherRuns the watcher that follows the clipboard.
›
Linux installRuns the install that sets up the Linux server and watcher units.
›
Windows scriptRuns the Windows clipboard script.
›
Windows installRuns the Windows install; uninstall.ps1 removes it.
›
Server testsRuns the server's tests.
›
‹ Home

docs

The written record: plans, designs, research, flows, changelog, case studies, incidents and the archive.

PlansOpens the plans, one dated folder each.
›
DesignsOpens the design rounds, one dated folder each.
›
ResearchOpens the research notes, one dated folder each.
›
FlowsOpens the flow cards and data models, by date.
›
ChangelogOpens the dated changelog entries.
›
Work itemsOpens the planned, urgent and work item lists.
›
Case studiesOpens the archived, human-reviewed experiments.
›
IncidentsOpens the dated machine incident records.
›
Intent filesOpens the intent files that set each module's rules.
›
Behavior featuresOpens the behavior features, one folder per module.
›
ArchiveOpens the archive of files moved out of projects; it is not backed up.
›
Raw answer
I mapped the whole workstation command line as one facade, `workstation` (alias `ws`), with a screen per group. I only had the file list and the README excerpts, not `workstation-cli/` or `zsh.d/workstation.zsh`, which the README describes but the dump doesn't include. The existing `workstation help` and `opencode help` could not be read, so the map follows the README's descriptions. Where a row duplicates an existing command, it points to that command rather than restating it, and `shell opencode` links to `opencode help` instead of repeating it. Names the README mentions but the dump doesn't show are listed in the questions.

```json
{"screens": [
{"path": [], "sentence": "The map of this workstation: pick a group to see what is inside it.", "rows": [
{"name": "Machine", "form": "workstation machine", "what": "Prints the machine screen: power, screen, network, repairs and background services of this Linux laptop."},
{"name": "Shell", "form": "workstation shell", "what": "Prints the shell screen: the zsh helpers for git, infrastructure, keys, OpenCode and audio."},
{"name": "Agents", "form": "workstation agents", "what": "Prints the agents screen: rules, skills, teams, sandbox, settings and sessions of the AI assistants."},
{"name": "Browser", "form": "workstation browser", "what": "Prints the browser screen: the persistent Chrome window, its command and its smoke tests."},
{"name": "Dashboard", "form": "workstation dashboard", "what": "Prints the dashboard screen: the two dashboard versions and their checks."},
{"name": "Input", "form": "workstation input", "what": "Prints the input screen: the keyboard and mouse shared with the Windows PC."},
{"name": "Windows", "form": "workstation windows", "what": "Prints the Windows screen: rebuilding the PC, keeping its skills in step, and cloning its work repos."},
{"name": "CVs", "form": "workstation cv", "what": "Prints the CV screen: the three CVs, their sources and how to rebuild them."},
{"name": "Clipboard", "form": "workstation clipboard", "what": "Prints the clipboard screen: the shared clipboard history server, watcher and picker."},
{"name": "Docs", "form": "workstation docs", "what": "Prints the docs screen: plans, designs, research, flows, changelog, case studies, incidents and the archive."}
]},
{"path": ["machine"], "sentence": "The Linux laptop's own fixes and background services.", "rows": [
{"name": "Power and lid", "form": "workstation machine power", "what": "Prints the power and lid screen: the CPU power profiles and the lid settings."},
{"name": "Screen", "form": "~/projects/workstation/fix_old_monitor_hdmi.sh", "what": "Runs the script that sets the mode and refresh rate of an external HDMI or DP screen."},
{"name": "Internet recovery", "form": "~/projects/workstation/linux-internet-recovery.sh", "what": "Runs the script that resets DNS and restarts networking; it asks for sudo."},
{"name": "Tailscale remote terminal", "form": "~/projects/workstation/recover-tailscale-remote-terminal.sh", "what": "Runs the script that repairs DNS, restarts Tailscale and checks the remote terminal on port 3500."},
{"name": "Repairs", "form": "workstation machine repairs", "what": "Prints the repairs screen: keyboard, mouse, disk and WhatsApp fixes."},
{"name": "Services", "form": "workstation machine services", "what": "Prints the services screen: the background services and timers that run here."}
]},
{"path": ["machine", "power"], "sentence": "The CPU power profiles and the laptop lid settings.", "rows": [
{"name": "Power saver", "form": "~/projects/workstation/cpu-min-power.sh", "what": "Runs the script that sets the power-saver profile, turbo off and the CPU capped at 8%; it asks for sudo."},
{"name": "Balanced", "form": "~/projects/workstation/cpu-normal-power.sh", "what": "Runs the script that sets the balanced profile, turbo on and the CPU cap back to 100%."},
{"name": "Keep running with lid closed", "form": "~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.sh", "what": "Runs the script that makes closing the lid do nothing; it applies after a reboot."},
{"name": "Restore default lid", "form": "~/projects/workstation/laptop-utilities/restore-default-lid-behavior.sh", "what": "Runs the script that removes that lid setting; it applies after a reboot."}
]},
{"path": ["machine", "repairs"], "sentence": "The one-command repairs for keyboard, mouse, disk and WhatsApp.", "rows": [
{"name": "Keyboard", "form": "fix-keyboard", "what": "Runs the keyboard repair defined in ~/projects/workstation/zsh.d/utils.zsh."},
{"name": "Mouse", "form": "fix-mouse", "what": "Runs the mouse repair defined in ~/projects/workstation/zsh.d/utils.zsh."},
{"name": "Disk", "form": "fix-disk", "what": "Runs the disk repair defined in ~/projects/workstation/zsh.d/utils.zsh."},
{"name": "WhatsApp", "form": "fix-whatsapp", "what": "Runs the WhatsApp repair defined in ~/projects/workstation/zsh.d/utils.zsh."}
]},
{"path": ["machine", "services"], "sentence": "The background services and timers that run on this machine.", "rows": [
{"name": "Shared keyboard and mouse", "form": "~/.config/systemd/user/deskflow.service", "what": "Starts and stops the Deskflow server, which starts with the graphical session."},
{"name": "Clipboard server", "form": "~/projects/workstation/clipstack/units/clipstack-server.service", "what": "Starts and stops the clipboard history server."},
{"name": "Clipboard watcher", "form": "~/projects/workstation/clipstack/units/clipstack-watcher.service", "what": "Starts and stops the clipboard watcher."},
{"name": "Supabase keepalive", "form": "~/projects/workstation/supabase-keepalive/supabase-keepalive.timer", "what": "Runs the Supabase keepalive script on a timer."},
{"name": "Codex Chrome bridge", "form": "~/projects/workstation/codex/chrome-bridge/codex-chrome-bridge.timer", "what": "Runs the bridge repair on a timer, keeping Codex's Chrome link in place."},
{"name": "Rules reminder", "form": "~/projects/workstation/docs/plans/2026-10-24-rules-per-role/reminder/rules-roles-reminder.timer", "what": "Runs the rules reminder on a timer."},
{"name": "Answer sync", "form": "~/.config/systemd/user/data-pull.timer", "what": "Runs the answer sync from the data repo every 5 minutes."},
{"name": "Remote terminal", "form": "systemctl --user status remote-terminal", "what": "Starts the remote terminal on port 3500."},
{"name": "All user timers", "form": "systemctl --user list-timers", "what": "Lists every user timer and when it next runs."}
]},
{"path": ["shell"], "sentence": "The zsh helpers in ~/.zsh.d, one group per topic.", "rows": [
{"name": "Git", "form": "workstation shell git", "what": "Prints the git screen: the checkout guard, git config and the commit and push hooks."},
{"name": "Infra", "form": "~/.zsh.d/infra.zsh", "what": "Opens the infra helpers: Docker and Compose, Prisma, Postgres, nginx and VPN commands."},
{"name": "Utilities", "form": "workstation shell utils", "what": "Prints the utilities screen: terminal title, port killing, IP aliases, lazy Node, and the Android, Java and Bun setup."},
{"name": "API keys", "form": "api-keys-edit", "what": "Opens the file of general-use API keys in the editor; keys are never in Git."},
{"name": "OpenCode", "form": "workstation shell opencode", "what": "Prints the OpenCode screen: profiles, switching, login, files and the OpenCode help."},
{"name": "Review", "form": "review-open", "what": "Opens a file in the review pane."},
{"name": "Audio share", "form": "workstation shell audio", "what": "Prints the audio screen: start, pause and status of audio sent to the Windows PC."},
{"name": "Dash path check", "form": "~/projects/workstation/zsh.d/dash-path-warn.zsh", "what": "Opens the dash path check; its purpose is not in the dump (see questions)."}
]},
{"path": ["shell", "git"], "sentence": "The git guard, config and hooks that apply to every repo.", "rows": [
{"name": "Checkout guard", "form": "~/projects/workstation/zsh.d/git-safety.zsh", "what": "Opens the git checkout wrapper, which lists files and asks [y/N] before discarding unstaged changes."},
{"name": "Git config", "form": "~/.gitconfig", "what": "Opens the git config: author, LFS, credential helper and hooks path."},
{"name": "Git hooks", "form": "~/.git-hooks/", "what": "Opens the Lefthook shims that run in every repo on commit and push."}
]},
{"path": ["shell", "utils"], "sentence": "The terminal helpers in zsh.d/utils.zsh.", "rows": [
{"name": "Set title", "form": "set-title", "what": "Sets the title of the terminal window."},
{"name": "Kill port", "form": "killport <port>", "what": "Stops the process listening on a port."},
{"name": "IP aliases", "form": "~/projects/workstation/zsh.d/utils.zsh", "what": "Opens the IP aliases defined in this file."},
{"name": "Node and npm", "form": "nvm", "what": "Loads nvm, node, npm and npx on first use, not at shell start."},
{"name": "Android, Java and Bun", "form": "~/projects/workstation/zsh.d/utils.zsh", "what": "Opens the Android, Java and Bun setup in this file."}
]},
{"path": ["shell", "opencode"], "sentence": "The OpenCode profile commands; OpenCode's own help is the full reference.", "rows": [
{"name": "Current profile", "form": "opencode-profile", "what": "Prints the name of the profile OpenCode uses now."},
{"name": "Profiles", "form": "opencode-profiles", "what": "Prints each profile and what it loads."},
{"name": "Switch profile", "form": "opencode-switch <name>", "what": "Switches the profile every new shell run uses."},
{"name": "Sign in", "form": "opencode-login <name>", "what": "Signs a profile's Claude Code in."},
{"name": "Profile files", "form": "opencode-files", "what": "Prints the current profile's files."},
{"name": "Edit a file", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files in the editor."},
{"name": "Profile definitions", "form": "~/projects/workstation/opencode-profiles/", "what": "Opens the profile definitions kept in Git."},
{"name": "Full help", "form": "opencode help", "what": "Prints the full OpenCode help: every profile's files and the commands."}
]},
{"path": ["shell", "audio"], "sentence": "The controls for this machine's audio, sent to the Windows PC over Tailscale.", "rows": [
{"name": "Start", "form": "audio-start", "what": "Starts sending all Linux audio to the Windows PC."},
{"name": "Pause", "form": "audio-pause", "what": "Pauses the audio share and restores the speakers."},
{"name": "Status", "form": "audio-share status", "what": "Prints whether the audio share is on."},
{"name": "Tone", "form": "audio-share tone", "what": "Plays the test tone to the Windows PC."}
]},
{"path": ["agents"], "sentence": "The AI assistants on this machine: their rules, skills, teams, sandbox, settings and sessions.", "rows": [
{"name": "Rules", "form": "rules", "what": "Prints the rules every org follows, from workboard/rules.yaml."},
{"name": "Skills", "form": "workstation agents skills", "what": "Prints the skills screen: the global skills and the copies kept here."},
{"name": "Roles and teams", "form": "workstation agents teams", "what": "Prints the teams screen: role skills, personas, starting a team and team files."},
{"name": "Agent Sandbox", "form": "workstation agents sandbox", "what": "Prints the sandbox screen: checking, listing and serving the agent records."},
{"name": "Config", "form": "workstation agents config", "what": "Prints the config screen: Claude and Codex settings, instructions and hooks."},
{"name": "Sessions and usage", "form": "workstation agents sessions", "what": "Prints the sessions screen: the main session, the usage guard and team-park."},
{"name": "Hermes", "form": "~/.local/bin/hermes", "what": "Runs the Hermes agent, which serves its two Telegram bots."},
{"name": "Data repo", "form": "~/projects/data/", "what": "Opens the data repo of cases, rule proposals, verdicts and reviews."}
]},
{"path": ["agents", "skills"], "sentence": "The skills agents load, and where their copies are kept.", "rows": [
{"name": "Global skills", "form": "~/projects/my-skills/", "what": "Opens the my-skills repo, the source of the global skills."},
{"name": "Skill links", "form": "~/.claude/skills/", "what": "Opens the folder where global skills are linked for Claude."},
{"name": "Install skills", "form": "~/projects/my-skills/install.sh", "what": "Runs the install that links skills into the skill folders."},
{"name": "Kept here", "form": "workstation agents skills kept", "what": "Prints the kept screen: the twelve skill copies in this repo, which load only once copied in."},
{"name": "Shortlist", "form": "~/projects/workstation/claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and what is installed."}
]},
{"path": ["agents", "skills", "kept"], "sentence": "The skill copies kept in this repo, one folder each.", "rows": [
{"name": "contextual-value-product-thinking", "form": "~/projects/workstation/claude/skills/contextual-value-product-thinking/", "what": "Opens the skill that analyses products through contextual human values."},
{"name": "elad12390--web-research-assistant", "form": "~/projects/workstation/claude/skills/elad12390--web-research-assistant/", "what": "Opens the web research MCP skill: search, crawling, stealth scraping and package lookups."},
{"name": "epic-fanout-planning", "form": "~/projects/workstation/claude/skills/epic-fanout-planning/", "what": "Opens the 10-step pattern for QA-gap epics with parallel fan-out."},
{"name": "impeccable", "form": "~/projects/workstation/claude/skills/impeccable/", "what": "Opens the frontend design skill: shape, critique, audit and polish."},
{"name": "api-key-creation", "form": "~/projects/workstation/claude/skills/api-key-creation/", "what": "Opens the troubleshooting skill for getting a missing API key with browser tools."},
{"name": "iterative-action-review", "form": "~/projects/workstation/claude/skills/iterative-action-review/", "what": "Opens the skill for reviewing a completed action as one iteration in a series."},
{"name": "post-feature-cleanup", "form": "~/projects/workstation/claude/skills/post-feature-cleanup/", "what": "Opens the pass that catches UI defects, leftovers and repo hygiene after a feature."},
{"name": "powershell-launching", "form": "~/projects/workstation/claude/skills/powershell-launching/", "what": "Opens the skill for launching PowerShell or a new terminal on Windows."},
{"name": "reboot-resume", "form": "~/projects/workstation/claude/skills/reboot-resume/", "what": "Opens the skill that preserves and resumes work across a reboot."},
{"name": "tank--communication-engineering", "form": "~/projects/workstation/claude/skills/tank--communication-engineering/", "what": "Opens the skill that applies engineering discipline to what an agent says."},
{"name": "tank--skill-creator", "form": "~/projects/workstation/claude/skills/tank--skill-creator/", "what": "Opens the skill for creating new skills."},
{"name": "tech-ledger", "form": "~/projects/workstation/claude/skills/tech-ledger/", "what": "Opens the skill that reads and writes the Tech Ledger of evaluated tech."}
]},
{"path": ["agents", "teams"], "sentence": "The roles and teams that agents work in, and where their files are.", "rows": [
{"name": "Worker role", "form": "~/projects/my-skills/worker/SKILL.md", "what": "Opens the worker's role skill."},
{"name": "Supervisor role", "form": "~/projects/my-skills/supervisor/SKILL.md", "what": "Opens the supervisor's role skill."},
{"name": "Admin role", "form": "~/projects/my-skills/admin/SKILL.md", "what": "Opens the admin's role skill."},
{"name": "QA agent role", "form": "~/projects/my-skills/qa-agent/SKILL.md", "what": "Opens the QA agent's role skill; no team starts it yet."},
{"name": "Claude personas", "form": "~/projects/my-skills/agents/", "what": "Opens the agents folder, one folder per agent with its Claude persona and OpenCode agent."},
{"name": "Start a team", "form": "/spawn-team <team>", "what": "Starts a team from a team file, such as worker-pair or research-team; Codex uses $spawn-team."},
{"name": "Team files", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files; a new team is a new file."},
{"name": "How team members talk", "form": "~/projects/my-skills/coordinated-agentic-session/", "what": "Opens the rules for how team members hand off work."}
]},
{"path": ["agents", "sandbox"], "sentence": "The Agent Sandbox: an agent's setup, run as a real session on a page.", "rows": [
{"name": "Start the sandbox", "form": "~/projects/workstation/agent-framework/agent serve", "what": "Starts the Agent Sandbox server, which serves the page at 127.0.0.1:8790."},
{"name": "Open the page", "form": "http://127.0.0.1:8790", "what": "Opens the Agent Sandbox page; it works only while the server runs."},
{"name": "Check the records", "form": "~/projects/workstation/agent-framework/agent check", "what": "Checks every agent record and refuses broken ones; exits 1 when one fails."},
{"name": "List the agents", "form": "~/projects/workstation/agent-framework/agent list", "what": "Lists each agent with its tier, model and number of tests."},
{"name": "Intent", "form": "~/projects/workstation/.idd/modules/agent-framework/INTENT.md", "what": "Opens the intent and rules for the agent framework."}
]},
{"path": ["agents", "config"], "sentence": "The global instructions and settings for Claude and Codex, and the Claude hooks.", "rows": [
{"name": "Claude instructions", "form": "~/.claude/CLAUDE.md", "what": "Opens the global rules every Claude session reads on Linux."},
{"name": "Claude settings", "form": "~/.claude/settings.json", "what": "Opens Claude Code's settings, which stay on this machine."},
{"name": "Codex config", "form": "~/.codex/config.toml", "what": "Opens Codex's config, where multi_agent_v2 is turned on."},
{"name": "Codex instructions", "form": "~/.codex/AGENTS.md", "what": "Opens the global agent notes Codex reads."},
{"name": "Hooks", "form": "workstation agents config hooks", "what": "Prints the hooks screen: the scripts wired into Claude's settings."},
{"name": "Windows copies", "form": "~/projects/workstation/claude/", "what": "Opens the repo copies that init-windows deploys to Windows."}
]},
{"path": ["agents", "config", "hooks"], "sentence": "The Claude hook scripts wired into ~/.claude/settings.json.", "rows": [
{"name": "Core rules", "form": "~/projects/workstation/claude/hooks/core-rules.sh", "what": "Opens the hook that enforces the core rules at session start and before Bash calls."},
{"name": "Machine history", "form": "~/projects/workstation/claude/hooks/machine-history.sh", "what": "Opens the machine-history hook."},
{"name": "Local server guard", "form": "~/projects/workstation/claude/hooks/local-server-guard.py", "what": "Opens the guard hook that runs before each Bash call."},
{"name": "Proof reminder", "form": "~/projects/workstation/claude/hooks/proof-reminder.sh", "what": "Opens the reminder hook that runs after edits and Bash calls."},
{"name": "Team activity", "form": "~/projects/workstation/claude/hooks/team-activity.sh", "what": "Opens the team activity hook."},
{"name": "Session types", "form": "~/projects/workstation/claude/session-types/session-types.sh", "what": "Opens the SessionStart hook that sets the session type."},
{"name": "Hook tests", "form": "sh ~/projects/workstation/claude/hooks/test_core_rules.sh", "what": "Runs the core rules hook tests."}
]},
{"path": ["agents", "sessions"], "sentence": "The Claude session tools: the main session, the usage guard and team-park.", "rows": [
{"name": "Main session", "form": "claude --main", "what": "Starts the main Claude session; -c continues it and -r resumes one."},
{"name": "Usage guard", "form": "~/bin/claude", "what": "Opens the claude wrapper that puts the usage guard in front of the native command."},
{"name": "Team park", "form": "team-park", "what": "Runs team-park; its README in claude/team-park says what it parks."}
]},
{"path": ["browser"], "sentence": "The Chrome this machine drives: one persistent window, the browser command and its checks.", "rows": [
{"name": "Browser status", "form": "browser status", "what": "Prints whether the background browser server is up."},
{"name": "Close the browser", "form": "browser close", "what": "Stops the browser window and its server."},
{"name": "Browser guide", "form": "~/projects/workstation/browser/README.md", "what": "Opens the browser command's guide, including how to record a feature as proof."},
{"name": "Start Chrome", "form": "~/projects/workstation/chrome/chrome.sh", "what": "Starts Chrome with the flags in chrome/flags; the only way to start it here."},
{"name": "Chrome setup", "form": "~/projects/workstation/chrome/install.sh", "what": "Runs the one-time setup that points Chrome's launchers at chrome.sh."},
{"name": "Chrome flags", "form": "~/projects/workstation/chrome/flags", "what": "Opens the Chrome flag list, which every start reads."},
{"name": "Smoke QA", "form": "jev-browser-test", "what": "Runs a goal in a browser and reports only the text and URL you assert."},
{"name": "Codex browser path", "form": "~/projects/workstation/codex/browser/", "what": "Opens Codex's direct Chrome command path and its live verification."}
]},
{"path": ["dashboard"], "sentence": "The screen that shows what waits for you, in two versions to compare.", "rows": [
{"name": "Dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard at http://127.0.0.1:8780."},
{"name": "Concepts server", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts version at http://127.0.0.1:8781, which differs only in its Projects panel."},
{"name": "Open the dashboard", "form": "http://127.0.0.1:8780", "what": "Opens the dashboard page; its server must be running."},
{"name": "Open the concepts", "form": "http://127.0.0.1:8781", "what": "Opens the concepts page; its server must be running."},
{"name": "Dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the dashboard's 199 checks against the real data and a real server."},
{"name": "Concepts checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the concepts version's 17 checks."},
{"name": "Design rounds", "form": "~/projects/workstation/docs/design/2026-10-17-dashboard/", "what": "Opens the design rounds that chose the look."}
]},
{"path": ["input"], "sentence": "The keyboard and mouse shared between the laptop and the Windows PC.", "rows": [
{"name": "Deskflow guide", "form": "~/projects/workstation/deskflow/README.md", "what": "Opens the Deskflow guide: daily use, the permission prompt and recovery."},
{"name": "Restart Deskflow", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input capture."},
{"name": "Deskflow config", "form": "~/.config/Deskflow/Deskflow.conf", "what": "Opens the Deskflow settings on this laptop."},
{"name": "Keyboard follows the mouse", "form": "~/projects/workstation/deskflow/usb-mouse/README.md#keyboard-follows-the-mouse", "what": "Opens how the keyboard follows the mouse, and how to stop it."},
{"name": "USB mouse sharing", "form": "~/projects/workstation/deskflow/usb-mouse/", "what": "Opens the Windows USB mouse sharing files; forwarding has been off since 2026-10-20."},
{"name": "Network audit", "form": "~/projects/workstation/deskflow/NETWORK-AUDIT.md", "what": "Opens the network audit for Deskflow."},
{"name": "Retired Lan Mouse", "form": "~/projects/workstation/lan-mouse/README.md", "what": "Opens the retired Lan Mouse setup, kept for rollback only."}
]},
{"path": ["windows"], "sentence": "The Windows PC: its rebuild, checks, skill sync and work repos.", "rows": [
{"name": "Rebuild", "form": "~/projects/workstation/init-windows/Start-Install.cmd", "what": "Runs the install that rebuilds the dev environment from the manifests; it asks for admin approval."},
{"name": "Check the install", "form": "~/projects/workstation/init-windows/Smoke-Test-Windows.ps1", "what": "Runs the checks on the installed environment."},
{"name": "Roll back", "form": "~/projects/workstation/init-windows/Remove-WindowsPack.ps1", "what": "Runs the rollback that removes the installed pack."},
{"name": "Bootstrap guide", "form": "~/projects/workstation/init-windows/README.md", "what": "Opens the bootstrap guide."},
{"name": "Inventory", "form": "~/projects/workstation/init-windows/inventory.md", "what": "Opens what the install captured."},
{"name": "Sign-ins to redo", "form": "~/projects/workstation/init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand."},
{"name": "Skill sync guide", "form": "~/projects/workstation/skills-sync-windows/README.md", "what": "Opens how Windows skills stay in step with my-skills."},
{"name": "Skill sync check", "form": "~/projects/workstation/skills-sync-windows/Test-Sync.ps1", "what": "Runs the skill sync test on Windows."},
{"name": "Clone work repos", "form": "~/projects/workstation/repos/Clone-BetecRepos.ps1", "what": "Runs the clone of every missing Betec repo; existing folders are left alone."}
]},
{"path": ["cv"], "sentence": "The three CVs, their LaTeX sources and how their PDFs are rebuilt.", "rows": [
{"name": "Full Stack Developer", "form": "~/projects/workstation/cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
{"name": "AI Full Stack Engineer", "form": "~/projects/workstation/cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
{"name": "AI Integrations", "form": "~/projects/workstation/cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
{"name": "Sources", "form": "~/projects/workstation/cv/", "what": "Opens the CV folder with the LaTeX sources and shared parts."},
{"name": "Rebuild PDFs", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-ai-full-stack.tex", "what": "Runs pdflatex on each CV source, which rebuilds its PDF."},
{"name": "Plain-text versions", "form": "~/projects/workstation/cv/text/build-full.sh", "what": "Runs the build of the plain-text CVs."},
{"name": "HTML design version", "form": "~/projects/workstation/cv/design/build-design.py", "what": "Runs the build of the HTML design version."},
{"name": "Dated versions", "form": "~/projects/workstation/cv/versions/", "what": "Opens the dated copies of the CVs."},
{"name": "Experience notes", "form": "~/projects/workstation/cv/experience-notes.md", "what": "Opens the factual notes the CVs are built from."},
{"name": "Workflow", "form": "~/projects/workstation/cv/WORKFLOW.md", "what": "Opens the CV workflow."}
]},
{"path": ["clipboard"], "sentence": "The shared clipboard history: its server, watcher, picker and Windows side.", "rows": [
{"name": "Picker", "form": "~/projects/workstation/clipstack/picker.py", "what": "Runs the picker, where you choose an earlier clip."},
{"name": "Server", "form": "~/projects/workstation/clipstack/server.py", "what": "Runs the server that holds the history."},
{"name": "Watcher", "form": "~/projects/workstation/clipstack/watcher.py", "what": "Runs the watcher that follows the clipboard."},
{"name": "Linux install", "form": "~/projects/workstation/clipstack/install.sh", "what": "Runs the install that sets up the Linux server and watcher units."},
{"name": "Windows script", "form": "~/projects/workstation/clipstack/windows/clipstack.ahk", "what": "Runs the Windows clipboard script."},
{"name": "Windows install", "form": "~/projects/workstation/clipstack/windows/install.ps1", "what": "Runs the Windows install; uninstall.ps1 removes it."},
{"name": "Server tests", "form": "~/projects/workstation/clipstack/test_server.py", "what": "Runs the server's tests."}
]},
{"path": ["docs"], "sentence": "The written record: plans, designs, research, flows, changelog, case studies, incidents and the archive.", "rows": [
{"name": "Plans", "form": "~/projects/workstation/docs/plans/", "what": "Opens the plans, one dated folder each."},
{"name": "Designs", "form": "~/projects/workstation/docs/design/", "what": "Opens the design rounds, one dated folder each."},
{"name": "Research", "form": "~/projects/workstation/docs/research/", "what": "Opens the research notes, one dated folder each."},
{"name": "Flows", "form": "~/projects/workstation/docs/flows/", "what": "Opens the flow cards and data models, by date."},
{"name": "Changelog", "form": "~/projects/workstation/docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "Work items", "form": "~/projects/workstation/docs/items/", "what": "Opens the planned, urgent and work item lists."},
{"name": "Case studies", "form": "~/projects/workstation/case-studies/", "what": "Opens the archived, human-reviewed experiments."},
{"name": "Incidents", "form": "~/projects/workstation/reference/incidents/", "what": "Opens the dated machine incident records."},
{"name": "Intent files", "form": "~/projects/workstation/.idd/", "what": "Opens the intent files that set each module's rules."},
{"name": "Behavior features", "form": "~/projects/workstation/.bdd/features/", "what": "Opens the behavior features, one folder per module."},
{"name": "Archive", "form": "~/archive/", "what": "Opens the archive of files moved out of projects; it is not backed up."}
]}
],
"questions": [
"Aliases: the README already gives `workstation`, `ws` and `setup`. Keep `setup`? It is a common word and clashes easily. Recommendation: keep `workstation` and `ws`, and check `whence -a setup` before deciding.",
"Top groups: the map has ten groups. Recommendation: keep them as drawn. The alternative is to fold `input` into `machine`, since both are small Linux hardware groups.",
"Runnable or open-only: the power, lid, network, screen and repair rows say what they run. Should the thin commands run them (some ask for sudo) or only open the script? Recommendation: run the machine fixes through thin commands and open the rest.",
"Retired items: the map keeps one Lan Mouse row for rollback and leaves out the retired `codex/playwright-mcp` setup and the USB forwarding that is off. Recommendation: keep it this way.",
"Live state: should `machine services` show each unit's running state when printed, or only list the unit files? Recommendation: show the state, since it is the only live view of the machine.",
"Names to confirm: the README names `resume-kvm`, `workstation-cli/`, `zsh.d/workstation.zsh`, `audio-share/`, `init-windows/inventory.md` and `cv/cv-master.md`, but the file list does not show them. The purpose of `zsh.d/dash-path-warn.zsh` is also not in the dump. The map keeps all of them; please confirm they exist and what the dash path check does.",
"Credentials: the README says `infra.zsh` and `utils.zsh` embed credentials. The map lists the files and shows no values. Recommendation: do not add a row flagging them; the existing `secrets-checklist.md` already covers rotation."
]}
```

screen-decomposition, first draft · run 2 exit=0 seconds=205 · prompt

P1 Recall: 0.914P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.183
As terminal help
Everything this workstation has, grouped by what you are trying to do.
Agentsworkstation agentsOpens the agents screen: rules, dashboard, sandbox, skills, teams, assistant setup and Hermes.
Browserworkstation browserOpens the browser screen: the browser command, Chrome and the smoke-test tool.
Machineworkstation machineOpens the machine screen: power, lid, network, monitor and repair scripts for this Linux machine.
Sharing with Windowsworkstation sharingOpens the sharing screen: the mouse, keyboard, audio and clipboard shared with the Windows PC.
Windowsworkstation windowsOpens the Windows screen: the PC's setup, skill sync, work repos and mirrored desktop files.
Shellworkstation shellOpens the shell screen: zsh helpers, git, OpenCode profiles and API keys.
Documentsworkstation documentsOpens the documents screen: CVs, plans, case studies, item lists and the repo guide.
agents
The agent system: its rules, dashboard, sandbox, skills, teams, assistant setup and Hermes.
Rulesworkstation agents rulesOpens the rules screen: the rules every org follows and how they are printed.
Dashboardworkstation agents dashboardOpens the dashboard screen: what waits for you and the team's live activity.
Sandboxworkstation agents sandboxOpens the sandbox screen: the Agent Sandbox page and the agent records behind it.
Skillsworkstation agents skillsOpens the skills screen: where global skills live and which skills this repo keeps as backups.
Teamsworkstation agents teamsOpens the teams screen: starting a team, its roles, and the data repo it writes to.
Assistantsworkstation agents assistantsOpens the assistants screen: Claude and Codex global instructions, settings, hooks and plugins.
Hermesworkstation agents hermesOpens the Hermes screen: the Hermes agent launcher, its configuration and its restore runbook.
agents › rules
The rules every org follows, printed on demand and kept in one file.
Rules commandrules [folder]Prints the rules for every org, or for the folder you give, with the escalation policy among them.
Rules file~/projects/workstation/workboard/rules.yamlOpens the rules file, which only the user or an accepted rule proposal may change.
Rule metadata~/projects/workstation/workboard/rules-meta.yamlOpens the metadata file that goes with the rules.
Generated rules~/.claude/references/rules.mdOpens the generated copy that every session reads, made from the rules file.
Rules checks~/projects/workstation/workboard/test_rules.pyRuns the checks for the rules file.
agents › dashboard
The dashboard on this machine, in its two versions, with its checks and guides.
Dashboard serverpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard at http://127.0.0.1:8780, the page you open in a browser.
Dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the dashboard checks against the real data and a real server.
Concepts versionpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts version at http://127.0.0.1:8781, which differs only in its Projects panel.
Concepts checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the concepts version checks.
Dashboard guide~/projects/workstation/dashboard/README.mdOpens the dashboard guide: tabs, what it writes, and hot reload.
Dashboard intent~/projects/workstation/.idd/modules/dashboard/INTENT.mdOpens the dashboard's intent and rules.
Dashboard flow card~/projects/workstation/docs/flows/2026-10-17/flow-card.mdOpens the flow card for the dashboard's screens.
agents › sandbox
The Agent Sandbox: the page where you change an agent's setup and send it a message, and the records behind it.
Sandbox page~/projects/workstation/agent-framework/agent serveStarts the sandbox page at http://127.0.0.1:8790.
Check agents~/projects/workstation/agent-framework/agent checkChecks every agent record and refuses broken ones with exit 1.
List agents~/projects/workstation/agent-framework/agent listLists the agents with their tier, model and number of tests.
Framework guide~/projects/workstation/agent-framework/README.mdOpens the framework guide: how the page works and the words it uses.
Framework intent~/projects/workstation/.idd/modules/agent-framework/INTENT.mdOpens the framework's intent and rules.
Sandbox product plan~/projects/workstation/docs/plans/2026-10-22-agent-sandbox/prd.htmlOpens the sandbox's product plan and mockups.
agents › skills
Skills: where the global skills are kept, and which skills this repo keeps as backups.
Global skills~/projects/my-skills/Opens the global skills repo, whose install script links each skill into the agents' skill folders.
Global skills install~/projects/my-skills/install.shRuns the installer that links skills into the agents' skill folders.
Kept skillsworkstation agents skills keptOpens the list of the skills this repo keeps as backups, one folder each.
Skill shortlist~/projects/workstation/claude/skills-shortlist.mdOpens the skills researched on skills.sh, with a note of what is installed.
agents › skills › kept
The skills this repo keeps as backups, one folder each.
Tech Ledgerclaude/skills/tech-ledger/Opens the skill that reads and writes the betec Tech Ledger of evaluated tech.
API key creationclaude/skills/api-key-creation/Opens the skill for getting a missing API key with browser tools instead of escalating.
Clone websiteclaude/skills/clone-website/Opens the skill that reverse-engineers and clones websites with parallel builders.
Contextual value product thinkingclaude/skills/contextual-value-product-thinking/Opens the skill for analyzing products and startup ideas through contextual human values.
Web research assistantclaude/skills/elad12390--web-research-assistant/Opens the web research skill for search, crawling and package lookups; its setup is in SETUP-NOTES.md.
Epic fan-out planningclaude/skills/epic-fanout-planning/Opens the 10-step pattern for QA-gap epics with parallel agents and release gates.
Impeccableclaude/skills/impeccable/Opens the frontend design skill: shape, critique, audit and polish.
Iterative action reviewclaude/skills/iterative-action-review/Opens the skill for reviewing one real-world action as an iteration in a series.
Lab experimentclaude/skills/lab-experiment/Opens the skill for running an experiment in the ai-lab project.
Mentor modeclaude/skills/mentor-mode/Opens the mentor-mode skill with its teaching references and page scripts.
Post-feature cleanupclaude/skills/post-feature-cleanup/Opens the pass that runs after writing code: UI defects, leftovers and repo hygiene.
PowerShell launchingclaude/skills/powershell-launching/Opens the skill for launching PowerShell or a new terminal window on Windows.
Reboot resumeclaude/skills/reboot-resume/Opens the skill that preserves and resumes work across a reboot or restart.
Resume projectclaude/skills/resume-project/Opens the resume-project skill and its CLI script.
SolaraAI content calendarclaude/skills/solaraai-content-calendar/Opens the SolaraAI content calendar skill.
SolaraAI deploymentclaude/skills/solaraai-deployment/Opens the SolaraAI deploy-flow skill with its commands, services and workflows.
SolaraAI designclaude/skills/solaraai-design/Opens the SolaraAI design-system skill with its components.
SolaraAI formsclaude/skills/solaraai-forms/Opens the SolaraAI skill for form behavior.
Supabaseclaude/skills/supabase/Opens Supabase's own skill: auth, RLS, migrations, CLI and debugging.
Supabase Postgres best practicesclaude/skills/supabase-postgres-best-practices/Opens Supabase's Postgres performance rules.
Communication engineeringclaude/skills/tank--communication-engineering/Opens the skill that applies engineering discipline to what an agent says and how much.
Skill creatorclaude/skills/tank--skill-creator/Opens the skill for creating new skills.
Tech CV writerclaude/skills/tech-cv-writer/Opens the CV writer skill with its ATS, bullet and template references.
agents › teams
How teams are started, and the roles, files and data they run on.
Start a team/spawn-team <team> (Claude) or $spawn-team <team> (Codex)Starts a team from its team file, with an admin and its members.
Team files~/projects/my-skills/spawn-team/teams/Opens the team files, such as worker-pair and research-team.
Worker role~/projects/my-skills/worker/SKILL.mdOpens the worker role's skill.
Supervisor role~/projects/my-skills/supervisor/SKILL.mdOpens the supervisor role's skill.
Admin role~/projects/my-skills/admin/SKILL.mdOpens the admin role's skill.
QA agent role~/projects/my-skills/qa-agent/SKILL.mdOpens the qa-agent role's skill; no team file starts it yet.
Claude personas~/projects/my-skills/agents/<id>/claude.mdOpens a role's Claude persona, such as worker or supervisor.
Team handoff rules~/projects/my-skills/coordinated-agentic-session/references/handoff.mdOpens the rules for how team members talk to each other.
QA agent notes~/projects/workstation/docs/roles/qa-agent.mdOpens the qa-agent role notes kept in this repo.
Supervision backlog~/projects/betec/workboard/docs/supervision-backlog.mdOpens the supervision backlog, which lives outside this repo.
Data repo~/projects/data/Opens the data repo: cases, rule proposals, verdicts and troubleshooting.
Answer sync~/projects/data/bin/syncRuns the answer sync; a timer runs it every 5 minutes.
agents › assistants
Claude and Codex global instructions, settings, hooks, plugins and tools on this setup.
Global rules~/projects/workstation/claude/CLAUDE.mdOpens the global rules: browser automation, communication, research and presenting work.
Shorter agent notes~/projects/workstation/claude/AGENTS.mdOpens the shorter global agent notes.
Claude settings~/projects/workstation/claude/settings.jsonOpens Claude Code's settings, which init-windows deploys to Windows.
Codex config~/projects/workstation/codex/config.tomlOpens the Codex CLI config, which init-windows deploys to Windows.
Linux instruction mirror~/projects/workstation/claude/linux-global/Opens the mirror of this machine's installed instruction files.
Hook scripts~/projects/workstation/claude/hooks/Opens the hook scripts Claude runs at session start and on tool use.
Core rules checks~/projects/workstation/claude/hooks/test_core_rules.shRuns the checks for the core-rules hook.
Session types~/projects/workstation/claude/session-types/Opens the session-types folder: the SessionStart hook and the main-session wrapper.
Usage guard~/projects/workstation/claude/usage-guard/Opens the usage guard: the claude wrapper that sits ahead of the native claude.
Usage guard install~/projects/workstation/claude/usage-guard/install.shRuns the installer that puts the claude wrapper on the PATH.
Team park~/.local/bin/team-parkRuns team-park, the tool from claude/team-park, which its README describes.
Review pane plugin~/projects/workstation/claude/mods/review-pane/Opens the review pane plugin for Claude Code.
Changelog pane plugin~/projects/workstation/claude/mods/changelog-pane/Opens the changelog pane plugin for Claude Code.
Team board plugin~/projects/workstation/claude/mods/team-board/Opens the team board plugin for Claude Code.
Scratchpad plugin~/projects/workstation/claude/mods/scratchpad-playground/Opens the scratchpad plugin for Claude Code.
Communication notes~/projects/workstation/claude/communication-framework.mdOpens the communication design notes, a draft that nothing enforces yet.
agents › hermes
The Hermes agent on this machine: its launcher, configuration and restore.
Hermes launcher~/.local/bin/hermesRuns the Hermes agent launcher.
Hermes guide~/projects/workstation/hermes/README.mdOpens the Hermes guide: install, current configuration and what is not backed up.
Restore runbook~/projects/workstation/hermes/RESTORE.mdOpens the runbook for restoring Hermes.
Default profile example~/projects/workstation/hermes/default.config.example.yamlOpens the secret-free example settings for the default profile.
Jobs profile example~/projects/workstation/hermes/jobs.config.example.yamlOpens the secret-free example settings for the jobs profile.
Backup record~/projects/workstation/hermes/BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
browser
The browser: the browser command, Chrome, the Codex bridge and the smoke-test tool.
Browser commandbrowserRuns browser steps, given as a JSON list, against one Chrome window that stays open between calls.
Browser statusbrowser statusPrints whether the background server and Chrome are up.
Browser closebrowser closeCloses Chrome and stops the background server.
Recording proof~/projects/workstation/browser/README.md#recording-proofOpens the recordStart and recordStop steps, the one supported way to record a tab.
Browser guide~/projects/workstation/browser/README.mdOpens the browser guide: every action, viewport preset, network capture and login gotcha.
Start Chrome~/projects/workstation/chrome/chrome.shRuns Chrome with the recording flag, the only way to start Chrome on this machine.
Chrome setup~/projects/workstation/chrome/install.shRuns the one-time setup that points google-chrome at chrome.sh.
Chrome flags~/projects/workstation/chrome/flagsOpens the flag list that every Chrome start reads; edit this one list only.
Chrome guide~/projects/workstation/chrome/README.mdOpens the Chrome guide: why it starts this way and its limits.
Codex Chrome bridge~/projects/workstation/codex/chrome-bridge/install.shRuns the installer that keeps Codex's Chrome plugin link and patch in place.
Codex Chrome path~/projects/workstation/codex/browser/README.mdOpens the guide to Codex's direct Chrome command path and its live check.
Smoke-test tooljev-browser-testRuns a goal in a browser and reports only the text and URL you asked for.
Smoke-test install~/projects/workstation/jev-browser-test/install.shRuns the installer, which pins the upstream revision and places the CLI in ~/.local/bin.
Smoke-test guide~/projects/workstation/jev-browser-test/README.mdOpens the smoke-test guide: the privacy boundary, exit codes and the Jev loop.
Smoke-test keys~/.config/jev-browser-test/envOpens the private env file for the smoke test's keys, which stays out of git.
machine
Power, lid, network, monitor and repair scripts for this Linux machine.
Power saver~/projects/workstation/cpu-min-power.shRuns the power-saver profile: turbo off and CPU capped at 8%; asks for sudo.
Balanced power~/projects/workstation/cpu-normal-power.shRuns the balanced profile: turbo on and the CPU cap back at 100%.
Keep running with lid closed~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.shRuns the change that makes closing the lid do nothing; it applies after a reboot.
Restore lid behavior~/projects/workstation/laptop-utilities/restore-default-lid-behavior.shRuns the removal of that lid change; it applies after a reboot.
HDMI monitor fix~/projects/workstation/fix_old_monitor_hdmi.shRuns xrandr to set the external output's mode and refresh rate.
Internet recovery~/projects/workstation/linux-internet-recovery.shRuns the DNS and network reset; it re-runs itself with sudo.
Tailscale remote terminal~/projects/workstation/recover-tailscale-remote-terminal.shRuns the Tailscale repair and checks the remote terminal on port 3500.
Supabase keepalive~/projects/workstation/supabase-keepalive/install.shRuns the installer for the Supabase keepalive timer.
Keyboard repairfix-keyboardRuns the keyboard repair helper from zsh.d/utils.zsh.
Mouse repairfix-mouseRuns the mouse repair helper from zsh.d/utils.zsh.
Disk repairfix-diskRuns the disk repair helper from zsh.d/utils.zsh.
WhatsApp repairfix-whatsappRuns the WhatsApp repair helper from zsh.d/utils.zsh.
windows
The Windows PC: its setup, skill sync, work repos and mirrored desktop files.
Setupworkstation windows setupOpens the setup screen: install, checks, roll back, and the manifests.
Skill syncworkstation windows syncOpens the sync screen: how the PC keeps its skills in step with my-skills.
Clone work repos~/projects/workstation/repos/Clone-BetecRepos.ps1Runs the clone of each missing Betec work repo; it is safe to run again.
Desktop mirror~/projects/workstation/claude/windows-global/Opens the mirror of the Windows desktop's installed CLAUDE.md and docs.
Desktop backup~/projects/workstation/claude/backups/desktop-v2-2026/Opens the portable snapshot of the Windows desktop's instruction package.
windows › setup
Setting up the Windows PC: install, checks, rollback, the manifests and the sign-ins to redo.
Install~/projects/workstation/init-windows/Start-Install.cmdRuns the one-command install of programs, Node, VS Code, Git config and user scripts.
Smoke test~/projects/workstation/init-windows/Smoke-Test-Windows.ps1Runs the smoke test of the Windows setup.
Verify~/projects/workstation/init-windows/Verify-Windows.ps1Runs the checks on the installed setup.
Export~/projects/workstation/init-windows/Export-Windows.ps1Runs the export that captures this machine into the manifests.
Roll back~/projects/workstation/init-windows/Remove-WindowsPack.ps1Runs the rollback of what the install added.
Manifests~/projects/workstation/init-windows/manifests/Opens the exact manifests: programs, Node versions, VS Code extensions and managed files.
User scripts~/projects/workstation/init-windows/user-scripts/Opens the scripts copied into the PC's Scripts folder.
Sign-ins to redo~/projects/workstation/init-windows/secrets-checklist.mdOpens the list of sign-ins you redo by hand after an install.
Setup guide~/projects/workstation/init-windows/README.mdOpens the full guide to the Windows setup.
windows › sync
How the Windows PC keeps its skills in step with my-skills.
Sync run~/projects/workstation/skills-sync-windows/Sync-Skills.ps1Runs the protected skill sync; GitHub starts it on each trusted push to master.
Sync tests~/projects/workstation/skills-sync-windows/Test-Sync.ps1Runs the skill sync tests.
Account check~/projects/workstation/skills-sync-windows/Test-Account.ps1Runs the check of the runner account's rights.
Last syncC:\ProgramData\MySkillsSync\state\last-success.jsonOpens the record of the latest successful sync.
Verification~/projects/workstation/skills-sync-windows/verification.mdOpens the record of how the sync was verified.
Sync guide~/projects/workstation/skills-sync-windows/README.mdOpens the sync guide: the runner, its install and who can change what.
sharing
What is shared between this laptop and the Windows PC: mouse, keyboard, audio and clipboard.
Mouse and keyboardworkstation sharing deskflowOpens the Deskflow screen: the shared mouse and keyboard, its service, settings and recovery.
Audioworkstation sharing audioOpens the audio screen: sending this laptop's audio to the Windows PC.
Clipboardworkstation sharing clipboardOpens the shared clipboard screen: the clipstack server, watcher and picker.
Lan Mouse (retired)~/projects/workstation/lan-mouse/README.mdOpens the retired Lan Mouse guide, kept for rollback.
sharing › deskflow
The Deskflow shared mouse and keyboard: its guide, service, settings and notes.
Deskflow guide~/projects/workstation/deskflow/README.mdOpens the Deskflow guide: everyday use and recovery.
Deskflow server~/.config/systemd/user/deskflow.serviceStarts the Deskflow server with the graphical session; it is the only server.
Linux settings~/.config/Deskflow/Deskflow.confOpens the Linux Deskflow settings copied from deskflow/linux.conf.
Resume shared inputresume-kvmRuns Deskflow again and asks for input capture after a Cancel.
USB mouse notes~/projects/workstation/deskflow/usb-mouse/README.mdOpens the USB mouse notes: how the keyboard follows the mouse and how to turn USB sharing back on.
Network audit~/projects/workstation/deskflow/NETWORK-AUDIT.mdOpens the network audit of Deskflow.
Firewall lockdown~/projects/workstation/deskflow/deskflow-lockdown.nftOpens the nftables lockdown rules for Deskflow.
sharing › audio
Sending this laptop's audio to the Windows PC over Tailscale, and taking it back.
Start audioaudio-startStarts sending all Linux audio to the Windows PC; pausing restores the speakers.
Pause audioaudio-pausePauses the sharing and restores the speakers.
Audio statusaudio-share statusPrints whether audio is going to Windows.
Audio share entry~/projects/workstation/README.md (entry dated 2026-10-23)Opens the README entry that describes the audio share.
sharing › clipboard
The shared clipboard, clipstack: its picker, server, watcher and Windows side.
Clipboard picker~/projects/workstation/clipstack/picker.pyRuns the picker that chooses from the shared clipboard.
Clipstack server~/projects/workstation/clipstack/units/clipstack-server.serviceStarts the clipstack server with the user session.
Clipstack watcher~/projects/workstation/clipstack/units/clipstack-watcher.serviceStarts the watcher that follows what is copied.
Clipstack install~/projects/workstation/clipstack/install.shRuns the install of the Linux side.
Windows side~/projects/workstation/clipstack/windows/clipstack.ahkRuns the Windows side of the shared clipboard, an AutoHotkey script.
Windows side intent~/projects/workstation/clipstack/windows/INTENT.mdOpens the Windows side's intent and rules.
shell
The shell: zsh helpers, git, OpenCode profiles and API keys.
Helpersworkstation shell helpersOpens the helpers screen: each zsh.d file and what it adds to the shell.
Gitworkstation shell gitOpens the git screen: git config, the checkout guard and the hooks.
OpenCode profilesworkstation shell opencodeOpens the OpenCode screen: the commands that run and switch each profile.
shell › helpers
The zsh helpers in zsh.d, one file per topic, each sourced from ~/.zshrc.
Infra helpers~/projects/workstation/zsh.d/infra.zshOpens the file: Docker and Compose, Prisma, Postgres, nginx and VPN shortcuts.
Utilities~/projects/workstation/zsh.d/utils.zshOpens the file: terminal helpers, IP aliases, lazy nvm and node, Android, Java and Bun setup, and the fix-* repairs.
API keys~/projects/workstation/zsh.d/api-keys.zshOpens the file that exports the general-use API keys from ~/.config/api-keys/env.
Edit API keysapi-keys-editOpens ~/.config/api-keys/env in the editor; the file never goes to git.
Review open~/projects/workstation/zsh.d/review-open.zshOpens the file that defines review-open, also installed for bash and agents.
Rules command~/projects/workstation/zsh.d/rules.zshOpens the file that defines the rules command.
Dashboard path warning~/projects/workstation/zsh.d/dash-path-warn.zshOpens the file with the dashboard path warning; its purpose is taken from the name alone.
Workstation command~/projects/workstation/zsh.d/workstation.zshOpens the file that defines workstation, ws and setup, the commands for this map.
shell › git
Git on this machine: its config, the checkout guard and the hooks that run in every repo.
Git config~/projects/workstation/.gitconfigOpens the repo copy of ~/.gitconfig: identity, LFS, credential helper and hooks path.
Checkout guard~/projects/workstation/zsh.d/git-safety.zshOpens the file that makes git checkout list the files and ask [y/N] before discarding changes.
Git hooks~/projects/workstation/git-hooks/Opens the Lefthook hooks that run in every repo, with the push and commit gates.
Scenario gate~/projects/workstation/git-hooks/scenario-gate.pyOpens the scenario gate script the git hooks use.
shell › opencode
OpenCode profiles: the files each profile loads, and the commands that run and switch them.
OpenCodeopencode (also oc)Runs OpenCode with the current profile.
Current profileopencode-profileNames the current profile.
Profile listopencode-profilesPrints what each profile loads.
Switch profileopencode-switch <name>Switches every shell's new runs to the named profile.
Profile loginopencode-loginSigns a profile's Claude Code in.
Profile filesopencode-filesLists the current profile's files.
Edit profile fileopencode-edit <file>Opens one of the current profile's files in the editor.
OpenCode helpopencode help (also oc help)Prints every profile's files, one column each, and the commands.
Profiles tool~/projects/workstation/opencode-profiles/profiles.pyRuns the profiles tool behind these commands.
Experimental profile~/projects/workstation/opencode-profiles/private-leb-experimental/Opens the files of the experimental profile.
Profile tests~/projects/workstation/opencode-profiles/test_profiles.pyRuns the profile tests.
documents
Documents: CVs, plans, case studies, item lists, the repo guide and the project's intent.
CVsworkstation documents cvsOpens the CVs screen: the three CVs as PDFs, their sources and dated versions.
Plans and designworkstation documents plansOpens the plans screen: dated plans, design pitches, flow cards, research and changelog.
Cases and incidentsworkstation documents casesOpens the cases screen: case studies and incident records, one folder or file each.
Urgent items~/projects/workstation/docs/items/urgent.item.mdOpens the urgent items.
Planned items~/projects/workstation/docs/items/planned.item.mdOpens the planned items.
Work items~/projects/workstation/docs/items/work.item.mdOpens the work items.
Playbook~/projects/workstation/docs/playbooks/talk-while-team-builds.mdOpens the playbook for talking while a team builds.
Repo guide~/projects/workstation/README.mdOpens the repo guide: where each file lands on the machine.
Project intent~/projects/workstation/.idd/project.intent.mdOpens the project's intent.
Slide images~/projects/workstation/copy/Opens the three slide images: today, subsystems and reviews.
documents › cvs
The three CVs: PDFs to send, LaTeX sources to edit, and their dated versions.
Full Stack Developer CV~/projects/workstation/cv/cv-full-stack.pdfOpens the Full Stack Developer CV as a PDF.
AI Full Stack Engineer CV~/projects/workstation/cv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV as a PDF.
AI Integrations CV~/projects/workstation/cv/cv-ai-integrations.pdfOpens the AI Integrations CV as a PDF.
LaTeX sources~/projects/workstation/cv/*.texOpens the .tex source of a CV, the file you edit.
Rebuild one CVpdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.texRuns pdflatex to rebuild one CV's PDF from its source.
Plain-text versions~/projects/workstation/cv/text/build-full.shRuns the build of the plain-text CV versions.
Dated versions~/projects/workstation/cv/versions/Opens the dated CV versions, 2026-10-04 and its v2.
CV guide~/projects/workstation/cv/README.mdOpens the CV guide: sources and the rebuild steps.
CV workflow~/projects/workstation/cv/WORKFLOW.mdOpens the CV workflow notes.
documents › plans
Dated plans, design pitches, flow cards, research and changelog entries, one folder per piece of work.
Plans~/projects/workstation/docs/plans/Opens the plans folder, with one dated plan per piece of work.
Design~/projects/workstation/docs/design/Opens the design folders: pitches and recommendations.
Flow cards~/projects/workstation/docs/flows/Opens the flow cards: how each screen's flow was designed.
Research~/projects/workstation/docs/research/Opens the research notes, one dated folder each.
Functional research~/projects/workstation/docs/functional-research/2026-10-21/Opens the comparison of agent frameworks, such as CrewAI and Agno.
Changelog~/projects/workstation/docs/changelog/Opens the dated changelog entries.
documents › cases
Case studies and incidents: human-reviewed experiments and machine incidents, one folder or file each.
Codebot return case~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/Opens the case of one design request run with and without the conceptual-modeling skill.
Signal garden case~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/Opens the documentation exhibit that separates Blume's explanation from Astryx's live interface.
Kernel browser results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the Kernel cloud browser results, which live outside this repo.
Lid-closed incident~/projects/workstation/reference/incidents/2026-10-01-codebot-lid-closed.mdOpens the incident record: CodeBot kept serving with the lid closed.
Incident index~/projects/workstation/reference/README.mdOpens the index of workstation reference cases.
Questions
  • Facade name: keep workstation and ws, and drop setup if whence finds a clash? Recommendation: yes.
  • Kept skills: the skill tree has 22 folders and the README table lists 12. Keep all 22 on one screen, and split into general and SolaraAI/Supabase only if it grows? Recommendation: yes.
  • Lan Mouse (retired): keep it as the last row under Sharing, marked retired, or hide it? Recommendation: keep it for rollback.
  • Seven top groups: keep Sharing with Windows as its own group, or fold it into Machine? Recommendation: keep it separate.
  • dash-path-warn.zsh: what does this file do? I wrote its row from the name alone.
  • Please confirm these exist before the CLI is built: zsh.d/workstation.zsh, workstation-cli/, audio-share/, zsh.d/audio-share.zsh, Start-Install.cmd, init-windows/inventory.md, and the resume-kvm command. The rows stay in the map until then.
As phone screens

Home

Everything this workstation has, grouped by what you are trying to do.

AgentsOpens the agents screen: rules, dashboard, sandbox, skills, teams, assistant setup and Hermes.
›
BrowserOpens the browser screen: the browser command, Chrome and the smoke-test tool.
›
MachineOpens the machine screen: power, lid, network, monitor and repair scripts for this Linux machine.
›
Sharing with WindowsOpens the sharing screen: the mouse, keyboard, audio and clipboard shared with the Windows PC.
›
WindowsOpens the Windows screen: the PC's setup, skill sync, work repos and mirrored desktop files.
›
ShellOpens the shell screen: zsh helpers, git, OpenCode profiles and API keys.
›
DocumentsOpens the documents screen: CVs, plans, case studies, item lists and the repo guide.
›
‹ Home

agents

The agent system: its rules, dashboard, sandbox, skills, teams, assistant setup and Hermes.

RulesOpens the rules screen: the rules every org follows and how they are printed.
›
DashboardOpens the dashboard screen: what waits for you and the team's live activity.
›
SandboxOpens the sandbox screen: the Agent Sandbox page and the agent records behind it.
›
SkillsOpens the skills screen: where global skills live and which skills this repo keeps as backups.
›
TeamsOpens the teams screen: starting a team, its roles, and the data repo it writes to.
›
AssistantsOpens the assistants screen: Claude and Codex global instructions, settings, hooks and plugins.
›
HermesOpens the Hermes screen: the Hermes agent launcher, its configuration and its restore runbook.
›
‹ agents

rules

The rules every org follows, printed on demand and kept in one file.

Rules commandPrints the rules for every org, or for the folder you give, with the escalation policy among them.
›
Rules fileOpens the rules file, which only the user or an accepted rule proposal may change.
›
Rule metadataOpens the metadata file that goes with the rules.
›
Generated rulesOpens the generated copy that every session reads, made from the rules file.
›
Rules checksRuns the checks for the rules file.
›
‹ agents

dashboard

The dashboard on this machine, in its two versions, with its checks and guides.

Dashboard serverStarts the dashboard at http://127.0.0.1:8780, the page you open in a browser.
›
Dashboard checksRuns the dashboard checks against the real data and a real server.
›
Concepts versionStarts the concepts version at http://127.0.0.1:8781, which differs only in its Projects panel.
›
Concepts checksRuns the concepts version checks.
›
Dashboard guideOpens the dashboard guide: tabs, what it writes, and hot reload.
›
Dashboard intentOpens the dashboard's intent and rules.
›
Dashboard flow cardOpens the flow card for the dashboard's screens.
›
‹ agents

sandbox

The Agent Sandbox: the page where you change an agent's setup and send it a message, and the records behind it.

Sandbox pageStarts the sandbox page at http://127.0.0.1:8790.
›
Check agentsChecks every agent record and refuses broken ones with exit 1.
›
List agentsLists the agents with their tier, model and number of tests.
›
Framework guideOpens the framework guide: how the page works and the words it uses.
›
Framework intentOpens the framework's intent and rules.
›
Sandbox product planOpens the sandbox's product plan and mockups.
›
‹ agents

skills

Skills: where the global skills are kept, and which skills this repo keeps as backups.

Global skillsOpens the global skills repo, whose install script links each skill into the agents' skill folders.
›
Global skills installRuns the installer that links skills into the agents' skill folders.
›
Kept skillsOpens the list of the skills this repo keeps as backups, one folder each.
›
Skill shortlistOpens the skills researched on skills.sh, with a note of what is installed.
›
‹ skills

kept

The skills this repo keeps as backups, one folder each.

Tech LedgerOpens the skill that reads and writes the betec Tech Ledger of evaluated tech.
›
API key creationOpens the skill for getting a missing API key with browser tools instead of escalating.
›
Clone websiteOpens the skill that reverse-engineers and clones websites with parallel builders.
›
Contextual value product thinkingOpens the skill for analyzing products and startup ideas through contextual human values.
›
Web research assistantOpens the web research skill for search, crawling and package lookups; its setup is in SETUP-NOTES.md.
›
Epic fan-out planningOpens the 10-step pattern for QA-gap epics with parallel agents and release gates.
›
ImpeccableOpens the frontend design skill: shape, critique, audit and polish.
›
Iterative action reviewOpens the skill for reviewing one real-world action as an iteration in a series.
›
Lab experimentOpens the skill for running an experiment in the ai-lab project.
›
Mentor modeOpens the mentor-mode skill with its teaching references and page scripts.
›
Post-feature cleanupOpens the pass that runs after writing code: UI defects, leftovers and repo hygiene.
›
PowerShell launchingOpens the skill for launching PowerShell or a new terminal window on Windows.
›
Reboot resumeOpens the skill that preserves and resumes work across a reboot or restart.
›
Resume projectOpens the resume-project skill and its CLI script.
›
SolaraAI content calendarOpens the SolaraAI content calendar skill.
›
SolaraAI deploymentOpens the SolaraAI deploy-flow skill with its commands, services and workflows.
›
SolaraAI designOpens the SolaraAI design-system skill with its components.
›
SolaraAI formsOpens the SolaraAI skill for form behavior.
›
SupabaseOpens Supabase's own skill: auth, RLS, migrations, CLI and debugging.
›
Supabase Postgres best practicesOpens Supabase's Postgres performance rules.
›
Communication engineeringOpens the skill that applies engineering discipline to what an agent says and how much.
›
Skill creatorOpens the skill for creating new skills.
›
Tech CV writerOpens the CV writer skill with its ATS, bullet and template references.
›
‹ agents

teams

How teams are started, and the roles, files and data they run on.

Start a teamStarts a team from its team file, with an admin and its members.
›
Team filesOpens the team files, such as worker-pair and research-team.
›
Worker roleOpens the worker role's skill.
›
Supervisor roleOpens the supervisor role's skill.
›
Admin roleOpens the admin role's skill.
›
QA agent roleOpens the qa-agent role's skill; no team file starts it yet.
›
Claude personasOpens a role's Claude persona, such as worker or supervisor.
›
Team handoff rulesOpens the rules for how team members talk to each other.
›
QA agent notesOpens the qa-agent role notes kept in this repo.
›
Supervision backlogOpens the supervision backlog, which lives outside this repo.
›
Data repoOpens the data repo: cases, rule proposals, verdicts and troubleshooting.
›
Answer syncRuns the answer sync; a timer runs it every 5 minutes.
›
‹ agents

assistants

Claude and Codex global instructions, settings, hooks, plugins and tools on this setup.

Global rulesOpens the global rules: browser automation, communication, research and presenting work.
›
Shorter agent notesOpens the shorter global agent notes.
›
Claude settingsOpens Claude Code's settings, which init-windows deploys to Windows.
›
Codex configOpens the Codex CLI config, which init-windows deploys to Windows.
›
Linux instruction mirrorOpens the mirror of this machine's installed instruction files.
›
Hook scriptsOpens the hook scripts Claude runs at session start and on tool use.
›
Core rules checksRuns the checks for the core-rules hook.
›
Session typesOpens the session-types folder: the SessionStart hook and the main-session wrapper.
›
Usage guardOpens the usage guard: the claude wrapper that sits ahead of the native claude.
›
Usage guard installRuns the installer that puts the claude wrapper on the PATH.
›
Team parkRuns team-park, the tool from claude/team-park, which its README describes.
›
Review pane pluginOpens the review pane plugin for Claude Code.
›
Changelog pane pluginOpens the changelog pane plugin for Claude Code.
›
Team board pluginOpens the team board plugin for Claude Code.
›
Scratchpad pluginOpens the scratchpad plugin for Claude Code.
›
Communication notesOpens the communication design notes, a draft that nothing enforces yet.
›
‹ agents

hermes

The Hermes agent on this machine: its launcher, configuration and restore.

Hermes launcherRuns the Hermes agent launcher.
›
Hermes guideOpens the Hermes guide: install, current configuration and what is not backed up.
›
Restore runbookOpens the runbook for restoring Hermes.
›
Default profile exampleOpens the secret-free example settings for the default profile.
›
Jobs profile exampleOpens the secret-free example settings for the jobs profile.
›
Backup recordOpens the record of the 2026-10-02 backup.
›
‹ Home

browser

The browser: the browser command, Chrome, the Codex bridge and the smoke-test tool.

Browser commandRuns browser steps, given as a JSON list, against one Chrome window that stays open between calls.
›
Browser statusPrints whether the background server and Chrome are up.
›
Browser closeCloses Chrome and stops the background server.
›
Recording proofOpens the recordStart and recordStop steps, the one supported way to record a tab.
›
Browser guideOpens the browser guide: every action, viewport preset, network capture and login gotcha.
›
Start ChromeRuns Chrome with the recording flag, the only way to start Chrome on this machine.
›
Chrome setupRuns the one-time setup that points google-chrome at chrome.sh.
›
Chrome flagsOpens the flag list that every Chrome start reads; edit this one list only.
›
Chrome guideOpens the Chrome guide: why it starts this way and its limits.
›
Codex Chrome bridgeRuns the installer that keeps Codex's Chrome plugin link and patch in place.
›
Codex Chrome pathOpens the guide to Codex's direct Chrome command path and its live check.
›
Smoke-test toolRuns a goal in a browser and reports only the text and URL you asked for.
›
Smoke-test installRuns the installer, which pins the upstream revision and places the CLI in ~/.local/bin.
›
Smoke-test guideOpens the smoke-test guide: the privacy boundary, exit codes and the Jev loop.
›
Smoke-test keysOpens the private env file for the smoke test's keys, which stays out of git.
›
‹ Home

machine

Power, lid, network, monitor and repair scripts for this Linux machine.

Power saverRuns the power-saver profile: turbo off and CPU capped at 8%; asks for sudo.
›
Balanced powerRuns the balanced profile: turbo on and the CPU cap back at 100%.
›
Keep running with lid closedRuns the change that makes closing the lid do nothing; it applies after a reboot.
›
Restore lid behaviorRuns the removal of that lid change; it applies after a reboot.
›
HDMI monitor fixRuns xrandr to set the external output's mode and refresh rate.
›
Internet recoveryRuns the DNS and network reset; it re-runs itself with sudo.
›
Tailscale remote terminalRuns the Tailscale repair and checks the remote terminal on port 3500.
›
Supabase keepaliveRuns the installer for the Supabase keepalive timer.
›
Keyboard repairRuns the keyboard repair helper from zsh.d/utils.zsh.
›
Mouse repairRuns the mouse repair helper from zsh.d/utils.zsh.
›
Disk repairRuns the disk repair helper from zsh.d/utils.zsh.
›
WhatsApp repairRuns the WhatsApp repair helper from zsh.d/utils.zsh.
›
‹ Home

windows

The Windows PC: its setup, skill sync, work repos and mirrored desktop files.

SetupOpens the setup screen: install, checks, roll back, and the manifests.
›
Skill syncOpens the sync screen: how the PC keeps its skills in step with my-skills.
›
Clone work reposRuns the clone of each missing Betec work repo; it is safe to run again.
›
Desktop mirrorOpens the mirror of the Windows desktop's installed CLAUDE.md and docs.
›
Desktop backupOpens the portable snapshot of the Windows desktop's instruction package.
›
‹ windows

setup

Setting up the Windows PC: install, checks, rollback, the manifests and the sign-ins to redo.

InstallRuns the one-command install of programs, Node, VS Code, Git config and user scripts.
›
Smoke testRuns the smoke test of the Windows setup.
›
VerifyRuns the checks on the installed setup.
›
ExportRuns the export that captures this machine into the manifests.
›
Roll backRuns the rollback of what the install added.
›
ManifestsOpens the exact manifests: programs, Node versions, VS Code extensions and managed files.
›
User scriptsOpens the scripts copied into the PC's Scripts folder.
›
Sign-ins to redoOpens the list of sign-ins you redo by hand after an install.
›
Setup guideOpens the full guide to the Windows setup.
›
‹ windows

sync

How the Windows PC keeps its skills in step with my-skills.

Sync runRuns the protected skill sync; GitHub starts it on each trusted push to master.
›
Sync testsRuns the skill sync tests.
›
Account checkRuns the check of the runner account's rights.
›
Last syncOpens the record of the latest successful sync.
›
VerificationOpens the record of how the sync was verified.
›
Sync guideOpens the sync guide: the runner, its install and who can change what.
›
‹ Home

sharing

What is shared between this laptop and the Windows PC: mouse, keyboard, audio and clipboard.

Mouse and keyboardOpens the Deskflow screen: the shared mouse and keyboard, its service, settings and recovery.
›
AudioOpens the audio screen: sending this laptop's audio to the Windows PC.
›
ClipboardOpens the shared clipboard screen: the clipstack server, watcher and picker.
›
Lan Mouse (retired)Opens the retired Lan Mouse guide, kept for rollback.
›
‹ sharing

deskflow

The Deskflow shared mouse and keyboard: its guide, service, settings and notes.

Deskflow guideOpens the Deskflow guide: everyday use and recovery.
›
Deskflow serverStarts the Deskflow server with the graphical session; it is the only server.
›
Linux settingsOpens the Linux Deskflow settings copied from deskflow/linux.conf.
›
Resume shared inputRuns Deskflow again and asks for input capture after a Cancel.
›
USB mouse notesOpens the USB mouse notes: how the keyboard follows the mouse and how to turn USB sharing back on.
›
Network auditOpens the network audit of Deskflow.
›
Firewall lockdownOpens the nftables lockdown rules for Deskflow.
›
‹ sharing

audio

Sending this laptop's audio to the Windows PC over Tailscale, and taking it back.

Start audioStarts sending all Linux audio to the Windows PC; pausing restores the speakers.
›
Pause audioPauses the sharing and restores the speakers.
›
Audio statusPrints whether audio is going to Windows.
›
Audio share entryOpens the README entry that describes the audio share.
›
‹ sharing

clipboard

The shared clipboard, clipstack: its picker, server, watcher and Windows side.

Clipboard pickerRuns the picker that chooses from the shared clipboard.
›
Clipstack serverStarts the clipstack server with the user session.
›
Clipstack watcherStarts the watcher that follows what is copied.
›
Clipstack installRuns the install of the Linux side.
›
Windows sideRuns the Windows side of the shared clipboard, an AutoHotkey script.
›
Windows side intentOpens the Windows side's intent and rules.
›
‹ Home

shell

The shell: zsh helpers, git, OpenCode profiles and API keys.

HelpersOpens the helpers screen: each zsh.d file and what it adds to the shell.
›
GitOpens the git screen: git config, the checkout guard and the hooks.
›
OpenCode profilesOpens the OpenCode screen: the commands that run and switch each profile.
›
‹ shell

helpers

The zsh helpers in zsh.d, one file per topic, each sourced from ~/.zshrc.

Infra helpersOpens the file: Docker and Compose, Prisma, Postgres, nginx and VPN shortcuts.
›
UtilitiesOpens the file: terminal helpers, IP aliases, lazy nvm and node, Android, Java and Bun setup, and the fix-* repairs.
›
API keysOpens the file that exports the general-use API keys from ~/.config/api-keys/env.
›
Edit API keysOpens ~/.config/api-keys/env in the editor; the file never goes to git.
›
Review openOpens the file that defines review-open, also installed for bash and agents.
›
Rules commandOpens the file that defines the rules command.
›
Dashboard path warningOpens the file with the dashboard path warning; its purpose is taken from the name alone.
›
Workstation commandOpens the file that defines workstation, ws and setup, the commands for this map.
›
‹ shell

git

Git on this machine: its config, the checkout guard and the hooks that run in every repo.

Git configOpens the repo copy of ~/.gitconfig: identity, LFS, credential helper and hooks path.
›
Checkout guardOpens the file that makes git checkout list the files and ask [y/N] before discarding changes.
›
Git hooksOpens the Lefthook hooks that run in every repo, with the push and commit gates.
›
Scenario gateOpens the scenario gate script the git hooks use.
›
‹ shell

opencode

OpenCode profiles: the files each profile loads, and the commands that run and switch them.

OpenCodeRuns OpenCode with the current profile.
›
Current profileNames the current profile.
›
Profile listPrints what each profile loads.
›
Switch profileSwitches every shell's new runs to the named profile.
›
Profile loginSigns a profile's Claude Code in.
›
Profile filesLists the current profile's files.
›
Edit profile fileOpens one of the current profile's files in the editor.
›
OpenCode helpPrints every profile's files, one column each, and the commands.
›
Profiles toolRuns the profiles tool behind these commands.
›
Experimental profileOpens the files of the experimental profile.
›
Profile testsRuns the profile tests.
›
‹ Home

documents

Documents: CVs, plans, case studies, item lists, the repo guide and the project's intent.

CVsOpens the CVs screen: the three CVs as PDFs, their sources and dated versions.
›
Plans and designOpens the plans screen: dated plans, design pitches, flow cards, research and changelog.
›
Cases and incidentsOpens the cases screen: case studies and incident records, one folder or file each.
›
Urgent itemsOpens the urgent items.
›
Planned itemsOpens the planned items.
›
Work itemsOpens the work items.
›
PlaybookOpens the playbook for talking while a team builds.
›
Repo guideOpens the repo guide: where each file lands on the machine.
›
Project intentOpens the project's intent.
›
Slide imagesOpens the three slide images: today, subsystems and reviews.
›
‹ documents

cvs

The three CVs: PDFs to send, LaTeX sources to edit, and their dated versions.

Full Stack Developer CVOpens the Full Stack Developer CV as a PDF.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV as a PDF.
›
AI Integrations CVOpens the AI Integrations CV as a PDF.
›
LaTeX sourcesOpens the .tex source of a CV, the file you edit.
›
Rebuild one CVRuns pdflatex to rebuild one CV's PDF from its source.
›
Plain-text versionsRuns the build of the plain-text CV versions.
›
Dated versionsOpens the dated CV versions, 2026-10-04 and its v2.
›
CV guideOpens the CV guide: sources and the rebuild steps.
›
CV workflowOpens the CV workflow notes.
›
‹ documents

plans

Dated plans, design pitches, flow cards, research and changelog entries, one folder per piece of work.

PlansOpens the plans folder, with one dated plan per piece of work.
›
DesignOpens the design folders: pitches and recommendations.
›
Flow cardsOpens the flow cards: how each screen's flow was designed.
›
ResearchOpens the research notes, one dated folder each.
›
Functional researchOpens the comparison of agent frameworks, such as CrewAI and Agno.
›
ChangelogOpens the dated changelog entries.
›
‹ documents

cases

Case studies and incidents: human-reviewed experiments and machine incidents, one folder or file each.

Codebot return caseOpens the case of one design request run with and without the conceptual-modeling skill.
›
Signal garden caseOpens the documentation exhibit that separates Blume's explanation from Astryx's live interface.
›
Kernel browser resultsOpens the Kernel cloud browser results, which live outside this repo.
›
Lid-closed incidentOpens the incident record: CodeBot kept serving with the lid closed.
›
Incident indexOpens the index of workstation reference cases.
›
Raw answer
# Map: workstation

## Scenario

Reasoning from the README and the file list (not observed use): a developer works on this Linux laptop, paired with a Windows PC. They reach for one of these moments:

- checking or changing the agent system (rules, dashboard, sandbox, skills, teams)
- running or recording something in the browser
- repairing or tuning this machine (power, lid, network, monitor)
- setting up or checking the Windows PC
- sharing the mouse, keyboard, audio or clipboard between the two machines
- editing shell helpers, git config, OpenCode profiles or API keys
- finding a document: a CV, a plan, a case study, an item list

## Inventory

About 130 things, all in the JSON below. Each row's form is a path or command taken from the file list or the README. Where the README names something the file list doesn't show, the row is kept and listed under questions.

## Questions for you

1. **Facade name.** The README gives `workstation`, `ws` and `setup`. `setup` is generic and may clash. **Recommendation:** keep `workstation` and `ws`, and drop `setup` if `whence` finds another command with that name.
2. **Kept skills.** The skill tree has 22 skill folders in `claude/skills/`, but the README's table lists 12. **Recommendation:** list all 22 on one screen now. If it grows, split it into "general" and "SolaraAI and Supabase".
3. **Retired Lan Mouse.** **Recommendation:** keep it as the last row under Sharing, marked retired, so rollback stays findable.
4. **Seven top groups.** **Recommendation:** keep Sharing as its own group. It is the one job that spans both machines. Folding it into Machine would make the top screen six groups, but Machine would then mix local repairs with cross-machine sharing.
5. **`dash-path-warn.zsh`.** Its purpose is not visible from the file name or the README. What does it do? I wrote its row from the name only.
6. **Files the README names but the dump does not show:** `zsh.d/workstation.zsh`, `workstation-cli/`, `audio-share/`, `zsh.d/audio-share.zsh`, `Start-Install.cmd`, `init-windows/inventory.md`, and the `resume-kvm` command. Please confirm they exist before the CLI is built. The rows stay in the map until then.

## Judgment calls

- **Verbs by kind.** Scripts and commands start with "Runs" or "Prints". Servers and services start with "Starts". Files and screens start with "Opens". A file row's verb is what opening it does.
- **Sub-screens.** Groups with more than about 8 rows are split: Windows (setup, sync), Sharing (Deskflow, audio, clipboard), Shell (helpers, git, OpenCode), Documents (CVs, plans, cases), Agents (skills, kept skills, assistants, Hermes).
- **Names.** Group and item names come from the README's own headings and words, such as "Shared clipboard", "Agent Sandbox", "Tech Ledger" and "Deskflow".
- **Credentials.** The README says `zsh.d/infra.zsh` and `zsh.d/utils.zsh` embed a credential. No credential value appears in the map, and the rows say only what the files are for.
- **The map itself.** The `workstation` command's own help is not a row, because it is the map.

```json
{"screens": [
{"path": [], "sentence": "Everything this workstation has, grouped by what you are trying to do.", "rows": [
{"name": "Agents", "form": "workstation agents", "what": "Opens the agents screen: rules, dashboard, sandbox, skills, teams, assistant setup and Hermes."},
{"name": "Browser", "form": "workstation browser", "what": "Opens the browser screen: the browser command, Chrome and the smoke-test tool."},
{"name": "Machine", "form": "workstation machine", "what": "Opens the machine screen: power, lid, network, monitor and repair scripts for this Linux machine."},
{"name": "Sharing with Windows", "form": "workstation sharing", "what": "Opens the sharing screen: the mouse, keyboard, audio and clipboard shared with the Windows PC."},
{"name": "Windows", "form": "workstation windows", "what": "Opens the Windows screen: the PC's setup, skill sync, work repos and mirrored desktop files."},
{"name": "Shell", "form": "workstation shell", "what": "Opens the shell screen: zsh helpers, git, OpenCode profiles and API keys."},
{"name": "Documents", "form": "workstation documents", "what": "Opens the documents screen: CVs, plans, case studies, item lists and the repo guide."}
]},
{"path": ["agents"], "sentence": "The agent system: its rules, dashboard, sandbox, skills, teams, assistant setup and Hermes.", "rows": [
{"name": "Rules", "form": "workstation agents rules", "what": "Opens the rules screen: the rules every org follows and how they are printed."},
{"name": "Dashboard", "form": "workstation agents dashboard", "what": "Opens the dashboard screen: what waits for you and the team's live activity."},
{"name": "Sandbox", "form": "workstation agents sandbox", "what": "Opens the sandbox screen: the Agent Sandbox page and the agent records behind it."},
{"name": "Skills", "form": "workstation agents skills", "what": "Opens the skills screen: where global skills live and which skills this repo keeps as backups."},
{"name": "Teams", "form": "workstation agents teams", "what": "Opens the teams screen: starting a team, its roles, and the data repo it writes to."},
{"name": "Assistants", "form": "workstation agents assistants", "what": "Opens the assistants screen: Claude and Codex global instructions, settings, hooks and plugins."},
{"name": "Hermes", "form": "workstation agents hermes", "what": "Opens the Hermes screen: the Hermes agent launcher, its configuration and its restore runbook."}
]},
{"path": ["agents", "rules"], "sentence": "The rules every org follows, printed on demand and kept in one file.", "rows": [
{"name": "Rules command", "form": "rules [folder]", "what": "Prints the rules for every org, or for the folder you give, with the escalation policy among them."},
{"name": "Rules file", "form": "~/projects/workstation/workboard/rules.yaml", "what": "Opens the rules file, which only the user or an accepted rule proposal may change."},
{"name": "Rule metadata", "form": "~/projects/workstation/workboard/rules-meta.yaml", "what": "Opens the metadata file that goes with the rules."},
{"name": "Generated rules", "form": "~/.claude/references/rules.md", "what": "Opens the generated copy that every session reads, made from the rules file."},
{"name": "Rules checks", "form": "~/projects/workstation/workboard/test_rules.py", "what": "Runs the checks for the rules file."}
]},
{"path": ["agents", "dashboard"], "sentence": "The dashboard on this machine, in its two versions, with its checks and guides.", "rows": [
{"name": "Dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard at http://127.0.0.1:8780, the page you open in a browser."},
{"name": "Dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the dashboard checks against the real data and a real server."},
{"name": "Concepts version", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts version at http://127.0.0.1:8781, which differs only in its Projects panel."},
{"name": "Concepts checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the concepts version checks."},
{"name": "Dashboard guide", "form": "~/projects/workstation/dashboard/README.md", "what": "Opens the dashboard guide: tabs, what it writes, and hot reload."},
{"name": "Dashboard intent", "form": "~/projects/workstation/.idd/modules/dashboard/INTENT.md", "what": "Opens the dashboard's intent and rules."},
{"name": "Dashboard flow card", "form": "~/projects/workstation/docs/flows/2026-10-17/flow-card.md", "what": "Opens the flow card for the dashboard's screens."}
]},
{"path": ["agents", "sandbox"], "sentence": "The Agent Sandbox: the page where you change an agent's setup and send it a message, and the records behind it.", "rows": [
{"name": "Sandbox page", "form": "~/projects/workstation/agent-framework/agent serve", "what": "Starts the sandbox page at http://127.0.0.1:8790."},
{"name": "Check agents", "form": "~/projects/workstation/agent-framework/agent check", "what": "Checks every agent record and refuses broken ones with exit 1."},
{"name": "List agents", "form": "~/projects/workstation/agent-framework/agent list", "what": "Lists the agents with their tier, model and number of tests."},
{"name": "Framework guide", "form": "~/projects/workstation/agent-framework/README.md", "what": "Opens the framework guide: how the page works and the words it uses."},
{"name": "Framework intent", "form": "~/projects/workstation/.idd/modules/agent-framework/INTENT.md", "what": "Opens the framework's intent and rules."},
{"name": "Sandbox product plan", "form": "~/projects/workstation/docs/plans/2026-10-22-agent-sandbox/prd.html", "what": "Opens the sandbox's product plan and mockups."}
]},
{"path": ["agents", "skills"], "sentence": "Skills: where the global skills are kept, and which skills this repo keeps as backups.", "rows": [
{"name": "Global skills", "form": "~/projects/my-skills/", "what": "Opens the global skills repo, whose install script links each skill into the agents' skill folders."},
{"name": "Global skills install", "form": "~/projects/my-skills/install.sh", "what": "Runs the installer that links skills into the agents' skill folders."},
{"name": "Kept skills", "form": "workstation agents skills kept", "what": "Opens the list of the skills this repo keeps as backups, one folder each."},
{"name": "Skill shortlist", "form": "~/projects/workstation/claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh, with a note of what is installed."}
]},
{"path": ["agents", "skills", "kept"], "sentence": "The skills this repo keeps as backups, one folder each.", "rows": [
{"name": "Tech Ledger", "form": "claude/skills/tech-ledger/", "what": "Opens the skill that reads and writes the betec Tech Ledger of evaluated tech."},
{"name": "API key creation", "form": "claude/skills/api-key-creation/", "what": "Opens the skill for getting a missing API key with browser tools instead of escalating."},
{"name": "Clone website", "form": "claude/skills/clone-website/", "what": "Opens the skill that reverse-engineers and clones websites with parallel builders."},
{"name": "Contextual value product thinking", "form": "claude/skills/contextual-value-product-thinking/", "what": "Opens the skill for analyzing products and startup ideas through contextual human values."},
{"name": "Web research assistant", "form": "claude/skills/elad12390--web-research-assistant/", "what": "Opens the web research skill for search, crawling and package lookups; its setup is in SETUP-NOTES.md."},
{"name": "Epic fan-out planning", "form": "claude/skills/epic-fanout-planning/", "what": "Opens the 10-step pattern for QA-gap epics with parallel agents and release gates."},
{"name": "Impeccable", "form": "claude/skills/impeccable/", "what": "Opens the frontend design skill: shape, critique, audit and polish."},
{"name": "Iterative action review", "form": "claude/skills/iterative-action-review/", "what": "Opens the skill for reviewing one real-world action as an iteration in a series."},
{"name": "Lab experiment", "form": "claude/skills/lab-experiment/", "what": "Opens the skill for running an experiment in the ai-lab project."},
{"name": "Mentor mode", "form": "claude/skills/mentor-mode/", "what": "Opens the mentor-mode skill with its teaching references and page scripts."},
{"name": "Post-feature cleanup", "form": "claude/skills/post-feature-cleanup/", "what": "Opens the pass that runs after writing code: UI defects, leftovers and repo hygiene."},
{"name": "PowerShell launching", "form": "claude/skills/powershell-launching/", "what": "Opens the skill for launching PowerShell or a new terminal window on Windows."},
{"name": "Reboot resume", "form": "claude/skills/reboot-resume/", "what": "Opens the skill that preserves and resumes work across a reboot or restart."},
{"name": "Resume project", "form": "claude/skills/resume-project/", "what": "Opens the resume-project skill and its CLI script."},
{"name": "SolaraAI content calendar", "form": "claude/skills/solaraai-content-calendar/", "what": "Opens the SolaraAI content calendar skill."},
{"name": "SolaraAI deployment", "form": "claude/skills/solaraai-deployment/", "what": "Opens the SolaraAI deploy-flow skill with its commands, services and workflows."},
{"name": "SolaraAI design", "form": "claude/skills/solaraai-design/", "what": "Opens the SolaraAI design-system skill with its components."},
{"name": "SolaraAI forms", "form": "claude/skills/solaraai-forms/", "what": "Opens the SolaraAI skill for form behavior."},
{"name": "Supabase", "form": "claude/skills/supabase/", "what": "Opens Supabase's own skill: auth, RLS, migrations, CLI and debugging."},
{"name": "Supabase Postgres best practices", "form": "claude/skills/supabase-postgres-best-practices/", "what": "Opens Supabase's Postgres performance rules."},
{"name": "Communication engineering", "form": "claude/skills/tank--communication-engineering/", "what": "Opens the skill that applies engineering discipline to what an agent says and how much."},
{"name": "Skill creator", "form": "claude/skills/tank--skill-creator/", "what": "Opens the skill for creating new skills."},
{"name": "Tech CV writer", "form": "claude/skills/tech-cv-writer/", "what": "Opens the CV writer skill with its ATS, bullet and template references."}
]},
{"path": ["agents", "teams"], "sentence": "How teams are started, and the roles, files and data they run on.", "rows": [
{"name": "Start a team", "form": "/spawn-team <team> (Claude) or $spawn-team <team> (Codex)", "what": "Starts a team from its team file, with an admin and its members."},
{"name": "Team files", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files, such as worker-pair and research-team."},
{"name": "Worker role", "form": "~/projects/my-skills/worker/SKILL.md", "what": "Opens the worker role's skill."},
{"name": "Supervisor role", "form": "~/projects/my-skills/supervisor/SKILL.md", "what": "Opens the supervisor role's skill."},
{"name": "Admin role", "form": "~/projects/my-skills/admin/SKILL.md", "what": "Opens the admin role's skill."},
{"name": "QA agent role", "form": "~/projects/my-skills/qa-agent/SKILL.md", "what": "Opens the qa-agent role's skill; no team file starts it yet."},
{"name": "Claude personas", "form": "~/projects/my-skills/agents/<id>/claude.md", "what": "Opens a role's Claude persona, such as worker or supervisor."},
{"name": "Team handoff rules", "form": "~/projects/my-skills/coordinated-agentic-session/references/handoff.md", "what": "Opens the rules for how team members talk to each other."},
{"name": "QA agent notes", "form": "~/projects/workstation/docs/roles/qa-agent.md", "what": "Opens the qa-agent role notes kept in this repo."},
{"name": "Supervision backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "Opens the supervision backlog, which lives outside this repo."},
{"name": "Data repo", "form": "~/projects/data/", "what": "Opens the data repo: cases, rule proposals, verdicts and troubleshooting."},
{"name": "Answer sync", "form": "~/projects/data/bin/sync", "what": "Runs the answer sync; a timer runs it every 5 minutes."}
]},
{"path": ["agents", "assistants"], "sentence": "Claude and Codex global instructions, settings, hooks, plugins and tools on this setup.", "rows": [
{"name": "Global rules", "form": "~/projects/workstation/claude/CLAUDE.md", "what": "Opens the global rules: browser automation, communication, research and presenting work."},
{"name": "Shorter agent notes", "form": "~/projects/workstation/claude/AGENTS.md", "what": "Opens the shorter global agent notes."},
{"name": "Claude settings", "form": "~/projects/workstation/claude/settings.json", "what": "Opens Claude Code's settings, which init-windows deploys to Windows."},
{"name": "Codex config", "form": "~/projects/workstation/codex/config.toml", "what": "Opens the Codex CLI config, which init-windows deploys to Windows."},
{"name": "Linux instruction mirror", "form": "~/projects/workstation/claude/linux-global/", "what": "Opens the mirror of this machine's installed instruction files."},
{"name": "Hook scripts", "form": "~/projects/workstation/claude/hooks/", "what": "Opens the hook scripts Claude runs at session start and on tool use."},
{"name": "Core rules checks", "form": "~/projects/workstation/claude/hooks/test_core_rules.sh", "what": "Runs the checks for the core-rules hook."},
{"name": "Session types", "form": "~/projects/workstation/claude/session-types/", "what": "Opens the session-types folder: the SessionStart hook and the main-session wrapper."},
{"name": "Usage guard", "form": "~/projects/workstation/claude/usage-guard/", "what": "Opens the usage guard: the claude wrapper that sits ahead of the native claude."},
{"name": "Usage guard install", "form": "~/projects/workstation/claude/usage-guard/install.sh", "what": "Runs the installer that puts the claude wrapper on the PATH."},
{"name": "Team park", "form": "~/.local/bin/team-park", "what": "Runs team-park, the tool from claude/team-park, which its README describes."},
{"name": "Review pane plugin", "form": "~/projects/workstation/claude/mods/review-pane/", "what": "Opens the review pane plugin for Claude Code."},
{"name": "Changelog pane plugin", "form": "~/projects/workstation/claude/mods/changelog-pane/", "what": "Opens the changelog pane plugin for Claude Code."},
{"name": "Team board plugin", "form": "~/projects/workstation/claude/mods/team-board/", "what": "Opens the team board plugin for Claude Code."},
{"name": "Scratchpad plugin", "form": "~/projects/workstation/claude/mods/scratchpad-playground/", "what": "Opens the scratchpad plugin for Claude Code."},
{"name": "Communication notes", "form": "~/projects/workstation/claude/communication-framework.md", "what": "Opens the communication design notes, a draft that nothing enforces yet."}
]},
{"path": ["agents", "hermes"], "sentence": "The Hermes agent on this machine: its launcher, configuration and restore.", "rows": [
{"name": "Hermes launcher", "form": "~/.local/bin/hermes", "what": "Runs the Hermes agent launcher."},
{"name": "Hermes guide", "form": "~/projects/workstation/hermes/README.md", "what": "Opens the Hermes guide: install, current configuration and what is not backed up."},
{"name": "Restore runbook", "form": "~/projects/workstation/hermes/RESTORE.md", "what": "Opens the runbook for restoring Hermes."},
{"name": "Default profile example", "form": "~/projects/workstation/hermes/default.config.example.yaml", "what": "Opens the secret-free example settings for the default profile."},
{"name": "Jobs profile example", "form": "~/projects/workstation/hermes/jobs.config.example.yaml", "what": "Opens the secret-free example settings for the jobs profile."},
{"name": "Backup record", "form": "~/projects/workstation/hermes/BACKUP-2026-10-02.md", "what": "Opens the record of the 2026-10-02 backup."}
]},
{"path": ["browser"], "sentence": "The browser: the browser command, Chrome, the Codex bridge and the smoke-test tool.", "rows": [
{"name": "Browser command", "form": "browser", "what": "Runs browser steps, given as a JSON list, against one Chrome window that stays open between calls."},
{"name": "Browser status", "form": "browser status", "what": "Prints whether the background server and Chrome are up."},
{"name": "Browser close", "form": "browser close", "what": "Closes Chrome and stops the background server."},
{"name": "Recording proof", "form": "~/projects/workstation/browser/README.md#recording-proof", "what": "Opens the recordStart and recordStop steps, the one supported way to record a tab."},
{"name": "Browser guide", "form": "~/projects/workstation/browser/README.md", "what": "Opens the browser guide: every action, viewport preset, network capture and login gotcha."},
{"name": "Start Chrome", "form": "~/projects/workstation/chrome/chrome.sh", "what": "Runs Chrome with the recording flag, the only way to start Chrome on this machine."},
{"name": "Chrome setup", "form": "~/projects/workstation/chrome/install.sh", "what": "Runs the one-time setup that points google-chrome at chrome.sh."},
{"name": "Chrome flags", "form": "~/projects/workstation/chrome/flags", "what": "Opens the flag list that every Chrome start reads; edit this one list only."},
{"name": "Chrome guide", "form": "~/projects/workstation/chrome/README.md", "what": "Opens the Chrome guide: why it starts this way and its limits."},
{"name": "Codex Chrome bridge", "form": "~/projects/workstation/codex/chrome-bridge/install.sh", "what": "Runs the installer that keeps Codex's Chrome plugin link and patch in place."},
{"name": "Codex Chrome path", "form": "~/projects/workstation/codex/browser/README.md", "what": "Opens the guide to Codex's direct Chrome command path and its live check."},
{"name": "Smoke-test tool", "form": "jev-browser-test", "what": "Runs a goal in a browser and reports only the text and URL you asked for."},
{"name": "Smoke-test install", "form": "~/projects/workstation/jev-browser-test/install.sh", "what": "Runs the installer, which pins the upstream revision and places the CLI in ~/.local/bin."},
{"name": "Smoke-test guide", "form": "~/projects/workstation/jev-browser-test/README.md", "what": "Opens the smoke-test guide: the privacy boundary, exit codes and the Jev loop."},
{"name": "Smoke-test keys", "form": "~/.config/jev-browser-test/env", "what": "Opens the private env file for the smoke test's keys, which stays out of git."}
]},
{"path": ["machine"], "sentence": "Power, lid, network, monitor and repair scripts for this Linux machine.", "rows": [
{"name": "Power saver", "form": "~/projects/workstation/cpu-min-power.sh", "what": "Runs the power-saver profile: turbo off and CPU capped at 8%; asks for sudo."},
{"name": "Balanced power", "form": "~/projects/workstation/cpu-normal-power.sh", "what": "Runs the balanced profile: turbo on and the CPU cap back at 100%."},
{"name": "Keep running with lid closed", "form": "~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.sh", "what": "Runs the change that makes closing the lid do nothing; it applies after a reboot."},
{"name": "Restore lid behavior", "form": "~/projects/workstation/laptop-utilities/restore-default-lid-behavior.sh", "what": "Runs the removal of that lid change; it applies after a reboot."},
{"name": "HDMI monitor fix", "form": "~/projects/workstation/fix_old_monitor_hdmi.sh", "what": "Runs xrandr to set the external output's mode and refresh rate."},
{"name": "Internet recovery", "form": "~/projects/workstation/linux-internet-recovery.sh", "what": "Runs the DNS and network reset; it re-runs itself with sudo."},
{"name": "Tailscale remote terminal", "form": "~/projects/workstation/recover-tailscale-remote-terminal.sh", "what": "Runs the Tailscale repair and checks the remote terminal on port 3500."},
{"name": "Supabase keepalive", "form": "~/projects/workstation/supabase-keepalive/install.sh", "what": "Runs the installer for the Supabase keepalive timer."},
{"name": "Keyboard repair", "form": "fix-keyboard", "what": "Runs the keyboard repair helper from zsh.d/utils.zsh."},
{"name": "Mouse repair", "form": "fix-mouse", "what": "Runs the mouse repair helper from zsh.d/utils.zsh."},
{"name": "Disk repair", "form": "fix-disk", "what": "Runs the disk repair helper from zsh.d/utils.zsh."},
{"name": "WhatsApp repair", "form": "fix-whatsapp", "what": "Runs the WhatsApp repair helper from zsh.d/utils.zsh."}
]},
{"path": ["windows"], "sentence": "The Windows PC: its setup, skill sync, work repos and mirrored desktop files.", "rows": [
{"name": "Setup", "form": "workstation windows setup", "what": "Opens the setup screen: install, checks, roll back, and the manifests."},
{"name": "Skill sync", "form": "workstation windows sync", "what": "Opens the sync screen: how the PC keeps its skills in step with my-skills."},
{"name": "Clone work repos", "form": "~/projects/workstation/repos/Clone-BetecRepos.ps1", "what": "Runs the clone of each missing Betec work repo; it is safe to run again."},
{"name": "Desktop mirror", "form": "~/projects/workstation/claude/windows-global/", "what": "Opens the mirror of the Windows desktop's installed CLAUDE.md and docs."},
{"name": "Desktop backup", "form": "~/projects/workstation/claude/backups/desktop-v2-2026/", "what": "Opens the portable snapshot of the Windows desktop's instruction package."}
]},
{"path": ["windows", "setup"], "sentence": "Setting up the Windows PC: install, checks, rollback, the manifests and the sign-ins to redo.", "rows": [
{"name": "Install", "form": "~/projects/workstation/init-windows/Start-Install.cmd", "what": "Runs the one-command install of programs, Node, VS Code, Git config and user scripts."},
{"name": "Smoke test", "form": "~/projects/workstation/init-windows/Smoke-Test-Windows.ps1", "what": "Runs the smoke test of the Windows setup."},
{"name": "Verify", "form": "~/projects/workstation/init-windows/Verify-Windows.ps1", "what": "Runs the checks on the installed setup."},
{"name": "Export", "form": "~/projects/workstation/init-windows/Export-Windows.ps1", "what": "Runs the export that captures this machine into the manifests."},
{"name": "Roll back", "form": "~/projects/workstation/init-windows/Remove-WindowsPack.ps1", "what": "Runs the rollback of what the install added."},
{"name": "Manifests", "form": "~/projects/workstation/init-windows/manifests/", "what": "Opens the exact manifests: programs, Node versions, VS Code extensions and managed files."},
{"name": "User scripts", "form": "~/projects/workstation/init-windows/user-scripts/", "what": "Opens the scripts copied into the PC's Scripts folder."},
{"name": "Sign-ins to redo", "form": "~/projects/workstation/init-windows/secrets-checklist.md", "what": "Opens the list of sign-ins you redo by hand after an install."},
{"name": "Setup guide", "form": "~/projects/workstation/init-windows/README.md", "what": "Opens the full guide to the Windows setup."}
]},
{"path": ["windows", "sync"], "sentence": "How the Windows PC keeps its skills in step with my-skills.", "rows": [
{"name": "Sync run", "form": "~/projects/workstation/skills-sync-windows/Sync-Skills.ps1", "what": "Runs the protected skill sync; GitHub starts it on each trusted push to master."},
{"name": "Sync tests", "form": "~/projects/workstation/skills-sync-windows/Test-Sync.ps1", "what": "Runs the skill sync tests."},
{"name": "Account check", "form": "~/projects/workstation/skills-sync-windows/Test-Account.ps1", "what": "Runs the check of the runner account's rights."},
{"name": "Last sync", "form": "C:\\ProgramData\\MySkillsSync\\state\\last-success.json", "what": "Opens the record of the latest successful sync."},
{"name": "Verification", "form": "~/projects/workstation/skills-sync-windows/verification.md", "what": "Opens the record of how the sync was verified."},
{"name": "Sync guide", "form": "~/projects/workstation/skills-sync-windows/README.md", "what": "Opens the sync guide: the runner, its install and who can change what."}
]},
{"path": ["sharing"], "sentence": "What is shared between this laptop and the Windows PC: mouse, keyboard, audio and clipboard.", "rows": [
{"name": "Mouse and keyboard", "form": "workstation sharing deskflow", "what": "Opens the Deskflow screen: the shared mouse and keyboard, its service, settings and recovery."},
{"name": "Audio", "form": "workstation sharing audio", "what": "Opens the audio screen: sending this laptop's audio to the Windows PC."},
{"name": "Clipboard", "form": "workstation sharing clipboard", "what": "Opens the shared clipboard screen: the clipstack server, watcher and picker."},
{"name": "Lan Mouse (retired)", "form": "~/projects/workstation/lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide, kept for rollback."}
]},
{"path": ["sharing", "deskflow"], "sentence": "The Deskflow shared mouse and keyboard: its guide, service, settings and notes.", "rows": [
{"name": "Deskflow guide", "form": "~/projects/workstation/deskflow/README.md", "what": "Opens the Deskflow guide: everyday use and recovery."},
{"name": "Deskflow server", "form": "~/.config/systemd/user/deskflow.service", "what": "Starts the Deskflow server with the graphical session; it is the only server."},
{"name": "Linux settings", "form": "~/.config/Deskflow/Deskflow.conf", "what": "Opens the Linux Deskflow settings copied from deskflow/linux.conf."},
{"name": "Resume shared input", "form": "resume-kvm", "what": "Runs Deskflow again and asks for input capture after a Cancel."},
{"name": "USB mouse notes", "form": "~/projects/workstation/deskflow/usb-mouse/README.md", "what": "Opens the USB mouse notes: how the keyboard follows the mouse and how to turn USB sharing back on."},
{"name": "Network audit", "form": "~/projects/workstation/deskflow/NETWORK-AUDIT.md", "what": "Opens the network audit of Deskflow."},
{"name": "Firewall lockdown", "form": "~/projects/workstation/deskflow/deskflow-lockdown.nft", "what": "Opens the nftables lockdown rules for Deskflow."}
]},
{"path": ["sharing", "audio"], "sentence": "Sending this laptop's audio to the Windows PC over Tailscale, and taking it back.", "rows": [
{"name": "Start audio", "form": "audio-start", "what": "Starts sending all Linux audio to the Windows PC; pausing restores the speakers."},
{"name": "Pause audio", "form": "audio-pause", "what": "Pauses the sharing and restores the speakers."},
{"name": "Audio status", "form": "audio-share status", "what": "Prints whether audio is going to Windows."},
{"name": "Audio share entry", "form": "~/projects/workstation/README.md (entry dated 2026-10-23)", "what": "Opens the README entry that describes the audio share."}
]},
{"path": ["sharing", "clipboard"], "sentence": "The shared clipboard, clipstack: its picker, server, watcher and Windows side.", "rows": [
{"name": "Clipboard picker", "form": "~/projects/workstation/clipstack/picker.py", "what": "Runs the picker that chooses from the shared clipboard."},
{"name": "Clipstack server", "form": "~/projects/workstation/clipstack/units/clipstack-server.service", "what": "Starts the clipstack server with the user session."},
{"name": "Clipstack watcher", "form": "~/projects/workstation/clipstack/units/clipstack-watcher.service", "what": "Starts the watcher that follows what is copied."},
{"name": "Clipstack install", "form": "~/projects/workstation/clipstack/install.sh", "what": "Runs the install of the Linux side."},
{"name": "Windows side", "form": "~/projects/workstation/clipstack/windows/clipstack.ahk", "what": "Runs the Windows side of the shared clipboard, an AutoHotkey script."},
{"name": "Windows side intent", "form": "~/projects/workstation/clipstack/windows/INTENT.md", "what": "Opens the Windows side's intent and rules."}
]},
{"path": ["shell"], "sentence": "The shell: zsh helpers, git, OpenCode profiles and API keys.", "rows": [
{"name": "Helpers", "form": "workstation shell helpers", "what": "Opens the helpers screen: each zsh.d file and what it adds to the shell."},
{"name": "Git", "form": "workstation shell git", "what": "Opens the git screen: git config, the checkout guard and the hooks."},
{"name": "OpenCode profiles", "form": "workstation shell opencode", "what": "Opens the OpenCode screen: the commands that run and switch each profile."}
]},
{"path": ["shell", "helpers"], "sentence": "The zsh helpers in zsh.d, one file per topic, each sourced from ~/.zshrc.", "rows": [
{"name": "Infra helpers", "form": "~/projects/workstation/zsh.d/infra.zsh", "what": "Opens the file: Docker and Compose, Prisma, Postgres, nginx and VPN shortcuts."},
{"name": "Utilities", "form": "~/projects/workstation/zsh.d/utils.zsh", "what": "Opens the file: terminal helpers, IP aliases, lazy nvm and node, Android, Java and Bun setup, and the fix-* repairs."},
{"name": "API keys", "form": "~/projects/workstation/zsh.d/api-keys.zsh", "what": "Opens the file that exports the general-use API keys from ~/.config/api-keys/env."},
{"name": "Edit API keys", "form": "api-keys-edit", "what": "Opens ~/.config/api-keys/env in the editor; the file never goes to git."},
{"name": "Review open", "form": "~/projects/workstation/zsh.d/review-open.zsh", "what": "Opens the file that defines review-open, also installed for bash and agents."},
{"name": "Rules command", "form": "~/projects/workstation/zsh.d/rules.zsh", "what": "Opens the file that defines the rules command."},
{"name": "Dashboard path warning", "form": "~/projects/workstation/zsh.d/dash-path-warn.zsh", "what": "Opens the file with the dashboard path warning; its purpose is taken from the name alone."},
{"name": "Workstation command", "form": "~/projects/workstation/zsh.d/workstation.zsh", "what": "Opens the file that defines workstation, ws and setup, the commands for this map."}
]},
{"path": ["shell", "git"], "sentence": "Git on this machine: its config, the checkout guard and the hooks that run in every repo.", "rows": [
{"name": "Git config", "form": "~/projects/workstation/.gitconfig", "what": "Opens the repo copy of ~/.gitconfig: identity, LFS, credential helper and hooks path."},
{"name": "Checkout guard", "form": "~/projects/workstation/zsh.d/git-safety.zsh", "what": "Opens the file that makes git checkout list the files and ask [y/N] before discarding changes."},
{"name": "Git hooks", "form": "~/projects/workstation/git-hooks/", "what": "Opens the Lefthook hooks that run in every repo, with the push and commit gates."},
{"name": "Scenario gate", "form": "~/projects/workstation/git-hooks/scenario-gate.py", "what": "Opens the scenario gate script the git hooks use."}
]},
{"path": ["shell", "opencode"], "sentence": "OpenCode profiles: the files each profile loads, and the commands that run and switch them.", "rows": [
{"name": "OpenCode", "form": "opencode (also oc)", "what": "Runs OpenCode with the current profile."},
{"name": "Current profile", "form": "opencode-profile", "what": "Names the current profile."},
{"name": "Profile list", "form": "opencode-profiles", "what": "Prints what each profile loads."},
{"name": "Switch profile", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "Profile login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "Profile files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "Edit profile file", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files in the editor."},
{"name": "OpenCode help", "form": "opencode help (also oc help)", "what": "Prints every profile's files, one column each, and the commands."},
{"name": "Profiles tool", "form": "~/projects/workstation/opencode-profiles/profiles.py", "what": "Runs the profiles tool behind these commands."},
{"name": "Experimental profile", "form": "~/projects/workstation/opencode-profiles/private-leb-experimental/", "what": "Opens the files of the experimental profile."},
{"name": "Profile tests", "form": "~/projects/workstation/opencode-profiles/test_profiles.py", "what": "Runs the profile tests."}
]},
{"path": ["documents"], "sentence": "Documents: CVs, plans, case studies, item lists, the repo guide and the project's intent.", "rows": [
{"name": "CVs", "form": "workstation documents cvs", "what": "Opens the CVs screen: the three CVs as PDFs, their sources and dated versions."},
{"name": "Plans and design", "form": "workstation documents plans", "what": "Opens the plans screen: dated plans, design pitches, flow cards, research and changelog."},
{"name": "Cases and incidents", "form": "workstation documents cases", "what": "Opens the cases screen: case studies and incident records, one folder or file each."},
{"name": "Urgent items", "form": "~/projects/workstation/docs/items/urgent.item.md", "what": "Opens the urgent items."},
{"name": "Planned items", "form": "~/projects/workstation/docs/items/planned.item.md", "what": "Opens the planned items."},
{"name": "Work items", "form": "~/projects/workstation/docs/items/work.item.md", "what": "Opens the work items."},
{"name": "Playbook", "form": "~/projects/workstation/docs/playbooks/talk-while-team-builds.md", "what": "Opens the playbook for talking while a team builds."},
{"name": "Repo guide", "form": "~/projects/workstation/README.md", "what": "Opens the repo guide: where each file lands on the machine."},
{"name": "Project intent", "form": "~/projects/workstation/.idd/project.intent.md", "what": "Opens the project's intent."},
{"name": "Slide images", "form": "~/projects/workstation/copy/", "what": "Opens the three slide images: today, subsystems and reviews."}
]},
{"path": ["documents", "cvs"], "sentence": "The three CVs: PDFs to send, LaTeX sources to edit, and their dated versions.", "rows": [
{"name": "Full Stack Developer CV", "form": "~/projects/workstation/cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV as a PDF."},
{"name": "AI Full Stack Engineer CV", "form": "~/projects/workstation/cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV as a PDF."},
{"name": "AI Integrations CV", "form": "~/projects/workstation/cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV as a PDF."},
{"name": "LaTeX sources", "form": "~/projects/workstation/cv/*.tex", "what": "Opens the .tex source of a CV, the file you edit."},
{"name": "Rebuild one CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex", "what": "Runs pdflatex to rebuild one CV's PDF from its source."},
{"name": "Plain-text versions", "form": "~/projects/workstation/cv/text/build-full.sh", "what": "Runs the build of the plain-text CV versions."},
{"name": "Dated versions", "form": "~/projects/workstation/cv/versions/", "what": "Opens the dated CV versions, 2026-10-04 and its v2."},
{"name": "CV guide", "form": "~/projects/workstation/cv/README.md", "what": "Opens the CV guide: sources and the rebuild steps."},
{"name": "CV workflow", "form": "~/projects/workstation/cv/WORKFLOW.md", "what": "Opens the CV workflow notes."}
]},
{"path": ["documents", "plans"], "sentence": "Dated plans, design pitches, flow cards, research and changelog entries, one folder per piece of work.", "rows": [
{"name": "Plans", "form": "~/projects/workstation/docs/plans/", "what": "Opens the plans folder, with one dated plan per piece of work."},
{"name": "Design", "form": "~/projects/workstation/docs/design/", "what": "Opens the design folders: pitches and recommendations."},
{"name": "Flow cards", "form": "~/projects/workstation/docs/flows/", "what": "Opens the flow cards: how each screen's flow was designed."},
{"name": "Research", "form": "~/projects/workstation/docs/research/", "what": "Opens the research notes, one dated folder each."},
{"name": "Functional research", "form": "~/projects/workstation/docs/functional-research/2026-10-21/", "what": "Opens the comparison of agent frameworks, such as CrewAI and Agno."},
{"name": "Changelog", "form": "~/projects/workstation/docs/changelog/", "what": "Opens the dated changelog entries."}
]},
{"path": ["documents", "cases"], "sentence": "Case studies and incidents: human-reviewed experiments and machine incidents, one folder or file each.", "rows": [
{"name": "Codebot return case", "form": "~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "Opens the case of one design request run with and without the conceptual-modeling skill."},
{"name": "Signal garden case", "form": "~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "Opens the documentation exhibit that separates Blume's explanation from Astryx's live interface."},
{"name": "Kernel browser results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the Kernel cloud browser results, which live outside this repo."},
{"name": "Lid-closed incident", "form": "~/projects/workstation/reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "Opens the incident record: CodeBot kept serving with the lid closed."},
{"name": "Incident index", "form": "~/projects/workstation/reference/README.md", "what": "Opens the index of workstation reference cases."}
]}
],
"questions": [
"Facade name: keep workstation and ws, and drop setup if whence finds a clash? Recommendation: yes.",
"Kept skills: the skill tree has 22 folders and the README table lists 12. Keep all 22 on one screen, and split into general and SolaraAI/Supabase only if it grows? Recommendation: yes.",
"Lan Mouse (retired): keep it as the last row under Sharing, marked retired, or hide it? Recommendation: keep it for rollback.",
"Seven top groups: keep Sharing with Windows as its own group, or fold it into Machine? Recommendation: keep it separate.",
"dash-path-warn.zsh: what does this file do? I wrote its row from the name alone.",
"Please confirm these exist before the CLI is built: zsh.d/workstation.zsh, workstation-cli/, audio-share/, zsh.d/audio-share.zsh, Start-Install.cmd, init-windows/inventory.md, and the resume-kvm command. The rows stay in the map until then."
]}
```

screen-decomposition, final · run 2 exit=0 seconds=213 · prompt

P1 Recall: 0.757P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.319
As terminal help
The workstation's groups, one per kind of job.
Shellworkstation shellShows the shell screen: zsh helpers, git config and hooks, and OpenCode.
Machineworkstation machineShows the machine screen: power, display, network, Deskflow and audio scripts.
AI assistantworkstation assistantShows the assistant screen: rules, settings, skills, agents and hooks.
Browserworkstation browserShows the browser screen: the browser command, Chrome and smoke QA.
Windowsworkstation windowsShows the Windows screen: the bootstrap, agent files and skill sync.
Documentsworkstation documentsShows the documents screen: CVs, case studies and reference cases.
Small toolsworkstation toolsShows the tools screen: the dashboard, clipstack and Hermes.
Docs and conventionsworkstation docsShows the docs screen: where things land, conventions, and the folders of plans, designs and research.
shell
The zsh helpers, git setup and OpenCode commands on this Linux machine.
Git config~/.gitconfigOpens the git config: author identity, LFS, the credential helper and the hooks path.
Git hooks~/.git-hooks/Opens the Lefthook hook shims that run in every repo.
Git checkout guardgit checkout (wrapper in ~/.zsh.d/git-safety.zsh)Lists the changed files and asks [y/N] before git checkout discards unstaged changes.
OpenCodeworkstation shell opencodeShows the OpenCode screen: the profile commands and the profile files.
Terminal and tool helpers~/.zsh.d/utils.zshRuns set-title and killport, and loads nvm, node and npm on first use.
Repair helpers~/.zsh.d/utils.zshRuns one repair: fix-keyboard, fix-mouse, fix-disk or fix-whatsapp.
API keys~/.config/api-keys/envExports the general-use API keys; api-keys-edit opens that file.
Infra shortcuts~/.zsh.d/infra.zshRuns the Docker/Compose, Prisma, Postgres, nginx and VPN shortcuts.
Review openreview-open (~/.local/bin/review-open)Opens a file for review; the details are not in the dump, so confirm them.
shell › opencode
The OpenCode profile commands and the profile files they use.
opencode and ocopencode, ocRuns OpenCode with the current profile.
Name the profileopencode-profile <name>Names the current profile.
Profile listopencode-profilesLists what each profile loads.
Switch profileopencode-switch <name>Switches every shell's new runs to the named profile.
Profile loginopencode-loginSigns a profile's Claude Code in.
Profile filesopencode-filesLists the current profile's files.
Edit a profile fileopencode-edit <file>Opens one of the current profile's files for editing.
Experimental profile folderopencode-profiles/private-leb-experimental/Opens the files of the experimental profile: CLAUDE.md, Claude settings and opencode.json.
machine
The scripts for power, display, network, Deskflow and audio on this Linux machine.
Powerworkstation machine powerShows the power screen: the CPU profile and lid scripts.
HDMI monitor modefix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output (default 1920x1080 at 59.88).
Internet recoverylinux-internet-recovery.shPoints DNS at systemd-resolved, restarts NetworkManager and cycles networking; re-runs itself with sudo.
Tailscale remote terminal recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled and starts the remote-terminal service, then checks port 3500.
Deskflowworkstation machine deskflowShows the Deskflow screen: the shared mouse and keyboard with Windows, its service and recovery.
Audio sharezsh.d/audio-share.zsh (audio-start, audio-pause)Sends all Linux audio to Windows over Tailscale (audio-start), and restores the speakers (audio-pause).
Supabase keepalivesupabase-keepalive/supabase-keepalive.timerRuns the Supabase keepalive on a systemd timer.
machine › power
The CPU profile and laptop lid scripts.
Power savercpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8% of max; asks for sudo.
Balancedcpu-normal-power.shSets the balanced profile, turns turbo on and removes the cap.
Keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shWrites a logind drop-in so closing the lid does nothing; applies after a reboot.
Restore default lid behaviorlaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in; applies after a reboot.
machine › deskflow
Deskflow: the shared mouse and keyboard with Windows, its settings, service and recovery.
Deskflow guidedeskflow/README.mdOpens the guide: everyday use, starting, and recovery.
Deskflow service~/.config/systemd/user/deskflow.serviceRuns the Deskflow server with the graphical session.
Linux settings~/.config/Deskflow/Deskflow.conf (from deskflow/linux.conf)Opens the Linux Deskflow settings.
Windows settingsdeskflow/windows.conf, deskflow/windows-service.confOpens the Windows client and service settings, which are copied separately.
Lockdown rulesdeskflow/deskflow-lockdown.nftOpens the nftables rules that lock Deskflow's network use.
Network auditdeskflow/NETWORK-AUDIT.mdOpens the Deskflow network audit.
Resume Deskflowresume-kvm (named in the guide, not in the dump)Starts Deskflow again and asks for input capture.
USB mouse sharingdeskflow/usb-mouse/README.mdOpens the notes on forwarding the Windows USB mouse, which has been off since 2026-10-20.
assistant
The AI assistant setup: rules, settings, skills, agents and hooks.
Global rulesclaude/linux-global/CLAUDE.mdOpens the global rules every Linux Claude session reads.
Global agent notesclaude/linux-global/AGENTS.mdOpens the shorter global agent notes.
Instruction backupsclaude/backups/Opens the saved copies of the global instructions; none loads on its own.
Communication frameworkclaude/communication-framework.mdOpens the draft design notes, which are not enforced yet.
Claude settings~/.claude/settings.jsonOpens Claude Code's settings (machine-local, not in Git).
Codex config~/.codex/config.tomlOpens the Codex CLI config (machine-local).
Rulesrules (~/.local/bin/rules)Prints the rules, for one folder if one is given.
Rules sourceworkboard/rules.yamlOpens the rules file, which changes only by the user or an accepted rule proposal.
Claude hooks~/.claude/hooks/Opens the hook scripts: rules at session start, server guard, history, proof reminder and team activity.
Skillsworkstation assistant skillsShows the skills screen: the global skills, kept backups and the shortlist.
Agentsworkstation assistant agentsShows the agents screen: checks, the sandbox, and where roles and teams are defined.
Claude commandclaude (~/bin/claude)Runs claude through the usage guard, ahead of the native install.
Usage guard guideclaude/usage-guard/README.mdOpens the usage guard's guide.
Main sessionclaude --main -c, claude --main -rContinues the main session (-c), or resumes one (-r).
Claude pluginsclaude/mods/Opens the Claude Code plugins kept here: changelog-pane, review-pane, scratchpad-playground and team-board.
Team parkteam-park (~/.local/bin/team-park)Runs team-park; its purpose is a question in the plan.
assistant › skills
The skills: the global repo, the kept backups and the shortlist.
Global skills~/projects/my-skillsOpens the global skills repo, which install.sh links into the skill folders of Claude, Codex and OpenCode.
Kept skillsworkstation assistant skills keptShows the kept skill backups, one per folder.
Skill shortlistclaude/skills-shortlist.mdOpens the skills researched on skills.sh and which of them are installed.
assistant › skills › kept
The skill backups kept in this repo; copy in the ones you want installed.
tech-ledgerclaude/skills/tech-ledger/SKILL.mdOpens the skill that reads and writes the betec Tech Ledger.
api-key-creationclaude/skills/api-key-creation/SKILL.mdOpens the skill for getting a missing API key with browser tools.
clone-websiteclaude/skills/clone-website/SKILL.mdOpens the skill that clones websites with parallel builder agents.
contextual-value-product-thinkingclaude/skills/contextual-value-product-thinking/SKILL.mdOpens the skill that analyzes products through contextual human values.
elad12390--web-research-assistantclaude/skills/elad12390--web-research-assistant/SKILL.mdOpens the web research MCP skill; its setup notes are in SETUP-NOTES.md.
epic-fanout-planningclaude/skills/epic-fanout-planning/SKILL.mdOpens the 10-step pattern for QA-gap epics with parallel fan-out.
impeccableclaude/skills/impeccable/SKILL.mdOpens the frontend design skill: shape, critique, audit and polish.
iterative-action-reviewclaude/skills/iterative-action-review/SKILL.mdOpens the skill for reviewing a completed action as one iteration.
lab-experimentclaude/skills/lab-experiment/SKILL.mdOpens the skill for running an experiment in ai-lab.
mentor-modeclaude/skills/mentor-mode/SKILL.mdOpens the mentor-mode skill and its teaching runtime.
post-feature-cleanupclaude/skills/post-feature-cleanup/SKILL.mdOpens the pass after writing code: UI defects, leftovers and repo hygiene.
powershell-launchingclaude/skills/powershell-launching/SKILL.mdOpens the skill for launching PowerShell or a new terminal on Windows.
reboot-resumeclaude/skills/reboot-resume/SKILL.mdOpens the skill that keeps work across a reboot or a Claude Code restart.
resume-projectclaude/skills/resume-project/SKILL.mdOpens the resume-project skill and its CLI script.
solaraai-content-calendarclaude/skills/solaraai-content-calendar/SKILL.mdOpens the SolaraAI content calendar skill.
solaraai-deploymentclaude/skills/solaraai-deployment/SKILL.mdOpens the SolaraAI deploy flow skill.
solaraai-designclaude/skills/solaraai-design/SKILL.mdOpens the SolaraAI design system skill.
solaraai-formsclaude/skills/solaraai-forms/SKILL.mdOpens the SolaraAI form behavior skill.
supabaseclaude/skills/supabase/SKILL.mdOpens the Supabase skill: Auth, RLS, migrations, CLI and debugging.
supabase-postgres-best-practicesclaude/skills/supabase-postgres-best-practices/SKILL.mdOpens Supabase's Postgres performance rules.
tank--communication-engineeringclaude/skills/tank--communication-engineering/SKILL.mdOpens the skill that applies engineering discipline to what an agent says.
tank--skill-creatorclaude/skills/tank--skill-creator/SKILL.mdOpens the skill for creating new skills.
tech-cv-writerclaude/skills/tech-cv-writer/SKILL.mdOpens the CV writing skill and its ATS and LaTeX references.
assistant › agents
Checking and serving agents, and where roles and teams are defined.
Agent check~/projects/workstation/agent-framework/agent checkRefuses broken agent records and exits 1.
Agent list~/projects/workstation/agent-framework/agent listPrints the agents with their tier, model and number of tests.
Agent Sandboxagent serve, then http://127.0.0.1:8790Serves the Agent Sandbox page, where an agent's setup is changed and asked.
Agent records~/projects/my-skills/agents/<id>/agent.yamlOpens an agent's record: its situations, saved tests and role skill.
Roles~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.mdOpens a role's skill: worker, supervisor, admin or qa-agent.
Teams~/projects/my-skills/spawn-team/SKILL.mdOpens how a team starts (/spawn-team), with the team files in spawn-team/teams/.
browser
The browser command, Chrome and the smoke QA command.
Browser commandbrowser (browser/browser.sh)Runs browser steps in JSON on one Chrome window kept open; browser status and browser close check and stop it.
Browser guidebrowser/README.mdOpens the browser guide: actions, viewport presets and login gotchas.
Recording proofbrowser with recordStart and recordStopRecords a tab as proof of a feature; the one supported way to record.
Chromeworkstation browser chromeShows the Chrome screen: the one start path and its flags.
Codex browser pathcodex/browser/README.mdOpens the Codex direct Chrome command path and its live checks.
Codex Chrome bridgecodex/chrome-bridge/install.shInstalls the watcher that repairs the Chrome plugin's latest link, as a systemd timer on Linux.
Behavioral smoke QAjev-browser-test (~/.local/bin/jev-browser-test)Runs one browser goal and reports the text and URL assertions it was given; it is not a visual check.
Smoke QA guidejev-browser-test/README.mdOpens the smoke QA guide: install, config and exit codes.
browser › chrome
Chrome as this machine starts it: the one start path and its flags.
Chrome startchrome/chrome.sh (also google-chrome)Starts Chrome with the flags in chrome/flags; the only way to start it here.
Chrome flagschrome/flagsOpens the flags list that chrome.sh and the browser command both read.
Chrome guidechrome/README.mdOpens the Chrome guide: why the recording flag exists and its limits.
Chrome installchrome/install.shInstalls the launcher links and desktop entry; run once per machine and after a Chrome update.
windows
The Windows machine: bootstrap, agent files, skill sync and repo cloning.
Bootstrapworkstation windows bootstrapShows the bootstrap screen: install, check, roll back and the captured lists.
Windows agent filesclaude/CLAUDE.md, claude/AGENTS.md, claude/settings.json, codex/config.tomlOpens the agent files that init-windows deploys to the Windows user profile.
Windows global copyclaude/windows-global/Opens the mirror of the Windows CLAUDE.md and its four docs.
Skill syncskills-sync-windows/README.mdOpens the Windows skill sync guide; a runner updates the skill links on trusted pushes to master.
Clone work reposrepos/Clone-BetecRepos.ps1Clones the missing Betec repos into the standard layout; safe to re-run.
Usage guard on Windowsclaude/usage-guard/Install-Windows.cmdInstalls the usage guard on Windows.
Codex Chrome bridge on Windowscodex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls a Scheduled Task that repairs the Chrome plugin's latest link.
windows › bootstrap
Rebuilding the Windows setup: install, check, roll back and the captured lists.
Installinit-windows/Start-Install.cmdInstalls the exact programs, Node versions, VS Code, Git config and user scripts from the manifests.
Checkinit-windows/Smoke-Test-Windows.ps1, init-windows/Verify-Windows.ps1Checks the install against the manifests.
Roll backinit-windows/Remove-WindowsPack.ps1Rolls the install back.
Bootstrap guideinit-windows/README.mdOpens the full guide to the Windows install.
Inventoryinit-windows/inventory.mdOpens what the capture included.
Sign-ins checklistinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand.
Manifestsinit-windows/manifests/Opens the exact lists: programs, Node versions, VS Code extensions and managed files.
Install logsinit-windows/logs/Opens the install log and its error log.
User scriptsinit-windows/user-scripts/Opens the Windows user scripts that init-windows copies to the Scripts folder: touchpad fixes, hibernate and Mongo restore.
documents
The working documents: CVs, case studies and reference cases.
CVsworkstation documents cvShows the CV screen: the versions, their sources and how to rebuild them.
Case studiesworkstation documents case-studiesShows the case studies: archived, human-reviewed experiments.
Reference casesreference/README.mdOpens the incident list; the 2026-10-01 CodeBot lid-closed case is its one entry.
documents › cv
The CVs: versions, sources and how to rebuild them.
CV guidecv/README.mdOpens the CV guide: versions, sources and rebuild commands.
CV workflowcv/WORKFLOW.mdOpens how a CV is updated and committed.
Full Stack Developer CVcv/cv-full-stack.pdfOpens the Full Stack Developer CV as a PDF.
AI Full Stack Engineer CVcv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV as a PDF.
AI Integrations CVcv/cv-ai-integrations.pdfOpens the AI Integrations CV as a PDF.
Rebuild a CVpdflatex -interaction=nonstopmode -halt-on-error <name>.tex, run in cv/Rebuilds one CV's PDF from its LaTeX source.
Plain text versionscv/text/build-full.shBuilds the plain-text CV versions.
Dated versionscv/versions/Opens the CV versions kept by date, 2026-10-04 and its v2.
HTML designcv/design/build-design.pyBuilds the HTML design of the AI Full Stack CV.
documents › case-studies
The archived, human-reviewed case studies.
Codebot returncase-studies/conceptual-modeling/2026-09-15-codebot-return/Opens the case: the same design request with and without the conceptual-modeling skill.
Signal gardencase-studies/blume-astryx/2026-09-16-signal-garden/Opens the exhibit that separates durable explanation (Blume) from the live interface (Astryx).
Kernel cloud browsers results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the results of testing Kernel cloud browsers on 2026-10-08; the file is outside this repo.
tools
The small tools, each with its own folder.
Dashboardworkstation tools dashboardShows the dashboard screen: its server, the concepts version and their checks.
Clipstackworkstation tools clipstackShows the clipstack screen: its services, picker and Windows part.
Hermesworkstation tools hermesShows the Hermes screen: the agent, its config examples and restore notes.
tools › dashboard
The dashboard and its concepts version: servers and checks.
Dashboard serverpython3 ~/projects/workstation/dashboard/server.py (http://127.0.0.1:8780)Runs the dashboard on http://127.0.0.1:8780; nothing starts it for you.
Dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the dashboard's 199 checks against the real data and a real server.
Concepts serverpython3 ~/projects/workstation/dashboard-concepts/server.py (http://127.0.0.1:8781)Runs the concepts version on http://127.0.0.1:8781, to compare with the dashboard.
Dashboard guidedashboard/README.mdOpens the dashboard guide: tabs, writes and hot reload.
tools › clipstack
Clipstack: its services, picker and the Windows part.
Clipstack installclipstack/install.shInstalls the clipstack user services.
Clipstack serverclipstack/units/clipstack-server.serviceRuns the clipstack server (server.py) as a user service.
Clipstack watcherclipstack/units/clipstack-watcher.serviceRuns the clipstack watcher (watcher.py) as a user service.
Clipstack pickerclipstack/picker.pyOpens the clipstack picker.
Clipstack on Windowsclipstack/windows/Opens the Windows clipstack: its AutoHotkey script, install and verify scripts.
tools › hermes
Hermes: the agent, its config examples and restore notes.
Hermes agenthermes (~/.local/bin/hermes)Runs the Hermes agent from its checkout in ~/projects/hermes-agent.
Hermes guidehermes/README.mdOpens the install notes and current configuration.
Restore runbookhermes/RESTORE.mdOpens the steps to restore Hermes.
Config exampleshermes/default.config.example.yaml, hermes/jobs.config.example.yamlOpens the example settings, with no secrets, for the default and jobs profiles.
Backup notehermes/BACKUP-2026-10-02.mdOpens the note on the 2026-10-02 backup.
docs
Where things land, the conventions, and the repo's folders of plans, designs and research.
Where things landREADME.md#where-things-landOpens the table of where each repo file lands on this machine.
Conventions and gotchasREADME.md#conventions-and-gotchasOpens the rules for copies, machine paths and where new things go.
Credentials in zsh.dzsh.d/infra.zsh, zsh.d/utils.zshOpens the two files that embed a git credential, which the secrets checklist says to rotate.
Plansdocs/plans/Opens the dated plans, one folder per change.
Designdocs/design/Opens the design passes: pitches, research and recommendations.
Flowsdocs/flows/Opens the flow cards and data models behind the dashboards.
Researchdocs/research/Opens the research notes and check runs.
Itemsdocs/items/Opens the planned, urgent and work items.
Changelogdocs/changelog/Opens the dated changelog entries.
Intents and features.idd/ and .bdd/Opens the intents and behavior features for each module.
Questions
  • dash-path-warn.zsh: what does it do? It has no row until you say. Recommendation: give one line; if it is abandoned, keep it off the map.
  • team-park and clipstack: their READMEs are not in the dump, so their purposes come from file names. Recommendation: confirm one line each before building. team-park stays on the AI assistant screen either way.
  • The README names a setup command as well as workstation and ws. Keep it as a second facade name, or drop it? Recommendation: keep workstation and ws only, unless you use the other name.
  • docs/roles/drafts-2026-10-23/.old/ and docs/superpowers/plans/ are left off the map. Recommendation: keep them off; say so if you want them listed.
  • lan-mouse/ and codex/playwright-mcp/ are retired per the README and stay off the map. Recommendation: confirm.
  • Kept skills: should the list of 23 folders be generated from claude/skills/ at build time instead of typed in? Recommendation: generate it, so a new skill folder appears without a typed edit.
As phone screens

Home

The workstation's groups, one per kind of job.

ShellShows the shell screen: zsh helpers, git config and hooks, and OpenCode.
›
MachineShows the machine screen: power, display, network, Deskflow and audio scripts.
›
AI assistantShows the assistant screen: rules, settings, skills, agents and hooks.
›
BrowserShows the browser screen: the browser command, Chrome and smoke QA.
›
WindowsShows the Windows screen: the bootstrap, agent files and skill sync.
›
DocumentsShows the documents screen: CVs, case studies and reference cases.
›
Small toolsShows the tools screen: the dashboard, clipstack and Hermes.
›
Docs and conventionsShows the docs screen: where things land, conventions, and the folders of plans, designs and research.
›
‹ Home

shell

The zsh helpers, git setup and OpenCode commands on this Linux machine.

Git configOpens the git config: author identity, LFS, the credential helper and the hooks path.
›
Git hooksOpens the Lefthook hook shims that run in every repo.
›
Git checkout guardLists the changed files and asks [y/N] before git checkout discards unstaged changes.
›
OpenCodeShows the OpenCode screen: the profile commands and the profile files.
›
Terminal and tool helpersRuns set-title and killport, and loads nvm, node and npm on first use.
›
Repair helpersRuns one repair: fix-keyboard, fix-mouse, fix-disk or fix-whatsapp.
›
API keysExports the general-use API keys; api-keys-edit opens that file.
›
Infra shortcutsRuns the Docker/Compose, Prisma, Postgres, nginx and VPN shortcuts.
›
Review openOpens a file for review; the details are not in the dump, so confirm them.
›
‹ shell

opencode

The OpenCode profile commands and the profile files they use.

opencode and ocRuns OpenCode with the current profile.
›
Name the profileNames the current profile.
›
Profile listLists what each profile loads.
›
Switch profileSwitches every shell's new runs to the named profile.
›
Profile loginSigns a profile's Claude Code in.
›
Profile filesLists the current profile's files.
›
Edit a profile fileOpens one of the current profile's files for editing.
›
Experimental profile folderOpens the files of the experimental profile: CLAUDE.md, Claude settings and opencode.json.
›
‹ Home

machine

The scripts for power, display, network, Deskflow and audio on this Linux machine.

PowerShows the power screen: the CPU profile and lid scripts.
›
HDMI monitor modeSets the mode and refresh rate of the external HDMI or DP output (default 1920x1080 at 59.88).
›
Internet recoveryPoints DNS at systemd-resolved, restarts NetworkManager and cycles networking; re-runs itself with sudo.
›
Tailscale remote terminal recoveryRepairs DNS, restarts tailscaled and starts the remote-terminal service, then checks port 3500.
›
DeskflowShows the Deskflow screen: the shared mouse and keyboard with Windows, its service and recovery.
›
Audio shareSends all Linux audio to Windows over Tailscale (audio-start), and restores the speakers (audio-pause).
›
Supabase keepaliveRuns the Supabase keepalive on a systemd timer.
›
‹ machine

power

The CPU profile and laptop lid scripts.

Power saverSets the power-saver profile, turns turbo off and caps the CPU at 8% of max; asks for sudo.
›
BalancedSets the balanced profile, turns turbo on and removes the cap.
›
Keep running with lid closedWrites a logind drop-in so closing the lid does nothing; applies after a reboot.
›
Restore default lid behaviorRemoves that drop-in; applies after a reboot.
›
‹ machine

deskflow

Deskflow: the shared mouse and keyboard with Windows, its settings, service and recovery.

Deskflow guideOpens the guide: everyday use, starting, and recovery.
›
Deskflow serviceRuns the Deskflow server with the graphical session.
›
Linux settingsOpens the Linux Deskflow settings.
›
Windows settingsOpens the Windows client and service settings, which are copied separately.
›
Lockdown rulesOpens the nftables rules that lock Deskflow's network use.
›
Network auditOpens the Deskflow network audit.
›
Resume DeskflowStarts Deskflow again and asks for input capture.
›
USB mouse sharingOpens the notes on forwarding the Windows USB mouse, which has been off since 2026-10-20.
›
‹ Home

assistant

The AI assistant setup: rules, settings, skills, agents and hooks.

Global rulesOpens the global rules every Linux Claude session reads.
›
Global agent notesOpens the shorter global agent notes.
›
Instruction backupsOpens the saved copies of the global instructions; none loads on its own.
›
Communication frameworkOpens the draft design notes, which are not enforced yet.
›
Claude settingsOpens Claude Code's settings (machine-local, not in Git).
›
Codex configOpens the Codex CLI config (machine-local).
›
RulesPrints the rules, for one folder if one is given.
›
Rules sourceOpens the rules file, which changes only by the user or an accepted rule proposal.
›
Claude hooksOpens the hook scripts: rules at session start, server guard, history, proof reminder and team activity.
›
SkillsShows the skills screen: the global skills, kept backups and the shortlist.
›
AgentsShows the agents screen: checks, the sandbox, and where roles and teams are defined.
›
Claude commandRuns claude through the usage guard, ahead of the native install.
›
Usage guard guideOpens the usage guard's guide.
›
Main sessionContinues the main session (-c), or resumes one (-r).
›
Claude pluginsOpens the Claude Code plugins kept here: changelog-pane, review-pane, scratchpad-playground and team-board.
›
Team parkRuns team-park; its purpose is a question in the plan.
›
‹ assistant

skills

The skills: the global repo, the kept backups and the shortlist.

Global skillsOpens the global skills repo, which install.sh links into the skill folders of Claude, Codex and OpenCode.
›
Kept skillsShows the kept skill backups, one per folder.
›
Skill shortlistOpens the skills researched on skills.sh and which of them are installed.
›
‹ skills

kept

The skill backups kept in this repo; copy in the ones you want installed.

tech-ledgerOpens the skill that reads and writes the betec Tech Ledger.
›
api-key-creationOpens the skill for getting a missing API key with browser tools.
›
clone-websiteOpens the skill that clones websites with parallel builder agents.
›
contextual-value-product-thinkingOpens the skill that analyzes products through contextual human values.
›
elad12390--web-research-assistantOpens the web research MCP skill; its setup notes are in SETUP-NOTES.md.
›
epic-fanout-planningOpens the 10-step pattern for QA-gap epics with parallel fan-out.
›
impeccableOpens the frontend design skill: shape, critique, audit and polish.
›
iterative-action-reviewOpens the skill for reviewing a completed action as one iteration.
›
lab-experimentOpens the skill for running an experiment in ai-lab.
›
mentor-modeOpens the mentor-mode skill and its teaching runtime.
›
post-feature-cleanupOpens the pass after writing code: UI defects, leftovers and repo hygiene.
›
powershell-launchingOpens the skill for launching PowerShell or a new terminal on Windows.
›
reboot-resumeOpens the skill that keeps work across a reboot or a Claude Code restart.
›
resume-projectOpens the resume-project skill and its CLI script.
›
solaraai-content-calendarOpens the SolaraAI content calendar skill.
›
solaraai-deploymentOpens the SolaraAI deploy flow skill.
›
solaraai-designOpens the SolaraAI design system skill.
›
solaraai-formsOpens the SolaraAI form behavior skill.
›
supabaseOpens the Supabase skill: Auth, RLS, migrations, CLI and debugging.
›
supabase-postgres-best-practicesOpens Supabase's Postgres performance rules.
›
tank--communication-engineeringOpens the skill that applies engineering discipline to what an agent says.
›
tank--skill-creatorOpens the skill for creating new skills.
›
tech-cv-writerOpens the CV writing skill and its ATS and LaTeX references.
›
‹ assistant

agents

Checking and serving agents, and where roles and teams are defined.

Agent checkRefuses broken agent records and exits 1.
›
Agent listPrints the agents with their tier, model and number of tests.
›
Agent SandboxServes the Agent Sandbox page, where an agent's setup is changed and asked.
›
Agent recordsOpens an agent's record: its situations, saved tests and role skill.
›
RolesOpens a role's skill: worker, supervisor, admin or qa-agent.
›
TeamsOpens how a team starts (/spawn-team), with the team files in spawn-team/teams/.
›
‹ Home

browser

The browser command, Chrome and the smoke QA command.

Browser commandRuns browser steps in JSON on one Chrome window kept open; browser status and browser close check and stop it.
›
Browser guideOpens the browser guide: actions, viewport presets and login gotchas.
›
Recording proofRecords a tab as proof of a feature; the one supported way to record.
›
ChromeShows the Chrome screen: the one start path and its flags.
›
Codex browser pathOpens the Codex direct Chrome command path and its live checks.
›
Codex Chrome bridgeInstalls the watcher that repairs the Chrome plugin's latest link, as a systemd timer on Linux.
›
Behavioral smoke QARuns one browser goal and reports the text and URL assertions it was given; it is not a visual check.
›
Smoke QA guideOpens the smoke QA guide: install, config and exit codes.
›
‹ browser

chrome

Chrome as this machine starts it: the one start path and its flags.

Chrome startStarts Chrome with the flags in chrome/flags; the only way to start it here.
›
Chrome flagsOpens the flags list that chrome.sh and the browser command both read.
›
Chrome guideOpens the Chrome guide: why the recording flag exists and its limits.
›
Chrome installInstalls the launcher links and desktop entry; run once per machine and after a Chrome update.
›
‹ Home

windows

The Windows machine: bootstrap, agent files, skill sync and repo cloning.

BootstrapShows the bootstrap screen: install, check, roll back and the captured lists.
›
Windows agent filesOpens the agent files that init-windows deploys to the Windows user profile.
›
Windows global copyOpens the mirror of the Windows CLAUDE.md and its four docs.
›
Skill syncOpens the Windows skill sync guide; a runner updates the skill links on trusted pushes to master.
›
Clone work reposClones the missing Betec repos into the standard layout; safe to re-run.
›
Usage guard on WindowsInstalls the usage guard on Windows.
›
Codex Chrome bridge on WindowsInstalls a Scheduled Task that repairs the Chrome plugin's latest link.
›
‹ windows

bootstrap

Rebuilding the Windows setup: install, check, roll back and the captured lists.

InstallInstalls the exact programs, Node versions, VS Code, Git config and user scripts from the manifests.
›
CheckChecks the install against the manifests.
›
Roll backRolls the install back.
›
Bootstrap guideOpens the full guide to the Windows install.
›
InventoryOpens what the capture included.
›
Sign-ins checklistOpens the sign-ins to redo by hand.
›
ManifestsOpens the exact lists: programs, Node versions, VS Code extensions and managed files.
›
Install logsOpens the install log and its error log.
›
User scriptsOpens the Windows user scripts that init-windows copies to the Scripts folder: touchpad fixes, hibernate and Mongo restore.
›
‹ Home

documents

The working documents: CVs, case studies and reference cases.

CVsShows the CV screen: the versions, their sources and how to rebuild them.
›
Case studiesShows the case studies: archived, human-reviewed experiments.
›
Reference casesOpens the incident list; the 2026-10-01 CodeBot lid-closed case is its one entry.
›
‹ documents

cv

The CVs: versions, sources and how to rebuild them.

CV guideOpens the CV guide: versions, sources and rebuild commands.
›
CV workflowOpens how a CV is updated and committed.
›
Full Stack Developer CVOpens the Full Stack Developer CV as a PDF.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV as a PDF.
›
AI Integrations CVOpens the AI Integrations CV as a PDF.
›
Rebuild a CVRebuilds one CV's PDF from its LaTeX source.
›
Plain text versionsBuilds the plain-text CV versions.
›
Dated versionsOpens the CV versions kept by date, 2026-10-04 and its v2.
›
HTML designBuilds the HTML design of the AI Full Stack CV.
›
‹ documents

case-studies

The archived, human-reviewed case studies.

Codebot returnOpens the case: the same design request with and without the conceptual-modeling skill.
›
Signal gardenOpens the exhibit that separates durable explanation (Blume) from the live interface (Astryx).
›
Kernel cloud browsers resultsOpens the results of testing Kernel cloud browsers on 2026-10-08; the file is outside this repo.
›
‹ Home

tools

The small tools, each with its own folder.

DashboardShows the dashboard screen: its server, the concepts version and their checks.
›
ClipstackShows the clipstack screen: its services, picker and Windows part.
›
HermesShows the Hermes screen: the agent, its config examples and restore notes.
›
‹ tools

dashboard

The dashboard and its concepts version: servers and checks.

Dashboard serverRuns the dashboard on http://127.0.0.1:8780; nothing starts it for you.
›
Dashboard checksRuns the dashboard's 199 checks against the real data and a real server.
›
Concepts serverRuns the concepts version on http://127.0.0.1:8781, to compare with the dashboard.
›
Dashboard guideOpens the dashboard guide: tabs, writes and hot reload.
›
‹ tools

clipstack

Clipstack: its services, picker and the Windows part.

Clipstack installInstalls the clipstack user services.
›
Clipstack serverRuns the clipstack server (server.py) as a user service.
›
Clipstack watcherRuns the clipstack watcher (watcher.py) as a user service.
›
Clipstack pickerOpens the clipstack picker.
›
Clipstack on WindowsOpens the Windows clipstack: its AutoHotkey script, install and verify scripts.
›
‹ tools

hermes

Hermes: the agent, its config examples and restore notes.

Hermes agentRuns the Hermes agent from its checkout in ~/projects/hermes-agent.
›
Hermes guideOpens the install notes and current configuration.
›
Restore runbookOpens the steps to restore Hermes.
›
Config examplesOpens the example settings, with no secrets, for the default and jobs profiles.
›
Backup noteOpens the note on the 2026-10-02 backup.
›
‹ Home

docs

Where things land, the conventions, and the repo's folders of plans, designs and research.

Where things landOpens the table of where each repo file lands on this machine.
›
Conventions and gotchasOpens the rules for copies, machine paths and where new things go.
›
Credentials in zsh.dOpens the two files that embed a git credential, which the secrets checklist says to rotate.
›
PlansOpens the dated plans, one folder per change.
›
DesignOpens the design passes: pitches, research and recommendations.
›
FlowsOpens the flow cards and data models behind the dashboards.
›
ResearchOpens the research notes and check runs.
›
ItemsOpens the planned, urgent and work items.
›
ChangelogOpens the dated changelog entries.
›
Intents and featuresOpens the intents and behavior features for each module.
›
Raw answer
## Plan: workstation map

**Scenario (reasoning from experience, not observed use):** Someone working at this Linux machine is partway through a task and asks where a thing lives: which command starts Chrome with the recording flag, which script fixes the HDMI mode, which OpenCode profile runs, where the Windows install is documented. They move one noun at a time.

**Inventory:** The rows in the JSON are the inventory. Each row's `form` is the thing's technical form, and the file it names is where it is defined.

**Judgment calls:**
- **Top screen:** Eight groups, using the README's own section names. Any group with more than about eight rows got a sub-screen (`opencode`, `power`, `deskflow`, `bootstrap`, `cv`, `case-studies`, `skills`, `agents`, `chrome`, `dashboard`, `clipstack`, `hermes`).
- **Command names:** I used `workstation` with `ws` as the facade, since the README already names them.
- **Retired and picture items left off:** `lan-mouse/` (the README says retired 2026-10-05) and `codex/playwright-mcp/` (retired). The screenshot and `copy/` folders are pictures, not things to reach.
- **Named but not in the dump:** `workstation-cli/`, `zsh.d/workstation.zsh`, `zsh.d/audio-share.zsh`, `resume-kvm`, `init-windows/inventory.md`, and the guides for clipstack and team-park. Their forms come from the README, so check them before building.
- **Verbs guessed from file names:** `review-open`, the clipstack server, watcher and picker, and `team-park` have no README line describing them. Confirm these first.
- **Not mapped:** `zsh.d/dash-path-warn.zsh` appears nowhere in the README, so it has no row until you say what it does.
- **Help is not a row:** `help` is a menu, so it is not an item on any screen.
- **Known credential issue:** Shown as a row pointing at the two files, not as a fix.
- **Kept skills:** The 23 folders in `claude/skills/`, not the README's 12-row table, which does not cover them all. Skills in `my-skills` are pointers, since their copies are not stored here.
- **Each thing on one screen:** Windows-deployed agent files sit under Windows, and Linux-installed copies sit under the AI assistant screen.

```json
{"screens": [
{"path": [], "sentence": "The workstation's groups, one per kind of job.", "rows": [
{"name": "Shell", "form": "workstation shell", "what": "Shows the shell screen: zsh helpers, git config and hooks, and OpenCode."},
{"name": "Machine", "form": "workstation machine", "what": "Shows the machine screen: power, display, network, Deskflow and audio scripts."},
{"name": "AI assistant", "form": "workstation assistant", "what": "Shows the assistant screen: rules, settings, skills, agents and hooks."},
{"name": "Browser", "form": "workstation browser", "what": "Shows the browser screen: the browser command, Chrome and smoke QA."},
{"name": "Windows", "form": "workstation windows", "what": "Shows the Windows screen: the bootstrap, agent files and skill sync."},
{"name": "Documents", "form": "workstation documents", "what": "Shows the documents screen: CVs, case studies and reference cases."},
{"name": "Small tools", "form": "workstation tools", "what": "Shows the tools screen: the dashboard, clipstack and Hermes."},
{"name": "Docs and conventions", "form": "workstation docs", "what": "Shows the docs screen: where things land, conventions, and the folders of plans, designs and research."}
]},
{"path": ["shell"], "sentence": "The zsh helpers, git setup and OpenCode commands on this Linux machine.", "rows": [
{"name": "Git config", "form": "~/.gitconfig", "what": "Opens the git config: author identity, LFS, the credential helper and the hooks path."},
{"name": "Git hooks", "form": "~/.git-hooks/", "what": "Opens the Lefthook hook shims that run in every repo."},
{"name": "Git checkout guard", "form": "git checkout (wrapper in ~/.zsh.d/git-safety.zsh)", "what": "Lists the changed files and asks [y/N] before git checkout discards unstaged changes."},
{"name": "OpenCode", "form": "workstation shell opencode", "what": "Shows the OpenCode screen: the profile commands and the profile files."},
{"name": "Terminal and tool helpers", "form": "~/.zsh.d/utils.zsh", "what": "Runs set-title and killport, and loads nvm, node and npm on first use."},
{"name": "Repair helpers", "form": "~/.zsh.d/utils.zsh", "what": "Runs one repair: fix-keyboard, fix-mouse, fix-disk or fix-whatsapp."},
{"name": "API keys", "form": "~/.config/api-keys/env", "what": "Exports the general-use API keys; api-keys-edit opens that file."},
{"name": "Infra shortcuts", "form": "~/.zsh.d/infra.zsh", "what": "Runs the Docker/Compose, Prisma, Postgres, nginx and VPN shortcuts."},
{"name": "Review open", "form": "review-open (~/.local/bin/review-open)", "what": "Opens a file for review; the details are not in the dump, so confirm them."}
]},
{"path": ["shell", "opencode"], "sentence": "The OpenCode profile commands and the profile files they use.", "rows": [
{"name": "opencode and oc", "form": "opencode, oc", "what": "Runs OpenCode with the current profile."},
{"name": "Name the profile", "form": "opencode-profile <name>", "what": "Names the current profile."},
{"name": "Profile list", "form": "opencode-profiles", "what": "Lists what each profile loads."},
{"name": "Switch profile", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "Profile login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "Profile files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "Edit a profile file", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files for editing."},
{"name": "Experimental profile folder", "form": "opencode-profiles/private-leb-experimental/", "what": "Opens the files of the experimental profile: CLAUDE.md, Claude settings and opencode.json."}
]},
{"path": ["machine"], "sentence": "The scripts for power, display, network, Deskflow and audio on this Linux machine.", "rows": [
{"name": "Power", "form": "workstation machine power", "what": "Shows the power screen: the CPU profile and lid scripts."},
{"name": "HDMI monitor mode", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output (default 1920x1080 at 59.88)."},
{"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "Points DNS at systemd-resolved, restarts NetworkManager and cycles networking; re-runs itself with sudo."},
{"name": "Tailscale remote terminal recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled and starts the remote-terminal service, then checks port 3500."},
{"name": "Deskflow", "form": "workstation machine deskflow", "what": "Shows the Deskflow screen: the shared mouse and keyboard with Windows, its service and recovery."},
{"name": "Audio share", "form": "zsh.d/audio-share.zsh (audio-start, audio-pause)", "what": "Sends all Linux audio to Windows over Tailscale (audio-start), and restores the speakers (audio-pause)."},
{"name": "Supabase keepalive", "form": "supabase-keepalive/supabase-keepalive.timer", "what": "Runs the Supabase keepalive on a systemd timer."}
]},
{"path": ["machine", "power"], "sentence": "The CPU profile and laptop lid scripts.", "rows": [
{"name": "Power saver", "form": "cpu-min-power.sh", "what": "Sets the power-saver profile, turns turbo off and caps the CPU at 8% of max; asks for sudo."},
{"name": "Balanced", "form": "cpu-normal-power.sh", "what": "Sets the balanced profile, turns turbo on and removes the cap."},
{"name": "Keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind drop-in so closing the lid does nothing; applies after a reboot."},
{"name": "Restore default lid behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in; applies after a reboot."}
]},
{"path": ["machine", "deskflow"], "sentence": "Deskflow: the shared mouse and keyboard with Windows, its settings, service and recovery.", "rows": [
{"name": "Deskflow guide", "form": "deskflow/README.md", "what": "Opens the guide: everyday use, starting, and recovery."},
{"name": "Deskflow service", "form": "~/.config/systemd/user/deskflow.service", "what": "Runs the Deskflow server with the graphical session."},
{"name": "Linux settings", "form": "~/.config/Deskflow/Deskflow.conf (from deskflow/linux.conf)", "what": "Opens the Linux Deskflow settings."},
{"name": "Windows settings", "form": "deskflow/windows.conf, deskflow/windows-service.conf", "what": "Opens the Windows client and service settings, which are copied separately."},
{"name": "Lockdown rules", "form": "deskflow/deskflow-lockdown.nft", "what": "Opens the nftables rules that lock Deskflow's network use."},
{"name": "Network audit", "form": "deskflow/NETWORK-AUDIT.md", "what": "Opens the Deskflow network audit."},
{"name": "Resume Deskflow", "form": "resume-kvm (named in the guide, not in the dump)", "what": "Starts Deskflow again and asks for input capture."},
{"name": "USB mouse sharing", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes on forwarding the Windows USB mouse, which has been off since 2026-10-20."}
]},
{"path": ["assistant"], "sentence": "The AI assistant setup: rules, settings, skills, agents and hooks.", "rows": [
{"name": "Global rules", "form": "claude/linux-global/CLAUDE.md", "what": "Opens the global rules every Linux Claude session reads."},
{"name": "Global agent notes", "form": "claude/linux-global/AGENTS.md", "what": "Opens the shorter global agent notes."},
{"name": "Instruction backups", "form": "claude/backups/", "what": "Opens the saved copies of the global instructions; none loads on its own."},
{"name": "Communication framework", "form": "claude/communication-framework.md", "what": "Opens the draft design notes, which are not enforced yet."},
{"name": "Claude settings", "form": "~/.claude/settings.json", "what": "Opens Claude Code's settings (machine-local, not in Git)."},
{"name": "Codex config", "form": "~/.codex/config.toml", "what": "Opens the Codex CLI config (machine-local)."},
{"name": "Rules", "form": "rules (~/.local/bin/rules)", "what": "Prints the rules, for one folder if one is given."},
{"name": "Rules source", "form": "workboard/rules.yaml", "what": "Opens the rules file, which changes only by the user or an accepted rule proposal."},
{"name": "Claude hooks", "form": "~/.claude/hooks/", "what": "Opens the hook scripts: rules at session start, server guard, history, proof reminder and team activity."},
{"name": "Skills", "form": "workstation assistant skills", "what": "Shows the skills screen: the global skills, kept backups and the shortlist."},
{"name": "Agents", "form": "workstation assistant agents", "what": "Shows the agents screen: checks, the sandbox, and where roles and teams are defined."},
{"name": "Claude command", "form": "claude (~/bin/claude)", "what": "Runs claude through the usage guard, ahead of the native install."},
{"name": "Usage guard guide", "form": "claude/usage-guard/README.md", "what": "Opens the usage guard's guide."},
{"name": "Main session", "form": "claude --main -c, claude --main -r", "what": "Continues the main session (-c), or resumes one (-r)."},
{"name": "Claude plugins", "form": "claude/mods/", "what": "Opens the Claude Code plugins kept here: changelog-pane, review-pane, scratchpad-playground and team-board."},
{"name": "Team park", "form": "team-park (~/.local/bin/team-park)", "what": "Runs team-park; its purpose is a question in the plan."}
]},
{"path": ["assistant", "skills"], "sentence": "The skills: the global repo, the kept backups and the shortlist.", "rows": [
{"name": "Global skills", "form": "~/projects/my-skills", "what": "Opens the global skills repo, which install.sh links into the skill folders of Claude, Codex and OpenCode."},
{"name": "Kept skills", "form": "workstation assistant skills kept", "what": "Shows the kept skill backups, one per folder."},
{"name": "Skill shortlist", "form": "claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and which of them are installed."}
]},
{"path": ["assistant", "skills", "kept"], "sentence": "The skill backups kept in this repo; copy in the ones you want installed.", "rows": [
{"name": "tech-ledger", "form": "claude/skills/tech-ledger/SKILL.md", "what": "Opens the skill that reads and writes the betec Tech Ledger."},
{"name": "api-key-creation", "form": "claude/skills/api-key-creation/SKILL.md", "what": "Opens the skill for getting a missing API key with browser tools."},
{"name": "clone-website", "form": "claude/skills/clone-website/SKILL.md", "what": "Opens the skill that clones websites with parallel builder agents."},
{"name": "contextual-value-product-thinking", "form": "claude/skills/contextual-value-product-thinking/SKILL.md", "what": "Opens the skill that analyzes products through contextual human values."},
{"name": "elad12390--web-research-assistant", "form": "claude/skills/elad12390--web-research-assistant/SKILL.md", "what": "Opens the web research MCP skill; its setup notes are in SETUP-NOTES.md."},
{"name": "epic-fanout-planning", "form": "claude/skills/epic-fanout-planning/SKILL.md", "what": "Opens the 10-step pattern for QA-gap epics with parallel fan-out."},
{"name": "impeccable", "form": "claude/skills/impeccable/SKILL.md", "what": "Opens the frontend design skill: shape, critique, audit and polish."},
{"name": "iterative-action-review", "form": "claude/skills/iterative-action-review/SKILL.md", "what": "Opens the skill for reviewing a completed action as one iteration."},
{"name": "lab-experiment", "form": "claude/skills/lab-experiment/SKILL.md", "what": "Opens the skill for running an experiment in ai-lab."},
{"name": "mentor-mode", "form": "claude/skills/mentor-mode/SKILL.md", "what": "Opens the mentor-mode skill and its teaching runtime."},
{"name": "post-feature-cleanup", "form": "claude/skills/post-feature-cleanup/SKILL.md", "what": "Opens the pass after writing code: UI defects, leftovers and repo hygiene."},
{"name": "powershell-launching", "form": "claude/skills/powershell-launching/SKILL.md", "what": "Opens the skill for launching PowerShell or a new terminal on Windows."},
{"name": "reboot-resume", "form": "claude/skills/reboot-resume/SKILL.md", "what": "Opens the skill that keeps work across a reboot or a Claude Code restart."},
{"name": "resume-project", "form": "claude/skills/resume-project/SKILL.md", "what": "Opens the resume-project skill and its CLI script."},
{"name": "solaraai-content-calendar", "form": "claude/skills/solaraai-content-calendar/SKILL.md", "what": "Opens the SolaraAI content calendar skill."},
{"name": "solaraai-deployment", "form": "claude/skills/solaraai-deployment/SKILL.md", "what": "Opens the SolaraAI deploy flow skill."},
{"name": "solaraai-design", "form": "claude/skills/solaraai-design/SKILL.md", "what": "Opens the SolaraAI design system skill."},
{"name": "solaraai-forms", "form": "claude/skills/solaraai-forms/SKILL.md", "what": "Opens the SolaraAI form behavior skill."},
{"name": "supabase", "form": "claude/skills/supabase/SKILL.md", "what": "Opens the Supabase skill: Auth, RLS, migrations, CLI and debugging."},
{"name": "supabase-postgres-best-practices", "form": "claude/skills/supabase-postgres-best-practices/SKILL.md", "what": "Opens Supabase's Postgres performance rules."},
{"name": "tank--communication-engineering", "form": "claude/skills/tank--communication-engineering/SKILL.md", "what": "Opens the skill that applies engineering discipline to what an agent says."},
{"name": "tank--skill-creator", "form": "claude/skills/tank--skill-creator/SKILL.md", "what": "Opens the skill for creating new skills."},
{"name": "tech-cv-writer", "form": "claude/skills/tech-cv-writer/SKILL.md", "what": "Opens the CV writing skill and its ATS and LaTeX references."}
]},
{"path": ["assistant", "agents"], "sentence": "Checking and serving agents, and where roles and teams are defined.", "rows": [
{"name": "Agent check", "form": "~/projects/workstation/agent-framework/agent check", "what": "Refuses broken agent records and exits 1."},
{"name": "Agent list", "form": "~/projects/workstation/agent-framework/agent list", "what": "Prints the agents with their tier, model and number of tests."},
{"name": "Agent Sandbox", "form": "agent serve, then http://127.0.0.1:8790", "what": "Serves the Agent Sandbox page, where an agent's setup is changed and asked."},
{"name": "Agent records", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "Opens an agent's record: its situations, saved tests and role skill."},
{"name": "Roles", "form": "~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.md", "what": "Opens a role's skill: worker, supervisor, admin or qa-agent."},
{"name": "Teams", "form": "~/projects/my-skills/spawn-team/SKILL.md", "what": "Opens how a team starts (/spawn-team), with the team files in spawn-team/teams/."}
]},
{"path": ["browser"], "sentence": "The browser command, Chrome and the smoke QA command.", "rows": [
{"name": "Browser command", "form": "browser (browser/browser.sh)", "what": "Runs browser steps in JSON on one Chrome window kept open; browser status and browser close check and stop it."},
{"name": "Browser guide", "form": "browser/README.md", "what": "Opens the browser guide: actions, viewport presets and login gotchas."},
{"name": "Recording proof", "form": "browser with recordStart and recordStop", "what": "Records a tab as proof of a feature; the one supported way to record."},
{"name": "Chrome", "form": "workstation browser chrome", "what": "Shows the Chrome screen: the one start path and its flags."},
{"name": "Codex browser path", "form": "codex/browser/README.md", "what": "Opens the Codex direct Chrome command path and its live checks."},
{"name": "Codex Chrome bridge", "form": "codex/chrome-bridge/install.sh", "what": "Installs the watcher that repairs the Chrome plugin's latest link, as a systemd timer on Linux."},
{"name": "Behavioral smoke QA", "form": "jev-browser-test (~/.local/bin/jev-browser-test)", "what": "Runs one browser goal and reports the text and URL assertions it was given; it is not a visual check."},
{"name": "Smoke QA guide", "form": "jev-browser-test/README.md", "what": "Opens the smoke QA guide: install, config and exit codes."}
]},
{"path": ["browser", "chrome"], "sentence": "Chrome as this machine starts it: the one start path and its flags.", "rows": [
{"name": "Chrome start", "form": "chrome/chrome.sh (also google-chrome)", "what": "Starts Chrome with the flags in chrome/flags; the only way to start it here."},
{"name": "Chrome flags", "form": "chrome/flags", "what": "Opens the flags list that chrome.sh and the browser command both read."},
{"name": "Chrome guide", "form": "chrome/README.md", "what": "Opens the Chrome guide: why the recording flag exists and its limits."},
{"name": "Chrome install", "form": "chrome/install.sh", "what": "Installs the launcher links and desktop entry; run once per machine and after a Chrome update."}
]},
{"path": ["windows"], "sentence": "The Windows machine: bootstrap, agent files, skill sync and repo cloning.", "rows": [
{"name": "Bootstrap", "form": "workstation windows bootstrap", "what": "Shows the bootstrap screen: install, check, roll back and the captured lists."},
{"name": "Windows agent files", "form": "claude/CLAUDE.md, claude/AGENTS.md, claude/settings.json, codex/config.toml", "what": "Opens the agent files that init-windows deploys to the Windows user profile."},
{"name": "Windows global copy", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows CLAUDE.md and its four docs."},
{"name": "Skill sync", "form": "skills-sync-windows/README.md", "what": "Opens the Windows skill sync guide; a runner updates the skill links on trusted pushes to master."},
{"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing Betec repos into the standard layout; safe to re-run."},
{"name": "Usage guard on Windows", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the usage guard on Windows."},
{"name": "Codex Chrome bridge on Windows", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs a Scheduled Task that repairs the Chrome plugin's latest link."}
]},
{"path": ["windows", "bootstrap"], "sentence": "Rebuilding the Windows setup: install, check, roll back and the captured lists.", "rows": [
{"name": "Install", "form": "init-windows/Start-Install.cmd", "what": "Installs the exact programs, Node versions, VS Code, Git config and user scripts from the manifests."},
{"name": "Check", "form": "init-windows/Smoke-Test-Windows.ps1, init-windows/Verify-Windows.ps1", "what": "Checks the install against the manifests."},
{"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Rolls the install back."},
{"name": "Bootstrap guide", "form": "init-windows/README.md", "what": "Opens the full guide to the Windows install."},
{"name": "Inventory", "form": "init-windows/inventory.md", "what": "Opens what the capture included."},
{"name": "Sign-ins checklist", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand."},
{"name": "Manifests", "form": "init-windows/manifests/", "what": "Opens the exact lists: programs, Node versions, VS Code extensions and managed files."},
{"name": "Install logs", "form": "init-windows/logs/", "what": "Opens the install log and its error log."},
{"name": "User scripts", "form": "init-windows/user-scripts/", "what": "Opens the Windows user scripts that init-windows copies to the Scripts folder: touchpad fixes, hibernate and Mongo restore."}
]},
{"path": ["documents"], "sentence": "The working documents: CVs, case studies and reference cases.", "rows": [
{"name": "CVs", "form": "workstation documents cv", "what": "Shows the CV screen: the versions, their sources and how to rebuild them."},
{"name": "Case studies", "form": "workstation documents case-studies", "what": "Shows the case studies: archived, human-reviewed experiments."},
{"name": "Reference cases", "form": "reference/README.md", "what": "Opens the incident list; the 2026-10-01 CodeBot lid-closed case is its one entry."}
]},
{"path": ["documents", "cv"], "sentence": "The CVs: versions, sources and how to rebuild them.", "rows": [
{"name": "CV guide", "form": "cv/README.md", "what": "Opens the CV guide: versions, sources and rebuild commands."},
{"name": "CV workflow", "form": "cv/WORKFLOW.md", "what": "Opens how a CV is updated and committed."},
{"name": "Full Stack Developer CV", "form": "cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV as a PDF."},
{"name": "AI Full Stack Engineer CV", "form": "cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV as a PDF."},
{"name": "AI Integrations CV", "form": "cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV as a PDF."},
{"name": "Rebuild a CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error <name>.tex, run in cv/", "what": "Rebuilds one CV's PDF from its LaTeX source."},
{"name": "Plain text versions", "form": "cv/text/build-full.sh", "what": "Builds the plain-text CV versions."},
{"name": "Dated versions", "form": "cv/versions/", "what": "Opens the CV versions kept by date, 2026-10-04 and its v2."},
{"name": "HTML design", "form": "cv/design/build-design.py", "what": "Builds the HTML design of the AI Full Stack CV."}
]},
{"path": ["documents", "case-studies"], "sentence": "The archived, human-reviewed case studies.", "rows": [
{"name": "Codebot return", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "Opens the case: the same design request with and without the conceptual-modeling skill."},
{"name": "Signal garden", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "Opens the exhibit that separates durable explanation (Blume) from the live interface (Astryx)."},
{"name": "Kernel cloud browsers results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the results of testing Kernel cloud browsers on 2026-10-08; the file is outside this repo."}
]},
{"path": ["tools"], "sentence": "The small tools, each with its own folder.", "rows": [
{"name": "Dashboard", "form": "workstation tools dashboard", "what": "Shows the dashboard screen: its server, the concepts version and their checks."},
{"name": "Clipstack", "form": "workstation tools clipstack", "what": "Shows the clipstack screen: its services, picker and Windows part."},
{"name": "Hermes", "form": "workstation tools hermes", "what": "Shows the Hermes screen: the agent, its config examples and restore notes."}
]},
{"path": ["tools", "dashboard"], "sentence": "The dashboard and its concepts version: servers and checks.", "rows": [
{"name": "Dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py (http://127.0.0.1:8780)", "what": "Runs the dashboard on http://127.0.0.1:8780; nothing starts it for you."},
{"name": "Dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the dashboard's 199 checks against the real data and a real server."},
{"name": "Concepts server", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py (http://127.0.0.1:8781)", "what": "Runs the concepts version on http://127.0.0.1:8781, to compare with the dashboard."},
{"name": "Dashboard guide", "form": "dashboard/README.md", "what": "Opens the dashboard guide: tabs, writes and hot reload."}
]},
{"path": ["tools", "clipstack"], "sentence": "Clipstack: its services, picker and the Windows part.", "rows": [
{"name": "Clipstack install", "form": "clipstack/install.sh", "what": "Installs the clipstack user services."},
{"name": "Clipstack server", "form": "clipstack/units/clipstack-server.service", "what": "Runs the clipstack server (server.py) as a user service."},
{"name": "Clipstack watcher", "form": "clipstack/units/clipstack-watcher.service", "what": "Runs the clipstack watcher (watcher.py) as a user service."},
{"name": "Clipstack picker", "form": "clipstack/picker.py", "what": "Opens the clipstack picker."},
{"name": "Clipstack on Windows", "form": "clipstack/windows/", "what": "Opens the Windows clipstack: its AutoHotkey script, install and verify scripts."}
]},
{"path": ["tools", "hermes"], "sentence": "Hermes: the agent, its config examples and restore notes.", "rows": [
{"name": "Hermes agent", "form": "hermes (~/.local/bin/hermes)", "what": "Runs the Hermes agent from its checkout in ~/projects/hermes-agent."},
{"name": "Hermes guide", "form": "hermes/README.md", "what": "Opens the install notes and current configuration."},
{"name": "Restore runbook", "form": "hermes/RESTORE.md", "what": "Opens the steps to restore Hermes."},
{"name": "Config examples", "form": "hermes/default.config.example.yaml, hermes/jobs.config.example.yaml", "what": "Opens the example settings, with no secrets, for the default and jobs profiles."},
{"name": "Backup note", "form": "hermes/BACKUP-2026-10-02.md", "what": "Opens the note on the 2026-10-02 backup."}
]},
{"path": ["docs"], "sentence": "Where things land, the conventions, and the repo's folders of plans, designs and research.", "rows": [
{"name": "Where things land", "form": "README.md#where-things-land", "what": "Opens the table of where each repo file lands on this machine."},
{"name": "Conventions and gotchas", "form": "README.md#conventions-and-gotchas", "what": "Opens the rules for copies, machine paths and where new things go."},
{"name": "Credentials in zsh.d", "form": "zsh.d/infra.zsh, zsh.d/utils.zsh", "what": "Opens the two files that embed a git credential, which the secrets checklist says to rotate."},
{"name": "Plans", "form": "docs/plans/", "what": "Opens the dated plans, one folder per change."},
{"name": "Design", "form": "docs/design/", "what": "Opens the design passes: pitches, research and recommendations."},
{"name": "Flows", "form": "docs/flows/", "what": "Opens the flow cards and data models behind the dashboards."},
{"name": "Research", "form": "docs/research/", "what": "Opens the research notes and check runs."},
{"name": "Items", "form": "docs/items/", "what": "Opens the planned, urgent and work items."},
{"name": "Changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "Intents and features", "form": ".idd/ and .bdd/", "what": "Opens the intents and behavior features for each module."}
]}
],
"questions": [
"dash-path-warn.zsh: what does it do? It has no row until you say. Recommendation: give one line; if it is abandoned, keep it off the map.",
"team-park and clipstack: their READMEs are not in the dump, so their purposes come from file names. Recommendation: confirm one line each before building. team-park stays on the AI assistant screen either way.",
"The README names a setup command as well as workstation and ws. Keep it as a second facade name, or drop it? Recommendation: keep workstation and ws only, unless you use the other name.",
"docs/roles/drafts-2026-10-23/.old/ and docs/superpowers/plans/ are left off the map. Recommendation: keep them off; say so if you want them listed.",
"lan-mouse/ and codex/playwright-mcp/ are retired per the README and stay off the map. Recommendation: confirm.",
"Kept skills: should the list of 23 folders be generated from claude/skills/ at build time instead of typed in? Recommendation: generate it, so a new skill folder appears without a typed edit."
]}
```

No skill · run 3 exit=0 seconds=204 · prompt

P1 Recall: 0.8P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.446P5 Short top: 21P6 Own words: 1.0P8 Worded per screen: 1P9 Grouping (ARI): 0.265
As terminal help
Everything this machine's workstation kit lets you reach, grouped by what you want to do. Opened by workstation, ws, or setup.
Shell helpersworkstation shellCommands loaded in every terminal: git safety, Docker and Postgres, terminal helpers, API keys, review opening.
Gitworkstation gitGit settings and the hooks that gate pushes and commits in every repo.
Machineworkstation machineLinux power, display, internet, Tailscale, laptop lid, repairs and background services.
Browserworkstation browserDrive one persistent Chrome window from the command line, and record proof of a feature.
Chromeworkstation chromeStart Chrome the one approved way, so recordings run without a prompt.
Agentsworkstation agentsCheck agent records and test them in the Agent Sandbox page.
Claudeworkstation claudeClaude Code setup: global rules, settings, hooks, skills, sessions, plugins, team park, usage guard.
Reviewworkstation reviewOpen a review of changes in the review pane.
Codexworkstation codexCodex config and the Chrome bridge that keeps its plugin working.
Dashboardworkstation dashboardOne screen of what waits for you: cases, rule changes, and calls agents made alone.
Deskflowworkstation deskflowShare the laptop trackpad and keyboard with the Windows PC over Tailscale.
Clipboardworkstation clipboardClipboard history shared between Linux and Windows, with a picker.
Audioworkstation audioSend Linux audio to the Windows machine and restore the speakers.
CVsworkstation cvThe three CV versions, their PDFs, and how to rebuild them.
Windowsworkstation windowsRebuild the Windows dev environment, clone work repos, and sync skills.
Rulesworkstation rulesThe rules every agent follows, printed for a folder.
Hermesworkstation hermesThe source-installed Hermes agent, its config, and its restore runbook.
Jevworkstation jevBrowser smoke checks, and asking Jev for a decision.
OpenCodeworkstation opencodeSwitch, inspect, and edit OpenCode profiles.
Installworkstation installWhere each repo file goes on this machine.
Recordsworkstation recordsCase studies, incidents, plans, research, and behavior specs. Read only.
shell
Helpers sourced from zsh.d into every terminal. Each row is a group; exact names are read from the file.
Git safetygit checkout (wrapped in zsh.d/git-safety.zsh)Lists the files and asks [y/N] before discarding unstaged changes.
Infrastructurefunctions in zsh.d/infra.zshDocker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands.
Terminal and utilitiesfunctions in zsh.d/utils.zshset-title, killport, IP aliases, lazy-loaded nvm, node, npm, npx, Android, Java, and Bun setup.
API keysapi-keys-editOpens the general-use API keys file, which is kept out of Git.
Review openreview-openOpens a review from bash and agents, via ~/.local/bin/review-open.
git
Git settings and the gates that run in every repo.
Git settings~/.gitconfigAuthor identity, Git LFS, credential store, large HTTP buffer, and the hooks path.
Git hooksworkstation git hooksThe Lefthook shims and the gates they enforce.
git › hooks
Lefthook shims in ~/.git-hooks that run in every repo. They need lefthook on PATH.
Push gate~/.git-hooks/pre-pushBlocks pushes that lack an approval note, and direct pushes to main in repos marked pull-request.
Commit gate~/.git-hooks/commit-msgBlocks commits on main in repos marked pull-request.
Other shims~/.git-hooks/pre-commit and prepare-commit-msgGenerated by Lefthook.
Scenario gate~/.git-hooks/scenario-gate.pyGate script the hooks call; see the file.
Restore gates after reinstall~/.git-hooks/Running lefthook install overwrites the gate lines; add them back by hand.
machine
Linux machine helpers: power, display, internet, Tailscale, lid, repairs, and background services.
Battery savercpu-min-power.shPower-saver profile, turbo off, CPU capped at 8 percent. Intel P-state only; asks for sudo.
Normal powercpu-normal-power.shBalanced profile, turbo on, cap back to 100 percent.
External monitorfix_old_monitor_hdmi.shSets mode and refresh rate on the HDMI or DP output. Options: --output, --mode, --rate, --quiet.
Internet recoverylinux-internet-recovery.shResets DNS and cycles networking. Re-runs itself with sudo.
Remote terminal recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, waits for reconnect, starts remote-terminal, checks port 3500.
Laptop lidworkstation machine lidKeep the laptop running with the lid closed, or restore the default.
Repairsworkstation machine repairRepair helpers for keyboard, mouse, disk, and WhatsApp.
Background servicesworkstation machine servicesServices and timers that run without you.
machine › lid
Lid behavior. Both changes apply after a reboot.
Keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shWrites a logind drop-in so closing the lid does nothing. Keep the laptop ventilated.
Restore default lid behaviorlaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in.
Closed-lid incidentreference/incidents/2026-10-01-codebot-lid-closed.mdThe test record: passed for 1 minute 46 seconds.
machine › repair
Repair helpers in zsh.d/utils.zsh. Run the one for the device that misbehaves.
fix-keyboardfunction in zsh.d/utils.zshRepairs the keyboard.
fix-mousefunction in zsh.d/utils.zshRepairs the mouse.
fix-diskfunction in zsh.d/utils.zshRepairs disk trouble.
fix-whatsappfunction in zsh.d/utils.zshRepairs WhatsApp; see the function for the steps.
machine › services
Services and timers that run in the background. Nothing here needs you to start it, except where noted.
Clipstack serverclipstack/units/clipstack-server.service (user unit)Runs the clipboard history server.
Clipstack watcherclipstack/units/clipstack-watcher.service (user unit)Watches the clipboard for changes.
Supabase keepalivesupabase-keepalive/supabase-keepalive.timerKeeps the Supabase project awake; installed by supabase-keepalive/install.sh.
Codex Chrome bridge timercodex/chrome-bridge/codex-chrome-bridge.timerRepairs the Chrome plugin's latest link and patch.
Deskflow serverdeskflow/deskflow.service (user unit)Shares the keyboard and mouse; starts with the graphical session.
Answer sync~/.config/systemd/user/ data-pull timerPulls case answers every 5 minutes.
Dashboard serverpython3 ~/projects/workstation/dashboard/server.pyNot a service. Starts only when you run it by hand.
browser
The browser command: one real Chrome window kept open across calls, so login and page state survive.
Run stepsbrowser '<json array of steps>'Runs the actions in order on the one page; prints results as JSON.
Statusbrowser statusShows whether the background server and browser are up.
Closebrowser closeCloses Chrome and stops the server.
Record proofworkstation browser recordThe one supported way to record a tab as proof of a feature.
Installcd browser && npm install && npm linkOnce per machine.
Actions and login notesbrowser/README.mdFull action list, viewport presets, annotating, network capture, login gotchas.
Start Chromeworkstation chromeChrome must be started through chrome.sh for recordings to run without a prompt.
browser › record
Record proof that a feature works. Requires Chrome started through chrome.sh, so the tab titled REC-TARGET is picked with no prompt.
Start recordingrecordStart step in the browser stepsBegins recording the tab.
Stop recordingrecordStop step in the browser stepsEnds the recording.
Still imagescreenshot step with a pathFor stills, not recordings.
Step by stepbrowser/README.md, Recording proofThe full how-to.
chrome
Chrome starts only through chrome.sh, which adds the recording flag.
Start Chromechrome/chrome.shThe one way to start Chrome. Menu entries and app shortcuts use it too.
Install the launcherchrome/install.shLinks the google-chrome commands and menu entry to chrome.sh. Then quit and restart Chrome.
Flagschrome/flagsThe one list of Chrome flags. Edit only here.
Check the flagpgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'Confirms a running Chrome has the flag.
Full noteschrome/README.mdWhy it exists, and its limits.
agents
Agent records, checked before any session starts, and the Agent Sandbox page for testing them.
Check records~/projects/workstation/agent-framework/agent checkRefuses broken records; exits 1 when one is broken.
List agents~/projects/workstation/agent-framework/agent listAgents, with tier, model, and number of tests.
Agent Sandbox page~/projects/workstation/agent-framework/agent serve, then http://127.0.0.1:8790Pick an agent, change its setup, type a message, press Ask.
Sandbox page partsworkstation agents sandboxWhat each part of the page does.
Roles and teams/spawn-team <team> (Claude) or $spawn-team <team> (Codex)Starts a team from my-skills spawn-team team files.
Agent intent.idd/modules/agent-framework/INTENT.mdIntent and rules for the agent framework.
Sandbox PRDdocs/plans/2026-10-22-agent-sandbox/prd.htmlProduct requirements and mockups.
Agent rulesworkstation rulesThe rules every agent follows.
agents › sandbox
The Agent Sandbox page at http://127.0.0.1:8790: one conversation, with the setup in one line at the top.
Setup lineheader of the pageClick to change agent, model, effort, folder, rules, memory, skill versions, or tools. The next message uses it.
AskAsk buttonSends the typed message.
Expectationsleft column, ExpectationsWhat every next answer must or must not do, such as must call Read.
Did it react rightright panelFor the clicked message: which expectations passed or failed, what it did, which calls failed.
Every stepclosed section, Every step in orderThe raw steps.
Answer againAnswer again with another setupAnswers the same message with a changed setup, side by side.
Reply from hereReply from hereContinues from that answer, as if later turns never happened.
Save as testSave as testAsks the same message again later from the same point.
Start fromStart from, before the first messageOptional ready-made first message and folder of files.
claude
Claude Code setup for this machine and the Windows desktop. These are copies; see install for where they go.
Global rulesclaude/CLAUDE.mdBrowser automation, communication style, research protocol, how to present work.
Short agent notesclaude/AGENTS.mdThe shorter global agent notes.
Settingsclaude/settings.jsonClaude Code settings.
Linux global mirrorclaude/linux-global/Copy of the installed Linux instruction files. Machine settings stay local.
Windows global mirrorclaude/windows-global/Copy of the Windows user .claude instruction files and their four docs.
Hooksworkstation claude hooksHooks that run by themselves.
Sessionsworkstation claude sessionsContinue or resume main sessions.
Skillsworkstation claude skillsSkills kept here and how to install them.
Pluginsworkstation claude modsReview pane, changelog pane, scratchpad, and team board plugins.
Team parkworkstation claude team-parkThe team-park command.
Usage guardworkstation claude usage-guardThe claude command wrapper that guards usage.
Backupsclaude/backups/Portable snapshots of the desktop instruction packages. Not loaded automatically.
Communication framework draftclaude/communication-framework.mdDesign notes. Not enforced anywhere yet.
Skill shortlistclaude/skills-shortlist.mdSkills researched on skills.sh.
claude › hooks
Hooks that run by themselves on sessions and tool calls. Nothing to type; wired in ~/.claude/settings.json.
Core rules~/.claude/hooks/core-rules.shRule hook on SessionStart and on Bash calls.
Machine history~/.claude/hooks/machine-history.shMachine history hook; see the file.
Team activity~/.claude/hooks/team-activity.shTeam activity hook; see the file.
Local server guard~/.claude/hooks/local-server-guard.pyChecks Bash calls before they run (PreToolUse on Bash).
Proof reminder~/.claude/hooks/proof-reminder.shReminds to prove the work after Edit, MultiEdit, Write, and Bash.
Session types~/.claude/hooks/session-types.shSessionStart hook for session types.
Core rules testsclaude/hooks/test_core_rules.shTests the core rules hook.
claude › sessions
Named main sessions, run through the claude wrapper.
Continue main sessionclaude --main -cContinues the latest main session.
Resume a main sessionclaude --main -rChooses one to resume.
Main sessions script~/.claude/hooks/main-sessions.pyRun by the wrapper for -c and -r.
Session types testsclaude/session-types/tests/run.shRuns the session types tests.
Session types designclaude/session-types/docs/design/Design notes for the changelog timeline and picker views.
claude › skills
Skills kept here as backups. Global skills live in the my-skills repo and are linked by its install.sh.
Kept skillsworkstation claude skills keptEvery skill kept here, and what each one does.
Install a kept skillcopy into ~/.claude/skills/Copy in by hand the ones you want installed.
Global skills~/projects/my-skills (install.sh)Links into ~/.claude/skills, ~/.codex/skills, and ~/.config/opencode/skills.
Skill shortlistclaude/skills-shortlist.mdSkills researched on skills.sh.
Skill design rulevolatility-based-skill-design (my-skills; claude/linux-global/skills/)Skills must declare metadata.usage-tier.
claude › skills › kept
Skills kept under claude/skills, plus the two Linux global skills. Each is a folder with SKILL.md.
tech-ledgerclaude/skills/tech-ledger/Read and write the betec Tech Ledger of evaluated tech.
api-key-creationclaude/skills/api-key-creation/Get a missing API key with browser tools (admin tier).
clone-websiteclaude/skills/clone-website/Reverse-engineer and clone websites with parallel builders.
contextual-value-product-thinkingclaude/skills/contextual-value-product-thinking/Analyze products and startup ideas through human values.
web-research-assistantclaude/skills/elad12390--web-research-assistant/Web research MCP server hosted on liel-windows; setup in SETUP-NOTES.md.
epic-fanout-planningclaude/skills/epic-fanout-planning/Ten-step pattern for QA-gap epics with parallel fan-out.
impeccableclaude/skills/impeccable/Frontend design: shape, critique, audit, polish.
iterative-action-reviewclaude/skills/iterative-action-review/Review a completed real-world action as one iteration.
lab-experimentclaude/skills/lab-experiment/How to run an experiment in the ai-lab project.
mentor-modeclaude/skills/mentor-mode/scripts/serve_mentor.pyTeaching page; prepare_mentor_page.py builds it, serve_mentor.py serves it.
post-feature-cleanupclaude/skills/post-feature-cleanup/Pass after writing code: UI defects, leftovers, repo hygiene.
powershell-launchingclaude/skills/powershell-launching/Launch PowerShell or a new terminal on Windows.
reboot-resumeclaude/skills/reboot-resume/Preserve and resume work across a reboot or restart.
resume-projectclaude/skills/resume-project/scripts/resume_project.pyResume a project; CLI notes in references/cli.md.
solaraai skills (four)claude/skills/solaraai-*/SolaraAI content calendar, deployment, design system, and forms.
supabase skills (two)claude/skills/supabase/ and supabase-postgres-best-practices/Supabase's skill, and its Postgres performance rules.
tank--communication-engineeringclaude/skills/tank--communication-engineering/Engineering discipline for what an agent says and how much.
tank--skill-creatorclaude/skills/tank--skill-creator/Create new skills; scripts/quick_validate.py checks them.
tech-cv-writerclaude/skills/tech-cv-writer/CV writing: ATS architecture, bullet formulas, templates.
Linux global skills (two)claude/linux-global/skills/tank--bulletproof/ and volatility-based-skill-design/Behavior protocol and skill design, as installed on Linux.
claude › mods
Plugins for the Claude Code interface. Each is a folder with hooks, types, and tests.
Review paneclaude/mods/review-pane/The plugin behind workstation review.
Changelog paneclaude/mods/changelog-pane/Changelog pane plugin.
Scratchpad playgroundclaude/mods/scratchpad-playground/Scratchpad plugin.
Team boardclaude/mods/team-board/Team board plugin.
claude › team-park
Team park: the team-park command, from claude/team-park/.
Run team parkteam-park (~/.local/bin/team-park)Runs the team park tool. Details: claude/team-park/README.md.
Testsclaude/team-park/test_team_park.pyTests for team park.
claude › usage-guard
Usage guard: the claude command wrapper, with its installers and tests.
Claude wrapperclaude (~/bin/claude, ahead of ~/.local/bin/claude)Runs the usage guard before Claude Code.
Install on Linuxclaude/usage-guard/install.shInstalls the wrapper beside the native claude.
Install on Windowsclaude/usage-guard/Install-Windows.cmdWindows install, with Install-Windows.ps1 and Launcher.cs.
Request budget testsclaude/usage-guard/tests/test_request_budget.pyTests the request budget.
Live refresh checkclaude/usage-guard/tests/live-refresh.pyChecks usage refresh against live data.
Plugin hooksclaude/usage-guard/plugin/hooks/Plugin hooks, including shared-usage.py.
Resolved findingsclaude/usage-guard/.bdd/qa/resolutions/Resolved stale-usage and request-budget findings.
codex
Codex CLI config and its Chrome helpers.
Codex configcodex/config.tomlCodex CLI config; deployed to the Windows user .codex folder by init-windows.
Chrome bridgeworkstation codex chrome-bridgeKeeps the Chrome plugin's latest link and its navigation patch working.
Direct Chrome pathcodex/browser/README.mdCodex's direct Chrome command path. Its recorder is superseded by workstation browser record.
codex › chrome-bridge
Keeps Codex's Chrome plugin working. Each machine patches its own local cache.
Install on Linuxcodex/chrome-bridge/install.shInstalls the systemd user watcher and timer.
Install on Windowscodex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls a current-user Scheduled Task. PowerShell script beside it.
Repair nowcodex/chrome-bridge/repair.mjsFixes the latest link and the patch by hand.
Watcher unitcodex/chrome-bridge/codex-chrome-bridge.pathWatches the Codex plugin folder.
Setup notescodex/chrome-bridge/README.mdRestart requirements and details.
review
Review pane: open a review of changes.
Open a reviewreview-open (~/.local/bin/review-open)Opens a review; the same command works from bash and agents.
Review pane pluginclaude/mods/review-pane/The plugin behind the pane.
Chosen designclaude/mods/review-pane/docs/design/2026-10-18-review-pane/recommendation.mdThe recommended design, with pitches and research beside it.
Flow cardclaude/mods/review-pane/docs/flows/2026-10-18/flow-card.mdHow the review flow goes.
dashboard
The dashboard: one screen for its owner, read at a glance. It runs only when you start it.
Start the dashboardpython3 ~/projects/workstation/dashboard/server.pyOpens at http://127.0.0.1:8780, or another port you pass. Listens on this machine only.
Waiting tabworkstation dashboard waitingThe default tab: cases asked, rule changes proposed, calls made alone.
Overview tabOverview tab on the dashboard pageCounts of cases and rule changes, the running team as lanes, and counts by kind.
Third tabtab on the dashboard page, named in dashboard/README.mdCut off in the dump; confirm the name before building this row.
Concepts versionworkstation dashboard conceptsSecond version at http://127.0.0.1:8781 with a Projects panel.
Readerreader panel over the right columnOpens the rows and the open item's file.
Testspython3 -I -m unittest discover -s ~/projects/workstation/dashboardChecks against the real data and a real server.
Design roundsdocs/design/2026-10-17-dashboard/Pitches and recommendation behind the look.
dashboard › waiting
Three groups: Decisions, Rule changes, Decided alone. Newest day first; older days sit behind Show.
Answer a caseanswer box on a Decisions rowPosts your answer as a comment on the case's GitHub issue.
Accept or reject a rule changeAccept or Reject on a Rule changes rowSets status in the proposal file under ~/projects/data/global/rule-proposals/ and adds a Decision line.
Review a call decided aloneJustified, Should have asked, Wrong call, and a noteSets review in the case file and writes the note under Final feedback. No GitHub call.
Open an item's file/api/file?path=...&as=htmlShows the rendered file; raw HTML shows as text.
Show older daysShow buttonOpens the older rows.
Data refreshpage refreshes every 30 secondsKeeps the groups current.
Saved answersdata timer, within 5 minutesYour answers are committed by the data timer.
dashboard › concepts
Concepts version: same server as the dashboard, with a Projects panel in the bottom-right corner.
Startpython3 ~/projects/workstation/dashboard-concepts/server.pyOpens at http://127.0.0.1:8781, or another port you pass.
Projects panelProjects panel, bottom rightOne cell per project, grouped by org, with Agent system and This machine buttons.
Testspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts17 checks against the real data and a real server.
Data modeldocs/flows/2026-10-17/data-model.mdWhat contains what.
deskflow
Deskflow shares the laptop trackpad and keyboard with the Windows PC over Tailscale. Installed 2026-10-05.
Everyday usemove past the laptop's right edgeControls Windows; move past Windows' left edge to return. Each machine keeps its own display.
Keyboard follows the mouseworkstation deskflow usb-mouseHow the keyboard follows the mouse you pick up, and the forwarding that is off.
Recoveryworkstation deskflow recoveryWhat to do when Deskflow stops.
Settings filesworkstation deskflow settingsConfig copies and where each lands on this machine.
Network auditdeskflow/NETWORK-AUDIT.mdNetwork audit notes.
Firewall rulesdeskflow/deskflow-lockdown.nftFirewall rules for Deskflow.
Full guidedeskflow/README.mdEverything, including the GNOME input-capture prompt.
deskflow › usb-mouse
Forwarding the Windows USB mouse to Linux has been off since 2026-10-20 because it felt slow.
Forwarding servicedeskflow-usb-mouse.service (disabled)Turn it back on by the steps in its README.
Keyboard follows the mousedeskflow/usb-mouse/README.md, Keyboard follows the mouseHow it works and how to stop it.
Verification notesdeskflow/usb-mouse/VERIFICATION.mdVerification record.
Focus ruledeskflow/usb-mouse/70-deskflow-focus.rulesFocus rule file in the usb-mouse folder.
deskflow › recovery
Steps when Deskflow stops. GNOME asks to allow input capture on each server start.
Start again and askresume-kvmStarts Deskflow and asks for input capture again.
Input capture promptGNOME promptClick Allow. Cancel stops Deskflow with exit code 0, so systemd does not restart it.
Full recovery notesdeskflow/README.md, If itThe full recovery steps.
deskflow › settings
Config files for Deskflow and where each one lands.
Linux client configdeskflow/linux.conf to ~/.config/Deskflow/Deskflow.confLinux settings.
Linux server configdeskflow/server.conf to ~/.config/Deskflow/server.confServer settings.
Service unitdeskflow/deskflow.service to ~/.config/systemd/user/deskflow.serviceThe user service.
Keyboard layout drop-indeskflow/deskflow.service.d/keyboard-layout.confKeyboard layout for the service.
Windows settingsdeskflow/windows.conf and windows-service.confSeparate client and service settings. See deskflow/README.md, repository copies.
clipboard
Clipstack: clipboard history shared between Linux and Windows, with a picker.
Pickerpython3 ~/projects/workstation/clipstack/picker.pyOpens the picker to choose an earlier clipboard item.
Serverclipstack/server.py (service clipstack-server)Keeps the history.
Watcherclipstack/watcher.py (service clipstack-watcher)Watches the clipboard for changes.
Install on Linuxclipstack/install.shInstalls the services.
Windows sideclipstack/windows/clipstack.ahk, plus install.ps1, uninstall.ps1, and verify.ps1.
Testsclipstack/test_server.py and clipstack/windows/tests/run-tests.ps1Automated tests for the server and Windows side.
Shared clipboard plandocs/plans/2026-10-26-shared-clipboard/plan.mdThe plan behind it.
audio
Send all Linux audio to the Windows machine over Tailscale, then restore the speakers.
Start sendingaudio-startSends Linux audio to the Windows machine.
Pauseaudio-pauseRestores the speakers.
On, off, status, toneaudio-share on, off, status, toneSame as start and pause, plus status and a tone option.
Sink and portnull sink windows_share; tcp port 4953The virtual output and the port its audio is served on.
Windows playerwindows-audio-share agentRuns the Windows ffplay reconnect loop.
Source filesaudio-share/ and zsh.d/audio-share.zshNot in the file list given; confirm they exist before building this screen.
cv
The three CVs: sources, PDFs, and how to rebuild them.
Full Stack Developercv/cv-full-stack.pdf (source cv/cv-full-stack.tex)The full stack CV.
AI Full Stack Engineercv/cv-ai-full-stack.pdf (source cv/cv-ai-full-stack.tex)The AI full stack version.
AI Integrationscv/cv-ai-integrations.pdf (source cv/cv-ai-integrations.tex)The AI integrations version.
Rebuildpdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.texRun from cv/. Repeat for each version.
Text versionscv/text/build-full.shPlain text versions.
Design HTMLcv/design/build-design.pyBuilds the design HTML and PDF.
Dated versionscv/versions/Snapshots from 2026-10-04 and 2026-10-04-v2.
Workflowcv/WORKFLOW.mdHow to update and publish.
CV writing helpclaude/skills/tech-cv-writer/Bullet formulas, ATS, and templates.
Compatibility links/home/liel/projects/tech-cv-workspace/Symlinks to cv/ that Hermes uses.
windows
The Windows side: rebuild a dev machine, clone work repos, sync skills. These run on Windows; this screen describes them.
Install the environmentinit-windows/Start-Install.cmdInstalls programs, Node, VS Code, Git config, user scripts, and opens Chrome sign-in.
Check the installinit-windows/Smoke-Test-Windows.ps1 and Verify-Windows.ps1Checks what was installed.
Roll backinit-windows/Remove-WindowsPack.ps1Rolls back using the install journal.
Exportinit-windows/Export-Windows.ps1Export script; see init-windows/README.md.
What was capturedinit-windows/inventory.mdInventory of what the install captures.
Sign-ins to redoinit-windows/secrets-checklist.mdSign-ins to redo by hand.
Clone work reposrepos/Clone-BetecRepos.ps1Clones missing repos; safe to re-run.
Skill syncworkstation windows skills-syncKeeps Windows skill links current from my-skills.
Full guideinit-windows/README.mdThe full install guide.
Windows global mirrorclaude/windows-global/Copy of the desktop's global instruction files.
windows › skills-sync
Skill sync on Windows: a self-hosted runner updates my-skills on each trusted push to master.
Runner serviceactions.runner.Lebnor-my-skills.my-skills-liel-windowsRuns the sync; starts automatically.
Sync scriptskills-sync-windows/Sync-Skills.ps1Verifies the checkout, fetches, fast-forwards, and re-runs install.ps1.
Catch-up taskMySkillsSync-CatchUp scheduled taskRuns once after startup, with three retries.
Last successlast-success.json in the MySkillsSync state folderRecord of the latest successful sync.
Testsskills-sync-windows/Test-Sync.ps1 and Test-Account.ps1Checks the sync and the runner account.
Detailsskills-sync-windows/README.mdComponents, permissions, and trust boundaries.
Verification notesskills-sync-windows/verification.mdVerification record.
rules
Rules every agent follows, from workboard/rules.yaml. Changed only by you or by an accepted rule proposal.
Print rulesrules [folder]Prints the rules for a folder (~/.local/bin/rules).
Rules fileworkboard/rules.yamlThe rules themselves.
Rule metadataworkboard/rules-meta.yamlMetadata for each rule.
Generated copy~/.claude/references/rules.mdGenerated from the rules file; sessions are told to read it on start.
Propose a changerule proposal file in ~/projects/data/global/rule-proposals/Accept or reject it on the dashboard waiting screen.
Testsworkboard/test_rules.py and workboard/test_org_folder.pyChecks the rules and org folder.
Rules per role plandocs/plans/2026-10-24-rules-per-role/plan.mdPlan for rules per role. The reminder timer is in its reminder folder.
hermes
Hermes: the source-installed agent. Two profiles, default and jobs, and one gateway for two Telegram bots.
Runhermes (~/.local/bin/hermes)Launcher. The checkout is at ~/projects/hermes-agent.
Example settingshermes/default.config.example.yaml and jobs.config.example.yamlSecret-free example settings.
Restorehermes/RESTORE.mdRestore runbook.
Backup recordhermes/BACKUP-2026-10-02.mdRecord of the 2026-10-02 backup.
Shell PATH additionhermes/zprofile-path.zshThe PATH addition for ~/.zprofile.
Secrets and state~/.hermesNot in Git. Secrets sit in mode 600 files.
Full statushermes/README.mdCurrent configuration and install history.
jev
Jev: browser smoke checks, and asking Jev for decisions. Reports only the text and URL you assert.
Run a browser checkjev-browser-test (~/.local/bin/jev-browser-test)Gives a URL and a goal, then checks the visible text and final URL.
Ask Jevjev '<context>' -c '<question>' <options>,other_none -jGets a choice. Confidence at 0.85 or more may count as approved; lower is guidance only.
Installjev-browser-test/install.shClones and pins the upstream tool, then installs the CLI.
Secrets~/.config/jev-browser-test/envAPI keys, mode 600. Not in Git.
Instructionsjev-browser-test/instructions.mdInstructions for agents using the tool.
Full guidejev-browser-test/README.mdShared profile, exit codes, privacy boundary.
opencode
OpenCode profiles: each profile loads its own files. These commands work in every shell.
Current profileopencode-profileNames the current profile.
All profilesopencode-profilesShows what each profile loads.
Switchopencode-switch <name>Switches new runs in every shell to that profile.
Sign in Claude Codeopencode-loginSigns a profile's Claude Code in.
Profile filesopencode-filesLists the current profile's files.
Edit a fileopencode-edit <file>Opens one profile file.
Helpopencode help (also oc help, opencode-help, oc-help)One column per profile. With more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it.
Runopencode or ocRuns OpenCode with the current profile.
Profile tool and testsopencode-profiles/profiles.py and test_profiles.pyThe profile tool and its tests.
install
Where each repo file goes on this machine. Files are copies; compare a pair with diff before deciding which side wins.
Git config.gitconfig to ~/.gitconfigGit settings.
Shell helperszsh.d/*.zsh to ~/.zsh.d/Sourced by ~/.zshrc.
Git hooksgit-hooks/* to ~/.git-hooks/Lefthook shims.
Claude hook scriptsclaude/hooks/* to ~/.claude/hooks/Wired in ~/.claude/settings.json.
Session scriptsclaude/session-types/ scripts to ~/.claude/hooks/Session types hook and main-sessions.py.
Claude wrapperclaude/usage-guard/claude to ~/bin/claudeThe usage-guard wrapper.
Team parkclaude/team-park/team_park.py to ~/.local/bin/team-parkThe team-park command.
Rulesworkboard/rules.yamlRead by the rules command.
Skillsclaude/skills/* to ~/.claude/skills/Copy in the ones you want.
Windows instruction filesclaude/CLAUDE.md and claude/settings.json to the Windows user .claude folder; codex/config.toml to the .codex folderDeployed by init-windows.
Keep in placeclaude/CLAUDE.md, claude/AGENTS.md, claude/settings.json, codex/config.tomlinit-windows reads these by relative path. Do not move them.
Deskflow and user scriptsworkstation deskflow settings; init-windows/user-scripts/*Deskflow config copies, and Windows user scripts.
records
Dated records: case studies, incidents, plans, research, and behavior specs. Read only.
Case studiesworkstation records case-studiesArchived, human-reviewed experiments.
Incidentsreference/incidents/ (index: reference/README.md)Dated machine failures and repairs.
Plans and designworkstation records plansDated plans, design rounds, research, changelog, and flows.
Module intent.idd/modules/*/INTENT.mdIntent and behavior for each module.
Behavior scenarios.bdd/features/*/Behavior scenarios per feature, plus QA findings in .bdd/qa/findings/.
records › case-studies
Three archived experiments, one folder each, each with its own README.
Codebot returncase-studies/conceptual-modeling/2026-09-15-codebot-return/The same design request with and without the conceptual-modeling skill. The skill-guided run was judged better.
Signal gardencase-studies/blume-astryx/2026-09-16-signal-garden/A documentation exhibit that separates the explanation from the live interface.
Kernel cloud browsers/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdCloud browsers tested live: use cases, speed against local Chrome, and session recording.
records › plans
Dated plans, design rounds, research, and changelog. Read them; nothing runs from here.
Plansdocs/plans/Dated plans, such as opencode profiles, the rule list, Claude personas, shared clipboard, and workstation projects.
Design roundsdocs/design/Pitches and recommendations for the dashboard, waiting, and agent sandbox.
Researchdocs/research/ and docs/functional-research/Phase checks, proven methods, and functional research.
Changelogdocs/changelog/Patch notes.
Flowsdocs/flows/Flow cards and data models.
Questions
  • Credentials in zsh.d: infra.zsh (git_pull_with_creds, Prisma init) and utils.zsh (update-gitlab-token) embed a credential in git URLs. Should the help screens list those helpers? Recommendation: leave them out of the map until the credential is rotated and moved to a credential manager, since the secrets checklist already says to treat it as compromised.
  • Retired and superseded tools: lan-mouse (retired 2026-10-05), codex/playwright-mcp (retired), and the codex/browser recorder (superseded by browser recordStart and recordStop). Should they appear? Recommendation: leave them off the top-level and sub-screens, and mention them only in Records, since the README keeps some of them as rollback files.
  • Command names: the README gives one command three names, workstation, ws, and setup. setup is generic and may clash with other tools. Recommendation: keep workstation and ws, and drop setup from the help text.
  • Files missing from the dump: workstation-cli/ and zsh.d/workstation.zsh, audio-share/ and zsh.d/audio-share.zsh, and Verify-Windows.ps1 are described in READMEs but absent from the file list. I planned those screens from the READMEs. Recommendation: confirm they exist before building the workstation, audio, and Windows screens.
  • Windows items on a Linux help screen (init-windows, skill sync, Windows clipstack, Windows Codex bridge): should they be listed or left out? Recommendation: list them, marked as Windows, with their file path as the form, since this CLI cannot run them.
  • Dashboard concepts: a separate top-level item, or a version under dashboard? Recommendation: keep it under dashboard, since it shares the same server code.
  • Dashboard start: it is not a service and runs only when started by hand. Should the help offer a service command? Recommendation: keep it manual; the README leaves service setup to you.
  • Hooks: show the hooks that run by themselves under Claude, or hide them? Recommendation: show them with their wiring path, since they change what an agent sees.
  • Records: list the dated folders only, or make each openable? Recommendation: list them with their folder path, since they are read by hand.
As phone screens

Home

Everything this machine's workstation kit lets you reach, grouped by what you want to do. Opened by workstation, ws, or setup.

Shell helpersCommands loaded in every terminal: git safety, Docker and Postgres, terminal helpers, API keys, review opening.
›
GitGit settings and the hooks that gate pushes and commits in every repo.
›
MachineLinux power, display, internet, Tailscale, laptop lid, repairs and background services.
›
BrowserDrive one persistent Chrome window from the command line, and record proof of a feature.
›
ChromeStart Chrome the one approved way, so recordings run without a prompt.
›
AgentsCheck agent records and test them in the Agent Sandbox page.
›
ClaudeClaude Code setup: global rules, settings, hooks, skills, sessions, plugins, team park, usage guard.
›
ReviewOpen a review of changes in the review pane.
›
CodexCodex config and the Chrome bridge that keeps its plugin working.
›
DashboardOne screen of what waits for you: cases, rule changes, and calls agents made alone.
›
DeskflowShare the laptop trackpad and keyboard with the Windows PC over Tailscale.
›
ClipboardClipboard history shared between Linux and Windows, with a picker.
›
AudioSend Linux audio to the Windows machine and restore the speakers.
›
CVsThe three CV versions, their PDFs, and how to rebuild them.
›
WindowsRebuild the Windows dev environment, clone work repos, and sync skills.
›
RulesThe rules every agent follows, printed for a folder.
›
HermesThe source-installed Hermes agent, its config, and its restore runbook.
›
JevBrowser smoke checks, and asking Jev for a decision.
›
OpenCodeSwitch, inspect, and edit OpenCode profiles.
›
InstallWhere each repo file goes on this machine.
›
RecordsCase studies, incidents, plans, research, and behavior specs. Read only.
›
‹ Home

shell

Helpers sourced from zsh.d into every terminal. Each row is a group; exact names are read from the file.

Git safetyLists the files and asks [y/N] before discarding unstaged changes.
›
InfrastructureDocker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands.
›
Terminal and utilitiesset-title, killport, IP aliases, lazy-loaded nvm, node, npm, npx, Android, Java, and Bun setup.
›
API keysOpens the general-use API keys file, which is kept out of Git.
›
Review openOpens a review from bash and agents, via ~/.local/bin/review-open.
›
‹ Home

git

Git settings and the gates that run in every repo.

Git settingsAuthor identity, Git LFS, credential store, large HTTP buffer, and the hooks path.
›
Git hooksThe Lefthook shims and the gates they enforce.
›
‹ git

hooks

Lefthook shims in ~/.git-hooks that run in every repo. They need lefthook on PATH.

Push gateBlocks pushes that lack an approval note, and direct pushes to main in repos marked pull-request.
›
Commit gateBlocks commits on main in repos marked pull-request.
›
Other shimsGenerated by Lefthook.
›
Scenario gateGate script the hooks call; see the file.
›
Restore gates after reinstallRunning lefthook install overwrites the gate lines; add them back by hand.
›
‹ Home

machine

Linux machine helpers: power, display, internet, Tailscale, lid, repairs, and background services.

Battery saverPower-saver profile, turbo off, CPU capped at 8 percent. Intel P-state only; asks for sudo.
›
Normal powerBalanced profile, turbo on, cap back to 100 percent.
›
External monitorSets mode and refresh rate on the HDMI or DP output. Options: --output, --mode, --rate, --quiet.
›
Internet recoveryResets DNS and cycles networking. Re-runs itself with sudo.
›
Remote terminal recoveryRepairs DNS, restarts tailscaled, waits for reconnect, starts remote-terminal, checks port 3500.
›
Laptop lidKeep the laptop running with the lid closed, or restore the default.
›
RepairsRepair helpers for keyboard, mouse, disk, and WhatsApp.
›
Background servicesServices and timers that run without you.
›
‹ machine

lid

Lid behavior. Both changes apply after a reboot.

Keep running with lid closedWrites a logind drop-in so closing the lid does nothing. Keep the laptop ventilated.
›
Restore default lid behaviorRemoves that drop-in.
›
Closed-lid incidentThe test record: passed for 1 minute 46 seconds.
›
‹ machine

repair

Repair helpers in zsh.d/utils.zsh. Run the one for the device that misbehaves.

fix-keyboardRepairs the keyboard.
›
fix-mouseRepairs the mouse.
›
fix-diskRepairs disk trouble.
›
fix-whatsappRepairs WhatsApp; see the function for the steps.
›
‹ machine

services

Services and timers that run in the background. Nothing here needs you to start it, except where noted.

Clipstack serverRuns the clipboard history server.
›
Clipstack watcherWatches the clipboard for changes.
›
Supabase keepaliveKeeps the Supabase project awake; installed by supabase-keepalive/install.sh.
›
Codex Chrome bridge timerRepairs the Chrome plugin's latest link and patch.
›
Deskflow serverShares the keyboard and mouse; starts with the graphical session.
›
Answer syncPulls case answers every 5 minutes.
›
Dashboard serverNot a service. Starts only when you run it by hand.
›
‹ Home

browser

The browser command: one real Chrome window kept open across calls, so login and page state survive.

Run stepsRuns the actions in order on the one page; prints results as JSON.
›
StatusShows whether the background server and browser are up.
›
CloseCloses Chrome and stops the server.
›
Record proofThe one supported way to record a tab as proof of a feature.
›
InstallOnce per machine.
›
Actions and login notesFull action list, viewport presets, annotating, network capture, login gotchas.
›
Start ChromeChrome must be started through chrome.sh for recordings to run without a prompt.
›
‹ browser

record

Record proof that a feature works. Requires Chrome started through chrome.sh, so the tab titled REC-TARGET is picked with no prompt.

Start recordingBegins recording the tab.
›
Stop recordingEnds the recording.
›
Still imageFor stills, not recordings.
›
Step by stepThe full how-to.
›
‹ Home

chrome

Chrome starts only through chrome.sh, which adds the recording flag.

Start ChromeThe one way to start Chrome. Menu entries and app shortcuts use it too.
›
Install the launcherLinks the google-chrome commands and menu entry to chrome.sh. Then quit and restart Chrome.
›
FlagsThe one list of Chrome flags. Edit only here.
›
Check the flagConfirms a running Chrome has the flag.
›
Full notesWhy it exists, and its limits.
›
‹ Home

agents

Agent records, checked before any session starts, and the Agent Sandbox page for testing them.

Check recordsRefuses broken records; exits 1 when one is broken.
›
List agentsAgents, with tier, model, and number of tests.
›
Agent Sandbox pagePick an agent, change its setup, type a message, press Ask.
›
Sandbox page partsWhat each part of the page does.
›
Roles and teamsStarts a team from my-skills spawn-team team files.
›
Agent intentIntent and rules for the agent framework.
›
Sandbox PRDProduct requirements and mockups.
›
Agent rulesThe rules every agent follows.
›
‹ agents

sandbox

The Agent Sandbox page at http://127.0.0.1:8790: one conversation, with the setup in one line at the top.

Setup lineClick to change agent, model, effort, folder, rules, memory, skill versions, or tools. The next message uses it.
›
AskSends the typed message.
›
ExpectationsWhat every next answer must or must not do, such as must call Read.
›
Did it react rightFor the clicked message: which expectations passed or failed, what it did, which calls failed.
›
Every stepThe raw steps.
›
Answer againAnswers the same message with a changed setup, side by side.
›
Reply from hereContinues from that answer, as if later turns never happened.
›
Save as testAsks the same message again later from the same point.
›
Start fromOptional ready-made first message and folder of files.
›
‹ Home

claude

Claude Code setup for this machine and the Windows desktop. These are copies; see install for where they go.

Global rulesBrowser automation, communication style, research protocol, how to present work.
›
Short agent notesThe shorter global agent notes.
›
SettingsClaude Code settings.
›
Linux global mirrorCopy of the installed Linux instruction files. Machine settings stay local.
›
Windows global mirrorCopy of the Windows user .claude instruction files and their four docs.
›
HooksHooks that run by themselves.
›
SessionsContinue or resume main sessions.
›
SkillsSkills kept here and how to install them.
›
PluginsReview pane, changelog pane, scratchpad, and team board plugins.
›
Team parkThe team-park command.
›
Usage guardThe claude command wrapper that guards usage.
›
BackupsPortable snapshots of the desktop instruction packages. Not loaded automatically.
›
Communication framework draftDesign notes. Not enforced anywhere yet.
›
Skill shortlistSkills researched on skills.sh.
›
‹ claude

hooks

Hooks that run by themselves on sessions and tool calls. Nothing to type; wired in ~/.claude/settings.json.

Core rulesRule hook on SessionStart and on Bash calls.
›
Machine historyMachine history hook; see the file.
›
Team activityTeam activity hook; see the file.
›
Local server guardChecks Bash calls before they run (PreToolUse on Bash).
›
Proof reminderReminds to prove the work after Edit, MultiEdit, Write, and Bash.
›
Session typesSessionStart hook for session types.
›
Core rules testsTests the core rules hook.
›
‹ claude

sessions

Named main sessions, run through the claude wrapper.

Continue main sessionContinues the latest main session.
›
Resume a main sessionChooses one to resume.
›
Main sessions scriptRun by the wrapper for -c and -r.
›
Session types testsRuns the session types tests.
›
Session types designDesign notes for the changelog timeline and picker views.
›
‹ claude

skills

Skills kept here as backups. Global skills live in the my-skills repo and are linked by its install.sh.

Kept skillsEvery skill kept here, and what each one does.
›
Install a kept skillCopy in by hand the ones you want installed.
›
Global skillsLinks into ~/.claude/skills, ~/.codex/skills, and ~/.config/opencode/skills.
›
Skill shortlistSkills researched on skills.sh.
›
Skill design ruleSkills must declare metadata.usage-tier.
›
‹ skills

kept

Skills kept under claude/skills, plus the two Linux global skills. Each is a folder with SKILL.md.

tech-ledgerRead and write the betec Tech Ledger of evaluated tech.
›
api-key-creationGet a missing API key with browser tools (admin tier).
›
clone-websiteReverse-engineer and clone websites with parallel builders.
›
contextual-value-product-thinkingAnalyze products and startup ideas through human values.
›
web-research-assistantWeb research MCP server hosted on liel-windows; setup in SETUP-NOTES.md.
›
epic-fanout-planningTen-step pattern for QA-gap epics with parallel fan-out.
›
impeccableFrontend design: shape, critique, audit, polish.
›
iterative-action-reviewReview a completed real-world action as one iteration.
›
lab-experimentHow to run an experiment in the ai-lab project.
›
mentor-modeTeaching page; prepare_mentor_page.py builds it, serve_mentor.py serves it.
›
post-feature-cleanupPass after writing code: UI defects, leftovers, repo hygiene.
›
powershell-launchingLaunch PowerShell or a new terminal on Windows.
›
reboot-resumePreserve and resume work across a reboot or restart.
›
resume-projectResume a project; CLI notes in references/cli.md.
›
solaraai skills (four)SolaraAI content calendar, deployment, design system, and forms.
›
supabase skills (two)Supabase's skill, and its Postgres performance rules.
›
tank--communication-engineeringEngineering discipline for what an agent says and how much.
›
tank--skill-creatorCreate new skills; scripts/quick_validate.py checks them.
›
tech-cv-writerCV writing: ATS architecture, bullet formulas, templates.
›
Linux global skills (two)Behavior protocol and skill design, as installed on Linux.
›
‹ claude

mods

Plugins for the Claude Code interface. Each is a folder with hooks, types, and tests.

Review paneThe plugin behind workstation review.
›
Changelog paneChangelog pane plugin.
›
Scratchpad playgroundScratchpad plugin.
›
Team boardTeam board plugin.
›
‹ claude

team-park

Team park: the team-park command, from claude/team-park/.

Run team parkRuns the team park tool. Details: claude/team-park/README.md.
›
TestsTests for team park.
›
‹ claude

usage-guard

Usage guard: the claude command wrapper, with its installers and tests.

Claude wrapperRuns the usage guard before Claude Code.
›
Install on LinuxInstalls the wrapper beside the native claude.
›
Install on WindowsWindows install, with Install-Windows.ps1 and Launcher.cs.
›
Request budget testsTests the request budget.
›
Live refresh checkChecks usage refresh against live data.
›
Plugin hooksPlugin hooks, including shared-usage.py.
›
Resolved findingsResolved stale-usage and request-budget findings.
›
‹ Home

codex

Codex CLI config and its Chrome helpers.

Codex configCodex CLI config; deployed to the Windows user .codex folder by init-windows.
›
Chrome bridgeKeeps the Chrome plugin's latest link and its navigation patch working.
›
Direct Chrome pathCodex's direct Chrome command path. Its recorder is superseded by workstation browser record.
›
‹ codex

chrome-bridge

Keeps Codex's Chrome plugin working. Each machine patches its own local cache.

Install on LinuxInstalls the systemd user watcher and timer.
›
Install on WindowsInstalls a current-user Scheduled Task. PowerShell script beside it.
›
Repair nowFixes the latest link and the patch by hand.
›
Watcher unitWatches the Codex plugin folder.
›
Setup notesRestart requirements and details.
›
‹ Home

review

Review pane: open a review of changes.

Open a reviewOpens a review; the same command works from bash and agents.
›
Review pane pluginThe plugin behind the pane.
›
Chosen designThe recommended design, with pitches and research beside it.
›
Flow cardHow the review flow goes.
›
‹ Home

dashboard

The dashboard: one screen for its owner, read at a glance. It runs only when you start it.

Start the dashboardOpens at http://127.0.0.1:8780, or another port you pass. Listens on this machine only.
›
Waiting tabThe default tab: cases asked, rule changes proposed, calls made alone.
›
Overview tabCounts of cases and rule changes, the running team as lanes, and counts by kind.
›
Third tabCut off in the dump; confirm the name before building this row.
›
Concepts versionSecond version at http://127.0.0.1:8781 with a Projects panel.
›
ReaderOpens the rows and the open item's file.
›
TestsChecks against the real data and a real server.
›
Design roundsPitches and recommendation behind the look.
›
‹ dashboard

waiting

Three groups: Decisions, Rule changes, Decided alone. Newest day first; older days sit behind Show.

Answer a casePosts your answer as a comment on the case's GitHub issue.
›
Accept or reject a rule changeSets status in the proposal file under ~/projects/data/global/rule-proposals/ and adds a Decision line.
›
Review a call decided aloneSets review in the case file and writes the note under Final feedback. No GitHub call.
›
Open an item's fileShows the rendered file; raw HTML shows as text.
›
Show older daysOpens the older rows.
›
Data refreshKeeps the groups current.
›
Saved answersYour answers are committed by the data timer.
›
‹ dashboard

concepts

Concepts version: same server as the dashboard, with a Projects panel in the bottom-right corner.

StartOpens at http://127.0.0.1:8781, or another port you pass.
›
Projects panelOne cell per project, grouped by org, with Agent system and This machine buttons.
›
Tests17 checks against the real data and a real server.
›
Data modelWhat contains what.
›
‹ Home

deskflow

Deskflow shares the laptop trackpad and keyboard with the Windows PC over Tailscale. Installed 2026-10-05.

Everyday useControls Windows; move past Windows' left edge to return. Each machine keeps its own display.
›
Keyboard follows the mouseHow the keyboard follows the mouse you pick up, and the forwarding that is off.
›
RecoveryWhat to do when Deskflow stops.
›
Settings filesConfig copies and where each lands on this machine.
›
Network auditNetwork audit notes.
›
Firewall rulesFirewall rules for Deskflow.
›
Full guideEverything, including the GNOME input-capture prompt.
›
‹ deskflow

usb-mouse

Forwarding the Windows USB mouse to Linux has been off since 2026-10-20 because it felt slow.

Forwarding serviceTurn it back on by the steps in its README.
›
Keyboard follows the mouseHow it works and how to stop it.
›
Verification notesVerification record.
›
Focus ruleFocus rule file in the usb-mouse folder.
›
‹ deskflow

recovery

Steps when Deskflow stops. GNOME asks to allow input capture on each server start.

Start again and askStarts Deskflow and asks for input capture again.
›
Input capture promptClick Allow. Cancel stops Deskflow with exit code 0, so systemd does not restart it.
›
Full recovery notesThe full recovery steps.
›
‹ deskflow

settings

Config files for Deskflow and where each one lands.

Linux client configLinux settings.
›
Linux server configServer settings.
›
Service unitThe user service.
›
Keyboard layout drop-inKeyboard layout for the service.
›
Windows settingsSeparate client and service settings. See deskflow/README.md, repository copies.
›
‹ Home

clipboard

Clipstack: clipboard history shared between Linux and Windows, with a picker.

PickerOpens the picker to choose an earlier clipboard item.
›
ServerKeeps the history.
›
WatcherWatches the clipboard for changes.
›
Install on LinuxInstalls the services.
›
Windows sideclipstack.ahk, plus install.ps1, uninstall.ps1, and verify.ps1.
›
TestsAutomated tests for the server and Windows side.
›
Shared clipboard planThe plan behind it.
›
‹ Home

audio

Send all Linux audio to the Windows machine over Tailscale, then restore the speakers.

Start sendingSends Linux audio to the Windows machine.
›
PauseRestores the speakers.
›
On, off, status, toneSame as start and pause, plus status and a tone option.
›
Sink and portThe virtual output and the port its audio is served on.
›
Windows playerRuns the Windows ffplay reconnect loop.
›
Source filesNot in the file list given; confirm they exist before building this screen.
›
‹ Home

cv

The three CVs: sources, PDFs, and how to rebuild them.

Full Stack DeveloperThe full stack CV.
›
AI Full Stack EngineerThe AI full stack version.
›
AI IntegrationsThe AI integrations version.
›
RebuildRun from cv/. Repeat for each version.
›
Text versionsPlain text versions.
›
Design HTMLBuilds the design HTML and PDF.
›
Dated versionsSnapshots from 2026-10-04 and 2026-10-04-v2.
›
WorkflowHow to update and publish.
›
CV writing helpBullet formulas, ATS, and templates.
›
Compatibility linksSymlinks to cv/ that Hermes uses.
›
‹ Home

windows

The Windows side: rebuild a dev machine, clone work repos, sync skills. These run on Windows; this screen describes them.

Install the environmentInstalls programs, Node, VS Code, Git config, user scripts, and opens Chrome sign-in.
›
Check the installChecks what was installed.
›
Roll backRolls back using the install journal.
›
ExportExport script; see init-windows/README.md.
›
What was capturedInventory of what the install captures.
›
Sign-ins to redoSign-ins to redo by hand.
›
Clone work reposClones missing repos; safe to re-run.
›
Skill syncKeeps Windows skill links current from my-skills.
›
Full guideThe full install guide.
›
Windows global mirrorCopy of the desktop's global instruction files.
›
‹ windows

skills-sync

Skill sync on Windows: a self-hosted runner updates my-skills on each trusted push to master.

Runner serviceRuns the sync; starts automatically.
›
Sync scriptVerifies the checkout, fetches, fast-forwards, and re-runs install.ps1.
›
Catch-up taskRuns once after startup, with three retries.
›
Last successRecord of the latest successful sync.
›
TestsChecks the sync and the runner account.
›
DetailsComponents, permissions, and trust boundaries.
›
Verification notesVerification record.
›
‹ Home

rules

Rules every agent follows, from workboard/rules.yaml. Changed only by you or by an accepted rule proposal.

Print rulesPrints the rules for a folder (~/.local/bin/rules).
›
Rules fileThe rules themselves.
›
Rule metadataMetadata for each rule.
›
Generated copyGenerated from the rules file; sessions are told to read it on start.
›
Propose a changeAccept or reject it on the dashboard waiting screen.
›
TestsChecks the rules and org folder.
›
Rules per role planPlan for rules per role. The reminder timer is in its reminder folder.
›
‹ Home

hermes

Hermes: the source-installed agent. Two profiles, default and jobs, and one gateway for two Telegram bots.

RunLauncher. The checkout is at ~/projects/hermes-agent.
›
Example settingsSecret-free example settings.
›
RestoreRestore runbook.
›
Backup recordRecord of the 2026-10-02 backup.
›
Shell PATH additionThe PATH addition for ~/.zprofile.
›
Secrets and stateNot in Git. Secrets sit in mode 600 files.
›
Full statusCurrent configuration and install history.
›
‹ Home

jev

Jev: browser smoke checks, and asking Jev for decisions. Reports only the text and URL you assert.

Run a browser checkGives a URL and a goal, then checks the visible text and final URL.
›
Ask JevGets a choice. Confidence at 0.85 or more may count as approved; lower is guidance only.
›
InstallClones and pins the upstream tool, then installs the CLI.
›
SecretsAPI keys, mode 600. Not in Git.
›
InstructionsInstructions for agents using the tool.
›
Full guideShared profile, exit codes, privacy boundary.
›
‹ Home

opencode

OpenCode profiles: each profile loads its own files. These commands work in every shell.

Current profileNames the current profile.
›
All profilesShows what each profile loads.
›
SwitchSwitches new runs in every shell to that profile.
›
Sign in Claude CodeSigns a profile's Claude Code in.
›
Profile filesLists the current profile's files.
›
Edit a fileOpens one profile file.
›
HelpOne column per profile. With more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it.
›
RunRuns OpenCode with the current profile.
›
Profile tool and testsThe profile tool and its tests.
›
‹ Home

install

Where each repo file goes on this machine. Files are copies; compare a pair with diff before deciding which side wins.

Git configGit settings.
›
Shell helpersSourced by ~/.zshrc.
›
Git hooksLefthook shims.
›
Claude hook scriptsWired in ~/.claude/settings.json.
›
Session scriptsSession types hook and main-sessions.py.
›
Claude wrapperThe usage-guard wrapper.
›
Team parkThe team-park command.
›
RulesRead by the rules command.
›
SkillsCopy in the ones you want.
›
Windows instruction filesDeployed by init-windows.
›
Keep in placeinit-windows reads these by relative path. Do not move them.
›
Deskflow and user scriptsDeskflow config copies, and Windows user scripts.
›
‹ Home

records

Dated records: case studies, incidents, plans, research, and behavior specs. Read only.

Case studiesArchived, human-reviewed experiments.
›
IncidentsDated machine failures and repairs.
›
Plans and designDated plans, design rounds, research, changelog, and flows.
›
Module intentIntent and behavior for each module.
›
Behavior scenariosBehavior scenarios per feature, plus QA findings in .bdd/qa/findings/.
›
‹ records

case-studies

Three archived experiments, one folder each, each with its own README.

Codebot returnThe same design request with and without the conceptual-modeling skill. The skill-guided run was judged better.
›
Signal gardenA documentation exhibit that separates the explanation from the live interface.
›
Kernel cloud browsersCloud browsers tested live: use cases, speed against local Chrome, and session recording.
›
‹ records

plans

Dated plans, design rounds, research, and changelog. Read them; nothing runs from here.

PlansDated plans, such as opencode profiles, the rule list, Claude personas, shared clipboard, and workstation projects.
›
Design roundsPitches and recommendations for the dashboard, waiting, and agent sandbox.
›
ResearchPhase checks, proven methods, and functional research.
›
ChangelogPatch notes.
›
FlowsFlow cards and data models.
›
Raw answer
The map below covers the 21 top-level areas, each opened by `workstation <area>`, plus sub-screens for the ones with several parts. Most of it comes from the READMEs in the dump. Some rows are inferred from file names where the README was cut off or missing (team-park, the third dashboard tab, parts of the Deskflow recovery notes, and some hooks). The questions cover the decisions I could not make for you.

```json
{"screens": [
 {"path": [], "sentence": "Everything this machine's workstation kit lets you reach, grouped by what you want to do. Opened by workstation, ws, or setup.", "rows": [
   {"name": "Shell helpers", "form": "workstation shell", "what": "Commands loaded in every terminal: git safety, Docker and Postgres, terminal helpers, API keys, review opening."},
   {"name": "Git", "form": "workstation git", "what": "Git settings and the hooks that gate pushes and commits in every repo."},
   {"name": "Machine", "form": "workstation machine", "what": "Linux power, display, internet, Tailscale, laptop lid, repairs and background services."},
   {"name": "Browser", "form": "workstation browser", "what": "Drive one persistent Chrome window from the command line, and record proof of a feature."},
   {"name": "Chrome", "form": "workstation chrome", "what": "Start Chrome the one approved way, so recordings run without a prompt."},
   {"name": "Agents", "form": "workstation agents", "what": "Check agent records and test them in the Agent Sandbox page."},
   {"name": "Claude", "form": "workstation claude", "what": "Claude Code setup: global rules, settings, hooks, skills, sessions, plugins, team park, usage guard."},
   {"name": "Review", "form": "workstation review", "what": "Open a review of changes in the review pane."},
   {"name": "Codex", "form": "workstation codex", "what": "Codex config and the Chrome bridge that keeps its plugin working."},
   {"name": "Dashboard", "form": "workstation dashboard", "what": "One screen of what waits for you: cases, rule changes, and calls agents made alone."},
   {"name": "Deskflow", "form": "workstation deskflow", "what": "Share the laptop trackpad and keyboard with the Windows PC over Tailscale."},
   {"name": "Clipboard", "form": "workstation clipboard", "what": "Clipboard history shared between Linux and Windows, with a picker."},
   {"name": "Audio", "form": "workstation audio", "what": "Send Linux audio to the Windows machine and restore the speakers."},
   {"name": "CVs", "form": "workstation cv", "what": "The three CV versions, their PDFs, and how to rebuild them."},
   {"name": "Windows", "form": "workstation windows", "what": "Rebuild the Windows dev environment, clone work repos, and sync skills."},
   {"name": "Rules", "form": "workstation rules", "what": "The rules every agent follows, printed for a folder."},
   {"name": "Hermes", "form": "workstation hermes", "what": "The source-installed Hermes agent, its config, and its restore runbook."},
   {"name": "Jev", "form": "workstation jev", "what": "Browser smoke checks, and asking Jev for a decision."},
   {"name": "OpenCode", "form": "workstation opencode", "what": "Switch, inspect, and edit OpenCode profiles."},
   {"name": "Install", "form": "workstation install", "what": "Where each repo file goes on this machine."},
   {"name": "Records", "form": "workstation records", "what": "Case studies, incidents, plans, research, and behavior specs. Read only."}
 ]},
 {"path": ["shell"], "sentence": "Helpers sourced from zsh.d into every terminal. Each row is a group; exact names are read from the file.", "rows": [
   {"name": "Git safety", "form": "git checkout (wrapped in zsh.d/git-safety.zsh)", "what": "Lists the files and asks [y/N] before discarding unstaged changes."},
   {"name": "Infrastructure", "form": "functions in zsh.d/infra.zsh", "what": "Docker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands."},
   {"name": "Terminal and utilities", "form": "functions in zsh.d/utils.zsh", "what": "set-title, killport, IP aliases, lazy-loaded nvm, node, npm, npx, Android, Java, and Bun setup."},
   {"name": "API keys", "form": "api-keys-edit", "what": "Opens the general-use API keys file, which is kept out of Git."},
   {"name": "Review open", "form": "review-open", "what": "Opens a review from bash and agents, via ~/.local/bin/review-open."}
 ]},
 {"path": ["git"], "sentence": "Git settings and the gates that run in every repo.", "rows": [
   {"name": "Git settings", "form": "~/.gitconfig", "what": "Author identity, Git LFS, credential store, large HTTP buffer, and the hooks path."},
   {"name": "Git hooks", "form": "workstation git hooks", "what": "The Lefthook shims and the gates they enforce."}
 ]},
 {"path": ["git", "hooks"], "sentence": "Lefthook shims in ~/.git-hooks that run in every repo. They need lefthook on PATH.", "rows": [
   {"name": "Push gate", "form": "~/.git-hooks/pre-push", "what": "Blocks pushes that lack an approval note, and direct pushes to main in repos marked pull-request."},
   {"name": "Commit gate", "form": "~/.git-hooks/commit-msg", "what": "Blocks commits on main in repos marked pull-request."},
   {"name": "Other shims", "form": "~/.git-hooks/pre-commit and prepare-commit-msg", "what": "Generated by Lefthook."},
   {"name": "Scenario gate", "form": "~/.git-hooks/scenario-gate.py", "what": "Gate script the hooks call; see the file."},
   {"name": "Restore gates after reinstall", "form": "~/.git-hooks/", "what": "Running lefthook install overwrites the gate lines; add them back by hand."}
 ]},
 {"path": ["machine"], "sentence": "Linux machine helpers: power, display, internet, Tailscale, lid, repairs, and background services.", "rows": [
   {"name": "Battery saver", "form": "cpu-min-power.sh", "what": "Power-saver profile, turbo off, CPU capped at 8 percent. Intel P-state only; asks for sudo."},
   {"name": "Normal power", "form": "cpu-normal-power.sh", "what": "Balanced profile, turbo on, cap back to 100 percent."},
   {"name": "External monitor", "form": "fix_old_monitor_hdmi.sh", "what": "Sets mode and refresh rate on the HDMI or DP output. Options: --output, --mode, --rate, --quiet."},
   {"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "Resets DNS and cycles networking. Re-runs itself with sudo."},
   {"name": "Remote terminal recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, waits for reconnect, starts remote-terminal, checks port 3500."},
   {"name": "Laptop lid", "form": "workstation machine lid", "what": "Keep the laptop running with the lid closed, or restore the default."},
   {"name": "Repairs", "form": "workstation machine repair", "what": "Repair helpers for keyboard, mouse, disk, and WhatsApp."},
   {"name": "Background services", "form": "workstation machine services", "what": "Services and timers that run without you."}
 ]},
 {"path": ["machine", "lid"], "sentence": "Lid behavior. Both changes apply after a reboot.", "rows": [
   {"name": "Keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind drop-in so closing the lid does nothing. Keep the laptop ventilated."},
   {"name": "Restore default lid behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in."},
   {"name": "Closed-lid incident", "form": "reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "The test record: passed for 1 minute 46 seconds."}
 ]},
 {"path": ["machine", "repair"], "sentence": "Repair helpers in zsh.d/utils.zsh. Run the one for the device that misbehaves.", "rows": [
   {"name": "fix-keyboard", "form": "function in zsh.d/utils.zsh", "what": "Repairs the keyboard."},
   {"name": "fix-mouse", "form": "function in zsh.d/utils.zsh", "what": "Repairs the mouse."},
   {"name": "fix-disk", "form": "function in zsh.d/utils.zsh", "what": "Repairs disk trouble."},
   {"name": "fix-whatsapp", "form": "function in zsh.d/utils.zsh", "what": "Repairs WhatsApp; see the function for the steps."}
 ]},
 {"path": ["machine", "services"], "sentence": "Services and timers that run in the background. Nothing here needs you to start it, except where noted.", "rows": [
   {"name": "Clipstack server", "form": "clipstack/units/clipstack-server.service (user unit)", "what": "Runs the clipboard history server."},
   {"name": "Clipstack watcher", "form": "clipstack/units/clipstack-watcher.service (user unit)", "what": "Watches the clipboard for changes."},
   {"name": "Supabase keepalive", "form": "supabase-keepalive/supabase-keepalive.timer", "what": "Keeps the Supabase project awake; installed by supabase-keepalive/install.sh."},
   {"name": "Codex Chrome bridge timer", "form": "codex/chrome-bridge/codex-chrome-bridge.timer", "what": "Repairs the Chrome plugin's latest link and patch."},
   {"name": "Deskflow server", "form": "deskflow/deskflow.service (user unit)", "what": "Shares the keyboard and mouse; starts with the graphical session."},
   {"name": "Answer sync", "form": "~/.config/systemd/user/ data-pull timer", "what": "Pulls case answers every 5 minutes."},
   {"name": "Dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Not a service. Starts only when you run it by hand."}
 ]},
 {"path": ["browser"], "sentence": "The browser command: one real Chrome window kept open across calls, so login and page state survive.", "rows": [
   {"name": "Run steps", "form": "browser '<json array of steps>'", "what": "Runs the actions in order on the one page; prints results as JSON."},
   {"name": "Status", "form": "browser status", "what": "Shows whether the background server and browser are up."},
   {"name": "Close", "form": "browser close", "what": "Closes Chrome and stops the server."},
   {"name": "Record proof", "form": "workstation browser record", "what": "The one supported way to record a tab as proof of a feature."},
   {"name": "Install", "form": "cd browser && npm install && npm link", "what": "Once per machine."},
   {"name": "Actions and login notes", "form": "browser/README.md", "what": "Full action list, viewport presets, annotating, network capture, login gotchas."},
   {"name": "Start Chrome", "form": "workstation chrome", "what": "Chrome must be started through chrome.sh for recordings to run without a prompt."}
 ]},
 {"path": ["browser", "record"], "sentence": "Record proof that a feature works. Requires Chrome started through chrome.sh, so the tab titled REC-TARGET is picked with no prompt.", "rows": [
   {"name": "Start recording", "form": "recordStart step in the browser steps", "what": "Begins recording the tab."},
   {"name": "Stop recording", "form": "recordStop step in the browser steps", "what": "Ends the recording."},
   {"name": "Still image", "form": "screenshot step with a path", "what": "For stills, not recordings."},
   {"name": "Step by step", "form": "browser/README.md, Recording proof", "what": "The full how-to."}
 ]},
 {"path": ["chrome"], "sentence": "Chrome starts only through chrome.sh, which adds the recording flag.", "rows": [
   {"name": "Start Chrome", "form": "chrome/chrome.sh", "what": "The one way to start Chrome. Menu entries and app shortcuts use it too."},
   {"name": "Install the launcher", "form": "chrome/install.sh", "what": "Links the google-chrome commands and menu entry to chrome.sh. Then quit and restart Chrome."},
   {"name": "Flags", "form": "chrome/flags", "what": "The one list of Chrome flags. Edit only here."},
   {"name": "Check the flag", "form": "pgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'", "what": "Confirms a running Chrome has the flag."},
   {"name": "Full notes", "form": "chrome/README.md", "what": "Why it exists, and its limits."}
 ]},
 {"path": ["agents"], "sentence": "Agent records, checked before any session starts, and the Agent Sandbox page for testing them.", "rows": [
   {"name": "Check records", "form": "~/projects/workstation/agent-framework/agent check", "what": "Refuses broken records; exits 1 when one is broken."},
   {"name": "List agents", "form": "~/projects/workstation/agent-framework/agent list", "what": "Agents, with tier, model, and number of tests."},
   {"name": "Agent Sandbox page", "form": "~/projects/workstation/agent-framework/agent serve, then http://127.0.0.1:8790", "what": "Pick an agent, change its setup, type a message, press Ask."},
   {"name": "Sandbox page parts", "form": "workstation agents sandbox", "what": "What each part of the page does."},
   {"name": "Roles and teams", "form": "/spawn-team <team> (Claude) or $spawn-team <team> (Codex)", "what": "Starts a team from my-skills spawn-team team files."},
   {"name": "Agent intent", "form": ".idd/modules/agent-framework/INTENT.md", "what": "Intent and rules for the agent framework."},
   {"name": "Sandbox PRD", "form": "docs/plans/2026-10-22-agent-sandbox/prd.html", "what": "Product requirements and mockups."},
   {"name": "Agent rules", "form": "workstation rules", "what": "The rules every agent follows."}
 ]},
 {"path": ["agents", "sandbox"], "sentence": "The Agent Sandbox page at http://127.0.0.1:8790: one conversation, with the setup in one line at the top.", "rows": [
   {"name": "Setup line", "form": "header of the page", "what": "Click to change agent, model, effort, folder, rules, memory, skill versions, or tools. The next message uses it."},
   {"name": "Ask", "form": "Ask button", "what": "Sends the typed message."},
   {"name": "Expectations", "form": "left column, Expectations", "what": "What every next answer must or must not do, such as must call Read."},
   {"name": "Did it react right", "form": "right panel", "what": "For the clicked message: which expectations passed or failed, what it did, which calls failed."},
   {"name": "Every step", "form": "closed section, Every step in order", "what": "The raw steps."},
   {"name": "Answer again", "form": "Answer again with another setup", "what": "Answers the same message with a changed setup, side by side."},
   {"name": "Reply from here", "form": "Reply from here", "what": "Continues from that answer, as if later turns never happened."},
   {"name": "Save as test", "form": "Save as test", "what": "Asks the same message again later from the same point."},
   {"name": "Start from", "form": "Start from, before the first message", "what": "Optional ready-made first message and folder of files."}
 ]},
 {"path": ["claude"], "sentence": "Claude Code setup for this machine and the Windows desktop. These are copies; see install for where they go.", "rows": [
   {"name": "Global rules", "form": "claude/CLAUDE.md", "what": "Browser automation, communication style, research protocol, how to present work."},
   {"name": "Short agent notes", "form": "claude/AGENTS.md", "what": "The shorter global agent notes."},
   {"name": "Settings", "form": "claude/settings.json", "what": "Claude Code settings."},
   {"name": "Linux global mirror", "form": "claude/linux-global/", "what": "Copy of the installed Linux instruction files. Machine settings stay local."},
   {"name": "Windows global mirror", "form": "claude/windows-global/", "what": "Copy of the Windows user .claude instruction files and their four docs."},
   {"name": "Hooks", "form": "workstation claude hooks", "what": "Hooks that run by themselves."},
   {"name": "Sessions", "form": "workstation claude sessions", "what": "Continue or resume main sessions."},
   {"name": "Skills", "form": "workstation claude skills", "what": "Skills kept here and how to install them."},
   {"name": "Plugins", "form": "workstation claude mods", "what": "Review pane, changelog pane, scratchpad, and team board plugins."},
   {"name": "Team park", "form": "workstation claude team-park", "what": "The team-park command."},
   {"name": "Usage guard", "form": "workstation claude usage-guard", "what": "The claude command wrapper that guards usage."},
   {"name": "Backups", "form": "claude/backups/", "what": "Portable snapshots of the desktop instruction packages. Not loaded automatically."},
   {"name": "Communication framework draft", "form": "claude/communication-framework.md", "what": "Design notes. Not enforced anywhere yet."},
   {"name": "Skill shortlist", "form": "claude/skills-shortlist.md", "what": "Skills researched on skills.sh."}
 ]},
 {"path": ["claude", "hooks"], "sentence": "Hooks that run by themselves on sessions and tool calls. Nothing to type; wired in ~/.claude/settings.json.", "rows": [
   {"name": "Core rules", "form": "~/.claude/hooks/core-rules.sh", "what": "Rule hook on SessionStart and on Bash calls."},
   {"name": "Machine history", "form": "~/.claude/hooks/machine-history.sh", "what": "Machine history hook; see the file."},
   {"name": "Team activity", "form": "~/.claude/hooks/team-activity.sh", "what": "Team activity hook; see the file."},
   {"name": "Local server guard", "form": "~/.claude/hooks/local-server-guard.py", "what": "Checks Bash calls before they run (PreToolUse on Bash)."},
   {"name": "Proof reminder", "form": "~/.claude/hooks/proof-reminder.sh", "what": "Reminds to prove the work after Edit, MultiEdit, Write, and Bash."},
   {"name": "Session types", "form": "~/.claude/hooks/session-types.sh", "what": "SessionStart hook for session types."},
   {"name": "Core rules tests", "form": "claude/hooks/test_core_rules.sh", "what": "Tests the core rules hook."}
 ]},
 {"path": ["claude", "sessions"], "sentence": "Named main sessions, run through the claude wrapper.", "rows": [
   {"name": "Continue main session", "form": "claude --main -c", "what": "Continues the latest main session."},
   {"name": "Resume a main session", "form": "claude --main -r", "what": "Chooses one to resume."},
   {"name": "Main sessions script", "form": "~/.claude/hooks/main-sessions.py", "what": "Run by the wrapper for -c and -r."},
   {"name": "Session types tests", "form": "claude/session-types/tests/run.sh", "what": "Runs the session types tests."},
   {"name": "Session types design", "form": "claude/session-types/docs/design/", "what": "Design notes for the changelog timeline and picker views."}
 ]},
 {"path": ["claude", "skills"], "sentence": "Skills kept here as backups. Global skills live in the my-skills repo and are linked by its install.sh.", "rows": [
   {"name": "Kept skills", "form": "workstation claude skills kept", "what": "Every skill kept here, and what each one does."},
   {"name": "Install a kept skill", "form": "copy into ~/.claude/skills/", "what": "Copy in by hand the ones you want installed."},
   {"name": "Global skills", "form": "~/projects/my-skills (install.sh)", "what": "Links into ~/.claude/skills, ~/.codex/skills, and ~/.config/opencode/skills."},
   {"name": "Skill shortlist", "form": "claude/skills-shortlist.md", "what": "Skills researched on skills.sh."},
   {"name": "Skill design rule", "form": "volatility-based-skill-design (my-skills; claude/linux-global/skills/)", "what": "Skills must declare metadata.usage-tier."}
 ]},
 {"path": ["claude", "skills", "kept"], "sentence": "Skills kept under claude/skills, plus the two Linux global skills. Each is a folder with SKILL.md.", "rows": [
   {"name": "tech-ledger", "form": "claude/skills/tech-ledger/", "what": "Read and write the betec Tech Ledger of evaluated tech."},
   {"name": "api-key-creation", "form": "claude/skills/api-key-creation/", "what": "Get a missing API key with browser tools (admin tier)."},
   {"name": "clone-website", "form": "claude/skills/clone-website/", "what": "Reverse-engineer and clone websites with parallel builders."},
   {"name": "contextual-value-product-thinking", "form": "claude/skills/contextual-value-product-thinking/", "what": "Analyze products and startup ideas through human values."},
   {"name": "web-research-assistant", "form": "claude/skills/elad12390--web-research-assistant/", "what": "Web research MCP server hosted on liel-windows; setup in SETUP-NOTES.md."},
   {"name": "epic-fanout-planning", "form": "claude/skills/epic-fanout-planning/", "what": "Ten-step pattern for QA-gap epics with parallel fan-out."},
   {"name": "impeccable", "form": "claude/skills/impeccable/", "what": "Frontend design: shape, critique, audit, polish."},
   {"name": "iterative-action-review", "form": "claude/skills/iterative-action-review/", "what": "Review a completed real-world action as one iteration."},
   {"name": "lab-experiment", "form": "claude/skills/lab-experiment/", "what": "How to run an experiment in the ai-lab project."},
   {"name": "mentor-mode", "form": "claude/skills/mentor-mode/scripts/serve_mentor.py", "what": "Teaching page; prepare_mentor_page.py builds it, serve_mentor.py serves it."},
   {"name": "post-feature-cleanup", "form": "claude/skills/post-feature-cleanup/", "what": "Pass after writing code: UI defects, leftovers, repo hygiene."},
   {"name": "powershell-launching", "form": "claude/skills/powershell-launching/", "what": "Launch PowerShell or a new terminal on Windows."},
   {"name": "reboot-resume", "form": "claude/skills/reboot-resume/", "what": "Preserve and resume work across a reboot or restart."},
   {"name": "resume-project", "form": "claude/skills/resume-project/scripts/resume_project.py", "what": "Resume a project; CLI notes in references/cli.md."},
   {"name": "solaraai skills (four)", "form": "claude/skills/solaraai-*/", "what": "SolaraAI content calendar, deployment, design system, and forms."},
   {"name": "supabase skills (two)", "form": "claude/skills/supabase/ and supabase-postgres-best-practices/", "what": "Supabase's skill, and its Postgres performance rules."},
   {"name": "tank--communication-engineering", "form": "claude/skills/tank--communication-engineering/", "what": "Engineering discipline for what an agent says and how much."},
   {"name": "tank--skill-creator", "form": "claude/skills/tank--skill-creator/", "what": "Create new skills; scripts/quick_validate.py checks them."},
   {"name": "tech-cv-writer", "form": "claude/skills/tech-cv-writer/", "what": "CV writing: ATS architecture, bullet formulas, templates."},
   {"name": "Linux global skills (two)", "form": "claude/linux-global/skills/tank--bulletproof/ and volatility-based-skill-design/", "what": "Behavior protocol and skill design, as installed on Linux."}
 ]},
 {"path": ["claude", "mods"], "sentence": "Plugins for the Claude Code interface. Each is a folder with hooks, types, and tests.", "rows": [
   {"name": "Review pane", "form": "claude/mods/review-pane/", "what": "The plugin behind workstation review."},
   {"name": "Changelog pane", "form": "claude/mods/changelog-pane/", "what": "Changelog pane plugin."},
   {"name": "Scratchpad playground", "form": "claude/mods/scratchpad-playground/", "what": "Scratchpad plugin."},
   {"name": "Team board", "form": "claude/mods/team-board/", "what": "Team board plugin."}
 ]},
 {"path": ["claude", "team-park"], "sentence": "Team park: the team-park command, from claude/team-park/.", "rows": [
   {"name": "Run team park", "form": "team-park (~/.local/bin/team-park)", "what": "Runs the team park tool. Details: claude/team-park/README.md."},
   {"name": "Tests", "form": "claude/team-park/test_team_park.py", "what": "Tests for team park."}
 ]},
 {"path": ["claude", "usage-guard"], "sentence": "Usage guard: the claude command wrapper, with its installers and tests.", "rows": [
   {"name": "Claude wrapper", "form": "claude (~/bin/claude, ahead of ~/.local/bin/claude)", "what": "Runs the usage guard before Claude Code."},
   {"name": "Install on Linux", "form": "claude/usage-guard/install.sh", "what": "Installs the wrapper beside the native claude."},
   {"name": "Install on Windows", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Windows install, with Install-Windows.ps1 and Launcher.cs."},
   {"name": "Request budget tests", "form": "claude/usage-guard/tests/test_request_budget.py", "what": "Tests the request budget."},
   {"name": "Live refresh check", "form": "claude/usage-guard/tests/live-refresh.py", "what": "Checks usage refresh against live data."},
   {"name": "Plugin hooks", "form": "claude/usage-guard/plugin/hooks/", "what": "Plugin hooks, including shared-usage.py."},
   {"name": "Resolved findings", "form": "claude/usage-guard/.bdd/qa/resolutions/", "what": "Resolved stale-usage and request-budget findings."}
 ]},
 {"path": ["codex"], "sentence": "Codex CLI config and its Chrome helpers.", "rows": [
   {"name": "Codex config", "form": "codex/config.toml", "what": "Codex CLI config; deployed to the Windows user .codex folder by init-windows."},
   {"name": "Chrome bridge", "form": "workstation codex chrome-bridge", "what": "Keeps the Chrome plugin's latest link and its navigation patch working."},
   {"name": "Direct Chrome path", "form": "codex/browser/README.md", "what": "Codex's direct Chrome command path. Its recorder is superseded by workstation browser record."}
 ]},
 {"path": ["codex", "chrome-bridge"], "sentence": "Keeps Codex's Chrome plugin working. Each machine patches its own local cache.", "rows": [
   {"name": "Install on Linux", "form": "codex/chrome-bridge/install.sh", "what": "Installs the systemd user watcher and timer."},
   {"name": "Install on Windows", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs a current-user Scheduled Task. PowerShell script beside it."},
   {"name": "Repair now", "form": "codex/chrome-bridge/repair.mjs", "what": "Fixes the latest link and the patch by hand."},
   {"name": "Watcher unit", "form": "codex/chrome-bridge/codex-chrome-bridge.path", "what": "Watches the Codex plugin folder."},
   {"name": "Setup notes", "form": "codex/chrome-bridge/README.md", "what": "Restart requirements and details."}
 ]},
 {"path": ["review"], "sentence": "Review pane: open a review of changes.", "rows": [
   {"name": "Open a review", "form": "review-open (~/.local/bin/review-open)", "what": "Opens a review; the same command works from bash and agents."},
   {"name": "Review pane plugin", "form": "claude/mods/review-pane/", "what": "The plugin behind the pane."},
   {"name": "Chosen design", "form": "claude/mods/review-pane/docs/design/2026-10-18-review-pane/recommendation.md", "what": "The recommended design, with pitches and research beside it."},
   {"name": "Flow card", "form": "claude/mods/review-pane/docs/flows/2026-10-18/flow-card.md", "what": "How the review flow goes."}
 ]},
 {"path": ["dashboard"], "sentence": "The dashboard: one screen for its owner, read at a glance. It runs only when you start it.", "rows": [
   {"name": "Start the dashboard", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Opens at http://127.0.0.1:8780, or another port you pass. Listens on this machine only."},
   {"name": "Waiting tab", "form": "workstation dashboard waiting", "what": "The default tab: cases asked, rule changes proposed, calls made alone."},
   {"name": "Overview tab", "form": "Overview tab on the dashboard page", "what": "Counts of cases and rule changes, the running team as lanes, and counts by kind."},
   {"name": "Third tab", "form": "tab on the dashboard page, named in dashboard/README.md", "what": "Cut off in the dump; confirm the name before building this row."},
   {"name": "Concepts version", "form": "workstation dashboard concepts", "what": "Second version at http://127.0.0.1:8781 with a Projects panel."},
   {"name": "Reader", "form": "reader panel over the right column", "what": "Opens the rows and the open item's file."},
   {"name": "Tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Checks against the real data and a real server."},
   {"name": "Design rounds", "form": "docs/design/2026-10-17-dashboard/", "what": "Pitches and recommendation behind the look."}
 ]},
 {"path": ["dashboard", "waiting"], "sentence": "Three groups: Decisions, Rule changes, Decided alone. Newest day first; older days sit behind Show.", "rows": [
   {"name": "Answer a case", "form": "answer box on a Decisions row", "what": "Posts your answer as a comment on the case's GitHub issue."},
   {"name": "Accept or reject a rule change", "form": "Accept or Reject on a Rule changes row", "what": "Sets status in the proposal file under ~/projects/data/global/rule-proposals/ and adds a Decision line."},
   {"name": "Review a call decided alone", "form": "Justified, Should have asked, Wrong call, and a note", "what": "Sets review in the case file and writes the note under Final feedback. No GitHub call."},
   {"name": "Open an item's file", "form": "/api/file?path=...&as=html", "what": "Shows the rendered file; raw HTML shows as text."},
   {"name": "Show older days", "form": "Show button", "what": "Opens the older rows."},
   {"name": "Data refresh", "form": "page refreshes every 30 seconds", "what": "Keeps the groups current."},
   {"name": "Saved answers", "form": "data timer, within 5 minutes", "what": "Your answers are committed by the data timer."}
 ]},
 {"path": ["dashboard", "concepts"], "sentence": "Concepts version: same server as the dashboard, with a Projects panel in the bottom-right corner.", "rows": [
   {"name": "Start", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Opens at http://127.0.0.1:8781, or another port you pass."},
   {"name": "Projects panel", "form": "Projects panel, bottom right", "what": "One cell per project, grouped by org, with Agent system and This machine buttons."},
   {"name": "Tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "17 checks against the real data and a real server."},
   {"name": "Data model", "form": "docs/flows/2026-10-17/data-model.md", "what": "What contains what."}
 ]},
 {"path": ["deskflow"], "sentence": "Deskflow shares the laptop trackpad and keyboard with the Windows PC over Tailscale. Installed 2026-10-05.", "rows": [
   {"name": "Everyday use", "form": "move past the laptop's right edge", "what": "Controls Windows; move past Windows' left edge to return. Each machine keeps its own display."},
   {"name": "Keyboard follows the mouse", "form": "workstation deskflow usb-mouse", "what": "How the keyboard follows the mouse you pick up, and the forwarding that is off."},
   {"name": "Recovery", "form": "workstation deskflow recovery", "what": "What to do when Deskflow stops."},
   {"name": "Settings files", "form": "workstation deskflow settings", "what": "Config copies and where each lands on this machine."},
   {"name": "Network audit", "form": "deskflow/NETWORK-AUDIT.md", "what": "Network audit notes."},
   {"name": "Firewall rules", "form": "deskflow/deskflow-lockdown.nft", "what": "Firewall rules for Deskflow."},
   {"name": "Full guide", "form": "deskflow/README.md", "what": "Everything, including the GNOME input-capture prompt."}
 ]},
 {"path": ["deskflow", "usb-mouse"], "sentence": "Forwarding the Windows USB mouse to Linux has been off since 2026-10-20 because it felt slow.", "rows": [
   {"name": "Forwarding service", "form": "deskflow-usb-mouse.service (disabled)", "what": "Turn it back on by the steps in its README."},
   {"name": "Keyboard follows the mouse", "form": "deskflow/usb-mouse/README.md, Keyboard follows the mouse", "what": "How it works and how to stop it."},
   {"name": "Verification notes", "form": "deskflow/usb-mouse/VERIFICATION.md", "what": "Verification record."},
   {"name": "Focus rule", "form": "deskflow/usb-mouse/70-deskflow-focus.rules", "what": "Focus rule file in the usb-mouse folder."}
 ]},
 {"path": ["deskflow", "recovery"], "sentence": "Steps when Deskflow stops. GNOME asks to allow input capture on each server start.", "rows": [
   {"name": "Start again and ask", "form": "resume-kvm", "what": "Starts Deskflow and asks for input capture again."},
   {"name": "Input capture prompt", "form": "GNOME prompt", "what": "Click Allow. Cancel stops Deskflow with exit code 0, so systemd does not restart it."},
   {"name": "Full recovery notes", "form": "deskflow/README.md, If it", "what": "The full recovery steps."}
 ]},
 {"path": ["deskflow", "settings"], "sentence": "Config files for Deskflow and where each one lands.", "rows": [
   {"name": "Linux client config", "form": "deskflow/linux.conf to ~/.config/Deskflow/Deskflow.conf", "what": "Linux settings."},
   {"name": "Linux server config", "form": "deskflow/server.conf to ~/.config/Deskflow/server.conf", "what": "Server settings."},
   {"name": "Service unit", "form": "deskflow/deskflow.service to ~/.config/systemd/user/deskflow.service", "what": "The user service."},
   {"name": "Keyboard layout drop-in", "form": "deskflow/deskflow.service.d/keyboard-layout.conf", "what": "Keyboard layout for the service."},
   {"name": "Windows settings", "form": "deskflow/windows.conf and windows-service.conf", "what": "Separate client and service settings. See deskflow/README.md, repository copies."}
 ]},
 {"path": ["clipboard"], "sentence": "Clipstack: clipboard history shared between Linux and Windows, with a picker.", "rows": [
   {"name": "Picker", "form": "python3 ~/projects/workstation/clipstack/picker.py", "what": "Opens the picker to choose an earlier clipboard item."},
   {"name": "Server", "form": "clipstack/server.py (service clipstack-server)", "what": "Keeps the history."},
   {"name": "Watcher", "form": "clipstack/watcher.py (service clipstack-watcher)", "what": "Watches the clipboard for changes."},
   {"name": "Install on Linux", "form": "clipstack/install.sh", "what": "Installs the services."},
   {"name": "Windows side", "form": "clipstack/windows/", "what": "clipstack.ahk, plus install.ps1, uninstall.ps1, and verify.ps1."},
   {"name": "Tests", "form": "clipstack/test_server.py and clipstack/windows/tests/run-tests.ps1", "what": "Automated tests for the server and Windows side."},
   {"name": "Shared clipboard plan", "form": "docs/plans/2026-10-26-shared-clipboard/plan.md", "what": "The plan behind it."}
 ]},
 {"path": ["audio"], "sentence": "Send all Linux audio to the Windows machine over Tailscale, then restore the speakers.", "rows": [
   {"name": "Start sending", "form": "audio-start", "what": "Sends Linux audio to the Windows machine."},
   {"name": "Pause", "form": "audio-pause", "what": "Restores the speakers."},
   {"name": "On, off, status, tone", "form": "audio-share on, off, status, tone", "what": "Same as start and pause, plus status and a tone option."},
   {"name": "Sink and port", "form": "null sink windows_share; tcp port 4953", "what": "The virtual output and the port its audio is served on."},
   {"name": "Windows player", "form": "windows-audio-share agent", "what": "Runs the Windows ffplay reconnect loop."},
   {"name": "Source files", "form": "audio-share/ and zsh.d/audio-share.zsh", "what": "Not in the file list given; confirm they exist before building this screen."}
 ]},
 {"path": ["cv"], "sentence": "The three CVs: sources, PDFs, and how to rebuild them.", "rows": [
   {"name": "Full Stack Developer", "form": "cv/cv-full-stack.pdf (source cv/cv-full-stack.tex)", "what": "The full stack CV."},
   {"name": "AI Full Stack Engineer", "form": "cv/cv-ai-full-stack.pdf (source cv/cv-ai-full-stack.tex)", "what": "The AI full stack version."},
   {"name": "AI Integrations", "form": "cv/cv-ai-integrations.pdf (source cv/cv-ai-integrations.tex)", "what": "The AI integrations version."},
   {"name": "Rebuild", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex", "what": "Run from cv/. Repeat for each version."},
   {"name": "Text versions", "form": "cv/text/build-full.sh", "what": "Plain text versions."},
   {"name": "Design HTML", "form": "cv/design/build-design.py", "what": "Builds the design HTML and PDF."},
   {"name": "Dated versions", "form": "cv/versions/", "what": "Snapshots from 2026-10-04 and 2026-10-04-v2."},
   {"name": "Workflow", "form": "cv/WORKFLOW.md", "what": "How to update and publish."},
   {"name": "CV writing help", "form": "claude/skills/tech-cv-writer/", "what": "Bullet formulas, ATS, and templates."},
   {"name": "Compatibility links", "form": "/home/liel/projects/tech-cv-workspace/", "what": "Symlinks to cv/ that Hermes uses."}
 ]},
 {"path": ["windows"], "sentence": "The Windows side: rebuild a dev machine, clone work repos, sync skills. These run on Windows; this screen describes them.", "rows": [
   {"name": "Install the environment", "form": "init-windows/Start-Install.cmd", "what": "Installs programs, Node, VS Code, Git config, user scripts, and opens Chrome sign-in."},
   {"name": "Check the install", "form": "init-windows/Smoke-Test-Windows.ps1 and Verify-Windows.ps1", "what": "Checks what was installed."},
   {"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Rolls back using the install journal."},
   {"name": "Export", "form": "init-windows/Export-Windows.ps1", "what": "Export script; see init-windows/README.md."},
   {"name": "What was captured", "form": "init-windows/inventory.md", "what": "Inventory of what the install captures."},
   {"name": "Sign-ins to redo", "form": "init-windows/secrets-checklist.md", "what": "Sign-ins to redo by hand."},
   {"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones missing repos; safe to re-run."},
   {"name": "Skill sync", "form": "workstation windows skills-sync", "what": "Keeps Windows skill links current from my-skills."},
   {"name": "Full guide", "form": "init-windows/README.md", "what": "The full install guide."},
   {"name": "Windows global mirror", "form": "claude/windows-global/", "what": "Copy of the desktop's global instruction files."}
 ]},
 {"path": ["windows", "skills-sync"], "sentence": "Skill sync on Windows: a self-hosted runner updates my-skills on each trusted push to master.", "rows": [
   {"name": "Runner service", "form": "actions.runner.Lebnor-my-skills.my-skills-liel-windows", "what": "Runs the sync; starts automatically."},
   {"name": "Sync script", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Verifies the checkout, fetches, fast-forwards, and re-runs install.ps1."},
   {"name": "Catch-up task", "form": "MySkillsSync-CatchUp scheduled task", "what": "Runs once after startup, with three retries."},
   {"name": "Last success", "form": "last-success.json in the MySkillsSync state folder", "what": "Record of the latest successful sync."},
   {"name": "Tests", "form": "skills-sync-windows/Test-Sync.ps1 and Test-Account.ps1", "what": "Checks the sync and the runner account."},
   {"name": "Details", "form": "skills-sync-windows/README.md", "what": "Components, permissions, and trust boundaries."},
   {"name": "Verification notes", "form": "skills-sync-windows/verification.md", "what": "Verification record."}
 ]},
 {"path": ["rules"], "sentence": "Rules every agent follows, from workboard/rules.yaml. Changed only by you or by an accepted rule proposal.", "rows": [
   {"name": "Print rules", "form": "rules [folder]", "what": "Prints the rules for a folder (~/.local/bin/rules)."},
   {"name": "Rules file", "form": "workboard/rules.yaml", "what": "The rules themselves."},
   {"name": "Rule metadata", "form": "workboard/rules-meta.yaml", "what": "Metadata for each rule."},
   {"name": "Generated copy", "form": "~/.claude/references/rules.md", "what": "Generated from the rules file; sessions are told to read it on start."},
   {"name": "Propose a change", "form": "rule proposal file in ~/projects/data/global/rule-proposals/", "what": "Accept or reject it on the dashboard waiting screen."},
   {"name": "Tests", "form": "workboard/test_rules.py and workboard/test_org_folder.py", "what": "Checks the rules and org folder."},
   {"name": "Rules per role plan", "form": "docs/plans/2026-10-24-rules-per-role/plan.md", "what": "Plan for rules per role. The reminder timer is in its reminder folder."}
 ]},
 {"path": ["hermes"], "sentence": "Hermes: the source-installed agent. Two profiles, default and jobs, and one gateway for two Telegram bots.", "rows": [
   {"name": "Run", "form": "hermes (~/.local/bin/hermes)", "what": "Launcher. The checkout is at ~/projects/hermes-agent."},
   {"name": "Example settings", "form": "hermes/default.config.example.yaml and jobs.config.example.yaml", "what": "Secret-free example settings."},
   {"name": "Restore", "form": "hermes/RESTORE.md", "what": "Restore runbook."},
   {"name": "Backup record", "form": "hermes/BACKUP-2026-10-02.md", "what": "Record of the 2026-10-02 backup."},
   {"name": "Shell PATH addition", "form": "hermes/zprofile-path.zsh", "what": "The PATH addition for ~/.zprofile."},
   {"name": "Secrets and state", "form": "~/.hermes", "what": "Not in Git. Secrets sit in mode 600 files."},
   {"name": "Full status", "form": "hermes/README.md", "what": "Current configuration and install history."}
 ]},
 {"path": ["jev"], "sentence": "Jev: browser smoke checks, and asking Jev for decisions. Reports only the text and URL you assert.", "rows": [
   {"name": "Run a browser check", "form": "jev-browser-test (~/.local/bin/jev-browser-test)", "what": "Gives a URL and a goal, then checks the visible text and final URL."},
   {"name": "Ask Jev", "form": "jev '<context>' -c '<question>' <options>,other_none -j", "what": "Gets a choice. Confidence at 0.85 or more may count as approved; lower is guidance only."},
   {"name": "Install", "form": "jev-browser-test/install.sh", "what": "Clones and pins the upstream tool, then installs the CLI."},
   {"name": "Secrets", "form": "~/.config/jev-browser-test/env", "what": "API keys, mode 600. Not in Git."},
   {"name": "Instructions", "form": "jev-browser-test/instructions.md", "what": "Instructions for agents using the tool."},
   {"name": "Full guide", "form": "jev-browser-test/README.md", "what": "Shared profile, exit codes, privacy boundary."}
 ]},
 {"path": ["opencode"], "sentence": "OpenCode profiles: each profile loads its own files. These commands work in every shell.", "rows": [
   {"name": "Current profile", "form": "opencode-profile", "what": "Names the current profile."},
   {"name": "All profiles", "form": "opencode-profiles", "what": "Shows what each profile loads."},
   {"name": "Switch", "form": "opencode-switch <name>", "what": "Switches new runs in every shell to that profile."},
   {"name": "Sign in Claude Code", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
   {"name": "Profile files", "form": "opencode-files", "what": "Lists the current profile's files."},
   {"name": "Edit a file", "form": "opencode-edit <file>", "what": "Opens one profile file."},
   {"name": "Help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "One column per profile. With more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it."},
   {"name": "Run", "form": "opencode or oc", "what": "Runs OpenCode with the current profile."},
   {"name": "Profile tool and tests", "form": "opencode-profiles/profiles.py and test_profiles.py", "what": "The profile tool and its tests."}
 ]},
 {"path": ["install"], "sentence": "Where each repo file goes on this machine. Files are copies; compare a pair with diff before deciding which side wins.", "rows": [
   {"name": "Git config", "form": ".gitconfig to ~/.gitconfig", "what": "Git settings."},
   {"name": "Shell helpers", "form": "zsh.d/*.zsh to ~/.zsh.d/", "what": "Sourced by ~/.zshrc."},
   {"name": "Git hooks", "form": "git-hooks/* to ~/.git-hooks/", "what": "Lefthook shims."},
   {"name": "Claude hook scripts", "form": "claude/hooks/* to ~/.claude/hooks/", "what": "Wired in ~/.claude/settings.json."},
   {"name": "Session scripts", "form": "claude/session-types/ scripts to ~/.claude/hooks/", "what": "Session types hook and main-sessions.py."},
   {"name": "Claude wrapper", "form": "claude/usage-guard/claude to ~/bin/claude", "what": "The usage-guard wrapper."},
   {"name": "Team park", "form": "claude/team-park/team_park.py to ~/.local/bin/team-park", "what": "The team-park command."},
   {"name": "Rules", "form": "workboard/rules.yaml", "what": "Read by the rules command."},
   {"name": "Skills", "form": "claude/skills/* to ~/.claude/skills/", "what": "Copy in the ones you want."},
   {"name": "Windows instruction files", "form": "claude/CLAUDE.md and claude/settings.json to the Windows user .claude folder; codex/config.toml to the .codex folder", "what": "Deployed by init-windows."},
   {"name": "Keep in place", "form": "claude/CLAUDE.md, claude/AGENTS.md, claude/settings.json, codex/config.toml", "what": "init-windows reads these by relative path. Do not move them."},
   {"name": "Deskflow and user scripts", "form": "workstation deskflow settings; init-windows/user-scripts/*", "what": "Deskflow config copies, and Windows user scripts."}
 ]},
 {"path": ["records"], "sentence": "Dated records: case studies, incidents, plans, research, and behavior specs. Read only.", "rows": [
   {"name": "Case studies", "form": "workstation records case-studies", "what": "Archived, human-reviewed experiments."},
   {"name": "Incidents", "form": "reference/incidents/ (index: reference/README.md)", "what": "Dated machine failures and repairs."},
   {"name": "Plans and design", "form": "workstation records plans", "what": "Dated plans, design rounds, research, changelog, and flows."},
   {"name": "Module intent", "form": ".idd/modules/*/INTENT.md", "what": "Intent and behavior for each module."},
   {"name": "Behavior scenarios", "form": ".bdd/features/*/", "what": "Behavior scenarios per feature, plus QA findings in .bdd/qa/findings/."}
 ]},
 {"path": ["records", "case-studies"], "sentence": "Three archived experiments, one folder each, each with its own README.", "rows": [
   {"name": "Codebot return", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "The same design request with and without the conceptual-modeling skill. The skill-guided run was judged better."},
   {"name": "Signal garden", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "A documentation exhibit that separates the explanation from the live interface."},
   {"name": "Kernel cloud browsers", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Cloud browsers tested live: use cases, speed against local Chrome, and session recording."}
 ]},
 {"path": ["records", "plans"], "sentence": "Dated plans, design rounds, research, and changelog. Read them; nothing runs from here.", "rows": [
   {"name": "Plans", "form": "docs/plans/", "what": "Dated plans, such as opencode profiles, the rule list, Claude personas, shared clipboard, and workstation projects."},
   {"name": "Design rounds", "form": "docs/design/", "what": "Pitches and recommendations for the dashboard, waiting, and agent sandbox."},
   {"name": "Research", "form": "docs/research/ and docs/functional-research/", "what": "Phase checks, proven methods, and functional research."},
   {"name": "Changelog", "form": "docs/changelog/", "what": "Patch notes."},
   {"name": "Flows", "form": "docs/flows/", "what": "Flow cards and data models."}
 ]}
],
"questions": [
 "Credentials in zsh.d: infra.zsh (git_pull_with_creds, Prisma init) and utils.zsh (update-gitlab-token) embed a credential in git URLs. Should the help screens list those helpers? Recommendation: leave them out of the map until the credential is rotated and moved to a credential manager, since the secrets checklist already says to treat it as compromised.",
 "Retired and superseded tools: lan-mouse (retired 2026-10-05), codex/playwright-mcp (retired), and the codex/browser recorder (superseded by browser recordStart and recordStop). Should they appear? Recommendation: leave them off the top-level and sub-screens, and mention them only in Records, since the README keeps some of them as rollback files.",
 "Command names: the README gives one command three names, workstation, ws, and setup. setup is generic and may clash with other tools. Recommendation: keep workstation and ws, and drop setup from the help text.",
 "Files missing from the dump: workstation-cli/ and zsh.d/workstation.zsh, audio-share/ and zsh.d/audio-share.zsh, and Verify-Windows.ps1 are described in READMEs but absent from the file list. I planned those screens from the READMEs. Recommendation: confirm they exist before building the workstation, audio, and Windows screens.",
 "Windows items on a Linux help screen (init-windows, skill sync, Windows clipstack, Windows Codex bridge): should they be listed or left out? Recommendation: list them, marked as Windows, with their file path as the form, since this CLI cannot run them.",
 "Dashboard concepts: a separate top-level item, or a version under dashboard? Recommendation: keep it under dashboard, since it shares the same server code.",
 "Dashboard start: it is not a service and runs only when started by hand. Should the help offer a service command? Recommendation: keep it manual; the README leaves service setup to you.",
 "Hooks: show the hooks that run by themselves under Claude, or hide them? Recommendation: show them with their wiring path, since they change what an agent sees.",
 "Records: list the dated folders only, or make each openable? Recommendation: list them with their folder path, since they are read by hand."
]}
```

Today's skills · run 3 exit=0 seconds=151 · prompt

P1 Recall: 0.543P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.38
As terminal help
The parts of this workstation kit, in seven groups. Run ws followed by a group name and help to list what is inside it.
Shell and gitws shellPrints the shell screen: git, servers, the terminal helpers, OpenCode, the API keys file and review-open.
Machinews machinePrints the machine screen: power, repair, the laptop lid, sharing with Windows, and the background services.
Agentsws agentsPrints the agents screen: the rules, the Agent Sandbox, main sessions, team-park, the usage guard, Hermes and the assistant setup.
Browserws browserPrints the browser screen: the browser command, Chrome, and the behavioral smoke test.
Dashboardsws dashboardsPrints the dashboards screen: the two local dashboards and their checks.
Windowsws windowsPrints the Windows screen: the bootstrap, its checks, the skills sync and the repo clones, all run on Windows.
Documentsws documentsPrints the documents screen: CVs, case studies, incident records, plans and this kit's guide.
shell
The shell helpers this kit copies into ~/.zsh.d: git, servers, the terminal, OpenCode, the keys file and review.
Gitws shell gitPrints the git screen: the checkout guard, the Git settings and the hooks.
Serversws shell serversPrints the servers screen: Docker and Compose, Prisma and Postgres, nginx and the VPN.
Terminalws shell terminalPrints the terminal screen: the window title, killport, the IP aliases and the Node, Android, Java and Bun setup.
OpenCodews shell opencodePrints the OpenCode screen: the profiles, what each loads, and the commands that switch and edit them.
API keys file~/.config/api-keys/envOpens the general-use API keys file, which stays out of Git.
review-openreview-openOpens a file for review, from zsh, bash or an agent.
Shell fileszsh.d/Opens the shell files in the repo that get copied to ~/.zsh.d.
shell › git
The git helpers: a guard on checkout, the Git settings, and the hooks that run in every repo.
Checkout guardgit checkout (wrapped in ~/.zsh.d/git-safety.zsh)Runs git checkout after listing the files and asking y or N before discarding unstaged changes.
Git settings~/.gitconfigOpens the Git settings: author, LFS, the credential store, the upload buffer and the hooks path.
Git hooks~/.git-hooks/Opens the Lefthook hook folder that runs in every repo and holds the push and commit gates.
shell › servers
The shortcuts for containers, databases, the web server and the VPN.
Docker and Compose~/.zsh.d/infra.zshRuns the Docker and Compose shortcuts.
Prisma and Postgres~/.zsh.d/infra.zshRuns the Prisma and Postgres helpers.
nginx and VPN~/.zsh.d/infra.zshRuns the nginx and VPN commands.
shell › terminal
The terminal helpers from utils.zsh: the window title, ports, IP aliases and the lazily loaded language tools.
Window titleset-titleSets the terminal window title.
killportkillportStops the process that holds a port.
IP aliases~/.zsh.d/utils.zshRuns the IP address aliases.
Node tools~/.zsh.d/utils.zshLoads nvm the first time node, npm or npx runs.
Android, Java and Bun~/.zsh.d/utils.zshSets up the Android, Java and Bun paths.
shell › opencode
The OpenCode profiles: what each one loads, and the commands that run, switch and edit them.
Run OpenCodeopencode (also oc)Runs OpenCode with the current profile.
Current profileopencode-profilePrints the name of the current profile.
Profiles tableopencode-profilesPrints each profile and the files it loads.
Switch profileopencode-switch <name>Switches the profile that every new run uses.
Sign in a profileopencode-login <name>Starts the sign-in of that profile's Claude Code.
Profile filesopencode-filesLists the current profile's files.
Edit a profile fileopencode-edit <file>Edits one of the current profile's files.
Profile helpopencode help (also oc help)Prints the profile help, and with more than 3 profiles writes a help page and opens it.
Profiles folderopencode-profiles/Opens the folder with each profile's files.
machine
Scripts that tune and repair this Linux laptop, and the sharing and background services that run on it.
Powerws machine powerPrints the power screen: the CPU profiles and the HDMI mode fix.
Repairws machine repairPrints the repair screen: internet, the remote terminal, and the keyboard, mouse, disk and WhatsApp fixes.
Laptop lidws machine laptopPrints the laptop screen: keeping it running with the lid closed.
Sharingws machine sharingPrints the sharing screen: Deskflow, audio to Windows, and the clipboard picker.
Servicesws machine servicesPrints the services screen: the background units this machine runs.
machine › power
The scripts that change the CPU power profile and the external display mode.
Power savercpu-min-power.shRuns the power-saver profile with turbo off and the CPU capped at 8 percent. Intel only, asks for sudo.
Balancedcpu-normal-power.shRuns the balanced profile with turbo on and the cap removed.
HDMI modefix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output.
machine › repair
The repair scripts for when the internet, the remote terminal, or a device stops working.
Internet recoverylinux-internet-recovery.shRestarts DNS and networking to bring the internet back.
Remote terminalrecover-tailscale-remote-terminal.shRestarts Tailscale and the remote terminal, then checks port 3500.
Keyboard fixfix-keyboardRuns the keyboard repair.
Mouse fixfix-mouseRuns the mouse repair.
Disk fixfix-diskRuns the disk repair.
WhatsApp fixfix-whatsappRuns the WhatsApp repair.
machine › laptop
The two switches for what closing the laptop lid does. Each applies after a reboot.
Keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shStops closing the lid from sleeping the laptop; applies after a reboot.
Restore lid behaviorlaptop-utilities/restore-default-lid-behavior.shRestores the default lid behavior; applies after a reboot.
machine › sharing
Keyboard and mouse sharing with Windows, audio sent to Windows, and the clipboard picker.
Start Deskflowresume-kvmStarts Deskflow again and asks for input access.
Deskflow settingsdeskflow/linux.confOpens the Linux Deskflow settings.
USB mouse sharing notesdeskflow/usb-mouse/README.mdOpens the notes on USB mouse sharing, which has been off since 2026-10-20.
Send audio to Windowsaudio-startStarts sending all Linux audio to the Windows machine over Tailscale.
Return audioaudio-pausePauses that send and restores the local speakers.
Clipboard pickerclipstack/picker.pyRuns the clipboard picker over the shared clipboard history.
machine › services
The background units this machine runs, as the files that define them.
Clipboard serverclipstack/units/clipstack-server.serviceOpens the clipboard server's unit file.
Clipboard watcherclipstack/units/clipstack-watcher.serviceOpens the clipboard watcher's unit file.
Deskflow servicedeskflow/deskflow.serviceOpens the Deskflow user service file.
Supabase keepalivesupabase-keepalive/supabase-keepalive.timerOpens the timer that keeps the Supabase connection alive.
Data pull~/projects/data/systemd/Opens the folder of the timer and service that pull answers every 5 minutes.
agents
The tools that run the AI assistants on this machine, and where their rules and setup live.
RulesrulesPrints the rules every organization follows.
Rules fileworkboard/rules.yamlOpens the rules file that rules prints.
Agent Sandboxws agents sandboxPrints the sandbox screen: the Agent Sandbox page and the checks on agent records.
Continue main sessionclaude --main -cContinues the main Claude session in this folder.
Resume a main sessionclaude --main -rResumes a chosen main Claude session.
Team parkteam-parkRuns the team parking script; see claude/team-park/README.md.
Claude with usage guardclaude (~/bin/claude)Runs Claude Code through the usage guard, ahead of the native command.
HermeshermesRuns the Hermes agent.
Assistant setupws agents setupPrints the setup screen: global instructions, settings, hooks, skills and the Codex bridge.
agents › sandbox
The Agent Sandbox page, and the checks that refuse broken agent records.
Sandbox pageagent serve (http://127.0.0.1:8790)Starts the Agent Sandbox page on port 8790.
Check agentsagent checkChecks every agent record and exits 1 on a broken one.
List agentsagent listLists the agents with their tier, model and number of tests.
agents › setup
The global instructions, settings, hooks and skills the assistants read, and where each one lives.
Claude instructionsclaude/CLAUDE.mdOpens the global instructions every Claude session reads.
Claude settingsclaude/settings.jsonOpens the Claude Code settings deployed to Windows.
Codex configcodex/config.tomlOpens the Codex CLI config.
Hooksclaude/hooks/Opens the hook scripts Claude runs at session start and on tool calls.
Global skills~/projects/my-skillsOpens the repo of global skills that install links into each assistant.
Skill backupsclaude/skills/Opens the backups of the skills kept in this repo.
Codex Chrome bridgecodex/chrome-bridge/install.shInstalls the bridge that keeps Codex's Chrome plugin link working.
Cases and proposals~/projects/data/Opens the data repo of cases, rule proposals and verdicts.
browser
The browser tools: one Chrome window kept open by one command, the Chrome launcher, and the smoke test.
Browser commandbrowserRuns browser steps against one Chrome window that stays open between calls.
Browser statusbrowser statusChecks whether the background browser server is up.
Browser closebrowser closeCloses Chrome and stops the background server.
Chromews browser chromePrints the Chrome screen: how Chrome starts, its flags and its install.
Recording guidebrowser/README.md#recording-proofOpens the browser guide, including how to record proof of a feature.
Codex browser notescodex/browser/README.mdOpens the notes on Codex's direct Chrome command path and its live check.
Smoke testjev-browser-testRuns a goal in a browser and reports only the text and URL checks it was given.
Smoke test installjev-browser-test/install.shInstalls the smoke test CLI at its pinned upstream revision.
browser › chrome
How Chrome is started on this machine: always through one launcher, with one flag list.
Start Chromechrome/chrome.shStarts Chrome with the recording flag. Use it instead of the real binary.
Chrome flagschrome/flagsOpens the one list of Chrome flags.
Launcher installchrome/install.shInstalls the launcher links and menu entry; run once per machine, then restart Chrome.
dashboards
The two local dashboards, each on its own port, and their checks.
Dashboardpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard at http://127.0.0.1:8780. Nothing starts it by itself.
Concepts dashboardpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts dashboard at http://127.0.0.1:8781, to compare with the first.
Dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the dashboard's checks against the real data and a real server.
Concepts checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the concepts dashboard's checks.
windows
The Windows machine's install, checks, skills sync and repo clones. These run on Windows, not from this shell.
Installinit-windows/Start-Install.cmdRuns the Windows install from the reviewed manifests; approve the admin prompt.
Checkinit-windows/Smoke-Test-Windows.ps1Checks the installed Windows environment against the manifests.
Roll backinit-windows/Remove-WindowsPack.ps1Removes the Windows pack, using the install journal.
Windows guideinit-windows/README.mdOpens the full Windows install guide.
Sign-ins checklistinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand.
Inventoryinit-windows/inventory.mdOpens what the install captured.
Skills syncskills-sync-windows/Sync-Skills.ps1Updates the Windows skill links from the skills repo.
Skills sync guideskills-sync-windows/README.mdOpens how the skills sync runs and what it is allowed to touch.
Clone work reposrepos/Clone-BetecRepos.ps1Clones the missing work repos and leaves existing folders alone.
documents
The written work kept in this repo: CVs, case studies, incident records, plans and this kit's guide.
CVsws documents cvPrints the CV screen: the three versions and how to rebuild them.
Case studiesws documents case-studiesPrints the case studies screen: the archived experiments, one folder each.
Incident recordsreference/Opens the dated incident records of machine failures and repairs.
Plans and researchdocs/Opens the dated plans, designs and research, one folder each.
Kit guideREADME.mdOpens the guide: where each file lands on the machine and how the kit is set up.
documents › cv
The three CV versions as PDFs, their sources, and how to rebuild them.
Full Stack Developer CVcv/cv-full-stack.pdfOpens the Full Stack Developer CV.
AI Full Stack Engineer CVcv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
AI Integrations CVcv/cv-ai-integrations.pdfOpens the AI Integrations CV.
Rebuild the PDFspdflatex, run in cv/ on each .tex fileRebuilds each CV's PDF from its LaTeX source.
Plain-text versionscv/text/build-full.shBuilds the plain-text versions of the CVs.
Readable mastercv/cv-master.mdOpens the readable master CV that the versions come from.
Dated versionscv/versions/Opens the dated CV snapshots.
CV workflowcv/WORKFLOW.mdOpens the workflow for updating the CVs.
documents › case-studies
The archived, human-reviewed experiments, one folder each.
Codebot returncase-studies/conceptual-modeling/2026-09-15-codebot-return/Opens the study of one design request run with and without the skill.
Signal gardencase-studies/blume-astryx/2026-09-16-signal-garden/Opens the study of a small interactive documentation exhibit.
Kernel use cases/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the Kernel cloud browser results. This file is outside this repo.
Questions
  • Names: is ws the facade, and are shell, machine, agents, browser, dashboards, windows and documents the right seven groups? Recommendation: yes. The name setup is also an alias in the README, so step 4 must check it for clashes before it is kept.
  • Existing aliases: opencode help, oc help, opencode-help and oc-help already work. Keep them as aliases that open ws shell opencode, or leave them alone? Recommendation: keep them, routed to the same screen, so nothing that works today breaks.
  • Credential helpers: git_pull_with_creds in infra.zsh and update-gitlab-token in utils.zsh embed a credential in git URLs. Recommendation: leave them off the map until the credential is rotated and moved. Confirm?
  • Windows screen: the rows run on Windows, and zsh cannot run them. Recommendation: keep the rows as the commands to run on Windows, marked as such, and do not wire them into zsh. Confirm?
  • Splits: shell has four sub-screens, machine has five, and agents, browser and documents each have one or two. Recommendation: approve these splits as drafted. Machine is the one most likely to need changing. Your call under step 6.
  • Unverified items, not in the dump: workstation-cli/workstation.py and zsh.d/workstation.zsh (the facade the README names, but not in the listing), zsh.d/audio-share.zsh and audio-share/, zsh.d/dash-path-warn.zsh, dashboard/snapshot.py, claude/team-park/README.md, the clipstack README (none is in the dump, so clipstack purposes come from file names), the purpose of supabase-keepalive, and the exact function names in infra.zsh and utils.zsh. Recommendation: add these files to the dump, or tell me their purposes, before the plan is final. Until then the rows above are named by their file.
As phone screens

Home

The parts of this workstation kit, in seven groups. Run ws followed by a group name and help to list what is inside it.

Shell and gitPrints the shell screen: git, servers, the terminal helpers, OpenCode, the API keys file and review-open.
›
MachinePrints the machine screen: power, repair, the laptop lid, sharing with Windows, and the background services.
›
AgentsPrints the agents screen: the rules, the Agent Sandbox, main sessions, team-park, the usage guard, Hermes and the assistant setup.
›
BrowserPrints the browser screen: the browser command, Chrome, and the behavioral smoke test.
›
DashboardsPrints the dashboards screen: the two local dashboards and their checks.
›
WindowsPrints the Windows screen: the bootstrap, its checks, the skills sync and the repo clones, all run on Windows.
›
DocumentsPrints the documents screen: CVs, case studies, incident records, plans and this kit's guide.
›
‹ Home

shell

The shell helpers this kit copies into ~/.zsh.d: git, servers, the terminal, OpenCode, the keys file and review.

GitPrints the git screen: the checkout guard, the Git settings and the hooks.
›
ServersPrints the servers screen: Docker and Compose, Prisma and Postgres, nginx and the VPN.
›
TerminalPrints the terminal screen: the window title, killport, the IP aliases and the Node, Android, Java and Bun setup.
›
OpenCodePrints the OpenCode screen: the profiles, what each loads, and the commands that switch and edit them.
›
API keys fileOpens the general-use API keys file, which stays out of Git.
›
review-openOpens a file for review, from zsh, bash or an agent.
›
Shell filesOpens the shell files in the repo that get copied to ~/.zsh.d.
›
‹ shell

git

The git helpers: a guard on checkout, the Git settings, and the hooks that run in every repo.

Checkout guardRuns git checkout after listing the files and asking y or N before discarding unstaged changes.
›
Git settingsOpens the Git settings: author, LFS, the credential store, the upload buffer and the hooks path.
›
Git hooksOpens the Lefthook hook folder that runs in every repo and holds the push and commit gates.
›
‹ shell

servers

The shortcuts for containers, databases, the web server and the VPN.

Docker and ComposeRuns the Docker and Compose shortcuts.
›
Prisma and PostgresRuns the Prisma and Postgres helpers.
›
nginx and VPNRuns the nginx and VPN commands.
›
‹ shell

terminal

The terminal helpers from utils.zsh: the window title, ports, IP aliases and the lazily loaded language tools.

Window titleSets the terminal window title.
›
killportStops the process that holds a port.
›
IP aliasesRuns the IP address aliases.
›
Node toolsLoads nvm the first time node, npm or npx runs.
›
Android, Java and BunSets up the Android, Java and Bun paths.
›
‹ shell

opencode

The OpenCode profiles: what each one loads, and the commands that run, switch and edit them.

Run OpenCodeRuns OpenCode with the current profile.
›
Current profilePrints the name of the current profile.
›
Profiles tablePrints each profile and the files it loads.
›
Switch profileSwitches the profile that every new run uses.
›
Sign in a profileStarts the sign-in of that profile's Claude Code.
›
Profile filesLists the current profile's files.
›
Edit a profile fileEdits one of the current profile's files.
›
Profile helpPrints the profile help, and with more than 3 profiles writes a help page and opens it.
›
Profiles folderOpens the folder with each profile's files.
›
‹ Home

machine

Scripts that tune and repair this Linux laptop, and the sharing and background services that run on it.

PowerPrints the power screen: the CPU profiles and the HDMI mode fix.
›
RepairPrints the repair screen: internet, the remote terminal, and the keyboard, mouse, disk and WhatsApp fixes.
›
Laptop lidPrints the laptop screen: keeping it running with the lid closed.
›
SharingPrints the sharing screen: Deskflow, audio to Windows, and the clipboard picker.
›
ServicesPrints the services screen: the background units this machine runs.
›
‹ machine

power

The scripts that change the CPU power profile and the external display mode.

Power saverRuns the power-saver profile with turbo off and the CPU capped at 8 percent. Intel only, asks for sudo.
›
BalancedRuns the balanced profile with turbo on and the cap removed.
›
HDMI modeSets the mode and refresh rate of the external HDMI or DP output.
›
‹ machine

repair

The repair scripts for when the internet, the remote terminal, or a device stops working.

Internet recoveryRestarts DNS and networking to bring the internet back.
›
Remote terminalRestarts Tailscale and the remote terminal, then checks port 3500.
›
Keyboard fixRuns the keyboard repair.
›
Mouse fixRuns the mouse repair.
›
Disk fixRuns the disk repair.
›
WhatsApp fixRuns the WhatsApp repair.
›
‹ machine

laptop

The two switches for what closing the laptop lid does. Each applies after a reboot.

Keep running with lid closedStops closing the lid from sleeping the laptop; applies after a reboot.
›
Restore lid behaviorRestores the default lid behavior; applies after a reboot.
›
‹ machine

sharing

Keyboard and mouse sharing with Windows, audio sent to Windows, and the clipboard picker.

Start DeskflowStarts Deskflow again and asks for input access.
›
Deskflow settingsOpens the Linux Deskflow settings.
›
USB mouse sharing notesOpens the notes on USB mouse sharing, which has been off since 2026-10-20.
›
Send audio to WindowsStarts sending all Linux audio to the Windows machine over Tailscale.
›
Return audioPauses that send and restores the local speakers.
›
Clipboard pickerRuns the clipboard picker over the shared clipboard history.
›
‹ machine

services

The background units this machine runs, as the files that define them.

Clipboard serverOpens the clipboard server's unit file.
›
Clipboard watcherOpens the clipboard watcher's unit file.
›
Deskflow serviceOpens the Deskflow user service file.
›
Supabase keepaliveOpens the timer that keeps the Supabase connection alive.
›
Data pullOpens the folder of the timer and service that pull answers every 5 minutes.
›
‹ Home

agents

The tools that run the AI assistants on this machine, and where their rules and setup live.

RulesPrints the rules every organization follows.
›
Rules fileOpens the rules file that rules prints.
›
Agent SandboxPrints the sandbox screen: the Agent Sandbox page and the checks on agent records.
›
Continue main sessionContinues the main Claude session in this folder.
›
Resume a main sessionResumes a chosen main Claude session.
›
Team parkRuns the team parking script; see claude/team-park/README.md.
›
Claude with usage guardRuns Claude Code through the usage guard, ahead of the native command.
›
HermesRuns the Hermes agent.
›
Assistant setupPrints the setup screen: global instructions, settings, hooks, skills and the Codex bridge.
›
‹ agents

sandbox

The Agent Sandbox page, and the checks that refuse broken agent records.

Sandbox pageStarts the Agent Sandbox page on port 8790.
›
Check agentsChecks every agent record and exits 1 on a broken one.
›
List agentsLists the agents with their tier, model and number of tests.
›
‹ agents

setup

The global instructions, settings, hooks and skills the assistants read, and where each one lives.

Claude instructionsOpens the global instructions every Claude session reads.
›
Claude settingsOpens the Claude Code settings deployed to Windows.
›
Codex configOpens the Codex CLI config.
›
HooksOpens the hook scripts Claude runs at session start and on tool calls.
›
Global skillsOpens the repo of global skills that install links into each assistant.
›
Skill backupsOpens the backups of the skills kept in this repo.
›
Codex Chrome bridgeInstalls the bridge that keeps Codex's Chrome plugin link working.
›
Cases and proposalsOpens the data repo of cases, rule proposals and verdicts.
›
‹ Home

browser

The browser tools: one Chrome window kept open by one command, the Chrome launcher, and the smoke test.

Browser commandRuns browser steps against one Chrome window that stays open between calls.
›
Browser statusChecks whether the background browser server is up.
›
Browser closeCloses Chrome and stops the background server.
›
ChromePrints the Chrome screen: how Chrome starts, its flags and its install.
›
Recording guideOpens the browser guide, including how to record proof of a feature.
›
Codex browser notesOpens the notes on Codex's direct Chrome command path and its live check.
›
Smoke testRuns a goal in a browser and reports only the text and URL checks it was given.
›
Smoke test installInstalls the smoke test CLI at its pinned upstream revision.
›
‹ browser

chrome

How Chrome is started on this machine: always through one launcher, with one flag list.

Start ChromeStarts Chrome with the recording flag. Use it instead of the real binary.
›
Chrome flagsOpens the one list of Chrome flags.
›
Launcher installInstalls the launcher links and menu entry; run once per machine, then restart Chrome.
›
‹ Home

dashboards

The two local dashboards, each on its own port, and their checks.

DashboardStarts the dashboard at http://127.0.0.1:8780. Nothing starts it by itself.
›
Concepts dashboardStarts the concepts dashboard at http://127.0.0.1:8781, to compare with the first.
›
Dashboard checksRuns the dashboard's checks against the real data and a real server.
›
Concepts checksRuns the concepts dashboard's checks.
›
‹ Home

windows

The Windows machine's install, checks, skills sync and repo clones. These run on Windows, not from this shell.

InstallRuns the Windows install from the reviewed manifests; approve the admin prompt.
›
CheckChecks the installed Windows environment against the manifests.
›
Roll backRemoves the Windows pack, using the install journal.
›
Windows guideOpens the full Windows install guide.
›
Sign-ins checklistOpens the sign-ins to redo by hand.
›
InventoryOpens what the install captured.
›
Skills syncUpdates the Windows skill links from the skills repo.
›
Skills sync guideOpens how the skills sync runs and what it is allowed to touch.
›
Clone work reposClones the missing work repos and leaves existing folders alone.
›
‹ Home

documents

The written work kept in this repo: CVs, case studies, incident records, plans and this kit's guide.

CVsPrints the CV screen: the three versions and how to rebuild them.
›
Case studiesPrints the case studies screen: the archived experiments, one folder each.
›
Incident recordsOpens the dated incident records of machine failures and repairs.
›
Plans and researchOpens the dated plans, designs and research, one folder each.
›
Kit guideOpens the guide: where each file lands on the machine and how the kit is set up.
›
‹ documents

cv

The three CV versions as PDFs, their sources, and how to rebuild them.

Full Stack Developer CVOpens the Full Stack Developer CV.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV.
›
AI Integrations CVOpens the AI Integrations CV.
›
Rebuild the PDFsRebuilds each CV's PDF from its LaTeX source.
›
Plain-text versionsBuilds the plain-text versions of the CVs.
›
Readable masterOpens the readable master CV that the versions come from.
›
Dated versionsOpens the dated CV snapshots.
›
CV workflowOpens the workflow for updating the CVs.
›
‹ documents

case-studies

The archived, human-reviewed experiments, one folder each.

Codebot returnOpens the study of one design request run with and without the skill.
›
Signal gardenOpens the study of a small interactive documentation exhibit.
›
Kernel use casesOpens the Kernel cloud browser results. This file is outside this repo.
›
Raw answer
## Plan: the `ws` command map for workstation

This is the planning pass only. Nothing is built or written. I worked from the file dump, so some commands are named only by their file (see the last question).

**Scenario (reasoning from the README, not observed):** the owner reaches for this kit at a terminal or through an agent, mostly to start a dashboard, recover the network or the laptop, switch an OpenCode profile, or open a CV or an incident record. Today those live in about ten files, so the map needs one front door.

**Choices I made:**
- **Seven top groups**, named from the README's own section words: shell and git, machine, agents, browser, dashboards, windows, documents. Each runs `ws <group>`, with `ws` as the facade alias the README already names.
- **Sub-screens** where a group would list more than about eight rows: `shell` (git, servers, terminal, opencode), `machine` (power, repair, laptop, sharing, services), `agents` (sandbox, setup), `browser` (chrome), `documents` (cv, case-studies).
- **Windows items** are listed as the commands and files to use on Windows. They are not runnable from zsh.
- **Credential helpers** are left off the map until the exposed token is rotated and moved, as the README's own checklist says.
- **Secrets** are excluded: `~/.hermes` and the `*.local.json` profile settings are not listed.

```json
{"screens": [
{"path": [], "sentence": "The parts of this workstation kit, in seven groups. Run ws followed by a group name and help to list what is inside it.", "rows": [
{"name": "Shell and git", "form": "ws shell", "what": "Prints the shell screen: git, servers, the terminal helpers, OpenCode, the API keys file and review-open."},
{"name": "Machine", "form": "ws machine", "what": "Prints the machine screen: power, repair, the laptop lid, sharing with Windows, and the background services."},
{"name": "Agents", "form": "ws agents", "what": "Prints the agents screen: the rules, the Agent Sandbox, main sessions, team-park, the usage guard, Hermes and the assistant setup."},
{"name": "Browser", "form": "ws browser", "what": "Prints the browser screen: the browser command, Chrome, and the behavioral smoke test."},
{"name": "Dashboards", "form": "ws dashboards", "what": "Prints the dashboards screen: the two local dashboards and their checks."},
{"name": "Windows", "form": "ws windows", "what": "Prints the Windows screen: the bootstrap, its checks, the skills sync and the repo clones, all run on Windows."},
{"name": "Documents", "form": "ws documents", "what": "Prints the documents screen: CVs, case studies, incident records, plans and this kit's guide."}
]},

{"path": ["shell"], "sentence": "The shell helpers this kit copies into ~/.zsh.d: git, servers, the terminal, OpenCode, the keys file and review.", "rows": [
{"name": "Git", "form": "ws shell git", "what": "Prints the git screen: the checkout guard, the Git settings and the hooks."},
{"name": "Servers", "form": "ws shell servers", "what": "Prints the servers screen: Docker and Compose, Prisma and Postgres, nginx and the VPN."},
{"name": "Terminal", "form": "ws shell terminal", "what": "Prints the terminal screen: the window title, killport, the IP aliases and the Node, Android, Java and Bun setup."},
{"name": "OpenCode", "form": "ws shell opencode", "what": "Prints the OpenCode screen: the profiles, what each loads, and the commands that switch and edit them."},
{"name": "API keys file", "form": "~/.config/api-keys/env", "what": "Opens the general-use API keys file, which stays out of Git."},
{"name": "review-open", "form": "review-open", "what": "Opens a file for review, from zsh, bash or an agent."},
{"name": "Shell files", "form": "zsh.d/", "what": "Opens the shell files in the repo that get copied to ~/.zsh.d."}
]},

{"path": ["shell", "git"], "sentence": "The git helpers: a guard on checkout, the Git settings, and the hooks that run in every repo.", "rows": [
{"name": "Checkout guard", "form": "git checkout (wrapped in ~/.zsh.d/git-safety.zsh)", "what": "Runs git checkout after listing the files and asking y or N before discarding unstaged changes."},
{"name": "Git settings", "form": "~/.gitconfig", "what": "Opens the Git settings: author, LFS, the credential store, the upload buffer and the hooks path."},
{"name": "Git hooks", "form": "~/.git-hooks/", "what": "Opens the Lefthook hook folder that runs in every repo and holds the push and commit gates."}
]},

{"path": ["shell", "servers"], "sentence": "The shortcuts for containers, databases, the web server and the VPN.", "rows": [
{"name": "Docker and Compose", "form": "~/.zsh.d/infra.zsh", "what": "Runs the Docker and Compose shortcuts."},
{"name": "Prisma and Postgres", "form": "~/.zsh.d/infra.zsh", "what": "Runs the Prisma and Postgres helpers."},
{"name": "nginx and VPN", "form": "~/.zsh.d/infra.zsh", "what": "Runs the nginx and VPN commands."}
]},

{"path": ["shell", "terminal"], "sentence": "The terminal helpers from utils.zsh: the window title, ports, IP aliases and the lazily loaded language tools.", "rows": [
{"name": "Window title", "form": "set-title", "what": "Sets the terminal window title."},
{"name": "killport", "form": "killport", "what": "Stops the process that holds a port."},
{"name": "IP aliases", "form": "~/.zsh.d/utils.zsh", "what": "Runs the IP address aliases."},
{"name": "Node tools", "form": "~/.zsh.d/utils.zsh", "what": "Loads nvm the first time node, npm or npx runs."},
{"name": "Android, Java and Bun", "form": "~/.zsh.d/utils.zsh", "what": "Sets up the Android, Java and Bun paths."}
]},

{"path": ["shell", "opencode"], "sentence": "The OpenCode profiles: what each one loads, and the commands that run, switch and edit them.", "rows": [
{"name": "Run OpenCode", "form": "opencode (also oc)", "what": "Runs OpenCode with the current profile."},
{"name": "Current profile", "form": "opencode-profile", "what": "Prints the name of the current profile."},
{"name": "Profiles table", "form": "opencode-profiles", "what": "Prints each profile and the files it loads."},
{"name": "Switch profile", "form": "opencode-switch <name>", "what": "Switches the profile that every new run uses."},
{"name": "Sign in a profile", "form": "opencode-login <name>", "what": "Starts the sign-in of that profile's Claude Code."},
{"name": "Profile files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "Edit a profile file", "form": "opencode-edit <file>", "what": "Edits one of the current profile's files."},
{"name": "Profile help", "form": "opencode help (also oc help)", "what": "Prints the profile help, and with more than 3 profiles writes a help page and opens it."},
{"name": "Profiles folder", "form": "opencode-profiles/", "what": "Opens the folder with each profile's files."}
]},

{"path": ["machine"], "sentence": "Scripts that tune and repair this Linux laptop, and the sharing and background services that run on it.", "rows": [
{"name": "Power", "form": "ws machine power", "what": "Prints the power screen: the CPU profiles and the HDMI mode fix."},
{"name": "Repair", "form": "ws machine repair", "what": "Prints the repair screen: internet, the remote terminal, and the keyboard, mouse, disk and WhatsApp fixes."},
{"name": "Laptop lid", "form": "ws machine laptop", "what": "Prints the laptop screen: keeping it running with the lid closed."},
{"name": "Sharing", "form": "ws machine sharing", "what": "Prints the sharing screen: Deskflow, audio to Windows, and the clipboard picker."},
{"name": "Services", "form": "ws machine services", "what": "Prints the services screen: the background units this machine runs."}
]},

{"path": ["machine", "power"], "sentence": "The scripts that change the CPU power profile and the external display mode.", "rows": [
{"name": "Power saver", "form": "cpu-min-power.sh", "what": "Runs the power-saver profile with turbo off and the CPU capped at 8 percent. Intel only, asks for sudo."},
{"name": "Balanced", "form": "cpu-normal-power.sh", "what": "Runs the balanced profile with turbo on and the cap removed."},
{"name": "HDMI mode", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output."}
]},

{"path": ["machine", "repair"], "sentence": "The repair scripts for when the internet, the remote terminal, or a device stops working.", "rows": [
{"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "Restarts DNS and networking to bring the internet back."},
{"name": "Remote terminal", "form": "recover-tailscale-remote-terminal.sh", "what": "Restarts Tailscale and the remote terminal, then checks port 3500."},
{"name": "Keyboard fix", "form": "fix-keyboard", "what": "Runs the keyboard repair."},
{"name": "Mouse fix", "form": "fix-mouse", "what": "Runs the mouse repair."},
{"name": "Disk fix", "form": "fix-disk", "what": "Runs the disk repair."},
{"name": "WhatsApp fix", "form": "fix-whatsapp", "what": "Runs the WhatsApp repair."}
]},

{"path": ["machine", "laptop"], "sentence": "The two switches for what closing the laptop lid does. Each applies after a reboot.", "rows": [
{"name": "Keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Stops closing the lid from sleeping the laptop; applies after a reboot."},
{"name": "Restore lid behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Restores the default lid behavior; applies after a reboot."}
]},

{"path": ["machine", "sharing"], "sentence": "Keyboard and mouse sharing with Windows, audio sent to Windows, and the clipboard picker.", "rows": [
{"name": "Start Deskflow", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input access."},
{"name": "Deskflow settings", "form": "deskflow/linux.conf", "what": "Opens the Linux Deskflow settings."},
{"name": "USB mouse sharing notes", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes on USB mouse sharing, which has been off since 2026-10-20."},
{"name": "Send audio to Windows", "form": "audio-start", "what": "Starts sending all Linux audio to the Windows machine over Tailscale."},
{"name": "Return audio", "form": "audio-pause", "what": "Pauses that send and restores the local speakers."},
{"name": "Clipboard picker", "form": "clipstack/picker.py", "what": "Runs the clipboard picker over the shared clipboard history."}
]},

{"path": ["machine", "services"], "sentence": "The background units this machine runs, as the files that define them.", "rows": [
{"name": "Clipboard server", "form": "clipstack/units/clipstack-server.service", "what": "Opens the clipboard server's unit file."},
{"name": "Clipboard watcher", "form": "clipstack/units/clipstack-watcher.service", "what": "Opens the clipboard watcher's unit file."},
{"name": "Deskflow service", "form": "deskflow/deskflow.service", "what": "Opens the Deskflow user service file."},
{"name": "Supabase keepalive", "form": "supabase-keepalive/supabase-keepalive.timer", "what": "Opens the timer that keeps the Supabase connection alive."},
{"name": "Data pull", "form": "~/projects/data/systemd/", "what": "Opens the folder of the timer and service that pull answers every 5 minutes."}
]},

{"path": ["agents"], "sentence": "The tools that run the AI assistants on this machine, and where their rules and setup live.", "rows": [
{"name": "Rules", "form": "rules", "what": "Prints the rules every organization follows."},
{"name": "Rules file", "form": "workboard/rules.yaml", "what": "Opens the rules file that rules prints."},
{"name": "Agent Sandbox", "form": "ws agents sandbox", "what": "Prints the sandbox screen: the Agent Sandbox page and the checks on agent records."},
{"name": "Continue main session", "form": "claude --main -c", "what": "Continues the main Claude session in this folder."},
{"name": "Resume a main session", "form": "claude --main -r", "what": "Resumes a chosen main Claude session."},
{"name": "Team park", "form": "team-park", "what": "Runs the team parking script; see claude/team-park/README.md."},
{"name": "Claude with usage guard", "form": "claude (~/bin/claude)", "what": "Runs Claude Code through the usage guard, ahead of the native command."},
{"name": "Hermes", "form": "hermes", "what": "Runs the Hermes agent."},
{"name": "Assistant setup", "form": "ws agents setup", "what": "Prints the setup screen: global instructions, settings, hooks, skills and the Codex bridge."}
]},

{"path": ["agents", "sandbox"], "sentence": "The Agent Sandbox page, and the checks that refuse broken agent records.", "rows": [
{"name": "Sandbox page", "form": "agent serve (http://127.0.0.1:8790)", "what": "Starts the Agent Sandbox page on port 8790."},
{"name": "Check agents", "form": "agent check", "what": "Checks every agent record and exits 1 on a broken one."},
{"name": "List agents", "form": "agent list", "what": "Lists the agents with their tier, model and number of tests."}
]},

{"path": ["agents", "setup"], "sentence": "The global instructions, settings, hooks and skills the assistants read, and where each one lives.", "rows": [
{"name": "Claude instructions", "form": "claude/CLAUDE.md", "what": "Opens the global instructions every Claude session reads."},
{"name": "Claude settings", "form": "claude/settings.json", "what": "Opens the Claude Code settings deployed to Windows."},
{"name": "Codex config", "form": "codex/config.toml", "what": "Opens the Codex CLI config."},
{"name": "Hooks", "form": "claude/hooks/", "what": "Opens the hook scripts Claude runs at session start and on tool calls."},
{"name": "Global skills", "form": "~/projects/my-skills", "what": "Opens the repo of global skills that install links into each assistant."},
{"name": "Skill backups", "form": "claude/skills/", "what": "Opens the backups of the skills kept in this repo."},
{"name": "Codex Chrome bridge", "form": "codex/chrome-bridge/install.sh", "what": "Installs the bridge that keeps Codex's Chrome plugin link working."},
{"name": "Cases and proposals", "form": "~/projects/data/", "what": "Opens the data repo of cases, rule proposals and verdicts."}
]},

{"path": ["browser"], "sentence": "The browser tools: one Chrome window kept open by one command, the Chrome launcher, and the smoke test.", "rows": [
{"name": "Browser command", "form": "browser", "what": "Runs browser steps against one Chrome window that stays open between calls."},
{"name": "Browser status", "form": "browser status", "what": "Checks whether the background browser server is up."},
{"name": "Browser close", "form": "browser close", "what": "Closes Chrome and stops the background server."},
{"name": "Chrome", "form": "ws browser chrome", "what": "Prints the Chrome screen: how Chrome starts, its flags and its install."},
{"name": "Recording guide", "form": "browser/README.md#recording-proof", "what": "Opens the browser guide, including how to record proof of a feature."},
{"name": "Codex browser notes", "form": "codex/browser/README.md", "what": "Opens the notes on Codex's direct Chrome command path and its live check."},
{"name": "Smoke test", "form": "jev-browser-test", "what": "Runs a goal in a browser and reports only the text and URL checks it was given."},
{"name": "Smoke test install", "form": "jev-browser-test/install.sh", "what": "Installs the smoke test CLI at its pinned upstream revision."}
]},

{"path": ["browser", "chrome"], "sentence": "How Chrome is started on this machine: always through one launcher, with one flag list.", "rows": [
{"name": "Start Chrome", "form": "chrome/chrome.sh", "what": "Starts Chrome with the recording flag. Use it instead of the real binary."},
{"name": "Chrome flags", "form": "chrome/flags", "what": "Opens the one list of Chrome flags."},
{"name": "Launcher install", "form": "chrome/install.sh", "what": "Installs the launcher links and menu entry; run once per machine, then restart Chrome."}
]},

{"path": ["dashboards"], "sentence": "The two local dashboards, each on its own port, and their checks.", "rows": [
{"name": "Dashboard", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard at http://127.0.0.1:8780. Nothing starts it by itself."},
{"name": "Concepts dashboard", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts dashboard at http://127.0.0.1:8781, to compare with the first."},
{"name": "Dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the dashboard's checks against the real data and a real server."},
{"name": "Concepts checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the concepts dashboard's checks."}
]},

{"path": ["windows"], "sentence": "The Windows machine's install, checks, skills sync and repo clones. These run on Windows, not from this shell.", "rows": [
{"name": "Install", "form": "init-windows/Start-Install.cmd", "what": "Runs the Windows install from the reviewed manifests; approve the admin prompt."},
{"name": "Check", "form": "init-windows/Smoke-Test-Windows.ps1", "what": "Checks the installed Windows environment against the manifests."},
{"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes the Windows pack, using the install journal."},
{"name": "Windows guide", "form": "init-windows/README.md", "what": "Opens the full Windows install guide."},
{"name": "Sign-ins checklist", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand."},
{"name": "Inventory", "form": "init-windows/inventory.md", "what": "Opens what the install captured."},
{"name": "Skills sync", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Updates the Windows skill links from the skills repo."},
{"name": "Skills sync guide", "form": "skills-sync-windows/README.md", "what": "Opens how the skills sync runs and what it is allowed to touch."},
{"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing work repos and leaves existing folders alone."}
]},

{"path": ["documents"], "sentence": "The written work kept in this repo: CVs, case studies, incident records, plans and this kit's guide.", "rows": [
{"name": "CVs", "form": "ws documents cv", "what": "Prints the CV screen: the three versions and how to rebuild them."},
{"name": "Case studies", "form": "ws documents case-studies", "what": "Prints the case studies screen: the archived experiments, one folder each."},
{"name": "Incident records", "form": "reference/", "what": "Opens the dated incident records of machine failures and repairs."},
{"name": "Plans and research", "form": "docs/", "what": "Opens the dated plans, designs and research, one folder each."},
{"name": "Kit guide", "form": "README.md", "what": "Opens the guide: where each file lands on the machine and how the kit is set up."}
]},

{"path": ["documents", "cv"], "sentence": "The three CV versions as PDFs, their sources, and how to rebuild them.", "rows": [
{"name": "Full Stack Developer CV", "form": "cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
{"name": "AI Full Stack Engineer CV", "form": "cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
{"name": "AI Integrations CV", "form": "cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
{"name": "Rebuild the PDFs", "form": "pdflatex, run in cv/ on each .tex file", "what": "Rebuilds each CV's PDF from its LaTeX source."},
{"name": "Plain-text versions", "form": "cv/text/build-full.sh", "what": "Builds the plain-text versions of the CVs."},
{"name": "Readable master", "form": "cv/cv-master.md", "what": "Opens the readable master CV that the versions come from."},
{"name": "Dated versions", "form": "cv/versions/", "what": "Opens the dated CV snapshots."},
{"name": "CV workflow", "form": "cv/WORKFLOW.md", "what": "Opens the workflow for updating the CVs."}
]},

{"path": ["documents", "case-studies"], "sentence": "The archived, human-reviewed experiments, one folder each.", "rows": [
{"name": "Codebot return", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "Opens the study of one design request run with and without the skill."},
{"name": "Signal garden", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "Opens the study of a small interactive documentation exhibit."},
{"name": "Kernel use cases", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the Kernel cloud browser results. This file is outside this repo."}
]}
],
"questions": [
"Names: is ws the facade, and are shell, machine, agents, browser, dashboards, windows and documents the right seven groups? Recommendation: yes. The name setup is also an alias in the README, so step 4 must check it for clashes before it is kept.",
"Existing aliases: opencode help, oc help, opencode-help and oc-help already work. Keep them as aliases that open ws shell opencode, or leave them alone? Recommendation: keep them, routed to the same screen, so nothing that works today breaks.",
"Credential helpers: git_pull_with_creds in infra.zsh and update-gitlab-token in utils.zsh embed a credential in git URLs. Recommendation: leave them off the map until the credential is rotated and moved. Confirm?",
"Windows screen: the rows run on Windows, and zsh cannot run them. Recommendation: keep the rows as the commands to run on Windows, marked as such, and do not wire them into zsh. Confirm?",
"Splits: shell has four sub-screens, machine has five, and agents, browser and documents each have one or two. Recommendation: approve these splits as drafted. Machine is the one most likely to need changing. Your call under step 6.",
"Unverified items, not in the dump: workstation-cli/workstation.py and zsh.d/workstation.zsh (the facade the README names, but not in the listing), zsh.d/audio-share.zsh and audio-share/, zsh.d/dash-path-warn.zsh, dashboard/snapshot.py, claude/team-park/README.md, the clipstack README (none is in the dump, so clipstack purposes come from file names), the purpose of supabase-keepalive, and the exact function names in infra.zsh and utils.zsh. Recommendation: add these files to the dump, or tell me their purposes, before the plan is final. Until then the rows above are named by their file."
]}
```

screen-decomposition, first draft · run 3 exit=0 seconds=282 · prompt

P1 Recall: 0.8P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 6P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.378
As terminal help
The workstation: this laptop's tools, scripts, agent setup and documents, grouped by what you want to do.
machineworkstation machineOpens the machine screen: fixes and settings for this Linux laptop, by what they change.
shellworkstation shellOpens the shell screen: the commands the terminal gets from zsh.d, the ones typed every day.
agentsworkstation agentsOpens the agents screen: the AI assistant setup, its rules and skills, sessions, dashboard, sandbox and Hermes.
browserworkstation browserOpens the browser screen: the browser command, Chrome's launcher, the Codex bridge and browser QA.
windowsworkstation windowsOpens the windows screen: what this repo rebuilds, syncs and installs on the Windows PC.
documentsworkstation documentsOpens the documents screen: CVs, design, case studies, plans, incidents and module intents.
machine
Fixes and settings for this Linux laptop, grouped by what they change.
powerworkstation machine powerOpens the power screen: CPU power profiles and the lid settings.
networkworkstation machine networkOpens the network screen: scripts that repair DNS, the internet, remote access and the audio share.
keyboard-and-mouseworkstation machine keyboard-and-mouseOpens the keyboard-and-mouse screen: sharing with the Windows PC and the keyboard and mouse repairs.
servicesworkstation machine servicesOpens the services screen: background services this laptop runs for other tools.
old monitor HDMI fixfix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output with xrandr.
machine › power
The CPU power profiles and what closing the laptop lid does.
power-savercpu-min-power.shStarts the power-saver profile (Intel P-state only): turbo off, CPU capped at 8% of max; asks for sudo.
balancedcpu-normal-power.shStarts the balanced profile (Intel P-state only): turbo on, cap back to 100%; asks for sudo.
lid stays awakelaptop-utilities/keep-running-with-lid-closed.shWrites the logind setting so closing the lid does nothing; applies after a reboot.
lid defaultlaptop-utilities/restore-default-lid-behavior.shRemoves that setting so closing the lid works as usual; applies after a reboot.
machine › network
Repair scripts for DNS, the internet and Tailscale remote access, and the audio share to Windows.
internet recoverylinux-internet-recovery.shEnables systemd-resolved, repoints resolv.conf, restarts NetworkManager and cycles networking; re-runs itself with sudo.
Tailscale remote terminal recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, waits up to 30 s for reconnect, starts the remote-terminal service and checks port 3500.
audio shareaudio-start (and audio-pause)Sends all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers.
machine › keyboard-and-mouse
Keyboard and mouse sharing with the Windows PC, and the keyboard and mouse repair helpers.
Deskflow guidedeskflow/README.mdOpens the Deskflow guide: everyday use, recovery and the restore boundaries.
Deskflow resumeresume-kvmStarts Deskflow again and asks GNOME to allow input capture after a canceled prompt stopped it.
USB mouse forwarding (off)deskflow/usb-mouse/README.mdOpens the notes on forwarding the Windows USB mouse, off since 2026-10-20.
Lan Mouse (retired)lan-mouse/README.mdOpens the retired Lan Mouse guide; do not run it alongside Deskflow.
fix-keyboardfix-keyboardRuns the keyboard repair helper from zsh.d/utils.zsh.
fix-mousefix-mouseRuns the mouse repair helper from zsh.d/utils.zsh.
machine › services
Background services this laptop runs for the clipboard, Supabase and the remote terminal.
clipboard serverclipstack/units/clipstack-server.serviceRuns the clipboard server (clipstack/server.py) as a service.
clipboard watcherclipstack/units/clipstack-watcher.serviceRuns the clipboard watcher (clipstack/watcher.py) as a service.
clipboard pickerclipstack/picker.pyRuns the clipboard picker, which chooses an earlier copy.
Supabase keep-alivesupabase-keepalive/supabase-keepalive.timerRuns supabase-keepalive.sh on a timer.
remote terminalremote-terminal (user service)Runs the remote terminal on port 3500; the Tailscale recovery checks that port.
shell
The commands the terminal gets from zsh.d, the ones typed every day.
gitworkstation shell gitOpens the git screen: the guarded checkout, git settings and the hooks.
opencodeworkstation shell opencodeOpens the opencode screen: running and switching the OpenCode profiles.
infraworkstation shell infraOpens the infra screen: Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
utilsworkstation shell utilsOpens the utils screen: terminal helpers, lazy-loaded tools, Android, Java and Bun setup, and repair helpers.
review-open~/.local/bin/review-openOpens a file for review; it works from bash and from agents too.
rules~/.local/bin/rulesPrints the rules, or one folder's rules when given a folder.
API keyszsh.d/api-keys.zshExports the general-use API keys from ~/.config/api-keys/env into every shell; they are never in Git.
api-keys-editapi-keys-editOpens the API keys file, ~/.config/api-keys/env, for editing.
dash path warningzsh.d/dash-path-warn.zshWarns in the shell about dash paths; the exact check is in the file.
shell › git
Git's guarded checkout, its settings, and the hooks that gate commits and pushes.
guarded checkoutgit checkout (zsh.d/git-safety.zsh)Lists the files and asks [y/N] before a checkout discards unstaged changes.
git settings~/.gitconfigSets the author identity, Git LFS, the credential helper and the hooks path for every repo.
git hooks~/.git-hooks/Runs the Lefthook gates on every git action, including the push and commit gates.
shell › opencode
The OpenCode commands: run it, name and switch its profiles, and edit their files.
opencodeopencode (also oc)Runs OpenCode with the current profile.
profile nameopencode-profileNames the current profile, the one opencode runs with.
profilesopencode-profilesShows what each profile loads.
switchopencode-switch <name>Switches every shell's new runs to the named profile.
loginopencode-loginSigns a profile's Claude Code in.
filesopencode-filesLists the current profile's files.
editopencode-edit <file>Opens one of the current profile's files to edit.
helpopencode help (also oc help, opencode-help, oc-help)Prints every profile's files, one column per profile, and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
shell › infra
Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts from zsh.d/infra.zsh.
Docker and Composezsh.d/infra.zshRuns the Docker and Compose shortcuts defined in the file.
Prisma and Postgreszsh.d/infra.zshRuns the Prisma and Postgres helpers defined in the file.
nginx and VPNzsh.d/infra.zshRuns the nginx and VPN commands defined in the file.
git pull with credentialsgit_pull_with_creds (zsh.d/infra.zsh)Pulls with a credential embedded in the URL; a known issue, see init-windows/secrets-checklist.md.
shell › utils
Terminal helpers, IP aliases, lazy-loaded tools, Android, Java and Bun setup, and repair helpers from zsh.d/utils.zsh.
set-titleset-titleSets the terminal window title.
killportkillportStops the process holding a port.
IP aliaseszsh.d/utils.zshSets up the short IP aliases defined there.
lazy-loaded toolszsh.d/utils.zshLoads nvm, node, npm and npx on first use.
Android, Java and Bunzsh.d/utils.zshSets up the Android, Java and Bun paths.
fix-keyboardfix-keyboardRuns the keyboard repair helper.
fix-mousefix-mouseRuns the mouse repair helper.
fix-diskfix-diskRuns the disk repair helper.
fix-whatsappfix-whatsappRuns the WhatsApp repair helper.
update-gitlab-tokenupdate-gitlab-tokenUpdates the GitLab token in git URLs; a known credential issue, see init-windows/secrets-checklist.md.
agents
The AI assistant setup: rules and skills, global files, sessions, the dashboard, the agent sandbox and Hermes.
instructionsworkstation agents instructionsOpens the instructions screen: rules, skills, hooks, roles and OpenCode profile files.
global filesworkstation agents global-filesOpens the global-files screen: the global instructions and settings for Claude and Codex.
sessionsworkstation agents sessionsOpens the sessions screen: main sessions, the usage-guarded claude command, and teams.
dashboardworkstation agents dashboardOpens the dashboard screen: the screen for cases, rule changes and calls waiting on you.
sandboxworkstation agents sandboxOpens the sandbox screen: the Agent Sandbox page, its checks, and the agent records.
hermesworkstation agents hermesOpens the hermes screen: the Hermes agent, its example settings and restore steps.
agents › instructions
The rules, skills, hook scripts, roles and profile files that agents read.
rulesrulesPrints the rules agents follow, from workboard/rules.yaml.
rules fileworkboard/rules.yamlSets every rule; only the user or an accepted rule proposal changes it.
rule metadataworkboard/rules-meta.yamlRecords each rule's metadata, which the rules command reads.
my-skills/home/liel/projects/my-skillsOpens the global skills; its install.sh links them into the agents' skill folders.
skill backupsclaude/skills/Opens the backup copies of skills kept here; copy one into ~/.claude/skills to install it.
skills shortlistclaude/skills-shortlist.mdLists the skills researched on skills.sh and whether each is installed.
rolesdocs/roles/Opens the role docs: the qa-agent role and the role drafts.
Claude hooksclaude/hooks/Opens the Claude hook scripts: core rules, machine history, team activity, proof reminder and local server guard; wired in ~/.claude/settings.json.
OpenCode profilesopencode-profiles/Opens each OpenCode profile's files; private-leb-experimental is the profile kept here.
agents › global-files
The global instruction and settings files for Claude and Codex, and the copies kept here.
Claude rulesclaude/CLAUDE.mdSets the global rules: browser automation, communication style, research and how to present work; init-windows deploys it to Windows.
agent notesclaude/AGENTS.mdSets the shorter global notes for agents; init-windows deploys it to Windows.
Claude settingsclaude/settings.jsonSets Claude Code's settings; init-windows deploys it to Windows.
Codex configcodex/config.tomlSets the Codex CLI config, including the multi_agent_v2 switch; init-windows deploys it to Windows.
Linux mirrorclaude/linux-global/Opens the mirror of the Linux machine's installed instruction files; diff it against ~/.claude to find drift.
communication draftclaude/communication-framework.mdOpens the draft design notes for communication; nothing enforces them yet.
agents › sessions
Starting agent sessions: main sessions, the usage-guarded claude command, and teams.
claude --mainclaude --main (-c continues, -r resumes)Runs the main session; -c continues it and -r resumes it.
claude~/bin/claudeRuns Claude Code through the usage guard, ahead of the native ~/.local/bin/claude.
usage guard installclaude/usage-guard/install.shInstalls the usage guard on this machine.
usage guard testsclaude/usage-guard/tests/Opens the usage guard's tests: request budget and live refresh.
team-park~/.local/bin/team-parkRuns team-park on a team; claude/team-park/README.md says what it parks.
start a team in Claude/spawn-team <team>Starts the named team from its team file, in Claude.
start a team in Codex$spawn-team <team>Starts the named team from its team file, in Codex.
team files~/projects/my-skills/spawn-team/teams/Opens the team files; a new team is a new file.
agents › dashboard
The dashboard: what waits on you (cases, rule changes, calls decided alone), and its concepts version.
dashboardpython3 dashboard/server.py, then http://127.0.0.1:8780Starts the dashboard server, where what waits on you is shown.
concepts versionpython3 dashboard-concepts/server.py, then http://127.0.0.1:8781Starts the concepts version, which groups projects by org.
dashboard checkspython3 -I -m unittest discover -s dashboardRuns the dashboard's 199 checks against the real data and a real server.
concepts checkspython3 -I -m unittest discover -s dashboard-conceptsRuns the concepts version's 17 checks against the real data and a real server.
agents › sandbox
The Agent Sandbox page, its checks and list of agents, and the agent records.
sandbox pageagent-framework/agent serve, then http://127.0.0.1:8790Starts the sandbox page, where you pick an agent, change its setup and ask it.
agent checkagent-framework/agent checkRefuses broken agent records; exits 1 when one is broken.
agent listagent-framework/agent listLists the agents with their tier, model and number of tests.
agent records~/projects/my-skills/agents/Opens the agent records: each agent.yaml, its tests and its role skill; results are kept in ~/projects/data/.
agents › hermes
Hermes, a separate agent app: its command, example settings, restore steps and install notes.
hermes~/.local/bin/hermesRuns Hermes from its checkout at ~/projects/hermes-agent.
restore runbookhermes/RESTORE.mdOpens the runbook for restoring Hermes from its encrypted archive.
default settings examplehermes/default.config.example.yamlOpens the secret-free example settings for the default profile.
jobs settings examplehermes/jobs.config.example.yamlOpens the secret-free example settings for the jobs profile.
install noteshermes/README.mdOpens the install notes and the configuration as of 2026-10-02.
backup recordhermes/BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
PATH linehermes/zprofile-path.zshMirrors the PATH line the installer added to ~/.zprofile.
browser
The browser tools: the browser command with recording, Chrome's launcher, the Codex bridge and browser QA.
browser commandbrowserRuns steps in one Chrome window kept open across calls, so login and page survive.
statusbrowser statusShows whether the background server and its browser are up.
closebrowser closeCloses the browser and stops the server.
recordStartbrowser with a recordStart stepStarts recording the tab for proof; a tab titled REC-TARGET is picked without a prompt.
recordStopbrowser with a recordStop stepStops that recording.
Chromeworkstation browser chromeOpens the chrome screen: the one launcher for Chrome and its flags.
Codexworkstation browser codexOpens the codex screen: the Chrome bridge and the direct Chrome path.
browser QAjev-browser-testChecks a goal in the browser and reports only the text and URL checks you give it.
jevjevAsks Jev a multiple-choice question for a decision; a choice is guidance, not proof.
browser › chrome
Chrome's one launcher, its flags, and the install that points every start at the launcher.
launcherchrome/chrome.shStarts Chrome with the flags in chrome/flags; the only way to start Chrome here.
flagschrome/flagsSets the flags Chrome starts with; edit only this file.
installchrome/install.shLinks google-chrome to the launcher and rewrites the menu entry; run once per machine and after a Chrome update.
check the flagpgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'Prints the capture flag of the running Chrome.
chrome guidechrome/README.mdOpens the guide: why Chrome starts this way, and its limits.
browser › codex
The Codex side of the browser: its Chrome bridge, its direct Chrome path, and the retired and older recorders.
Chrome bridgecodex/chrome-bridge/install.shKeeps the Codex Chrome plugin's latest link and reapplies its local file: navigation patch; on Linux, installs a systemd user watcher and timer.
direct Chrome pathcodex/browser/README.mdOpens Codex's direct Chrome command path and its live check.
Playwright MCP (retired)codex/playwright-mcp/README.mdOpens the retired Playwright MCP setup; it installs no browser server now.
older recordercodex/browser/tab-recorder.mjsRecords a tab with the older Codex recorder; for what the browser command drives, use recordStart instead.
windows
What this repo rebuilds, syncs and installs on the Windows PC.
rebuildworkstation windows rebuildOpens the rebuild screen: the Windows dev environment from manifests, its checks and its sign-ins.
syncworkstation windows syncOpens the sync screen: the skill sync from trusted pushes to master, and its tests.
installworkstation windows installOpens the install screen: clipboard history, the Deskflow client, the usage guard and the Codex bridge on Windows.
windows › rebuild
Rebuilding the Windows development environment from its manifests, checking it, and removing it.
rebuildinit-windows/Start-Install.cmdRebuilds the Windows dev environment; asks for administrator approval.
checkinit-windows/Smoke-Test-Windows.ps1Checks the install; Verify-Windows.ps1 checks it too.
roll backinit-windows/Remove-WindowsPack.ps1Removes the installed pack, using the install journal.
manifestsinit-windows/manifests/Opens the pinned programs, Node versions, VS Code extensions and managed files.
sign-insinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand after the install.
bootstrap guideinit-windows/README.mdOpens the full guide to the Windows bootstrap.
reposrepos/Clone-BetecRepos.ps1Clones the missing Betec repos into the standard layout; existing folders are left alone.
Windows global filesclaude/windows-global/Opens the mirror of the Windows desktop's installed CLAUDE.md and its four docs.
windows › sync
The Windows skill sync: its notes, its tests, and the account it runs as.
sync notesskills-sync-windows/README.mdOpens the notes on the runner that syncs skills to Windows on each trusted push to master.
sync testskills-sync-windows/Test-Sync.ps1Tests the skill sync on Windows.
account testskills-sync-windows/Test-Account.ps1Tests the runner account.
verificationskills-sync-windows/verification.mdOpens the record of how the sync was verified.
windows › install
Installers for the Windows PC: clipboard history, Deskflow, the usage guard and the Codex bridge.
clipboard installclipstack/windows/install.ps1Installs the Windows clipboard history, which runs clipstack.ahk.
clipboard checkclipstack/windows/verify.ps1Checks the clipboard install.
clipboard removalclipstack/windows/uninstall.ps1Removes the Windows clipboard history.
Deskflow clientdeskflow/README.md (Windows settings section)Opens the notes on the Windows Deskflow client and service settings.
usage guardclaude/usage-guard/Install-Windows.cmdInstalls the usage guard on Windows.
Codex bridgecodex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls the Codex Chrome bridge as a current-user Scheduled Task.
documents
Working documents: CVs, design, case studies, plans, incidents and the module intents.
CVsworkstation documents cvOpens the cv screen: the three CVs, their sources and dated copies.
designworkstation documents designOpens the design screen: design rounds, flows, research, work items, playbooks, changelog and screenshots.
case studiesworkstation documents case-studiesOpens the case-studies screen: the archived experiments with their evidence.
plansdocs/plans/Opens the plans, one folder per date and topic, each with its plan.md.
incidentsreference/README.mdOpens the index of dated machine incidents and their outcomes.
intents and features.idd/modules/ and .bdd/features/Opens each module's intent and behavior features; read them before changing the module.
documents › cv
The three CVs: the PDFs, their LaTeX sources, the text versions and the dated copies.
Full Stack Developercv/cv-full-stack.pdfOpens the Full Stack Developer CV.
AI Full Stack Engineercv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
AI Integrationscv/cv-ai-integrations.pdfOpens the AI Integrations CV.
rebuild a CVpdflatex -interaction=nonstopmode -halt-on-error <name>.tex, run in cv/Rebuilds one CV's PDF from its LaTeX source; commit the sources and PDFs together.
text versionscv/text/build-full.shBuilds the plain-text versions of the CVs.
dated copiescv/versions/Opens the dated copies (PDF, text and variables) of each CV version.
experience notescv/experience-notes.mdOpens the factual input the CVs are written from.
CV workflowcv/WORKFLOW.mdOpens the notes on how the CVs are updated.
documents › design
Design rounds, flows, research, work items, playbooks, changelog and screenshots.
design roundsdocs/design/Opens the design rounds, each with its pitches and recommendation.
design referencesdocs/design-references/Opens the reference mockups from earlier rounds.
flowsdocs/flows/Opens the flow cards and data models, one folder per date.
researchdocs/research/ and docs/functional-research/Opens the research notes, by date.
work itemsdocs/items/Opens the planned, urgent and work items.
playbooksdocs/playbooks/Opens the playbooks, such as talk-while-team-builds.md.
changelogdocs/changelog/Opens the changelog, one file per patch.
screenshotscopy/Shows three screenshots: today, subsystems and reviews.
documents › case-studies
The archived case studies, each with its own evidence.
codebot returncase-studies/conceptual-modeling/2026-09-15-codebot-return/README.mdOpens the case study of one design request run with and without the conceptual-modeling skill.
signal gardencase-studies/blume-astryx/2026-09-16-signal-garden/README.mdOpens the signal-garden exhibit study: durable explanation apart from the live interface.
Kernel cloud browsers/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the results on use cases, speed against local Chrome, and session recording.
Questions
  • Facade names: the README gives `workstation`, `setup` and `ws`. Recommend keeping `workstation` and `ws`, and dropping `setup` unless `whence -a setup` shows nothing else uses it.
  • Thin facade or wrapped commands: `browser`, `rules`, `opencode` and `review-open` keep their names and behavior, and the map only points to them. Recommend pointing, not wrapping, so nothing that works today changes.
  • Retired items (Lan Mouse, the Codex Playwright MCP setup, the older Codex recorder, the forwarded USB mouse that is off): show them under their group with 'retired' in the line, or hide them? Recommend showing them so rollback stays findable.
  • Credential helpers (`git_pull_with_creds`, `update-gitlab-token`): show them in help with the warning, or leave them out until the credentials are rotated? Recommend showing them with the warning, because help is where the known issue gets seen.
  • Folders of dated items (plans, design, research): split by month or by open/done once a folder's own index passes about 20 entries? Recommend waiting; the user chooses the split when it gets there.
As phone screens

Home

The workstation: this laptop's tools, scripts, agent setup and documents, grouped by what you want to do.

machineOpens the machine screen: fixes and settings for this Linux laptop, by what they change.
›
shellOpens the shell screen: the commands the terminal gets from zsh.d, the ones typed every day.
›
agentsOpens the agents screen: the AI assistant setup, its rules and skills, sessions, dashboard, sandbox and Hermes.
›
browserOpens the browser screen: the browser command, Chrome's launcher, the Codex bridge and browser QA.
›
windowsOpens the windows screen: what this repo rebuilds, syncs and installs on the Windows PC.
›
documentsOpens the documents screen: CVs, design, case studies, plans, incidents and module intents.
›
‹ Home

machine

Fixes and settings for this Linux laptop, grouped by what they change.

powerOpens the power screen: CPU power profiles and the lid settings.
›
networkOpens the network screen: scripts that repair DNS, the internet, remote access and the audio share.
›
keyboard-and-mouseOpens the keyboard-and-mouse screen: sharing with the Windows PC and the keyboard and mouse repairs.
›
servicesOpens the services screen: background services this laptop runs for other tools.
›
old monitor HDMI fixSets the mode and refresh rate of the external HDMI or DP output with xrandr.
›
‹ machine

power

The CPU power profiles and what closing the laptop lid does.

power-saverStarts the power-saver profile (Intel P-state only): turbo off, CPU capped at 8% of max; asks for sudo.
›
balancedStarts the balanced profile (Intel P-state only): turbo on, cap back to 100%; asks for sudo.
›
lid stays awakeWrites the logind setting so closing the lid does nothing; applies after a reboot.
›
lid defaultRemoves that setting so closing the lid works as usual; applies after a reboot.
›
‹ machine

network

Repair scripts for DNS, the internet and Tailscale remote access, and the audio share to Windows.

internet recoveryEnables systemd-resolved, repoints resolv.conf, restarts NetworkManager and cycles networking; re-runs itself with sudo.
›
Tailscale remote terminal recoveryRepairs DNS, restarts tailscaled, waits up to 30 s for reconnect, starts the remote-terminal service and checks port 3500.
›
audio shareSends all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers.
›
‹ machine

keyboard-and-mouse

Keyboard and mouse sharing with the Windows PC, and the keyboard and mouse repair helpers.

Deskflow guideOpens the Deskflow guide: everyday use, recovery and the restore boundaries.
›
Deskflow resumeStarts Deskflow again and asks GNOME to allow input capture after a canceled prompt stopped it.
›
USB mouse forwarding (off)Opens the notes on forwarding the Windows USB mouse, off since 2026-10-20.
›
Lan Mouse (retired)Opens the retired Lan Mouse guide; do not run it alongside Deskflow.
›
fix-keyboardRuns the keyboard repair helper from zsh.d/utils.zsh.
›
fix-mouseRuns the mouse repair helper from zsh.d/utils.zsh.
›
‹ machine

services

Background services this laptop runs for the clipboard, Supabase and the remote terminal.

clipboard serverRuns the clipboard server (clipstack/server.py) as a service.
›
clipboard watcherRuns the clipboard watcher (clipstack/watcher.py) as a service.
›
clipboard pickerRuns the clipboard picker, which chooses an earlier copy.
›
Supabase keep-aliveRuns supabase-keepalive.sh on a timer.
›
remote terminalRuns the remote terminal on port 3500; the Tailscale recovery checks that port.
›
‹ Home

shell

The commands the terminal gets from zsh.d, the ones typed every day.

gitOpens the git screen: the guarded checkout, git settings and the hooks.
›
opencodeOpens the opencode screen: running and switching the OpenCode profiles.
›
infraOpens the infra screen: Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
›
utilsOpens the utils screen: terminal helpers, lazy-loaded tools, Android, Java and Bun setup, and repair helpers.
›
review-openOpens a file for review; it works from bash and from agents too.
›
rulesPrints the rules, or one folder's rules when given a folder.
›
API keysExports the general-use API keys from ~/.config/api-keys/env into every shell; they are never in Git.
›
api-keys-editOpens the API keys file, ~/.config/api-keys/env, for editing.
›
dash path warningWarns in the shell about dash paths; the exact check is in the file.
›
‹ shell

git

Git's guarded checkout, its settings, and the hooks that gate commits and pushes.

guarded checkoutLists the files and asks [y/N] before a checkout discards unstaged changes.
›
git settingsSets the author identity, Git LFS, the credential helper and the hooks path for every repo.
›
git hooksRuns the Lefthook gates on every git action, including the push and commit gates.
›
‹ shell

opencode

The OpenCode commands: run it, name and switch its profiles, and edit their files.

opencodeRuns OpenCode with the current profile.
›
profile nameNames the current profile, the one opencode runs with.
›
profilesShows what each profile loads.
›
switchSwitches every shell's new runs to the named profile.
›
loginSigns a profile's Claude Code in.
›
filesLists the current profile's files.
›
editOpens one of the current profile's files to edit.
›
helpPrints every profile's files, one column per profile, and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it.
›
‹ shell

infra

Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts from zsh.d/infra.zsh.

Docker and ComposeRuns the Docker and Compose shortcuts defined in the file.
›
Prisma and PostgresRuns the Prisma and Postgres helpers defined in the file.
›
nginx and VPNRuns the nginx and VPN commands defined in the file.
›
git pull with credentialsPulls with a credential embedded in the URL; a known issue, see init-windows/secrets-checklist.md.
›
‹ shell

utils

Terminal helpers, IP aliases, lazy-loaded tools, Android, Java and Bun setup, and repair helpers from zsh.d/utils.zsh.

set-titleSets the terminal window title.
›
killportStops the process holding a port.
›
IP aliasesSets up the short IP aliases defined there.
›
lazy-loaded toolsLoads nvm, node, npm and npx on first use.
›
Android, Java and BunSets up the Android, Java and Bun paths.
›
fix-keyboardRuns the keyboard repair helper.
›
fix-mouseRuns the mouse repair helper.
›
fix-diskRuns the disk repair helper.
›
fix-whatsappRuns the WhatsApp repair helper.
›
update-gitlab-tokenUpdates the GitLab token in git URLs; a known credential issue, see init-windows/secrets-checklist.md.
›
‹ Home

agents

The AI assistant setup: rules and skills, global files, sessions, the dashboard, the agent sandbox and Hermes.

instructionsOpens the instructions screen: rules, skills, hooks, roles and OpenCode profile files.
›
global filesOpens the global-files screen: the global instructions and settings for Claude and Codex.
›
sessionsOpens the sessions screen: main sessions, the usage-guarded claude command, and teams.
›
dashboardOpens the dashboard screen: the screen for cases, rule changes and calls waiting on you.
›
sandboxOpens the sandbox screen: the Agent Sandbox page, its checks, and the agent records.
›
hermesOpens the hermes screen: the Hermes agent, its example settings and restore steps.
›
‹ agents

instructions

The rules, skills, hook scripts, roles and profile files that agents read.

rulesPrints the rules agents follow, from workboard/rules.yaml.
›
rules fileSets every rule; only the user or an accepted rule proposal changes it.
›
rule metadataRecords each rule's metadata, which the rules command reads.
›
my-skillsOpens the global skills; its install.sh links them into the agents' skill folders.
›
skill backupsOpens the backup copies of skills kept here; copy one into ~/.claude/skills to install it.
›
skills shortlistLists the skills researched on skills.sh and whether each is installed.
›
rolesOpens the role docs: the qa-agent role and the role drafts.
›
Claude hooksOpens the Claude hook scripts: core rules, machine history, team activity, proof reminder and local server guard; wired in ~/.claude/settings.json.
›
OpenCode profilesOpens each OpenCode profile's files; private-leb-experimental is the profile kept here.
›
‹ agents

global-files

The global instruction and settings files for Claude and Codex, and the copies kept here.

Claude rulesSets the global rules: browser automation, communication style, research and how to present work; init-windows deploys it to Windows.
›
agent notesSets the shorter global notes for agents; init-windows deploys it to Windows.
›
Claude settingsSets Claude Code's settings; init-windows deploys it to Windows.
›
Codex configSets the Codex CLI config, including the multi_agent_v2 switch; init-windows deploys it to Windows.
›
Linux mirrorOpens the mirror of the Linux machine's installed instruction files; diff it against ~/.claude to find drift.
›
communication draftOpens the draft design notes for communication; nothing enforces them yet.
›
‹ agents

sessions

Starting agent sessions: main sessions, the usage-guarded claude command, and teams.

claude --mainRuns the main session; -c continues it and -r resumes it.
›
claudeRuns Claude Code through the usage guard, ahead of the native ~/.local/bin/claude.
›
usage guard installInstalls the usage guard on this machine.
›
usage guard testsOpens the usage guard's tests: request budget and live refresh.
›
team-parkRuns team-park on a team; claude/team-park/README.md says what it parks.
›
start a team in ClaudeStarts the named team from its team file, in Claude.
›
start a team in CodexStarts the named team from its team file, in Codex.
›
team filesOpens the team files; a new team is a new file.
›
‹ agents

dashboard

The dashboard: what waits on you (cases, rule changes, calls decided alone), and its concepts version.

dashboardStarts the dashboard server, where what waits on you is shown.
›
concepts versionStarts the concepts version, which groups projects by org.
›
dashboard checksRuns the dashboard's 199 checks against the real data and a real server.
›
concepts checksRuns the concepts version's 17 checks against the real data and a real server.
›
‹ agents

sandbox

The Agent Sandbox page, its checks and list of agents, and the agent records.

sandbox pageStarts the sandbox page, where you pick an agent, change its setup and ask it.
›
agent checkRefuses broken agent records; exits 1 when one is broken.
›
agent listLists the agents with their tier, model and number of tests.
›
agent recordsOpens the agent records: each agent.yaml, its tests and its role skill; results are kept in ~/projects/data/.
›
‹ agents

hermes

Hermes, a separate agent app: its command, example settings, restore steps and install notes.

hermesRuns Hermes from its checkout at ~/projects/hermes-agent.
›
restore runbookOpens the runbook for restoring Hermes from its encrypted archive.
›
default settings exampleOpens the secret-free example settings for the default profile.
›
jobs settings exampleOpens the secret-free example settings for the jobs profile.
›
install notesOpens the install notes and the configuration as of 2026-10-02.
›
backup recordOpens the record of the 2026-10-02 backup.
›
PATH lineMirrors the PATH line the installer added to ~/.zprofile.
›
‹ Home

browser

The browser tools: the browser command with recording, Chrome's launcher, the Codex bridge and browser QA.

browser commandRuns steps in one Chrome window kept open across calls, so login and page survive.
›
statusShows whether the background server and its browser are up.
›
closeCloses the browser and stops the server.
›
recordStartStarts recording the tab for proof; a tab titled REC-TARGET is picked without a prompt.
›
recordStopStops that recording.
›
ChromeOpens the chrome screen: the one launcher for Chrome and its flags.
›
CodexOpens the codex screen: the Chrome bridge and the direct Chrome path.
›
browser QAChecks a goal in the browser and reports only the text and URL checks you give it.
›
jevAsks Jev a multiple-choice question for a decision; a choice is guidance, not proof.
›
‹ browser

chrome

Chrome's one launcher, its flags, and the install that points every start at the launcher.

launcherStarts Chrome with the flags in chrome/flags; the only way to start Chrome here.
›
flagsSets the flags Chrome starts with; edit only this file.
›
installLinks google-chrome to the launcher and rewrites the menu entry; run once per machine and after a Chrome update.
›
check the flagPrints the capture flag of the running Chrome.
›
chrome guideOpens the guide: why Chrome starts this way, and its limits.
›
‹ browser

codex

The Codex side of the browser: its Chrome bridge, its direct Chrome path, and the retired and older recorders.

Chrome bridgeKeeps the Codex Chrome plugin's latest link and reapplies its local file: navigation patch; on Linux, installs a systemd user watcher and timer.
›
direct Chrome pathOpens Codex's direct Chrome command path and its live check.
›
Playwright MCP (retired)Opens the retired Playwright MCP setup; it installs no browser server now.
›
older recorderRecords a tab with the older Codex recorder; for what the browser command drives, use recordStart instead.
›
‹ Home

windows

What this repo rebuilds, syncs and installs on the Windows PC.

rebuildOpens the rebuild screen: the Windows dev environment from manifests, its checks and its sign-ins.
›
syncOpens the sync screen: the skill sync from trusted pushes to master, and its tests.
›
installOpens the install screen: clipboard history, the Deskflow client, the usage guard and the Codex bridge on Windows.
›
‹ windows

rebuild

Rebuilding the Windows development environment from its manifests, checking it, and removing it.

rebuildRebuilds the Windows dev environment; asks for administrator approval.
›
checkChecks the install; Verify-Windows.ps1 checks it too.
›
roll backRemoves the installed pack, using the install journal.
›
manifestsOpens the pinned programs, Node versions, VS Code extensions and managed files.
›
sign-insOpens the sign-ins to redo by hand after the install.
›
bootstrap guideOpens the full guide to the Windows bootstrap.
›
reposClones the missing Betec repos into the standard layout; existing folders are left alone.
›
Windows global filesOpens the mirror of the Windows desktop's installed CLAUDE.md and its four docs.
›
‹ windows

sync

The Windows skill sync: its notes, its tests, and the account it runs as.

sync notesOpens the notes on the runner that syncs skills to Windows on each trusted push to master.
›
sync testTests the skill sync on Windows.
›
account testTests the runner account.
›
verificationOpens the record of how the sync was verified.
›
‹ windows

install

Installers for the Windows PC: clipboard history, Deskflow, the usage guard and the Codex bridge.

clipboard installInstalls the Windows clipboard history, which runs clipstack.ahk.
›
clipboard checkChecks the clipboard install.
›
clipboard removalRemoves the Windows clipboard history.
›
Deskflow clientOpens the notes on the Windows Deskflow client and service settings.
›
usage guardInstalls the usage guard on Windows.
›
Codex bridgeInstalls the Codex Chrome bridge as a current-user Scheduled Task.
›
‹ Home

documents

Working documents: CVs, design, case studies, plans, incidents and the module intents.

CVsOpens the cv screen: the three CVs, their sources and dated copies.
›
designOpens the design screen: design rounds, flows, research, work items, playbooks, changelog and screenshots.
›
case studiesOpens the case-studies screen: the archived experiments with their evidence.
›
plansOpens the plans, one folder per date and topic, each with its plan.md.
›
incidentsOpens the index of dated machine incidents and their outcomes.
›
intents and featuresOpens each module's intent and behavior features; read them before changing the module.
›
‹ documents

cv

The three CVs: the PDFs, their LaTeX sources, the text versions and the dated copies.

Full Stack DeveloperOpens the Full Stack Developer CV.
›
AI Full Stack EngineerOpens the AI Full Stack Engineer CV.
›
AI IntegrationsOpens the AI Integrations CV.
›
rebuild a CVRebuilds one CV's PDF from its LaTeX source; commit the sources and PDFs together.
›
text versionsBuilds the plain-text versions of the CVs.
›
dated copiesOpens the dated copies (PDF, text and variables) of each CV version.
›
experience notesOpens the factual input the CVs are written from.
›
CV workflowOpens the notes on how the CVs are updated.
›
‹ documents

design

Design rounds, flows, research, work items, playbooks, changelog and screenshots.

design roundsOpens the design rounds, each with its pitches and recommendation.
›
design referencesOpens the reference mockups from earlier rounds.
›
flowsOpens the flow cards and data models, one folder per date.
›
researchOpens the research notes, by date.
›
work itemsOpens the planned, urgent and work items.
›
playbooksOpens the playbooks, such as talk-while-team-builds.md.
›
changelogOpens the changelog, one file per patch.
›
screenshotsShows three screenshots: today, subsystems and reviews.
›
‹ documents

case-studies

The archived case studies, each with its own evidence.

codebot returnOpens the case study of one design request run with and without the conceptual-modeling skill.
›
signal gardenOpens the signal-garden exhibit study: durable explanation apart from the live interface.
›
Kernel cloud browsersOpens the results on use cases, speed against local Chrome, and session recording.
›
Raw answer
## Scenario

From the README and file tree, not observed use: the one developer on this Linux laptop reaches for this kit in a terminal during work. They fix the machine after a network, input, or power problem, start a tool such as the browser or dashboard, look up a rule or config, or update a CV.

## What the map covers

- **Six top groups**, named after the README's own headings: machine, shell, agents, browser, windows, documents.
- **Subscreens** where a group has more than about seven rows.
- **Collections as one row.** Plans, design rounds, research, and flows are each a folder row. The map doesn't list each dated folder, so a new plan doesn't change the map.
- **Paths** are relative to `~/projects/workstation/` unless shown with `~` or as absolute.

## Judgment calls

- **Unverified rows.** The dump doesn't show these: `workstation`/`setup`/`ws` and `zsh.d/workstation.zsh`, `workstation-cli/`, `audio-share`, `resume-kvm`, the `remote-terminal` unit, `jev`, and the function names inside `zsh.d/infra.zsh` and `zsh.d/utils.zsh`. Their "what" lines come from the README or file names. Step 1 must confirm them before the rows are final.
- **Truncated READMEs.** Several READMEs are cut at 2500 characters, so later sections may be missing rows.
- **Same thing, two screens.** `fix-keyboard`, `fix-mouse`, `rules`, and Deskflow each appear on two screens, worded differently for each.
- **Credentials.** The two credential helpers are named, not reproduced. The map cites the secrets checklist instead.
- **One map.** Linux and Windows share one map. Windows-only items live under `windows`.

```json
{"screens": [
{"path": [], "sentence": "The workstation: this laptop's tools, scripts, agent setup and documents, grouped by what you want to do.", "rows": [
 {"name": "machine", "form": "workstation machine", "what": "Opens the machine screen: fixes and settings for this Linux laptop, by what they change."},
 {"name": "shell", "form": "workstation shell", "what": "Opens the shell screen: the commands the terminal gets from zsh.d, the ones typed every day."},
 {"name": "agents", "form": "workstation agents", "what": "Opens the agents screen: the AI assistant setup, its rules and skills, sessions, dashboard, sandbox and Hermes."},
 {"name": "browser", "form": "workstation browser", "what": "Opens the browser screen: the browser command, Chrome's launcher, the Codex bridge and browser QA."},
 {"name": "windows", "form": "workstation windows", "what": "Opens the windows screen: what this repo rebuilds, syncs and installs on the Windows PC."},
 {"name": "documents", "form": "workstation documents", "what": "Opens the documents screen: CVs, design, case studies, plans, incidents and module intents."}
]},
{"path": ["machine"], "sentence": "Fixes and settings for this Linux laptop, grouped by what they change.", "rows": [
 {"name": "power", "form": "workstation machine power", "what": "Opens the power screen: CPU power profiles and the lid settings."},
 {"name": "network", "form": "workstation machine network", "what": "Opens the network screen: scripts that repair DNS, the internet, remote access and the audio share."},
 {"name": "keyboard-and-mouse", "form": "workstation machine keyboard-and-mouse", "what": "Opens the keyboard-and-mouse screen: sharing with the Windows PC and the keyboard and mouse repairs."},
 {"name": "services", "form": "workstation machine services", "what": "Opens the services screen: background services this laptop runs for other tools."},
 {"name": "old monitor HDMI fix", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output with xrandr."}
]},
{"path": ["machine", "power"], "sentence": "The CPU power profiles and what closing the laptop lid does.", "rows": [
 {"name": "power-saver", "form": "cpu-min-power.sh", "what": "Starts the power-saver profile (Intel P-state only): turbo off, CPU capped at 8% of max; asks for sudo."},
 {"name": "balanced", "form": "cpu-normal-power.sh", "what": "Starts the balanced profile (Intel P-state only): turbo on, cap back to 100%; asks for sudo."},
 {"name": "lid stays awake", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes the logind setting so closing the lid does nothing; applies after a reboot."},
 {"name": "lid default", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that setting so closing the lid works as usual; applies after a reboot."}
]},
{"path": ["machine", "network"], "sentence": "Repair scripts for DNS, the internet and Tailscale remote access, and the audio share to Windows.", "rows": [
 {"name": "internet recovery", "form": "linux-internet-recovery.sh", "what": "Enables systemd-resolved, repoints resolv.conf, restarts NetworkManager and cycles networking; re-runs itself with sudo."},
 {"name": "Tailscale remote terminal recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, waits up to 30 s for reconnect, starts the remote-terminal service and checks port 3500."},
 {"name": "audio share", "form": "audio-start (and audio-pause)", "what": "Sends all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers."}
]},
{"path": ["machine", "keyboard-and-mouse"], "sentence": "Keyboard and mouse sharing with the Windows PC, and the keyboard and mouse repair helpers.", "rows": [
 {"name": "Deskflow guide", "form": "deskflow/README.md", "what": "Opens the Deskflow guide: everyday use, recovery and the restore boundaries."},
 {"name": "Deskflow resume", "form": "resume-kvm", "what": "Starts Deskflow again and asks GNOME to allow input capture after a canceled prompt stopped it."},
 {"name": "USB mouse forwarding (off)", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes on forwarding the Windows USB mouse, off since 2026-10-20."},
 {"name": "Lan Mouse (retired)", "form": "lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide; do not run it alongside Deskflow."},
 {"name": "fix-keyboard", "form": "fix-keyboard", "what": "Runs the keyboard repair helper from zsh.d/utils.zsh."},
 {"name": "fix-mouse", "form": "fix-mouse", "what": "Runs the mouse repair helper from zsh.d/utils.zsh."}
]},
{"path": ["machine", "services"], "sentence": "Background services this laptop runs for the clipboard, Supabase and the remote terminal.", "rows": [
 {"name": "clipboard server", "form": "clipstack/units/clipstack-server.service", "what": "Runs the clipboard server (clipstack/server.py) as a service."},
 {"name": "clipboard watcher", "form": "clipstack/units/clipstack-watcher.service", "what": "Runs the clipboard watcher (clipstack/watcher.py) as a service."},
 {"name": "clipboard picker", "form": "clipstack/picker.py", "what": "Runs the clipboard picker, which chooses an earlier copy."},
 {"name": "Supabase keep-alive", "form": "supabase-keepalive/supabase-keepalive.timer", "what": "Runs supabase-keepalive.sh on a timer."},
 {"name": "remote terminal", "form": "remote-terminal (user service)", "what": "Runs the remote terminal on port 3500; the Tailscale recovery checks that port."}
]},
{"path": ["shell"], "sentence": "The commands the terminal gets from zsh.d, the ones typed every day.", "rows": [
 {"name": "git", "form": "workstation shell git", "what": "Opens the git screen: the guarded checkout, git settings and the hooks."},
 {"name": "opencode", "form": "workstation shell opencode", "what": "Opens the opencode screen: running and switching the OpenCode profiles."},
 {"name": "infra", "form": "workstation shell infra", "what": "Opens the infra screen: Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts."},
 {"name": "utils", "form": "workstation shell utils", "what": "Opens the utils screen: terminal helpers, lazy-loaded tools, Android, Java and Bun setup, and repair helpers."},
 {"name": "review-open", "form": "~/.local/bin/review-open", "what": "Opens a file for review; it works from bash and from agents too."},
 {"name": "rules", "form": "~/.local/bin/rules", "what": "Prints the rules, or one folder's rules when given a folder."},
 {"name": "API keys", "form": "zsh.d/api-keys.zsh", "what": "Exports the general-use API keys from ~/.config/api-keys/env into every shell; they are never in Git."},
 {"name": "api-keys-edit", "form": "api-keys-edit", "what": "Opens the API keys file, ~/.config/api-keys/env, for editing."},
 {"name": "dash path warning", "form": "zsh.d/dash-path-warn.zsh", "what": "Warns in the shell about dash paths; the exact check is in the file."}
]},
{"path": ["shell", "git"], "sentence": "Git's guarded checkout, its settings, and the hooks that gate commits and pushes.", "rows": [
 {"name": "guarded checkout", "form": "git checkout (zsh.d/git-safety.zsh)", "what": "Lists the files and asks [y/N] before a checkout discards unstaged changes."},
 {"name": "git settings", "form": "~/.gitconfig", "what": "Sets the author identity, Git LFS, the credential helper and the hooks path for every repo."},
 {"name": "git hooks", "form": "~/.git-hooks/", "what": "Runs the Lefthook gates on every git action, including the push and commit gates."}
]},
{"path": ["shell", "opencode"], "sentence": "The OpenCode commands: run it, name and switch its profiles, and edit their files.", "rows": [
 {"name": "opencode", "form": "opencode (also oc)", "what": "Runs OpenCode with the current profile."},
 {"name": "profile name", "form": "opencode-profile", "what": "Names the current profile, the one opencode runs with."},
 {"name": "profiles", "form": "opencode-profiles", "what": "Shows what each profile loads."},
 {"name": "switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
 {"name": "login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
 {"name": "files", "form": "opencode-files", "what": "Lists the current profile's files."},
 {"name": "edit", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files to edit."},
 {"name": "help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints every profile's files, one column per profile, and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it."}
]},
{"path": ["shell", "infra"], "sentence": "Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts from zsh.d/infra.zsh.", "rows": [
 {"name": "Docker and Compose", "form": "zsh.d/infra.zsh", "what": "Runs the Docker and Compose shortcuts defined in the file."},
 {"name": "Prisma and Postgres", "form": "zsh.d/infra.zsh", "what": "Runs the Prisma and Postgres helpers defined in the file."},
 {"name": "nginx and VPN", "form": "zsh.d/infra.zsh", "what": "Runs the nginx and VPN commands defined in the file."},
 {"name": "git pull with credentials", "form": "git_pull_with_creds (zsh.d/infra.zsh)", "what": "Pulls with a credential embedded in the URL; a known issue, see init-windows/secrets-checklist.md."}
]},
{"path": ["shell", "utils"], "sentence": "Terminal helpers, IP aliases, lazy-loaded tools, Android, Java and Bun setup, and repair helpers from zsh.d/utils.zsh.", "rows": [
 {"name": "set-title", "form": "set-title", "what": "Sets the terminal window title."},
 {"name": "killport", "form": "killport", "what": "Stops the process holding a port."},
 {"name": "IP aliases", "form": "zsh.d/utils.zsh", "what": "Sets up the short IP aliases defined there."},
 {"name": "lazy-loaded tools", "form": "zsh.d/utils.zsh", "what": "Loads nvm, node, npm and npx on first use."},
 {"name": "Android, Java and Bun", "form": "zsh.d/utils.zsh", "what": "Sets up the Android, Java and Bun paths."},
 {"name": "fix-keyboard", "form": "fix-keyboard", "what": "Runs the keyboard repair helper."},
 {"name": "fix-mouse", "form": "fix-mouse", "what": "Runs the mouse repair helper."},
 {"name": "fix-disk", "form": "fix-disk", "what": "Runs the disk repair helper."},
 {"name": "fix-whatsapp", "form": "fix-whatsapp", "what": "Runs the WhatsApp repair helper."},
 {"name": "update-gitlab-token", "form": "update-gitlab-token", "what": "Updates the GitLab token in git URLs; a known credential issue, see init-windows/secrets-checklist.md."}
]},
{"path": ["agents"], "sentence": "The AI assistant setup: rules and skills, global files, sessions, the dashboard, the agent sandbox and Hermes.", "rows": [
 {"name": "instructions", "form": "workstation agents instructions", "what": "Opens the instructions screen: rules, skills, hooks, roles and OpenCode profile files."},
 {"name": "global files", "form": "workstation agents global-files", "what": "Opens the global-files screen: the global instructions and settings for Claude and Codex."},
 {"name": "sessions", "form": "workstation agents sessions", "what": "Opens the sessions screen: main sessions, the usage-guarded claude command, and teams."},
 {"name": "dashboard", "form": "workstation agents dashboard", "what": "Opens the dashboard screen: the screen for cases, rule changes and calls waiting on you."},
 {"name": "sandbox", "form": "workstation agents sandbox", "what": "Opens the sandbox screen: the Agent Sandbox page, its checks, and the agent records."},
 {"name": "hermes", "form": "workstation agents hermes", "what": "Opens the hermes screen: the Hermes agent, its example settings and restore steps."}
]},
{"path": ["agents", "instructions"], "sentence": "The rules, skills, hook scripts, roles and profile files that agents read.", "rows": [
 {"name": "rules", "form": "rules", "what": "Prints the rules agents follow, from workboard/rules.yaml."},
 {"name": "rules file", "form": "workboard/rules.yaml", "what": "Sets every rule; only the user or an accepted rule proposal changes it."},
 {"name": "rule metadata", "form": "workboard/rules-meta.yaml", "what": "Records each rule's metadata, which the rules command reads."},
 {"name": "my-skills", "form": "/home/liel/projects/my-skills", "what": "Opens the global skills; its install.sh links them into the agents' skill folders."},
 {"name": "skill backups", "form": "claude/skills/", "what": "Opens the backup copies of skills kept here; copy one into ~/.claude/skills to install it."},
 {"name": "skills shortlist", "form": "claude/skills-shortlist.md", "what": "Lists the skills researched on skills.sh and whether each is installed."},
 {"name": "roles", "form": "docs/roles/", "what": "Opens the role docs: the qa-agent role and the role drafts."},
 {"name": "Claude hooks", "form": "claude/hooks/", "what": "Opens the Claude hook scripts: core rules, machine history, team activity, proof reminder and local server guard; wired in ~/.claude/settings.json."},
 {"name": "OpenCode profiles", "form": "opencode-profiles/", "what": "Opens each OpenCode profile's files; private-leb-experimental is the profile kept here."}
]},
{"path": ["agents", "global-files"], "sentence": "The global instruction and settings files for Claude and Codex, and the copies kept here.", "rows": [
 {"name": "Claude rules", "form": "claude/CLAUDE.md", "what": "Sets the global rules: browser automation, communication style, research and how to present work; init-windows deploys it to Windows."},
 {"name": "agent notes", "form": "claude/AGENTS.md", "what": "Sets the shorter global notes for agents; init-windows deploys it to Windows."},
 {"name": "Claude settings", "form": "claude/settings.json", "what": "Sets Claude Code's settings; init-windows deploys it to Windows."},
 {"name": "Codex config", "form": "codex/config.toml", "what": "Sets the Codex CLI config, including the multi_agent_v2 switch; init-windows deploys it to Windows."},
 {"name": "Linux mirror", "form": "claude/linux-global/", "what": "Opens the mirror of the Linux machine's installed instruction files; diff it against ~/.claude to find drift."},
 {"name": "communication draft", "form": "claude/communication-framework.md", "what": "Opens the draft design notes for communication; nothing enforces them yet."}
]},
{"path": ["agents", "sessions"], "sentence": "Starting agent sessions: main sessions, the usage-guarded claude command, and teams.", "rows": [
 {"name": "claude --main", "form": "claude --main (-c continues, -r resumes)", "what": "Runs the main session; -c continues it and -r resumes it."},
 {"name": "claude", "form": "~/bin/claude", "what": "Runs Claude Code through the usage guard, ahead of the native ~/.local/bin/claude."},
 {"name": "usage guard install", "form": "claude/usage-guard/install.sh", "what": "Installs the usage guard on this machine."},
 {"name": "usage guard tests", "form": "claude/usage-guard/tests/", "what": "Opens the usage guard's tests: request budget and live refresh."},
 {"name": "team-park", "form": "~/.local/bin/team-park", "what": "Runs team-park on a team; claude/team-park/README.md says what it parks."},
 {"name": "start a team in Claude", "form": "/spawn-team <team>", "what": "Starts the named team from its team file, in Claude."},
 {"name": "start a team in Codex", "form": "$spawn-team <team>", "what": "Starts the named team from its team file, in Codex."},
 {"name": "team files", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files; a new team is a new file."}
]},
{"path": ["agents", "dashboard"], "sentence": "The dashboard: what waits on you (cases, rule changes, calls decided alone), and its concepts version.", "rows": [
 {"name": "dashboard", "form": "python3 dashboard/server.py, then http://127.0.0.1:8780", "what": "Starts the dashboard server, where what waits on you is shown."},
 {"name": "concepts version", "form": "python3 dashboard-concepts/server.py, then http://127.0.0.1:8781", "what": "Starts the concepts version, which groups projects by org."},
 {"name": "dashboard checks", "form": "python3 -I -m unittest discover -s dashboard", "what": "Runs the dashboard's 199 checks against the real data and a real server."},
 {"name": "concepts checks", "form": "python3 -I -m unittest discover -s dashboard-concepts", "what": "Runs the concepts version's 17 checks against the real data and a real server."}
]},
{"path": ["agents", "sandbox"], "sentence": "The Agent Sandbox page, its checks and list of agents, and the agent records.", "rows": [
 {"name": "sandbox page", "form": "agent-framework/agent serve, then http://127.0.0.1:8790", "what": "Starts the sandbox page, where you pick an agent, change its setup and ask it."},
 {"name": "agent check", "form": "agent-framework/agent check", "what": "Refuses broken agent records; exits 1 when one is broken."},
 {"name": "agent list", "form": "agent-framework/agent list", "what": "Lists the agents with their tier, model and number of tests."},
 {"name": "agent records", "form": "~/projects/my-skills/agents/", "what": "Opens the agent records: each agent.yaml, its tests and its role skill; results are kept in ~/projects/data/."}
]},
{"path": ["agents", "hermes"], "sentence": "Hermes, a separate agent app: its command, example settings, restore steps and install notes.", "rows": [
 {"name": "hermes", "form": "~/.local/bin/hermes", "what": "Runs Hermes from its checkout at ~/projects/hermes-agent."},
 {"name": "restore runbook", "form": "hermes/RESTORE.md", "what": "Opens the runbook for restoring Hermes from its encrypted archive."},
 {"name": "default settings example", "form": "hermes/default.config.example.yaml", "what": "Opens the secret-free example settings for the default profile."},
 {"name": "jobs settings example", "form": "hermes/jobs.config.example.yaml", "what": "Opens the secret-free example settings for the jobs profile."},
 {"name": "install notes", "form": "hermes/README.md", "what": "Opens the install notes and the configuration as of 2026-10-02."},
 {"name": "backup record", "form": "hermes/BACKUP-2026-10-02.md", "what": "Opens the record of the 2026-10-02 backup."},
 {"name": "PATH line", "form": "hermes/zprofile-path.zsh", "what": "Mirrors the PATH line the installer added to ~/.zprofile."}
]},
{"path": ["browser"], "sentence": "The browser tools: the browser command with recording, Chrome's launcher, the Codex bridge and browser QA.", "rows": [
 {"name": "browser command", "form": "browser", "what": "Runs steps in one Chrome window kept open across calls, so login and page survive."},
 {"name": "status", "form": "browser status", "what": "Shows whether the background server and its browser are up."},
 {"name": "close", "form": "browser close", "what": "Closes the browser and stops the server."},
 {"name": "recordStart", "form": "browser with a recordStart step", "what": "Starts recording the tab for proof; a tab titled REC-TARGET is picked without a prompt."},
 {"name": "recordStop", "form": "browser with a recordStop step", "what": "Stops that recording."},
 {"name": "Chrome", "form": "workstation browser chrome", "what": "Opens the chrome screen: the one launcher for Chrome and its flags."},
 {"name": "Codex", "form": "workstation browser codex", "what": "Opens the codex screen: the Chrome bridge and the direct Chrome path."},
 {"name": "browser QA", "form": "jev-browser-test", "what": "Checks a goal in the browser and reports only the text and URL checks you give it."},
 {"name": "jev", "form": "jev", "what": "Asks Jev a multiple-choice question for a decision; a choice is guidance, not proof."}
]},
{"path": ["browser", "chrome"], "sentence": "Chrome's one launcher, its flags, and the install that points every start at the launcher.", "rows": [
 {"name": "launcher", "form": "chrome/chrome.sh", "what": "Starts Chrome with the flags in chrome/flags; the only way to start Chrome here."},
 {"name": "flags", "form": "chrome/flags", "what": "Sets the flags Chrome starts with; edit only this file."},
 {"name": "install", "form": "chrome/install.sh", "what": "Links google-chrome to the launcher and rewrites the menu entry; run once per machine and after a Chrome update."},
 {"name": "check the flag", "form": "pgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'", "what": "Prints the capture flag of the running Chrome."},
 {"name": "chrome guide", "form": "chrome/README.md", "what": "Opens the guide: why Chrome starts this way, and its limits."}
]},
{"path": ["browser", "codex"], "sentence": "The Codex side of the browser: its Chrome bridge, its direct Chrome path, and the retired and older recorders.", "rows": [
 {"name": "Chrome bridge", "form": "codex/chrome-bridge/install.sh", "what": "Keeps the Codex Chrome plugin's latest link and reapplies its local file: navigation patch; on Linux, installs a systemd user watcher and timer."},
 {"name": "direct Chrome path", "form": "codex/browser/README.md", "what": "Opens Codex's direct Chrome command path and its live check."},
 {"name": "Playwright MCP (retired)", "form": "codex/playwright-mcp/README.md", "what": "Opens the retired Playwright MCP setup; it installs no browser server now."},
 {"name": "older recorder", "form": "codex/browser/tab-recorder.mjs", "what": "Records a tab with the older Codex recorder; for what the browser command drives, use recordStart instead."}
]},
{"path": ["windows"], "sentence": "What this repo rebuilds, syncs and installs on the Windows PC.", "rows": [
 {"name": "rebuild", "form": "workstation windows rebuild", "what": "Opens the rebuild screen: the Windows dev environment from manifests, its checks and its sign-ins."},
 {"name": "sync", "form": "workstation windows sync", "what": "Opens the sync screen: the skill sync from trusted pushes to master, and its tests."},
 {"name": "install", "form": "workstation windows install", "what": "Opens the install screen: clipboard history, the Deskflow client, the usage guard and the Codex bridge on Windows."}
]},
{"path": ["windows", "rebuild"], "sentence": "Rebuilding the Windows development environment from its manifests, checking it, and removing it.", "rows": [
 {"name": "rebuild", "form": "init-windows/Start-Install.cmd", "what": "Rebuilds the Windows dev environment; asks for administrator approval."},
 {"name": "check", "form": "init-windows/Smoke-Test-Windows.ps1", "what": "Checks the install; Verify-Windows.ps1 checks it too."},
 {"name": "roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes the installed pack, using the install journal."},
 {"name": "manifests", "form": "init-windows/manifests/", "what": "Opens the pinned programs, Node versions, VS Code extensions and managed files."},
 {"name": "sign-ins", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand after the install."},
 {"name": "bootstrap guide", "form": "init-windows/README.md", "what": "Opens the full guide to the Windows bootstrap."},
 {"name": "repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing Betec repos into the standard layout; existing folders are left alone."},
 {"name": "Windows global files", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows desktop's installed CLAUDE.md and its four docs."}
]},
{"path": ["windows", "sync"], "sentence": "The Windows skill sync: its notes, its tests, and the account it runs as.", "rows": [
 {"name": "sync notes", "form": "skills-sync-windows/README.md", "what": "Opens the notes on the runner that syncs skills to Windows on each trusted push to master."},
 {"name": "sync test", "form": "skills-sync-windows/Test-Sync.ps1", "what": "Tests the skill sync on Windows."},
 {"name": "account test", "form": "skills-sync-windows/Test-Account.ps1", "what": "Tests the runner account."},
 {"name": "verification", "form": "skills-sync-windows/verification.md", "what": "Opens the record of how the sync was verified."}
]},
{"path": ["windows", "install"], "sentence": "Installers for the Windows PC: clipboard history, Deskflow, the usage guard and the Codex bridge.", "rows": [
 {"name": "clipboard install", "form": "clipstack/windows/install.ps1", "what": "Installs the Windows clipboard history, which runs clipstack.ahk."},
 {"name": "clipboard check", "form": "clipstack/windows/verify.ps1", "what": "Checks the clipboard install."},
 {"name": "clipboard removal", "form": "clipstack/windows/uninstall.ps1", "what": "Removes the Windows clipboard history."},
 {"name": "Deskflow client", "form": "deskflow/README.md (Windows settings section)", "what": "Opens the notes on the Windows Deskflow client and service settings."},
 {"name": "usage guard", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the usage guard on Windows."},
 {"name": "Codex bridge", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs the Codex Chrome bridge as a current-user Scheduled Task."}
]},
{"path": ["documents"], "sentence": "Working documents: CVs, design, case studies, plans, incidents and the module intents.", "rows": [
 {"name": "CVs", "form": "workstation documents cv", "what": "Opens the cv screen: the three CVs, their sources and dated copies."},
 {"name": "design", "form": "workstation documents design", "what": "Opens the design screen: design rounds, flows, research, work items, playbooks, changelog and screenshots."},
 {"name": "case studies", "form": "workstation documents case-studies", "what": "Opens the case-studies screen: the archived experiments with their evidence."},
 {"name": "plans", "form": "docs/plans/", "what": "Opens the plans, one folder per date and topic, each with its plan.md."},
 {"name": "incidents", "form": "reference/README.md", "what": "Opens the index of dated machine incidents and their outcomes."},
 {"name": "intents and features", "form": ".idd/modules/ and .bdd/features/", "what": "Opens each module's intent and behavior features; read them before changing the module."}
]},
{"path": ["documents", "cv"], "sentence": "The three CVs: the PDFs, their LaTeX sources, the text versions and the dated copies.", "rows": [
 {"name": "Full Stack Developer", "form": "cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
 {"name": "AI Full Stack Engineer", "form": "cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
 {"name": "AI Integrations", "form": "cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
 {"name": "rebuild a CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error <name>.tex, run in cv/", "what": "Rebuilds one CV's PDF from its LaTeX source; commit the sources and PDFs together."},
 {"name": "text versions", "form": "cv/text/build-full.sh", "what": "Builds the plain-text versions of the CVs."},
 {"name": "dated copies", "form": "cv/versions/", "what": "Opens the dated copies (PDF, text and variables) of each CV version."},
 {"name": "experience notes", "form": "cv/experience-notes.md", "what": "Opens the factual input the CVs are written from."},
 {"name": "CV workflow", "form": "cv/WORKFLOW.md", "what": "Opens the notes on how the CVs are updated."}
]},
{"path": ["documents", "design"], "sentence": "Design rounds, flows, research, work items, playbooks, changelog and screenshots.", "rows": [
 {"name": "design rounds", "form": "docs/design/", "what": "Opens the design rounds, each with its pitches and recommendation."},
 {"name": "design references", "form": "docs/design-references/", "what": "Opens the reference mockups from earlier rounds."},
 {"name": "flows", "form": "docs/flows/", "what": "Opens the flow cards and data models, one folder per date."},
 {"name": "research", "form": "docs/research/ and docs/functional-research/", "what": "Opens the research notes, by date."},
 {"name": "work items", "form": "docs/items/", "what": "Opens the planned, urgent and work items."},
 {"name": "playbooks", "form": "docs/playbooks/", "what": "Opens the playbooks, such as talk-while-team-builds.md."},
 {"name": "changelog", "form": "docs/changelog/", "what": "Opens the changelog, one file per patch."},
 {"name": "screenshots", "form": "copy/", "what": "Shows three screenshots: today, subsystems and reviews."}
]},
{"path": ["documents", "case-studies"], "sentence": "The archived case studies, each with its own evidence.", "rows": [
 {"name": "codebot return", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/README.md", "what": "Opens the case study of one design request run with and without the conceptual-modeling skill."},
 {"name": "signal garden", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "Opens the signal-garden exhibit study: durable explanation apart from the live interface."},
 {"name": "Kernel cloud browsers", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the results on use cases, speed against local Chrome, and session recording."}
]}
],
"questions": [
"Facade names: the README gives `workstation`, `setup` and `ws`. Recommend keeping `workstation` and `ws`, and dropping `setup` unless `whence -a setup` shows nothing else uses it.",
"Thin facade or wrapped commands: `browser`, `rules`, `opencode` and `review-open` keep their names and behavior, and the map only points to them. Recommend pointing, not wrapping, so nothing that works today changes.",
"Retired items (Lan Mouse, the Codex Playwright MCP setup, the older Codex recorder, the forwarded USB mouse that is off): show them under their group with 'retired' in the line, or hide them? Recommend showing them so rollback stays findable.",
"Credential helpers (`git_pull_with_creds`, `update-gitlab-token`): show them in help with the warning, or leave them out until the credentials are rotated? Recommend showing them with the warning, because help is where the known issue gets seen.",
"Folders of dated items (plans, design, research): split by month or by open/done once a folder's own index passes about 20 entries? Recommend waiting; the user chooses the split when it gets there."
]}
```

screen-decomposition, final · run 3 exit=0 seconds=233 · prompt

P1 Recall: 0.757P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.995P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.18
As terminal help
The workstation kit, grouped by what you are trying to do.
shellworkstation shellOpens the shell screen: the commands and files this kit adds to your terminal.
machineworkstation machineOpens the machine screen: Linux power, display, network, lid and repair scripts.
assistantworkstation assistantOpens the assistant screen: Claude, Codex, OpenCode and Hermes setup, rules, agents and the dashboard.
browserworkstation browserOpens the browser screen: the browser command, Chrome and browser QA.
windowsworkstation windowsOpens the windows screen: installing, checking and syncing the Windows machine.
sharingworkstation sharingOpens the sharing screen: the mouse, keyboard, clipboard and audio shared with Windows.
cvsworkstation cvsOpens the cvs screen: the CV PDFs and how to rebuild them.
referenceworkstation referenceOpens the reference screen: incident records, case studies and the project docs.
shell
The shell commands and files this kit adds to your terminal.
zsh.d~/projects/workstation/zsh.d/Opens the folder of shell files that zsh loads from ~/.zsh.d.
review-openreview-open <file>Opens a file for review.
git checkoutgit checkoutLists the files a checkout would discard and asks [y/N] before discarding them.
git hooks~/.git-hooks/Opens the git hook shims that run in every repo.
.gitconfig~/.gitconfigOpens git's identity, LFS, credential and hooks settings.
infra~/projects/workstation/zsh.d/infra.zshOpens the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts file.
utils~/projects/workstation/zsh.d/utils.zshOpens the terminal helpers, IP aliases, node setup and repair helpers file.
set-titleset-titleSets the terminal title.
killportkillportStops whatever is listening on a port.
api-keys~/projects/workstation/zsh.d/api-keys.zshExports the general-use API keys into each new shell.
api-keys-editapi-keys-editOpens the general-use API keys file, which is never kept in Git.
machine
The Linux machine's own scripts: power, display, network, lid and repairs.
cpu-min-power.sh~/projects/workstation/cpu-min-power.shSets the power-saver profile with turbo off and the CPU capped at 8%.
cpu-normal-power.sh~/projects/workstation/cpu-normal-power.shSets the balanced profile with turbo on and the CPU cap back to 100%.
fix_old_monitor_hdmi.sh~/projects/workstation/fix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output, 1920x1080 at 59.88 by default.
linux-internet-recovery.sh~/projects/workstation/linux-internet-recovery.shRepairs DNS and restarts networking.
recover-tailscale-remote-terminal.sh~/projects/workstation/recover-tailscale-remote-terminal.shRepairs DNS, restarts Tailscale and starts the remote terminal service.
keep-running-with-lid-closed.sh~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.shMakes closing the lid do nothing, after the next reboot.
restore-default-lid-behavior.sh~/projects/workstation/laptop-utilities/restore-default-lid-behavior.shPuts closing the lid back to the default, after the next reboot.
fix-keyboardfix-keyboardRepairs the keyboard.
fix-mousefix-mouseRepairs the mouse.
fix-diskfix-diskRepairs the disk.
fix-whatsappfix-whatsappRepairs WhatsApp.
assistant
The AI tools on this machine: their setup, rules, agents, dashboard and Hermes.
claudeworkstation assistant claudeOpens the claude screen: the Claude Code wrapper, global rules, settings and hooks.
opencodeworkstation assistant opencodeOpens the opencode screen: the profiles and the commands that run and switch them.
skillsworkstation assistant skillsOpens the skills screen: the skill folders kept here as backups.
agentsworkstation assistant agentsOpens the agents screen: agent checks, the sandbox page, team files and agent data.
dashboardworkstation assistant dashboardOpens the dashboard screen: the page, its servers and its checks.
hermesworkstation assistant hermesOpens the hermes screen: the Hermes launcher, runbooks and settings examples.
rulesrules [folder]Prints the rules, for the folder given.
workboard/rules.yaml~/projects/workstation/workboard/rules.yamlOpens the rules source that rules reads; only you or an accepted proposal changes it.
jevjev <context> -c <question> <options> [-j]Asks Jev to choose among the options you give, and -j says whether a confident pick counts as approved.
my-skills~/projects/my-skillsOpens the global skills repo, whose install.sh links its skills into the tool folders.
codex config~/projects/workstation/codex/config.tomlOpens the Codex CLI config, which is deployed to Windows.
chrome bridge~/projects/workstation/codex/chrome-bridge/install.shInstalls the watcher that keeps Codex's Chrome plugin link current.
codex browser~/projects/workstation/codex/browser/README.mdOpens Codex's direct Chrome command path and its live checks.
assistant › claude
The Claude Code setup on this machine: the wrapper, global rules, settings, hooks and mirrors.
claude~/bin/claudeRuns Claude Code through the usage guard, ahead of the native claude.
claude --main -cclaude --main -cContinues the main session.
claude --main -rclaude --main -rResumes a main session.
usage-guard~/projects/workstation/claude/usage-guard/Opens the usage guard: its install, Windows launcher and tests.
session-types~/projects/workstation/claude/session-types/Opens the session types and the main-session wrapper.
CLAUDE.md~/projects/workstation/claude/CLAUDE.mdOpens the global Claude rules: browser automation, communication, research and presenting work.
AGENTS.md~/projects/workstation/claude/AGENTS.mdOpens the shorter global agent notes.
settings.json~/projects/workstation/claude/settings.jsonOpens Claude Code's settings, which are deployed to Windows.
hooks~/projects/workstation/claude/hooks/Opens the hook scripts Claude Code runs: rules, history, team activity, proof reminder and server guard.
linux-global~/projects/workstation/claude/linux-global/Opens the mirror of this Linux machine's installed global instructions.
windows-global~/projects/workstation/claude/windows-global/Opens the mirror of the Windows desktop's installed instructions and docs.
desktop-v2-2026~/projects/workstation/claude/backups/desktop-v2-2026/Opens the portable snapshot of the Windows desktop instructions; it is not loaded automatically.
communication-framework~/projects/workstation/claude/communication-framework.mdOpens a draft of communication design notes; nothing enforces it yet.
skills-shortlist~/projects/workstation/claude/skills-shortlist.mdOpens the skills researched on skills.sh.
assistant › opencode
The OpenCode profiles: what each one loads, and the commands that run and switch them.
opencodeopencode (also oc)Runs opencode with the current profile's files.
opencode-profileopencode-profileShows the current opencode profile.
opencode-profilesopencode-profilesLists what each profile loads.
opencode-switchopencode-switch <name>Switches every shell's new runs to the named profile.
opencode-loginopencode-loginSigns a profile's Claude Code in.
opencode-filesopencode-filesLists the current profile's files.
opencode-editopencode-edit <file>Opens one of the current profile's files.
opencode helpopencode help (also oc help, opencode-help, oc-help)Prints every profile's files, one column per profile, and the commands; with more than 3 profiles, writes them to ~/.opencode-profiles/help.md and opens it.
opencode-profiles folder~/projects/workstation/opencode-profiles/Opens the profile definitions and their tests.
private-leb-experimental~/projects/workstation/opencode-profiles/private-leb-experimental/Opens the files of the private-leb-experimental profile.
assistant › skills
The skill folders kept in this repo as backups; the global skills live in my-skills.
skill backups~/projects/workstation/claude/skills/Opens the folder of skill backups; copy in the ones you want installed.
tech-ledger~/projects/workstation/claude/skills/tech-ledger/Opens the skill that reads and writes the betec Tech Ledger.
api-key-creation~/projects/workstation/claude/skills/api-key-creation/Opens the skill that gets a missing API key with browser tools.
clone-website~/projects/workstation/claude/skills/clone-website/Opens the skill that clones websites with parallel builder agents.
contextual-value-product-thinking~/projects/workstation/claude/skills/contextual-value-product-thinking/Opens the skill that analyzes products through contextual human values.
elad12390--web-research-assistant~/projects/workstation/claude/skills/elad12390--web-research-assistant/Opens the web research MCP server skill; its setup is in SETUP-NOTES.md.
epic-fanout-planning~/projects/workstation/claude/skills/epic-fanout-planning/Opens the pattern for QA-gap epics with parallel fan-out and release gates.
impeccable~/projects/workstation/claude/skills/impeccable/Opens the frontend design skill: shape, critique, audit, polish.
iterative-action-review~/projects/workstation/claude/skills/iterative-action-review/Opens the review of a completed real-world action.
lab-experiment~/projects/workstation/claude/skills/lab-experiment/Opens the skill for running an experiment in the ai-lab; its SKILL.md describes the steps.
mentor-mode~/projects/workstation/claude/skills/mentor-mode/Opens the mentor-mode skill; its SKILL.md describes the steps.
post-feature-cleanup~/projects/workstation/claude/skills/post-feature-cleanup/Opens the pass after writing code: UI defects, leftovers and repo hygiene.
powershell-launching~/projects/workstation/claude/skills/powershell-launching/Opens the skill for launching PowerShell or a new terminal on Windows.
reboot-resume~/projects/workstation/claude/skills/reboot-resume/Opens the skill that preserves and resumes work across a reboot or restart.
resume-project~/projects/workstation/claude/skills/resume-project/Opens the skill that resumes a project; its SKILL.md describes the steps.
solaraai-content-calendar~/projects/workstation/claude/skills/solaraai-content-calendar/Opens the SolaraAI content calendar skill.
solaraai-deployment~/projects/workstation/claude/skills/solaraai-deployment/Opens the SolaraAI deploy flow skill.
solaraai-design~/projects/workstation/claude/skills/solaraai-design/Opens the SolaraAI design system skill.
solaraai-forms~/projects/workstation/claude/skills/solaraai-forms/Opens the SolaraAI form behavior skill.
supabase~/projects/workstation/claude/skills/supabase/Opens Supabase's skill: Auth, RLS, migrations, CLI and debugging.
supabase-postgres-best-practices~/projects/workstation/claude/skills/supabase-postgres-best-practices/Opens Supabase's Postgres performance rules.
tank--communication-engineering~/projects/workstation/claude/skills/tank--communication-engineering/Opens the skill that applies engineering discipline to what an agent says.
tank--skill-creator~/projects/workstation/claude/skills/tank--skill-creator/Opens the skill for creating new skills.
tech-cv-writer~/projects/workstation/claude/skills/tech-cv-writer/Opens the skill for writing CVs; its references cover ATS, bullets and LaTeX.
assistant › agents
The agent system: its checks, the sandbox page, team files and the data the agents keep.
agent check~/projects/workstation/agent-framework/agent checkRefuses broken agent records and exits 1.
agent list~/projects/workstation/agent-framework/agent listLists the agents with their tier, model and number of tests.
agent serve~/projects/workstation/agent-framework/agent serveStarts the Agent Sandbox page at 127.0.0.1:8790.
Agent Sandbox pagehttp://127.0.0.1:8790Opens the sandbox: pick an agent, change its setup and ask it; needs agent serve running.
agent records~/projects/my-skills/agents/<id>/agent.yamlOpens an agent's record: its setup, situations and saved tests.
spawn-team/spawn-team <team> (Claude) or $spawn-team <team> (Codex)Starts a team from its team file.
team files~/projects/my-skills/spawn-team/teams/Opens the team files, such as worker-pair and research-team.
data~/projects/data/Opens the cases, rule proposals, verdicts and reviews the agents keep in a private repo.
archive~/archive/Opens the files moved out of projects; each folder has an ARCHIVE.md.
assistant › dashboard
The dashboard and its concepts version: the page, the servers and the checks.
dashboard serverpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard server on 127.0.0.1:8780, or on a port you pass.
dashboard pagehttp://127.0.0.1:8780Opens the dashboard: Waiting, Overview and the reader; needs the server running.
dashboard testspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the dashboard checks against the real data and a real server.
dashboard README~/projects/workstation/dashboard/README.mdOpens the dashboard guide: what it writes, hot reload and its tabs.
concepts serverpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts version on 127.0.0.1:8781, to compare with the dashboard.
concepts pagehttp://127.0.0.1:8781Opens the concepts version of the page; needs its server running.
concepts testspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the concepts checks against the real data and a real server.
assistant › hermes
Hermes, the agent installed from source: its launcher, runbooks and settings examples.
hermes~/.local/bin/hermesRuns Hermes, with its default and jobs profiles.
hermes README~/projects/workstation/hermes/README.mdOpens Hermes' install record and current configuration.
RESTORE.md~/projects/workstation/hermes/RESTORE.mdOpens the restore runbook for Hermes.
BACKUP-2026-10-02.md~/projects/workstation/hermes/BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
default.config.example.yaml~/projects/workstation/hermes/default.config.example.yamlOpens the secret-free settings example for the default profile.
jobs.config.example.yaml~/projects/workstation/hermes/jobs.config.example.yamlOpens the secret-free settings example for the jobs profile.
zprofile-path.zsh~/projects/workstation/hermes/zprofile-path.zshOpens the PATH line the installer added to ~/.zprofile.
hermes state~/.hermesOpens Hermes' state and secrets folder, which is not in Git.
browser
The browser command, Chrome and browser QA.
browserbrowser '<json-array-of-steps>'Runs browser steps on one persistent Chrome window; the first call starts it.
browser statusbrowser statusPrints whether the browser server and its window are up.
browser closebrowser closeCloses Chrome and stops the server.
recordStartrecordStart stepStarts recording the tab as proof of a feature.
recordStoprecordStop stepStops the recording.
browser README~/projects/workstation/browser/README.mdOpens the browser guide: every action, viewport preset, annotation and network capture.
chromeworkstation browser chromeOpens the chrome screen: the one way Chrome starts here.
qaworkstation browser qaOpens the qa screen: behavioral smoke tests of pages.
browser › chrome
Chrome: the one way it starts here, and the flags that let recordings run.
google-chromegoogle-chromeStarts Chrome through chrome.sh, with the recording flag.
chrome.sh~/projects/workstation/chrome/chrome.shOpens the launcher that adds the flags and starts Chrome.
install.sh~/projects/workstation/chrome/install.shLinks google-chrome to chrome.sh; run once per machine and again after a Chrome update.
flags~/projects/workstation/chrome/flagsOpens the one list of Chrome flags, read by chrome.sh and the recorder.
chrome README~/projects/workstation/chrome/README.mdOpens why Chrome starts this way and its limits.
browser › qa
Behavioral browser smoke QA: the CLI, its install, its secrets file and its guide.
jev-browser-testjev-browser-testRuns a goal in the browser and reports only the text and URL you asserted.
install.shsh ~/projects/workstation/jev-browser-test/install.shInstalls the CLI at one pinned upstream revision.
env file~/.config/jev-browser-test/envOpens the CLI's secrets file, mode 600, not kept in Git.
QA README~/projects/workstation/jev-browser-test/README.mdOpens the QA guide: exit codes, privacy boundary and the agent snippet.
windows
Setting up and checking the Windows machine: installs, scripts, skill sync and repos.
installworkstation windows installOpens the install screen: installing, checking and rolling back the Windows setup.
scriptsworkstation windows scriptsOpens the scripts screen: the user scripts for Windows.
skill-syncworkstation windows skill-syncOpens the skill-sync screen: how Windows keeps its skill folders current.
Clone-BetecRepos.ps1~/projects/workstation/repos/Clone-BetecRepos.ps1Clones the missing Betec repos into the standard layout; safe to re-run.
windows › install
Installing, checking and rolling back the Windows setup, with its logs and manifests.
Start-Install.cmd~/projects/workstation/init-windows/Start-Install.cmdInstalls the Windows environment from the manifests; approve the admin prompt.
Verify-Windows.ps1~/projects/workstation/init-windows/Verify-Windows.ps1Checks the install.
Smoke-Test-Windows.ps1~/projects/workstation/init-windows/Smoke-Test-Windows.ps1Runs the smoke test of the install.
Remove-WindowsPack.ps1~/projects/workstation/init-windows/Remove-WindowsPack.ps1Rolls the install back.
Export-Windows.ps1~/projects/workstation/init-windows/Export-Windows.ps1Exports the machine's current setup into the manifests.
Install-Windows.log~/projects/workstation/init-windows/logs/Install-Windows.logOpens the install log.
Install-Windows.errors.log~/projects/workstation/init-windows/logs/Install-Windows.errors.logOpens the install errors.
inventory.md~/projects/workstation/init-windows/inventory.mdOpens what the capture recorded.
secrets-checklist.md~/projects/workstation/init-windows/secrets-checklist.mdOpens the sign-ins to redo by hand.
manifests~/projects/workstation/init-windows/manifests/Opens the exact lists of programs, Node versions, npm packages and VS Code extensions.
configs~/projects/workstation/init-windows/configs/Opens the Git and VS Code configs deployed to Windows.
init-windows README~/projects/workstation/init-windows/README.mdOpens the full install guide.
windows › scripts
The user scripts for Windows: hibernate, touchpad fixes and MongoDB restore.
do_hibernate.ps1~/projects/workstation/init-windows/user-scripts/do_hibernate.ps1Hibernates the Windows PC.
fix_touchpad.ps1~/projects/workstation/init-windows/user-scripts/fix_touchpad.ps1Repairs the touchpad.
fix_touchpad2.ps1~/projects/workstation/init-windows/user-scripts/fix_touchpad2.ps1Repairs the touchpad, second variant.
fix_touchpad3.ps1~/projects/workstation/init-windows/user-scripts/fix_touchpad3.ps1Repairs the touchpad, third variant.
restore-mongo.ps1~/projects/workstation/init-windows/user-scripts/restore-mongo.ps1Restores MongoDB from a backup.
windows › skill-sync
How Windows keeps its skill folders in step with my-skills master.
Sync-Skills.ps1~/projects/workstation/skills-sync-windows/Sync-Skills.ps1Fast-forwards the existing checkout and relinks the skill folders.
Test-Sync.ps1~/projects/workstation/skills-sync-windows/Test-Sync.ps1Tests the sync.
Test-Account.ps1~/projects/workstation/skills-sync-windows/Test-Account.ps1Tests the runner account's rights.
runner serviceactions.runner.Lebnor-my-skills.my-skills-liel-windowsRuns the runner that starts a sync on trusted pushes to master.
catch-up taskMySkillsSync-CatchUpRuns the sync once after startup, retrying up to three times.
last-success.jsonC:\ProgramData\MySkillsSync\state\last-success.jsonOpens the record of the last successful sync.
verification.md~/projects/workstation/skills-sync-windows/verification.mdOpens how the sync was verified.
skill-sync README~/projects/workstation/skills-sync-windows/README.mdOpens the setup, permissions and security notes.
sharing
What is shared between the laptop and Windows: mouse and keyboard, clipboard and audio.
deskflowworkstation sharing deskflowOpens the deskflow screen: the shared mouse and keyboard, its service, settings and recovery.
clipstackworkstation sharing clipstackOpens the clipstack screen: the shared clipboard, its services and its Windows side.
audio-startaudio-startStarts sending all Linux audio to Windows over Tailscale.
audio-pauseaudio-pausePauses the sending and restores the speakers.
audio-shareaudio-share on|off|status|toneTurns sending on or off, shows its status, or plays a test tone.
sharing › deskflow
Deskflow, the shared mouse and keyboard between the laptop and Windows: service, settings and recovery.
resume-kvmresume-kvmStarts Deskflow again and asks GNOME for input capture.
Deskflow service~/.config/systemd/user/deskflow.serviceRuns the Deskflow server; it starts with the graphical session.
laptop settings~/.config/Deskflow/Deskflow.confOpens the laptop's Deskflow settings.
Windows settings~/projects/workstation/deskflow/windows.confOpens the Windows client and service settings, which are separate copies.
deskflow-lockdown.nft~/projects/workstation/deskflow/deskflow-lockdown.nftOpens the firewall rules that lock Deskflow's network down.
NETWORK-AUDIT.md~/projects/workstation/deskflow/NETWORK-AUDIT.mdOpens the Deskflow network audit.
deskflow README~/projects/workstation/deskflow/README.mdOpens the Deskflow guide: everyday use and recovery.
USB mouse notes~/projects/workstation/deskflow/usb-mouse/README.mdOpens the USB mouse notes, including how the keyboard follows the mouse.
USB mouse forwarding~/projects/workstation/deskflow/usb-mouse/deskflow-usb-mouse.serviceForwards the Windows USB mouse to the laptop; off since 2026-10-20.
sharing › clipstack
clipstack, the shared clipboard: its services, picker and Windows side.
install.sh~/projects/workstation/clipstack/install.shInstalls the clipboard server and watcher on Linux.
clipstack-server~/projects/workstation/clipstack/units/clipstack-server.serviceRuns the clipboard server.
clipstack-watcher~/projects/workstation/clipstack/units/clipstack-watcher.serviceRuns the clipboard watcher.
picker.py~/projects/workstation/clipstack/picker.pyShows the clipboard picker, to choose an item.
clipstack.ahk~/projects/workstation/clipstack/windows/clipstack.ahkRuns the clipboard script on Windows (AutoHotkey).
Windows install.ps1~/projects/workstation/clipstack/windows/install.ps1Installs the Windows clipboard side.
Windows verify.ps1~/projects/workstation/clipstack/windows/verify.ps1Checks the Windows clipboard side.
cvs
The CVs: the PDFs, their sources, the dated versions and the text and design builds.
cv-full-stack.pdf~/projects/workstation/cv/cv-full-stack.pdfOpens the Full Stack Developer CV.
cv-ai-full-stack.pdf~/projects/workstation/cv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
cv-ai-integrations.pdf~/projects/workstation/cv/cv-ai-integrations.pdfOpens the AI Integrations CV.
sourcesworkstation cvs sourcesOpens the sources screen: the LaTeX, the facts and how to rebuild.
versions~/projects/workstation/cv/versions/Opens the dated CV snapshots, 2026-10-04 and v2.
text~/projects/workstation/cv/text/Opens the plain-text CVs and the script that makes them.
design~/projects/workstation/cv/design/Opens the designed CV build: HTML and PDF from build-design.py.
cv README~/projects/workstation/cv/README.mdOpens the CV folder guide.
cvs › sources
The CV sources: LaTeX for each version, the facts they are built from, and how to rebuild them.
cv-full-stack.tex~/projects/workstation/cv/cv-full-stack.texOpens the Full Stack Developer CV's LaTeX source.
cv-ai-full-stack.tex~/projects/workstation/cv/cv-ai-full-stack.texOpens the AI Full Stack Engineer CV's LaTeX source.
cv-ai-integrations.tex~/projects/workstation/cv/cv-ai-integrations.texOpens the AI Integrations CV's LaTeX source.
rebuildpdflatex -interaction=nonstopmode -halt-on-error <version>.texRebuilds one CV PDF from its LaTeX source.
experience-notes.md~/projects/workstation/cv/experience-notes.mdOpens the factual input every CV is built from.
cv-master.md~/projects/workstation/cv/cv-master.mdOpens the readable master CV.
cv-material-draft.md~/projects/workstation/cv/cv-material-draft.mdOpens the drafting decisions behind the CVs.
WORKFLOW.md~/projects/workstation/cv/WORKFLOW.mdOpens the CV workflow: edit here, rebuild, then commit the sources and PDFs together.
reference
Records of machine incidents and verified states, the case studies, and the project docs.
closed-lid incident~/projects/workstation/reference/incidents/2026-10-01-codebot-lid-closed.mdOpens the record of the closed-lid test that passed on 2026-10-01.
reference README~/projects/workstation/reference/README.mdOpens the list of dated incident cases.
conceptual-modeling case~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/Opens the case where the skill-guided run was judged materially better.
signal garden case~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/Opens the exhibit separating durable explanation from the live interface.
Kernel results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the Kernel cloud browser results: speed, use cases and session recording.
docsworkstation reference docsOpens the docs screen: the project's changelog, plans, designs, research and records.
reference › docs
The project's docs folders and the intent, scenario and QA records.
changelog~/projects/workstation/docs/changelog/Opens the dated changelog entries.
plans~/projects/workstation/docs/plans/Opens the dated plan for each piece of work.
design~/projects/workstation/docs/design/Opens the design pitches, recommendations and research.
research~/projects/workstation/docs/research/Opens the research notes, including the phase checks.
functional-research~/projects/workstation/docs/functional-research/Opens the research on agent frameworks and their features.
flows~/projects/workstation/docs/flows/Opens the flow cards and data models.
items~/projects/workstation/docs/items/Opens the planned, urgent and work item lists.
roles~/projects/workstation/docs/roles/Opens the role definitions for qa-agent and the other roles.
playbooks~/projects/workstation/docs/playbooks/Opens the playbooks, such as talking while the team builds.
intent~/projects/workstation/.idd/modules/Opens each module's INTENT.md, its typed intent and rules.
scenarios~/projects/workstation/.bdd/features/Opens the behavior scenarios, one folder per feature.
QA findings~/projects/workstation/.bdd/qa/findings/Opens the QA findings, one file per check.
Questions
  • Noun names: use the short one-word nouns on the map (shell, machine, assistant, browser, windows, sharing, cvs, reference), or the README's headings word for word ("Shell and git", "Machine utilities")? Recommendation: the short nouns, since you type them on every command.
  • clipstack: it is not in the README, but the dump has clipstack/ and a 2026-10-26 shared-clipboard plan. Is it still in use, and do you want it under sharing with the noun clipstack? Recommendation: keep it, noun clipstack, since that is the project's own word.
  • Old backups: claude/backups/desktop-v1-2026 and linux-v1-2026-10-03 are not on the map. Recommendation: leave them off, because desktop-v2-2026 and the linux-global and windows-global mirrors replace them. Confirm, or tell me to list them.
  • dashboard-concepts: it is kept to compare with the dashboard. Recommendation: keep both on the map until you choose one, then remove the one you drop.
  • Skill list: the README table names 13 backed-up skills, but claude/skills/ holds 23, including clone-website, lab-experiment, mentor-mode, resume-project, four solaraai skills, two supabase skills and tech-cv-writer. Recommendation: list all 23 as the map does, and have the README table updated to match.
  • Machine screen: it has 11 rows. Recommendation: split it into machine power (the two cpu scripts, the two lid scripts, the HDMI script) and machine repair (the two network scripts and the four fix commands), so each screen stays short.
  • docs folders: the map lists each docs folder, not each dated plan or design. Recommendation: keep it that way, since the plans grow every week and listing them would overflow the screen.
  • Aliases: the README documents workstation, ws and setup for the same command. Recommendation: keep all three, since the README already uses them, and let cli-engineer confirm the names for clashes.
As phone screens

Home

The workstation kit, grouped by what you are trying to do.

shellOpens the shell screen: the commands and files this kit adds to your terminal.
›
machineOpens the machine screen: Linux power, display, network, lid and repair scripts.
›
assistantOpens the assistant screen: Claude, Codex, OpenCode and Hermes setup, rules, agents and the dashboard.
›
browserOpens the browser screen: the browser command, Chrome and browser QA.
›
windowsOpens the windows screen: installing, checking and syncing the Windows machine.
›
sharingOpens the sharing screen: the mouse, keyboard, clipboard and audio shared with Windows.
›
cvsOpens the cvs screen: the CV PDFs and how to rebuild them.
›
referenceOpens the reference screen: incident records, case studies and the project docs.
›
‹ Home

shell

The shell commands and files this kit adds to your terminal.

zsh.dOpens the folder of shell files that zsh loads from ~/.zsh.d.
›
review-openOpens a file for review.
›
git checkoutLists the files a checkout would discard and asks [y/N] before discarding them.
›
git hooksOpens the git hook shims that run in every repo.
›
.gitconfigOpens git's identity, LFS, credential and hooks settings.
›
infraOpens the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts file.
›
utilsOpens the terminal helpers, IP aliases, node setup and repair helpers file.
›
set-titleSets the terminal title.
›
killportStops whatever is listening on a port.
›
api-keysExports the general-use API keys into each new shell.
›
api-keys-editOpens the general-use API keys file, which is never kept in Git.
›
‹ Home

machine

The Linux machine's own scripts: power, display, network, lid and repairs.

cpu-min-power.shSets the power-saver profile with turbo off and the CPU capped at 8%.
›
cpu-normal-power.shSets the balanced profile with turbo on and the CPU cap back to 100%.
›
fix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output, 1920x1080 at 59.88 by default.
›
linux-internet-recovery.shRepairs DNS and restarts networking.
›
recover-tailscale-remote-terminal.shRepairs DNS, restarts Tailscale and starts the remote terminal service.
›
keep-running-with-lid-closed.shMakes closing the lid do nothing, after the next reboot.
›
restore-default-lid-behavior.shPuts closing the lid back to the default, after the next reboot.
›
fix-keyboardRepairs the keyboard.
›
fix-mouseRepairs the mouse.
›
fix-diskRepairs the disk.
›
fix-whatsappRepairs WhatsApp.
›
‹ Home

assistant

The AI tools on this machine: their setup, rules, agents, dashboard and Hermes.

claudeOpens the claude screen: the Claude Code wrapper, global rules, settings and hooks.
›
opencodeOpens the opencode screen: the profiles and the commands that run and switch them.
›
skillsOpens the skills screen: the skill folders kept here as backups.
›
agentsOpens the agents screen: agent checks, the sandbox page, team files and agent data.
›
dashboardOpens the dashboard screen: the page, its servers and its checks.
›
hermesOpens the hermes screen: the Hermes launcher, runbooks and settings examples.
›
rulesPrints the rules, for the folder given.
›
workboard/rules.yamlOpens the rules source that rules reads; only you or an accepted proposal changes it.
›
jevAsks Jev to choose among the options you give, and -j says whether a confident pick counts as approved.
›
my-skillsOpens the global skills repo, whose install.sh links its skills into the tool folders.
›
codex configOpens the Codex CLI config, which is deployed to Windows.
›
chrome bridgeInstalls the watcher that keeps Codex's Chrome plugin link current.
›
codex browserOpens Codex's direct Chrome command path and its live checks.
›
‹ assistant

claude

The Claude Code setup on this machine: the wrapper, global rules, settings, hooks and mirrors.

claudeRuns Claude Code through the usage guard, ahead of the native claude.
›
claude --main -cContinues the main session.
›
claude --main -rResumes a main session.
›
usage-guardOpens the usage guard: its install, Windows launcher and tests.
›
session-typesOpens the session types and the main-session wrapper.
›
CLAUDE.mdOpens the global Claude rules: browser automation, communication, research and presenting work.
›
AGENTS.mdOpens the shorter global agent notes.
›
settings.jsonOpens Claude Code's settings, which are deployed to Windows.
›
hooksOpens the hook scripts Claude Code runs: rules, history, team activity, proof reminder and server guard.
›
linux-globalOpens the mirror of this Linux machine's installed global instructions.
›
windows-globalOpens the mirror of the Windows desktop's installed instructions and docs.
›
desktop-v2-2026Opens the portable snapshot of the Windows desktop instructions; it is not loaded automatically.
›
communication-frameworkOpens a draft of communication design notes; nothing enforces it yet.
›
skills-shortlistOpens the skills researched on skills.sh.
›
‹ assistant

opencode

The OpenCode profiles: what each one loads, and the commands that run and switch them.

opencodeRuns opencode with the current profile's files.
›
opencode-profileShows the current opencode profile.
›
opencode-profilesLists what each profile loads.
›
opencode-switchSwitches every shell's new runs to the named profile.
›
opencode-loginSigns a profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editOpens one of the current profile's files.
›
opencode helpPrints every profile's files, one column per profile, and the commands; with more than 3 profiles, writes them to ~/.opencode-profiles/help.md and opens it.
›
opencode-profiles folderOpens the profile definitions and their tests.
›
private-leb-experimentalOpens the files of the private-leb-experimental profile.
›
‹ assistant

skills

The skill folders kept in this repo as backups; the global skills live in my-skills.

skill backupsOpens the folder of skill backups; copy in the ones you want installed.
›
tech-ledgerOpens the skill that reads and writes the betec Tech Ledger.
›
api-key-creationOpens the skill that gets a missing API key with browser tools.
›
clone-websiteOpens the skill that clones websites with parallel builder agents.
›
contextual-value-product-thinkingOpens the skill that analyzes products through contextual human values.
›
elad12390--web-research-assistantOpens the web research MCP server skill; its setup is in SETUP-NOTES.md.
›
epic-fanout-planningOpens the pattern for QA-gap epics with parallel fan-out and release gates.
›
impeccableOpens the frontend design skill: shape, critique, audit, polish.
›
iterative-action-reviewOpens the review of a completed real-world action.
›
lab-experimentOpens the skill for running an experiment in the ai-lab; its SKILL.md describes the steps.
›
mentor-modeOpens the mentor-mode skill; its SKILL.md describes the steps.
›
post-feature-cleanupOpens the pass after writing code: UI defects, leftovers and repo hygiene.
›
powershell-launchingOpens the skill for launching PowerShell or a new terminal on Windows.
›
reboot-resumeOpens the skill that preserves and resumes work across a reboot or restart.
›
resume-projectOpens the skill that resumes a project; its SKILL.md describes the steps.
›
solaraai-content-calendarOpens the SolaraAI content calendar skill.
›
solaraai-deploymentOpens the SolaraAI deploy flow skill.
›
solaraai-designOpens the SolaraAI design system skill.
›
solaraai-formsOpens the SolaraAI form behavior skill.
›
supabaseOpens Supabase's skill: Auth, RLS, migrations, CLI and debugging.
›
supabase-postgres-best-practicesOpens Supabase's Postgres performance rules.
›
tank--communication-engineeringOpens the skill that applies engineering discipline to what an agent says.
›
tank--skill-creatorOpens the skill for creating new skills.
›
tech-cv-writerOpens the skill for writing CVs; its references cover ATS, bullets and LaTeX.
›
‹ assistant

agents

The agent system: its checks, the sandbox page, team files and the data the agents keep.

agent checkRefuses broken agent records and exits 1.
›
agent listLists the agents with their tier, model and number of tests.
›
agent serveStarts the Agent Sandbox page at 127.0.0.1:8790.
›
Agent Sandbox pageOpens the sandbox: pick an agent, change its setup and ask it; needs agent serve running.
›
agent recordsOpens an agent's record: its setup, situations and saved tests.
›
spawn-teamStarts a team from its team file.
›
team filesOpens the team files, such as worker-pair and research-team.
›
dataOpens the cases, rule proposals, verdicts and reviews the agents keep in a private repo.
›
archiveOpens the files moved out of projects; each folder has an ARCHIVE.md.
›
‹ assistant

dashboard

The dashboard and its concepts version: the page, the servers and the checks.

dashboard serverStarts the dashboard server on 127.0.0.1:8780, or on a port you pass.
›
dashboard pageOpens the dashboard: Waiting, Overview and the reader; needs the server running.
›
dashboard testsRuns the dashboard checks against the real data and a real server.
›
dashboard READMEOpens the dashboard guide: what it writes, hot reload and its tabs.
›
concepts serverStarts the concepts version on 127.0.0.1:8781, to compare with the dashboard.
›
concepts pageOpens the concepts version of the page; needs its server running.
›
concepts testsRuns the concepts checks against the real data and a real server.
›
‹ assistant

hermes

Hermes, the agent installed from source: its launcher, runbooks and settings examples.

hermesRuns Hermes, with its default and jobs profiles.
›
hermes READMEOpens Hermes' install record and current configuration.
›
RESTORE.mdOpens the restore runbook for Hermes.
›
BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
›
default.config.example.yamlOpens the secret-free settings example for the default profile.
›
jobs.config.example.yamlOpens the secret-free settings example for the jobs profile.
›
zprofile-path.zshOpens the PATH line the installer added to ~/.zprofile.
›
hermes stateOpens Hermes' state and secrets folder, which is not in Git.
›
‹ Home

browser

The browser command, Chrome and browser QA.

browserRuns browser steps on one persistent Chrome window; the first call starts it.
›
browser statusPrints whether the browser server and its window are up.
›
browser closeCloses Chrome and stops the server.
›
recordStartStarts recording the tab as proof of a feature.
›
recordStopStops the recording.
›
browser READMEOpens the browser guide: every action, viewport preset, annotation and network capture.
›
chromeOpens the chrome screen: the one way Chrome starts here.
›
qaOpens the qa screen: behavioral smoke tests of pages.
›
‹ browser

chrome

Chrome: the one way it starts here, and the flags that let recordings run.

google-chromeStarts Chrome through chrome.sh, with the recording flag.
›
chrome.shOpens the launcher that adds the flags and starts Chrome.
›
install.shLinks google-chrome to chrome.sh; run once per machine and again after a Chrome update.
›
flagsOpens the one list of Chrome flags, read by chrome.sh and the recorder.
›
chrome READMEOpens why Chrome starts this way and its limits.
›
‹ browser

qa

Behavioral browser smoke QA: the CLI, its install, its secrets file and its guide.

jev-browser-testRuns a goal in the browser and reports only the text and URL you asserted.
›
install.shInstalls the CLI at one pinned upstream revision.
›
env fileOpens the CLI's secrets file, mode 600, not kept in Git.
›
QA READMEOpens the QA guide: exit codes, privacy boundary and the agent snippet.
›
‹ Home

windows

Setting up and checking the Windows machine: installs, scripts, skill sync and repos.

installOpens the install screen: installing, checking and rolling back the Windows setup.
›
scriptsOpens the scripts screen: the user scripts for Windows.
›
skill-syncOpens the skill-sync screen: how Windows keeps its skill folders current.
›
Clone-BetecRepos.ps1Clones the missing Betec repos into the standard layout; safe to re-run.
›
‹ windows

install

Installing, checking and rolling back the Windows setup, with its logs and manifests.

Start-Install.cmdInstalls the Windows environment from the manifests; approve the admin prompt.
›
Verify-Windows.ps1Checks the install.
›
Smoke-Test-Windows.ps1Runs the smoke test of the install.
›
Remove-WindowsPack.ps1Rolls the install back.
›
Export-Windows.ps1Exports the machine's current setup into the manifests.
›
Install-Windows.logOpens the install log.
›
Install-Windows.errors.logOpens the install errors.
›
inventory.mdOpens what the capture recorded.
›
secrets-checklist.mdOpens the sign-ins to redo by hand.
›
manifestsOpens the exact lists of programs, Node versions, npm packages and VS Code extensions.
›
configsOpens the Git and VS Code configs deployed to Windows.
›
init-windows READMEOpens the full install guide.
›
‹ windows

scripts

The user scripts for Windows: hibernate, touchpad fixes and MongoDB restore.

do_hibernate.ps1Hibernates the Windows PC.
›
fix_touchpad.ps1Repairs the touchpad.
›
fix_touchpad2.ps1Repairs the touchpad, second variant.
›
fix_touchpad3.ps1Repairs the touchpad, third variant.
›
restore-mongo.ps1Restores MongoDB from a backup.
›
‹ windows

skill-sync

How Windows keeps its skill folders in step with my-skills master.

Sync-Skills.ps1Fast-forwards the existing checkout and relinks the skill folders.
›
Test-Sync.ps1Tests the sync.
›
Test-Account.ps1Tests the runner account's rights.
›
runner serviceRuns the runner that starts a sync on trusted pushes to master.
›
catch-up taskRuns the sync once after startup, retrying up to three times.
›
last-success.jsonOpens the record of the last successful sync.
›
verification.mdOpens how the sync was verified.
›
skill-sync READMEOpens the setup, permissions and security notes.
›
‹ Home

sharing

What is shared between the laptop and Windows: mouse and keyboard, clipboard and audio.

deskflowOpens the deskflow screen: the shared mouse and keyboard, its service, settings and recovery.
›
clipstackOpens the clipstack screen: the shared clipboard, its services and its Windows side.
›
audio-startStarts sending all Linux audio to Windows over Tailscale.
›
audio-pausePauses the sending and restores the speakers.
›
audio-shareTurns sending on or off, shows its status, or plays a test tone.
›
‹ sharing

deskflow

Deskflow, the shared mouse and keyboard between the laptop and Windows: service, settings and recovery.

resume-kvmStarts Deskflow again and asks GNOME for input capture.
›
Deskflow serviceRuns the Deskflow server; it starts with the graphical session.
›
laptop settingsOpens the laptop's Deskflow settings.
›
Windows settingsOpens the Windows client and service settings, which are separate copies.
›
deskflow-lockdown.nftOpens the firewall rules that lock Deskflow's network down.
›
NETWORK-AUDIT.mdOpens the Deskflow network audit.
›
deskflow READMEOpens the Deskflow guide: everyday use and recovery.
›
USB mouse notesOpens the USB mouse notes, including how the keyboard follows the mouse.
›
USB mouse forwardingForwards the Windows USB mouse to the laptop; off since 2026-10-20.
›
‹ sharing

clipstack

clipstack, the shared clipboard: its services, picker and Windows side.

install.shInstalls the clipboard server and watcher on Linux.
›
clipstack-serverRuns the clipboard server.
›
clipstack-watcherRuns the clipboard watcher.
›
picker.pyShows the clipboard picker, to choose an item.
›
clipstack.ahkRuns the clipboard script on Windows (AutoHotkey).
›
Windows install.ps1Installs the Windows clipboard side.
›
Windows verify.ps1Checks the Windows clipboard side.
›
‹ Home

cvs

The CVs: the PDFs, their sources, the dated versions and the text and design builds.

cv-full-stack.pdfOpens the Full Stack Developer CV.
›
cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
›
cv-ai-integrations.pdfOpens the AI Integrations CV.
›
sourcesOpens the sources screen: the LaTeX, the facts and how to rebuild.
›
versionsOpens the dated CV snapshots, 2026-10-04 and v2.
›
textOpens the plain-text CVs and the script that makes them.
›
designOpens the designed CV build: HTML and PDF from build-design.py.
›
cv READMEOpens the CV folder guide.
›
‹ cvs

sources

The CV sources: LaTeX for each version, the facts they are built from, and how to rebuild them.

cv-full-stack.texOpens the Full Stack Developer CV's LaTeX source.
›
cv-ai-full-stack.texOpens the AI Full Stack Engineer CV's LaTeX source.
›
cv-ai-integrations.texOpens the AI Integrations CV's LaTeX source.
›
rebuildRebuilds one CV PDF from its LaTeX source.
›
experience-notes.mdOpens the factual input every CV is built from.
›
cv-master.mdOpens the readable master CV.
›
cv-material-draft.mdOpens the drafting decisions behind the CVs.
›
WORKFLOW.mdOpens the CV workflow: edit here, rebuild, then commit the sources and PDFs together.
›
‹ Home

reference

Records of machine incidents and verified states, the case studies, and the project docs.

closed-lid incidentOpens the record of the closed-lid test that passed on 2026-10-01.
›
reference READMEOpens the list of dated incident cases.
›
conceptual-modeling caseOpens the case where the skill-guided run was judged materially better.
›
signal garden caseOpens the exhibit separating durable explanation from the live interface.
›
Kernel resultsOpens the Kernel cloud browser results: speed, use cases and session recording.
›
docsOpens the docs screen: the project's changelog, plans, designs, research and records.
›
‹ reference

docs

The project's docs folders and the intent, scenario and QA records.

changelogOpens the dated changelog entries.
›
plansOpens the dated plan for each piece of work.
›
designOpens the design pitches, recommendations and research.
›
researchOpens the research notes, including the phase checks.
›
functional-researchOpens the research on agent frameworks and their features.
›
flowsOpens the flow cards and data models.
›
itemsOpens the planned, urgent and work item lists.
›
rolesOpens the role definitions for qa-agent and the other roles.
›
playbooksOpens the playbooks, such as talking while the team builds.
›
intentOpens each module's INTENT.md, its typed intent and rules.
›
scenariosOpens the behavior scenarios, one folder per feature.
›
QA findingsOpens the QA findings, one file per check.
›
Raw answer
The map is planning only. Nothing is built, and I could read only the dump, not the files it names.

**Scenario** (reasoning from the README, not observed): you are on the Linux laptop and reach for this kit mid-task. You want a command to run, a file to open, a machine fix when something breaks, the Windows setup, a CV, or a rule. You rarely need more than one of these at a time.

**Judgment calls**
- **Eight top groups**, each named by one noun from the README's headings: shell, machine, assistant, browser, windows, sharing, cvs, reference. OpenCode, the dashboard, Hermes, the agent system and the skills sit under assistant, since they are how the agents run and report.
- **Left off:** `lan-mouse` (you retired it on 2026-10-05) and `codex/playwright-mcp` (retired). Also left off are experiment outputs under `docs/research/` (the `out*`, `heldout` and `cases` folders), fixtures, tests, screenshots and fonts. You don't reach for those.
- **The top help screen** (`workstation`, `ws`, `setup`) is the map itself, so it has no row.
- **Unverified "what" lines:** some rows have a purpose the dump doesn't state. Examples are `resume-kvm`, `Export-Windows.ps1`, `snapshot.py`, `team-park`, the commands inside `infra.zsh` and `utils.zsh`, `restore-mongo.ps1`, and skills whose SKILL.md isn't in the dump. Their "what" comes from the name or the README. `cli-engineer` must read each one before the help text is written.
- **One screen per thing**, except where a thing is reached for a different reason from a second place. I found no such case, so each row appears once.
- **Where forms point:** to the repo copy where the repo is the source, and to the installed path where you open the installed file (Deskflow service and settings).
- **Security, not on the map:** the README says `infra.zsh` and `utils.zsh` embed a credential in git URLs and should be treated as compromised. Rotate it before building on top of those files.
- **Skill count mismatch:** the README table lists 13 backed-up skills, but `claude/skills/` holds 23. The map lists the folder as it is. See question 5.

```json
{"screens": [
{"path": [], "sentence": "The workstation kit, grouped by what you are trying to do.", "rows": [
{"name": "shell", "form": "workstation shell", "what": "Opens the shell screen: the commands and files this kit adds to your terminal."},
{"name": "machine", "form": "workstation machine", "what": "Opens the machine screen: Linux power, display, network, lid and repair scripts."},
{"name": "assistant", "form": "workstation assistant", "what": "Opens the assistant screen: Claude, Codex, OpenCode and Hermes setup, rules, agents and the dashboard."},
{"name": "browser", "form": "workstation browser", "what": "Opens the browser screen: the browser command, Chrome and browser QA."},
{"name": "windows", "form": "workstation windows", "what": "Opens the windows screen: installing, checking and syncing the Windows machine."},
{"name": "sharing", "form": "workstation sharing", "what": "Opens the sharing screen: the mouse, keyboard, clipboard and audio shared with Windows."},
{"name": "cvs", "form": "workstation cvs", "what": "Opens the cvs screen: the CV PDFs and how to rebuild them."},
{"name": "reference", "form": "workstation reference", "what": "Opens the reference screen: incident records, case studies and the project docs."}
]},
{"path": ["shell"], "sentence": "The shell commands and files this kit adds to your terminal.", "rows": [
{"name": "zsh.d", "form": "~/projects/workstation/zsh.d/", "what": "Opens the folder of shell files that zsh loads from ~/.zsh.d."},
{"name": "review-open", "form": "review-open <file>", "what": "Opens a file for review."},
{"name": "git checkout", "form": "git checkout", "what": "Lists the files a checkout would discard and asks [y/N] before discarding them."},
{"name": "git hooks", "form": "~/.git-hooks/", "what": "Opens the git hook shims that run in every repo."},
{"name": ".gitconfig", "form": "~/.gitconfig", "what": "Opens git's identity, LFS, credential and hooks settings."},
{"name": "infra", "form": "~/projects/workstation/zsh.d/infra.zsh", "what": "Opens the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts file."},
{"name": "utils", "form": "~/projects/workstation/zsh.d/utils.zsh", "what": "Opens the terminal helpers, IP aliases, node setup and repair helpers file."},
{"name": "set-title", "form": "set-title", "what": "Sets the terminal title."},
{"name": "killport", "form": "killport", "what": "Stops whatever is listening on a port."},
{"name": "api-keys", "form": "~/projects/workstation/zsh.d/api-keys.zsh", "what": "Exports the general-use API keys into each new shell."},
{"name": "api-keys-edit", "form": "api-keys-edit", "what": "Opens the general-use API keys file, which is never kept in Git."}
]},
{"path": ["machine"], "sentence": "The Linux machine's own scripts: power, display, network, lid and repairs.", "rows": [
{"name": "cpu-min-power.sh", "form": "~/projects/workstation/cpu-min-power.sh", "what": "Sets the power-saver profile with turbo off and the CPU capped at 8%."},
{"name": "cpu-normal-power.sh", "form": "~/projects/workstation/cpu-normal-power.sh", "what": "Sets the balanced profile with turbo on and the CPU cap back to 100%."},
{"name": "fix_old_monitor_hdmi.sh", "form": "~/projects/workstation/fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output, 1920x1080 at 59.88 by default."},
{"name": "linux-internet-recovery.sh", "form": "~/projects/workstation/linux-internet-recovery.sh", "what": "Repairs DNS and restarts networking."},
{"name": "recover-tailscale-remote-terminal.sh", "form": "~/projects/workstation/recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts Tailscale and starts the remote terminal service."},
{"name": "keep-running-with-lid-closed.sh", "form": "~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.sh", "what": "Makes closing the lid do nothing, after the next reboot."},
{"name": "restore-default-lid-behavior.sh", "form": "~/projects/workstation/laptop-utilities/restore-default-lid-behavior.sh", "what": "Puts closing the lid back to the default, after the next reboot."},
{"name": "fix-keyboard", "form": "fix-keyboard", "what": "Repairs the keyboard."},
{"name": "fix-mouse", "form": "fix-mouse", "what": "Repairs the mouse."},
{"name": "fix-disk", "form": "fix-disk", "what": "Repairs the disk."},
{"name": "fix-whatsapp", "form": "fix-whatsapp", "what": "Repairs WhatsApp."}
]},
{"path": ["assistant"], "sentence": "The AI tools on this machine: their setup, rules, agents, dashboard and Hermes.", "rows": [
{"name": "claude", "form": "workstation assistant claude", "what": "Opens the claude screen: the Claude Code wrapper, global rules, settings and hooks."},
{"name": "opencode", "form": "workstation assistant opencode", "what": "Opens the opencode screen: the profiles and the commands that run and switch them."},
{"name": "skills", "form": "workstation assistant skills", "what": "Opens the skills screen: the skill folders kept here as backups."},
{"name": "agents", "form": "workstation assistant agents", "what": "Opens the agents screen: agent checks, the sandbox page, team files and agent data."},
{"name": "dashboard", "form": "workstation assistant dashboard", "what": "Opens the dashboard screen: the page, its servers and its checks."},
{"name": "hermes", "form": "workstation assistant hermes", "what": "Opens the hermes screen: the Hermes launcher, runbooks and settings examples."},
{"name": "rules", "form": "rules [folder]", "what": "Prints the rules, for the folder given."},
{"name": "workboard/rules.yaml", "form": "~/projects/workstation/workboard/rules.yaml", "what": "Opens the rules source that rules reads; only you or an accepted proposal changes it."},
{"name": "jev", "form": "jev <context> -c <question> <options> [-j]", "what": "Asks Jev to choose among the options you give, and -j says whether a confident pick counts as approved."},
{"name": "my-skills", "form": "~/projects/my-skills", "what": "Opens the global skills repo, whose install.sh links its skills into the tool folders."},
{"name": "codex config", "form": "~/projects/workstation/codex/config.toml", "what": "Opens the Codex CLI config, which is deployed to Windows."},
{"name": "chrome bridge", "form": "~/projects/workstation/codex/chrome-bridge/install.sh", "what": "Installs the watcher that keeps Codex's Chrome plugin link current."},
{"name": "codex browser", "form": "~/projects/workstation/codex/browser/README.md", "what": "Opens Codex's direct Chrome command path and its live checks."}
]},
{"path": ["assistant", "claude"], "sentence": "The Claude Code setup on this machine: the wrapper, global rules, settings, hooks and mirrors.", "rows": [
{"name": "claude", "form": "~/bin/claude", "what": "Runs Claude Code through the usage guard, ahead of the native claude."},
{"name": "claude --main -c", "form": "claude --main -c", "what": "Continues the main session."},
{"name": "claude --main -r", "form": "claude --main -r", "what": "Resumes a main session."},
{"name": "usage-guard", "form": "~/projects/workstation/claude/usage-guard/", "what": "Opens the usage guard: its install, Windows launcher and tests."},
{"name": "session-types", "form": "~/projects/workstation/claude/session-types/", "what": "Opens the session types and the main-session wrapper."},
{"name": "CLAUDE.md", "form": "~/projects/workstation/claude/CLAUDE.md", "what": "Opens the global Claude rules: browser automation, communication, research and presenting work."},
{"name": "AGENTS.md", "form": "~/projects/workstation/claude/AGENTS.md", "what": "Opens the shorter global agent notes."},
{"name": "settings.json", "form": "~/projects/workstation/claude/settings.json", "what": "Opens Claude Code's settings, which are deployed to Windows."},
{"name": "hooks", "form": "~/projects/workstation/claude/hooks/", "what": "Opens the hook scripts Claude Code runs: rules, history, team activity, proof reminder and server guard."},
{"name": "linux-global", "form": "~/projects/workstation/claude/linux-global/", "what": "Opens the mirror of this Linux machine's installed global instructions."},
{"name": "windows-global", "form": "~/projects/workstation/claude/windows-global/", "what": "Opens the mirror of the Windows desktop's installed instructions and docs."},
{"name": "desktop-v2-2026", "form": "~/projects/workstation/claude/backups/desktop-v2-2026/", "what": "Opens the portable snapshot of the Windows desktop instructions; it is not loaded automatically."},
{"name": "communication-framework", "form": "~/projects/workstation/claude/communication-framework.md", "what": "Opens a draft of communication design notes; nothing enforces it yet."},
{"name": "skills-shortlist", "form": "~/projects/workstation/claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh."}
]},
{"path": ["assistant", "opencode"], "sentence": "The OpenCode profiles: what each one loads, and the commands that run and switch them.", "rows": [
{"name": "opencode", "form": "opencode (also oc)", "what": "Runs opencode with the current profile's files."},
{"name": "opencode-profile", "form": "opencode-profile", "what": "Shows the current opencode profile."},
{"name": "opencode-profiles", "form": "opencode-profiles", "what": "Lists what each profile loads."},
{"name": "opencode-switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "opencode-login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "opencode-files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "opencode-edit", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files."},
{"name": "opencode help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints every profile's files, one column per profile, and the commands; with more than 3 profiles, writes them to ~/.opencode-profiles/help.md and opens it."},
{"name": "opencode-profiles folder", "form": "~/projects/workstation/opencode-profiles/", "what": "Opens the profile definitions and their tests."},
{"name": "private-leb-experimental", "form": "~/projects/workstation/opencode-profiles/private-leb-experimental/", "what": "Opens the files of the private-leb-experimental profile."}
]},
{"path": ["assistant", "skills"], "sentence": "The skill folders kept in this repo as backups; the global skills live in my-skills.", "rows": [
{"name": "skill backups", "form": "~/projects/workstation/claude/skills/", "what": "Opens the folder of skill backups; copy in the ones you want installed."},
{"name": "tech-ledger", "form": "~/projects/workstation/claude/skills/tech-ledger/", "what": "Opens the skill that reads and writes the betec Tech Ledger."},
{"name": "api-key-creation", "form": "~/projects/workstation/claude/skills/api-key-creation/", "what": "Opens the skill that gets a missing API key with browser tools."},
{"name": "clone-website", "form": "~/projects/workstation/claude/skills/clone-website/", "what": "Opens the skill that clones websites with parallel builder agents."},
{"name": "contextual-value-product-thinking", "form": "~/projects/workstation/claude/skills/contextual-value-product-thinking/", "what": "Opens the skill that analyzes products through contextual human values."},
{"name": "elad12390--web-research-assistant", "form": "~/projects/workstation/claude/skills/elad12390--web-research-assistant/", "what": "Opens the web research MCP server skill; its setup is in SETUP-NOTES.md."},
{"name": "epic-fanout-planning", "form": "~/projects/workstation/claude/skills/epic-fanout-planning/", "what": "Opens the pattern for QA-gap epics with parallel fan-out and release gates."},
{"name": "impeccable", "form": "~/projects/workstation/claude/skills/impeccable/", "what": "Opens the frontend design skill: shape, critique, audit, polish."},
{"name": "iterative-action-review", "form": "~/projects/workstation/claude/skills/iterative-action-review/", "what": "Opens the review of a completed real-world action."},
{"name": "lab-experiment", "form": "~/projects/workstation/claude/skills/lab-experiment/", "what": "Opens the skill for running an experiment in the ai-lab; its SKILL.md describes the steps."},
{"name": "mentor-mode", "form": "~/projects/workstation/claude/skills/mentor-mode/", "what": "Opens the mentor-mode skill; its SKILL.md describes the steps."},
{"name": "post-feature-cleanup", "form": "~/projects/workstation/claude/skills/post-feature-cleanup/", "what": "Opens the pass after writing code: UI defects, leftovers and repo hygiene."},
{"name": "powershell-launching", "form": "~/projects/workstation/claude/skills/powershell-launching/", "what": "Opens the skill for launching PowerShell or a new terminal on Windows."},
{"name": "reboot-resume", "form": "~/projects/workstation/claude/skills/reboot-resume/", "what": "Opens the skill that preserves and resumes work across a reboot or restart."},
{"name": "resume-project", "form": "~/projects/workstation/claude/skills/resume-project/", "what": "Opens the skill that resumes a project; its SKILL.md describes the steps."},
{"name": "solaraai-content-calendar", "form": "~/projects/workstation/claude/skills/solaraai-content-calendar/", "what": "Opens the SolaraAI content calendar skill."},
{"name": "solaraai-deployment", "form": "~/projects/workstation/claude/skills/solaraai-deployment/", "what": "Opens the SolaraAI deploy flow skill."},
{"name": "solaraai-design", "form": "~/projects/workstation/claude/skills/solaraai-design/", "what": "Opens the SolaraAI design system skill."},
{"name": "solaraai-forms", "form": "~/projects/workstation/claude/skills/solaraai-forms/", "what": "Opens the SolaraAI form behavior skill."},
{"name": "supabase", "form": "~/projects/workstation/claude/skills/supabase/", "what": "Opens Supabase's skill: Auth, RLS, migrations, CLI and debugging."},
{"name": "supabase-postgres-best-practices", "form": "~/projects/workstation/claude/skills/supabase-postgres-best-practices/", "what": "Opens Supabase's Postgres performance rules."},
{"name": "tank--communication-engineering", "form": "~/projects/workstation/claude/skills/tank--communication-engineering/", "what": "Opens the skill that applies engineering discipline to what an agent says."},
{"name": "tank--skill-creator", "form": "~/projects/workstation/claude/skills/tank--skill-creator/", "what": "Opens the skill for creating new skills."},
{"name": "tech-cv-writer", "form": "~/projects/workstation/claude/skills/tech-cv-writer/", "what": "Opens the skill for writing CVs; its references cover ATS, bullets and LaTeX."}
]},
{"path": ["assistant", "agents"], "sentence": "The agent system: its checks, the sandbox page, team files and the data the agents keep.", "rows": [
{"name": "agent check", "form": "~/projects/workstation/agent-framework/agent check", "what": "Refuses broken agent records and exits 1."},
{"name": "agent list", "form": "~/projects/workstation/agent-framework/agent list", "what": "Lists the agents with their tier, model and number of tests."},
{"name": "agent serve", "form": "~/projects/workstation/agent-framework/agent serve", "what": "Starts the Agent Sandbox page at 127.0.0.1:8790."},
{"name": "Agent Sandbox page", "form": "http://127.0.0.1:8790", "what": "Opens the sandbox: pick an agent, change its setup and ask it; needs agent serve running."},
{"name": "agent records", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "Opens an agent's record: its setup, situations and saved tests."},
{"name": "spawn-team", "form": "/spawn-team <team> (Claude) or $spawn-team <team> (Codex)", "what": "Starts a team from its team file."},
{"name": "team files", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files, such as worker-pair and research-team."},
{"name": "data", "form": "~/projects/data/", "what": "Opens the cases, rule proposals, verdicts and reviews the agents keep in a private repo."},
{"name": "archive", "form": "~/archive/", "what": "Opens the files moved out of projects; each folder has an ARCHIVE.md."}
]},
{"path": ["assistant", "dashboard"], "sentence": "The dashboard and its concepts version: the page, the servers and the checks.", "rows": [
{"name": "dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard server on 127.0.0.1:8780, or on a port you pass."},
{"name": "dashboard page", "form": "http://127.0.0.1:8780", "what": "Opens the dashboard: Waiting, Overview and the reader; needs the server running."},
{"name": "dashboard tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the dashboard checks against the real data and a real server."},
{"name": "dashboard README", "form": "~/projects/workstation/dashboard/README.md", "what": "Opens the dashboard guide: what it writes, hot reload and its tabs."},
{"name": "concepts server", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts version on 127.0.0.1:8781, to compare with the dashboard."},
{"name": "concepts page", "form": "http://127.0.0.1:8781", "what": "Opens the concepts version of the page; needs its server running."},
{"name": "concepts tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the concepts checks against the real data and a real server."}
]},
{"path": ["assistant", "hermes"], "sentence": "Hermes, the agent installed from source: its launcher, runbooks and settings examples.", "rows": [
{"name": "hermes", "form": "~/.local/bin/hermes", "what": "Runs Hermes, with its default and jobs profiles."},
{"name": "hermes README", "form": "~/projects/workstation/hermes/README.md", "what": "Opens Hermes' install record and current configuration."},
{"name": "RESTORE.md", "form": "~/projects/workstation/hermes/RESTORE.md", "what": "Opens the restore runbook for Hermes."},
{"name": "BACKUP-2026-10-02.md", "form": "~/projects/workstation/hermes/BACKUP-2026-10-02.md", "what": "Opens the record of the 2026-10-02 backup."},
{"name": "default.config.example.yaml", "form": "~/projects/workstation/hermes/default.config.example.yaml", "what": "Opens the secret-free settings example for the default profile."},
{"name": "jobs.config.example.yaml", "form": "~/projects/workstation/hermes/jobs.config.example.yaml", "what": "Opens the secret-free settings example for the jobs profile."},
{"name": "zprofile-path.zsh", "form": "~/projects/workstation/hermes/zprofile-path.zsh", "what": "Opens the PATH line the installer added to ~/.zprofile."},
{"name": "hermes state", "form": "~/.hermes", "what": "Opens Hermes' state and secrets folder, which is not in Git."}
]},
{"path": ["browser"], "sentence": "The browser command, Chrome and browser QA.", "rows": [
{"name": "browser", "form": "browser '<json-array-of-steps>'", "what": "Runs browser steps on one persistent Chrome window; the first call starts it."},
{"name": "browser status", "form": "browser status", "what": "Prints whether the browser server and its window are up."},
{"name": "browser close", "form": "browser close", "what": "Closes Chrome and stops the server."},
{"name": "recordStart", "form": "recordStart step", "what": "Starts recording the tab as proof of a feature."},
{"name": "recordStop", "form": "recordStop step", "what": "Stops the recording."},
{"name": "browser README", "form": "~/projects/workstation/browser/README.md", "what": "Opens the browser guide: every action, viewport preset, annotation and network capture."},
{"name": "chrome", "form": "workstation browser chrome", "what": "Opens the chrome screen: the one way Chrome starts here."},
{"name": "qa", "form": "workstation browser qa", "what": "Opens the qa screen: behavioral smoke tests of pages."}
]},
{"path": ["browser", "chrome"], "sentence": "Chrome: the one way it starts here, and the flags that let recordings run.", "rows": [
{"name": "google-chrome", "form": "google-chrome", "what": "Starts Chrome through chrome.sh, with the recording flag."},
{"name": "chrome.sh", "form": "~/projects/workstation/chrome/chrome.sh", "what": "Opens the launcher that adds the flags and starts Chrome."},
{"name": "install.sh", "form": "~/projects/workstation/chrome/install.sh", "what": "Links google-chrome to chrome.sh; run once per machine and again after a Chrome update."},
{"name": "flags", "form": "~/projects/workstation/chrome/flags", "what": "Opens the one list of Chrome flags, read by chrome.sh and the recorder."},
{"name": "chrome README", "form": "~/projects/workstation/chrome/README.md", "what": "Opens why Chrome starts this way and its limits."}
]},
{"path": ["browser", "qa"], "sentence": "Behavioral browser smoke QA: the CLI, its install, its secrets file and its guide.", "rows": [
{"name": "jev-browser-test", "form": "jev-browser-test", "what": "Runs a goal in the browser and reports only the text and URL you asserted."},
{"name": "install.sh", "form": "sh ~/projects/workstation/jev-browser-test/install.sh", "what": "Installs the CLI at one pinned upstream revision."},
{"name": "env file", "form": "~/.config/jev-browser-test/env", "what": "Opens the CLI's secrets file, mode 600, not kept in Git."},
{"name": "QA README", "form": "~/projects/workstation/jev-browser-test/README.md", "what": "Opens the QA guide: exit codes, privacy boundary and the agent snippet."}
]},
{"path": ["windows"], "sentence": "Setting up and checking the Windows machine: installs, scripts, skill sync and repos.", "rows": [
{"name": "install", "form": "workstation windows install", "what": "Opens the install screen: installing, checking and rolling back the Windows setup."},
{"name": "scripts", "form": "workstation windows scripts", "what": "Opens the scripts screen: the user scripts for Windows."},
{"name": "skill-sync", "form": "workstation windows skill-sync", "what": "Opens the skill-sync screen: how Windows keeps its skill folders current."},
{"name": "Clone-BetecRepos.ps1", "form": "~/projects/workstation/repos/Clone-BetecRepos.ps1", "what": "Clones the missing Betec repos into the standard layout; safe to re-run."}
]},
{"path": ["windows", "install"], "sentence": "Installing, checking and rolling back the Windows setup, with its logs and manifests.", "rows": [
{"name": "Start-Install.cmd", "form": "~/projects/workstation/init-windows/Start-Install.cmd", "what": "Installs the Windows environment from the manifests; approve the admin prompt."},
{"name": "Verify-Windows.ps1", "form": "~/projects/workstation/init-windows/Verify-Windows.ps1", "what": "Checks the install."},
{"name": "Smoke-Test-Windows.ps1", "form": "~/projects/workstation/init-windows/Smoke-Test-Windows.ps1", "what": "Runs the smoke test of the install."},
{"name": "Remove-WindowsPack.ps1", "form": "~/projects/workstation/init-windows/Remove-WindowsPack.ps1", "what": "Rolls the install back."},
{"name": "Export-Windows.ps1", "form": "~/projects/workstation/init-windows/Export-Windows.ps1", "what": "Exports the machine's current setup into the manifests."},
{"name": "Install-Windows.log", "form": "~/projects/workstation/init-windows/logs/Install-Windows.log", "what": "Opens the install log."},
{"name": "Install-Windows.errors.log", "form": "~/projects/workstation/init-windows/logs/Install-Windows.errors.log", "what": "Opens the install errors."},
{"name": "inventory.md", "form": "~/projects/workstation/init-windows/inventory.md", "what": "Opens what the capture recorded."},
{"name": "secrets-checklist.md", "form": "~/projects/workstation/init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand."},
{"name": "manifests", "form": "~/projects/workstation/init-windows/manifests/", "what": "Opens the exact lists of programs, Node versions, npm packages and VS Code extensions."},
{"name": "configs", "form": "~/projects/workstation/init-windows/configs/", "what": "Opens the Git and VS Code configs deployed to Windows."},
{"name": "init-windows README", "form": "~/projects/workstation/init-windows/README.md", "what": "Opens the full install guide."}
]},
{"path": ["windows", "scripts"], "sentence": "The user scripts for Windows: hibernate, touchpad fixes and MongoDB restore.", "rows": [
{"name": "do_hibernate.ps1", "form": "~/projects/workstation/init-windows/user-scripts/do_hibernate.ps1", "what": "Hibernates the Windows PC."},
{"name": "fix_touchpad.ps1", "form": "~/projects/workstation/init-windows/user-scripts/fix_touchpad.ps1", "what": "Repairs the touchpad."},
{"name": "fix_touchpad2.ps1", "form": "~/projects/workstation/init-windows/user-scripts/fix_touchpad2.ps1", "what": "Repairs the touchpad, second variant."},
{"name": "fix_touchpad3.ps1", "form": "~/projects/workstation/init-windows/user-scripts/fix_touchpad3.ps1", "what": "Repairs the touchpad, third variant."},
{"name": "restore-mongo.ps1", "form": "~/projects/workstation/init-windows/user-scripts/restore-mongo.ps1", "what": "Restores MongoDB from a backup."}
]},
{"path": ["windows", "skill-sync"], "sentence": "How Windows keeps its skill folders in step with my-skills master.", "rows": [
{"name": "Sync-Skills.ps1", "form": "~/projects/workstation/skills-sync-windows/Sync-Skills.ps1", "what": "Fast-forwards the existing checkout and relinks the skill folders."},
{"name": "Test-Sync.ps1", "form": "~/projects/workstation/skills-sync-windows/Test-Sync.ps1", "what": "Tests the sync."},
{"name": "Test-Account.ps1", "form": "~/projects/workstation/skills-sync-windows/Test-Account.ps1", "what": "Tests the runner account's rights."},
{"name": "runner service", "form": "actions.runner.Lebnor-my-skills.my-skills-liel-windows", "what": "Runs the runner that starts a sync on trusted pushes to master."},
{"name": "catch-up task", "form": "MySkillsSync-CatchUp", "what": "Runs the sync once after startup, retrying up to three times."},
{"name": "last-success.json", "form": "C:\\ProgramData\\MySkillsSync\\state\\last-success.json", "what": "Opens the record of the last successful sync."},
{"name": "verification.md", "form": "~/projects/workstation/skills-sync-windows/verification.md", "what": "Opens how the sync was verified."},
{"name": "skill-sync README", "form": "~/projects/workstation/skills-sync-windows/README.md", "what": "Opens the setup, permissions and security notes."}
]},
{"path": ["sharing"], "sentence": "What is shared between the laptop and Windows: mouse and keyboard, clipboard and audio.", "rows": [
{"name": "deskflow", "form": "workstation sharing deskflow", "what": "Opens the deskflow screen: the shared mouse and keyboard, its service, settings and recovery."},
{"name": "clipstack", "form": "workstation sharing clipstack", "what": "Opens the clipstack screen: the shared clipboard, its services and its Windows side."},
{"name": "audio-start", "form": "audio-start", "what": "Starts sending all Linux audio to Windows over Tailscale."},
{"name": "audio-pause", "form": "audio-pause", "what": "Pauses the sending and restores the speakers."},
{"name": "audio-share", "form": "audio-share on|off|status|tone", "what": "Turns sending on or off, shows its status, or plays a test tone."}
]},
{"path": ["sharing", "deskflow"], "sentence": "Deskflow, the shared mouse and keyboard between the laptop and Windows: service, settings and recovery.", "rows": [
{"name": "resume-kvm", "form": "resume-kvm", "what": "Starts Deskflow again and asks GNOME for input capture."},
{"name": "Deskflow service", "form": "~/.config/systemd/user/deskflow.service", "what": "Runs the Deskflow server; it starts with the graphical session."},
{"name": "laptop settings", "form": "~/.config/Deskflow/Deskflow.conf", "what": "Opens the laptop's Deskflow settings."},
{"name": "Windows settings", "form": "~/projects/workstation/deskflow/windows.conf", "what": "Opens the Windows client and service settings, which are separate copies."},
{"name": "deskflow-lockdown.nft", "form": "~/projects/workstation/deskflow/deskflow-lockdown.nft", "what": "Opens the firewall rules that lock Deskflow's network down."},
{"name": "NETWORK-AUDIT.md", "form": "~/projects/workstation/deskflow/NETWORK-AUDIT.md", "what": "Opens the Deskflow network audit."},
{"name": "deskflow README", "form": "~/projects/workstation/deskflow/README.md", "what": "Opens the Deskflow guide: everyday use and recovery."},
{"name": "USB mouse notes", "form": "~/projects/workstation/deskflow/usb-mouse/README.md", "what": "Opens the USB mouse notes, including how the keyboard follows the mouse."},
{"name": "USB mouse forwarding", "form": "~/projects/workstation/deskflow/usb-mouse/deskflow-usb-mouse.service", "what": "Forwards the Windows USB mouse to the laptop; off since 2026-10-20."}
]},
{"path": ["sharing", "clipstack"], "sentence": "clipstack, the shared clipboard: its services, picker and Windows side.", "rows": [
{"name": "install.sh", "form": "~/projects/workstation/clipstack/install.sh", "what": "Installs the clipboard server and watcher on Linux."},
{"name": "clipstack-server", "form": "~/projects/workstation/clipstack/units/clipstack-server.service", "what": "Runs the clipboard server."},
{"name": "clipstack-watcher", "form": "~/projects/workstation/clipstack/units/clipstack-watcher.service", "what": "Runs the clipboard watcher."},
{"name": "picker.py", "form": "~/projects/workstation/clipstack/picker.py", "what": "Shows the clipboard picker, to choose an item."},
{"name": "clipstack.ahk", "form": "~/projects/workstation/clipstack/windows/clipstack.ahk", "what": "Runs the clipboard script on Windows (AutoHotkey)."},
{"name": "Windows install.ps1", "form": "~/projects/workstation/clipstack/windows/install.ps1", "what": "Installs the Windows clipboard side."},
{"name": "Windows verify.ps1", "form": "~/projects/workstation/clipstack/windows/verify.ps1", "what": "Checks the Windows clipboard side."}
]},
{"path": ["cvs"], "sentence": "The CVs: the PDFs, their sources, the dated versions and the text and design builds.", "rows": [
{"name": "cv-full-stack.pdf", "form": "~/projects/workstation/cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
{"name": "cv-ai-full-stack.pdf", "form": "~/projects/workstation/cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
{"name": "cv-ai-integrations.pdf", "form": "~/projects/workstation/cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
{"name": "sources", "form": "workstation cvs sources", "what": "Opens the sources screen: the LaTeX, the facts and how to rebuild."},
{"name": "versions", "form": "~/projects/workstation/cv/versions/", "what": "Opens the dated CV snapshots, 2026-10-04 and v2."},
{"name": "text", "form": "~/projects/workstation/cv/text/", "what": "Opens the plain-text CVs and the script that makes them."},
{"name": "design", "form": "~/projects/workstation/cv/design/", "what": "Opens the designed CV build: HTML and PDF from build-design.py."},
{"name": "cv README", "form": "~/projects/workstation/cv/README.md", "what": "Opens the CV folder guide."}
]},
{"path": ["cvs", "sources"], "sentence": "The CV sources: LaTeX for each version, the facts they are built from, and how to rebuild them.", "rows": [
{"name": "cv-full-stack.tex", "form": "~/projects/workstation/cv/cv-full-stack.tex", "what": "Opens the Full Stack Developer CV's LaTeX source."},
{"name": "cv-ai-full-stack.tex", "form": "~/projects/workstation/cv/cv-ai-full-stack.tex", "what": "Opens the AI Full Stack Engineer CV's LaTeX source."},
{"name": "cv-ai-integrations.tex", "form": "~/projects/workstation/cv/cv-ai-integrations.tex", "what": "Opens the AI Integrations CV's LaTeX source."},
{"name": "rebuild", "form": "pdflatex -interaction=nonstopmode -halt-on-error <version>.tex", "what": "Rebuilds one CV PDF from its LaTeX source."},
{"name": "experience-notes.md", "form": "~/projects/workstation/cv/experience-notes.md", "what": "Opens the factual input every CV is built from."},
{"name": "cv-master.md", "form": "~/projects/workstation/cv/cv-master.md", "what": "Opens the readable master CV."},
{"name": "cv-material-draft.md", "form": "~/projects/workstation/cv/cv-material-draft.md", "what": "Opens the drafting decisions behind the CVs."},
{"name": "WORKFLOW.md", "form": "~/projects/workstation/cv/WORKFLOW.md", "what": "Opens the CV workflow: edit here, rebuild, then commit the sources and PDFs together."}
]},
{"path": ["reference"], "sentence": "Records of machine incidents and verified states, the case studies, and the project docs.", "rows": [
{"name": "closed-lid incident", "form": "~/projects/workstation/reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "Opens the record of the closed-lid test that passed on 2026-10-01."},
{"name": "reference README", "form": "~/projects/workstation/reference/README.md", "what": "Opens the list of dated incident cases."},
{"name": "conceptual-modeling case", "form": "~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "Opens the case where the skill-guided run was judged materially better."},
{"name": "signal garden case", "form": "~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/", "what": "Opens the exhibit separating durable explanation from the live interface."},
{"name": "Kernel results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the Kernel cloud browser results: speed, use cases and session recording."},
{"name": "docs", "form": "workstation reference docs", "what": "Opens the docs screen: the project's changelog, plans, designs, research and records."}
]},
{"path": ["reference", "docs"], "sentence": "The project's docs folders and the intent, scenario and QA records.", "rows": [
{"name": "changelog", "form": "~/projects/workstation/docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "plans", "form": "~/projects/workstation/docs/plans/", "what": "Opens the dated plan for each piece of work."},
{"name": "design", "form": "~/projects/workstation/docs/design/", "what": "Opens the design pitches, recommendations and research."},
{"name": "research", "form": "~/projects/workstation/docs/research/", "what": "Opens the research notes, including the phase checks."},
{"name": "functional-research", "form": "~/projects/workstation/docs/functional-research/", "what": "Opens the research on agent frameworks and their features."},
{"name": "flows", "form": "~/projects/workstation/docs/flows/", "what": "Opens the flow cards and data models."},
{"name": "items", "form": "~/projects/workstation/docs/items/", "what": "Opens the planned, urgent and work item lists."},
{"name": "roles", "form": "~/projects/workstation/docs/roles/", "what": "Opens the role definitions for qa-agent and the other roles."},
{"name": "playbooks", "form": "~/projects/workstation/docs/playbooks/", "what": "Opens the playbooks, such as talking while the team builds."},
{"name": "intent", "form": "~/projects/workstation/.idd/modules/", "what": "Opens each module's INTENT.md, its typed intent and rules."},
{"name": "scenarios", "form": "~/projects/workstation/.bdd/features/", "what": "Opens the behavior scenarios, one folder per feature."},
{"name": "QA findings", "form": "~/projects/workstation/.bdd/qa/findings/", "what": "Opens the QA findings, one file per check."}
]}
],
"questions": [
"Noun names: use the short one-word nouns on the map (shell, machine, assistant, browser, windows, sharing, cvs, reference), or the README's headings word for word (\"Shell and git\", \"Machine utilities\")? Recommendation: the short nouns, since you type them on every command.",
"clipstack: it is not in the README, but the dump has clipstack/ and a 2026-10-26 shared-clipboard plan. Is it still in use, and do you want it under sharing with the noun clipstack? Recommendation: keep it, noun clipstack, since that is the project's own word.",
"Old backups: claude/backups/desktop-v1-2026 and linux-v1-2026-10-03 are not on the map. Recommendation: leave them off, because desktop-v2-2026 and the linux-global and windows-global mirrors replace them. Confirm, or tell me to list them.",
"dashboard-concepts: it is kept to compare with the dashboard. Recommendation: keep both on the map until you choose one, then remove the one you drop.",
"Skill list: the README table names 13 backed-up skills, but claude/skills/ holds 23, including clone-website, lab-experiment, mentor-mode, resume-project, four solaraai skills, two supabase skills and tech-cv-writer. Recommendation: list all 23 as the map does, and have the README table updated to match.",
"Machine screen: it has 11 rows. Recommendation: split it into machine power (the two cpu scripts, the two lid scripts, the HDMI script) and machine repair (the two network scripts and the four fix commands), so each screen stays short.",
"docs folders: the map lists each docs folder, not each dated plan or design. Recommendation: keep it that way, since the plans grow every week and listing them would overflow the screen.",
"Aliases: the README documents workstation, ws and setup for the same command. Recommendation: keep all three, since the README already uses them, and let cli-engineer confirm the names for clashes."
]}
```

No skill · run 4 exit=0 seconds=169 · prompt

P1 Recall: 0.743P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.439P5 Short top: 22P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.259
As terminal help
The main screen of the workstation command (also setup and ws): one line for each area of this kit. Each area opens its own screen. Rows with a command show that command.
Where things landREADME.md#where-things-landwhich file in this repo is copied to which place on the machine; files are copies and nothing installs itself
Shell helpersscreen: shellcommands loaded into every zsh session: git guard, infra, utilities, API keys, review-open
Machinescreen: machineLinux power profiles, network and Tailscale recovery, external display, laptop lid, repair commands
Browserscreen: browser (command: browser)one persistent Chrome window driven by steps; recording proof of a feature
Chromescreen: chromethe one way to start Chrome on this machine, with the recording flag
Jevscreen: jevsmoke-check a URL against a goal; consult Jev for a decision
Agentsscreen: agentcheck and list the typed agent records, start a team, open the Agent Sandbox page
Dashboardscreen: dashboardlocal page of what waits for you: asked cases, rule changes, calls decided alone
OpenCodescreen: opencoderun OpenCode with the current profile and manage the profiles
Rulesscreen: rulesprint the org rules and see how they change
Reviewscreen: reviewopen a review in the review pane
Claudescreen: claudeClaude Code sessions, usage guard, team park, skills, global instructions, hooks, plugins
Codexscreen: codexCodex config, the Chrome bridge, the direct Chrome path
Gitscreen: gitGit identity, credential helper, hooks and push and commit gates
Deskflowscreen: deskflowshare the laptop trackpad and keyboard with the Windows PC
Audioscreen: audiosend Linux audio to the Windows PC over Tailscale and restore it on pause
Windowsscreen: windowsscripts run on the Windows PC: environment rebuild, skills sync, repos, user scripts, clipboard
Clipboard historyscreen: clipstackclipboard history: picker, watcher and server
CVsscreen: cvbuild the three CV PDFs and their text versions
Hermesscreen: hermesthe Hermes agent: install, restore, profiles
Supabase keepalivescreen: keepalivea timer that runs the Supabase keepalive script
Recordsscreen: docsread-only records: incidents, case studies, plans, research, design, changelog
shell
Helpers loaded into zsh (some also into bash). Each row is a command or the file that holds it.
Git guardgit checkout (wrapped by zsh.d/git-safety.zsh)lists the files and asks [y/N] before discarding unstaged changes
Infrazsh.d/infra.zshDocker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands
Utilitieszsh.d/utils.zshset-title, killport, IP aliases, lazy nvm/node/npm/npx, Android/Java and Bun setup
API keysapi-keys-edit (opens ~/.config/api-keys/env)edit the general-use API keys, which stay out of Git; zsh.d/api-keys.zsh exports them
Review openreview-open (~/.local/bin/review-open)opens a review from zsh, bash or an agent
machine
Linux power, network, display, lid and repair commands. Most need sudo; the power scripts are for Intel P-state only.
Low powercpu-min-power.shpower-saver profile, turbo off, CPU capped at 8% of max
Normal powercpu-normal-power.shbalanced profile, turbo on, cap back to 100%
Internet recoverylinux-internet-recovery.shresets DNS to systemd-resolved, restarts NetworkManager, cycles networking; re-runs itself with sudo
Remote terminal recoveryrecover-tailscale-remote-terminal.shrepairs DNS, restarts tailscaled, starts the remote-terminal user service, checks port 3500
External displayfix_old_monitor_hdmi.sh [--output] [--mode] [--rate] [--quiet]sets the HDMI or DP output mode with xrandr; default 1920x1080 at 59.88
Keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shlogind drop-in so closing the lid does nothing; applies after reboot
Restore lid behaviorlaptop-utilities/restore-default-lid-behavior.shremoves that drop-in; applies after reboot
Repairsfix-keyboard, fix-mouse, fix-disk, fix-whatsapp (zsh.d/utils.zsh)one-step repairs for the usual breakages
browser
One real Chrome window that stays open across commands. Each command runs a list of steps on the same page and prints JSON.
Run stepsbrowser '<json-array-of-steps>' or browser steps.jsonruns the steps in order on the one page
Statusbrowser statusis the background server and browser up
Closebrowser closecloses Chrome and stops the server
Record a featuresteps recordStart and recordStopthe one supported way to record proof of a tab; use screenshot for stills
Installcd browser && npm install && npm linkonce per machine
Server port127.0.0.1:8848local port the background server answers on
Full referencebrowser/README.mdall actions, viewport presets, annotating, network capture, login gotchas
chrome
The single launcher for Chrome. Chrome reads its flags only when it starts, so a running Chrome must be restarted after a change.
Installchrome/install.shlinks google-chrome commands and the menu entry to chrome.sh; quit and restart Chrome afterwards
Launcherchrome/chrome.shadds the flags in chrome/flags and starts Chrome; never start Chrome by hand
Flagschrome/flagsthe only place the launch flags are edited
Check the flagpgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'confirms a running Chrome has the recording flag
Limitschrome/README.md#limitsLinux only so far (GNOME on Wayland, Chrome 145)
jev
Behavioral browser smoke QA: a goal and optional text or URL checks go in, the supplied assertions come out. It does not prove the page looks right.
Installsh jev-browser-test/install.shclones and pins jev-ultrafast, places the CLI in ~/.local/bin/jev-browser-test
Run a checkjev-browser-test (arguments in jev-browser-test/README.md)runs the goal against a browser and reports the assertions and exit code
Secrets file~/.config/jev-browser-test/env (mode 600)API keys and model settings; never in Git
Consult Jevjev "$CONTEXT" -c 'question' option1,option2,other_none -jasks Jev to choose; -c for multi-choice, -j for confidence; the answer is guidance, not proof
agent
Agents are typed records. Check and list them, open the sandbox, or start a team from a team file.
Checkagent-framework/agent checkrefuses broken records (exit 1)
Listagent-framework/agent listagents with tier, model and number of tests
Sandboxagent-framework/agent serve (http://127.0.0.1:8790)opens the Agent Sandbox page
Sandbox screenscreen: agent sandboxwhat each control on the sandbox page does
Start a team (Claude)/spawn-team <team>starts a team from a file in my-skills spawn-team/teams/
Start a team (Codex)$spawn-team <team>same team files, started from Codex
Agent record~/projects/my-skills/agents/<id>/agent.yamlthe agent's setup, situations and saved tests
Test results~/projects/data/<id>/eval-results/results of saved tests
Agent memory~/projects/data/<id>/memory/what the agent keeps between sessions
Sandbox plandocs/plans/2026-10-22-agent-sandbox/prd.htmlproduct requirements and mockups for the sandbox
agent › sandbox
The Agent Sandbox page: one conversation, a setup line in the header, and a judge panel for each answer.
Open the pagehttp://127.0.0.1:8790 (after agent serve)the page itself
Setup lineclick the header linechange agent, model, effort, folder, rules, memory, skill versions or tools; the next message uses it
Asktype in the message box and press Asksends a message
Start fromStart from control, before the first messagea ready-made first message and folder of files for one agent
Expectationsleft column, Expectationswhat the agent must or must not do on every answer, e.g. 'must call Read'
Did it react right?right panelexpectations passed or failed, what it did, and failed calls
Answer again with another setupcontrol on an answerthe same message answered by a changed setup, side by side
Reply from herecontrol on an answercontinues from that answer as if later turns never happened
Save as testcontrol on a messageasks the message again later; quick checks become exact checks
Every step, in orderclosed section under the answerthe raw steps
dashboard
A local page for its owner, read at a glance. Opens on Waiting. Desktop only, 1440 by 900.
Start the dashboardpython3 ~/projects/workstation/dashboard/server.py [port] (http://127.0.0.1:8780)runs the page; not started by any service
Waiting tab#waitingcases asked, rule changes proposed and calls decided alone, newest day first
Overview tab#overviewcounts on the left; the running team's lanes of reads and edits on the right
Item reader/api/file?path=...&as=htmlopens an item's real file over the right column
Answer a caseAnswer on an asked caseposts the answer as a comment on its GitHub issue
Accept or reject a rule changeAccept / Reject on a rule change (~/projects/data/global/rule-proposals/)sets status in that file; does not edit the rule itself
Review a decided-alone callJustified / Should have asked / Wrong call, plus a notesets review in the case file; no GitHub call
Dashboard testspython3 -I -m unittest discover -s ~/projects/workstation/dashboard199 checks against the real data and a real server
Concepts versionpython3 ~/projects/workstation/dashboard-concepts/server.py (http://127.0.0.1:8781)same page with a Projects panel instead; kept apart for comparison
Concepts testspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts17 checks
opencode
Run OpenCode with the current profile, and manage the profiles it loads.
Runopencode or ocruns OpenCode with the current profile
Current profileopencode-profilenames the current profile
What each profile loadsopencode-profilesshows the files each profile loads
Switchopencode-switch <name>switches every shell's new runs to that profile
Sign in Claude Codeopencode-loginsigns a profile's Claude Code in
List filesopencode-fileslists the current profile's files
Edit a fileopencode-edit <file>opens one of the profile's files
Helpopencode help (also oc help, opencode-help, oc-help)every profile's files, one column each; with more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it
Profile codeopencode-profiles/profiles.pythe profile logic; tests in test_profiles.py
Example profileopencode-profiles/private-leb-experimental/a profile folder with its CLAUDE.md, Claude settings and opencode.json
rules
The rules every org follows, escalation policy among them. They change only by the owner or an accepted proposal.
Print rulesrules [folder]prints the rules for a folder; sessions are told to run it at startup
Rules sourceworkboard/rules.yamlthe rules themselves
Rule metadataworkboard/rules-meta.yamlmetadata for each rule
Generated reference~/.claude/references/rules.mdgenerated from rules.yaml; do not edit
Proposals~/projects/data/global/rule-proposals/proposed rule changes, accepted or rejected in the dashboard
Testsworkboard/test_rules.py, workboard/test_org_folder.pychecks on the rules and folder handling
review
Open a review in the review pane.
Open a reviewreview-openopens a review from zsh
Wrapper for other shells~/.local/bin/review-opena short zsh wrapper for bash and agents
Review pane pluginclaude/mods/review-pane/the plugin itself; design notes in docs/design/2026-10-18-review-pane/
claude
Claude Code setup: sessions, the usage guard, team park, skills, global rules, hooks and plugins.
Main sessionclaude --main -c and claude --main -rcontinue or resume the main session (runs claude/session-types/main-sessions.py)
Session start hook~/.claude/hooks/session-types.shruns at each session start; run by Claude Code, not by you
Usage guard~/bin/claude (ahead of ~/.local/bin/claude); install: claude/usage-guard/install.shthe claude command with the usage guard; test files in claude/usage-guard/tests/
Usage guard on Windowsclaude/usage-guard/Install-Windows.cmdWindows install; Launcher.cs is the Windows launcher
Team parkteam-park (~/.local/bin/team-park)claude/team-park/team_park.py; purpose is in claude/team-park/README.md (not in the dump)
Skillsscreen: claude skillsskill backups and how to install them
Global rules and settingsclaude/CLAUDE.md, claude/AGENTS.md, claude/settings.jsondeployed to the Windows %USERPROFILE%/.claude folder by init-windows
Linux instruction mirrorclaude/linux-global/the installed Linux instruction files; settings stay on the machine
Hooksclaude/hooks/ (copied to ~/.claude/hooks/, wired in settings.json)core rules, machine history, team activity, local server guard, proof reminder; run by Claude Code
Pluginsclaude/mods/changelog-pane, review-pane, scratchpad-playground, team-board
Desktop snapshotclaude/backups/desktop-v2-2026/portable copy of the Windows desktop instructions; not installed automatically
claude › skills
Skill backups kept here. Copy in the ones you want. Global skills come from my-skills, not from this repo.
Install a skillcp -r claude/skills/<name> ~/.claude/skills/copies a skill into place
Global skills~/projects/my-skills (linked by its install.sh)skills linked into ~/.claude/skills, ~/.codex/skills and ~/.config/opencode/skills
Skill researchclaude/skills-shortlist.mdskills researched on skills.sh, with what is installed
Planning and review skillsclaude/skills/epic-fanout-planning/, iterative-action-review/, post-feature-cleanup/planning and checking work after it is built
Writing and thinking skillsclaude/skills/tank--communication-engineering/, contextual-value-product-thinking/, tech-cv-writer/how to say things and analyze products; CV writing
Windows and session skillsclaude/skills/powershell-launching/, reboot-resume/, resume-project/launching PowerShell, resuming work across restarts
Skill scriptsclaude/skills/resume-project/scripts/resume_project.py, claude/skills/mentor-mode/scripts/serve_mentor.py, claude/skills/tank--skill-creator/scripts/quick_validate.pyscripts shipped inside skills; run them directly
Web and tool skillsclaude/skills/elad12390--web-research-assistant/, impeccable/, clone-website/, supabase/, supabase-postgres-best-practices/, solaraai-*/research server, frontend design, website cloning, Supabase, SolaraAI
codex
Codex setup: its config, the Chrome bridge that keeps the plugin link working, and the direct Chrome path.
Configcodex/config.toml (%USERPROFILE%/.codex/config.toml on Windows)Codex CLI config; multi_agent_v2 is on under [features]
Bridge install on Linuxcodex/chrome-bridge/install.shinstalls a systemd user watcher and timer
Bridge install on Windowscodex/chrome-bridge/Install-CodexChromeBridge.cmdinstalls a current-user Scheduled Task
Bridge repaircodex/chrome-bridge/repair.mjsfixes the Chrome plugin's latest link and reapplies the local file: navigation patch
Bridge guidecodex/chrome-bridge/README.mdinstallation and restart requirements
Direct Chrome pathcodex/browser/README.mdCodex's direct Chrome command path and its live verification
git
Git identity and credential settings, and the hooks that block risky pushes and commits.
Git config~/.gitconfig (from .gitconfig)author identity, Git LFS, store credential helper, large http.postBuffer, hooks path
Hook shims~/.git-hooks/ (from git-hooks/)Lefthook shims for pre-commit, pre-push, prepare-commit-msg and commit-msg, plus scenario-gate.py
Push gatepre-push hookapproval note check; no push to main in repos marked team.gitpolicy pull-request
Commit gatecommit-msg hookno commit on main in a marked repo
Lefthook neededlefthook on PATHwithout it, every git action warns 'Can't find lefthook in PATH'; commits still go through
Reinstall warninglefthook installoverwrites the hooks; add the hooks back by hand after running it
Repoint an old clonegit remote set-url origin https://github.com/Lebnor/workstation.gitfor clones made before the rename from scripts
deskflow
Shares the laptop trackpad and keyboard with the Windows PC through Deskflow. Use the trackpad to move past the right edge into Windows.
Cross between machinesmove past the laptop's right edge; return past Windows' left edgemoves control between the two machines
Restart after a canceled promptresume-kvmrestarts the Linux server and asks GNOME for input capture again (command named in deskflow/README.md)
Linux server service~/.config/systemd/user/deskflow.service (from deskflow/deskflow.service)the Linux side; starts with the graphical session
Linux settings~/.config/Deskflow/Deskflow.conf and server.conf (from deskflow/linux.conf)Deskflow settings on Linux
Keyboard layout overridedeskflow/deskflow.service.d/keyboard-layout.confservice override for the keyboard layout
USB mouse sharingdeskflow/usb-mouse/README.mdforwarding of the Windows USB mouse; off since 2026-10-20; how to turn it back on
Keyboard follows the mousedeskflow/usb-mouse/README.md#keyboard-follows-the-mousewhich machine the keyboard follows, and how to stop it
Windows settingsdeskflow/windows.conf and deskflow/windows-service.confWindows client and service settings
Network notesdeskflow/NETWORK-AUDIT.md and deskflow/deskflow-lockdown.nftnetwork audit notes and the lockdown rules file
audio
Sends all Linux audio to the Windows PC over Tailscale and restores the speakers on pause. Documented in the README only; the audio-share folder is not in the dump.
Start sendingaudio-start (or audio-share on)makes the Windows share the default output
Pauseaudio-pause (or audio-share off)restores the speakers
Status and test toneaudio-share status and audio-share toneshows the state, or plays a test tone
Stream porttcp 4953 (monitor of null sink windows_share)raw PCM served to the Windows PC
Windows reconnect loopwindows-audio-share agentruns the Windows ffplay reconnect loop; you do not run it yourself
windows
Things that run on the Windows PC, from PowerShell or a double-clicked .cmd file. None of these run from Linux.
Environment rebuildscreen: windows initrebuild and check the Windows dev environment
Skills syncskills-sync-windows/Sync-Skills.ps1 (catch-up task: MySkillsSync-CatchUp)updates skill links from my-skills after trusted pushes to master and at startup
Sync stateC:/ProgramData/MySkillsSync/state/last-success.jsonthe latest successful sync
Clone work reposrepos/Clone-BetecRepos.ps1clones the missing repos in the Betec layout; safe to re-run
User scriptsinit-windows/user-scripts/ (copied to %USERPROFILE%/Scripts/)do_hibernate.ps1, fix_touchpad.ps1 (1 to 3), restore-mongo.ps1
Windows clipboard sideclipstack/windows/install.ps1, uninstall.ps1, verify.ps1, clipstack.ahkinstalls the Windows half of the clipboard history; tests in clipstack/windows/tests/run-tests.ps1
windows › init
Rebuilds the Windows dev environment from exact manifests. It is not an OS image, a personal-file backup or a credential backup.
Installinit-windows/Start-Install.cmdinstalls programs, Node versions, VS Code extensions and settings, Git config and user scripts; then opens Chrome sign-in and Default apps
Checkinit-windows/Smoke-Test-Windows.ps1 and Verify-Windows.ps1checks the install
Roll backinit-windows/Remove-WindowsPack.ps1rolls back the install using its journal
Capture current setupinit-windows/Export-Windows.ps1captures the current setup; name-based, check its header before running
Manifestsinit-windows/manifests/ (programs.json, node.json, vscode-extensions.txt, managed-files.json)the exact versions and lists the install uses
Inventoryinit-windows/inventory.mdwhat was captured
Sign-ins to redoinit-windows/secrets-checklist.mdaccounts to sign in to by hand; includes the credential that must be rotated
Logsinit-windows/logs/Install-Windows.log and Install-Windows.errors.loginstall and error logs
Full guideinit-windows/README.mdprerequisites, install steps and what is pinned
clipstack
Clipboard history with a Linux picker, a watcher and a server, plus a Windows side. Rows come from the file list; the README for this folder is not in the dump.
Pickerclipstack/picker.pylets you pick from the history; how it is launched is not in the dump
Watcherclipstack-watcher.service (clipstack/units/)watches the clipboard in the background
Serverclipstack-server.service (clipstack/units/) and clipstack/server.pyserves the history; tests in test_server.py
Installclipstack/install.shLinux install
Plandocs/plans/2026-10-26-shared-clipboard/plan.mdthe plan for the shared clipboard
cv
The CVs in three versions. Each PDF is built from its LaTeX source; text versions are generated too.
Full Stack Developercv/cv-full-stack.tex -> cv-full-stack.pdfthe Full Stack Developer version
AI Full Stack Engineercv/cv-ai-full-stack.tex -> cv-ai-full-stack.pdfthe AI Full Stack version
AI Integrationscv/cv-ai-integrations.tex -> cv-ai-integrations.pdfthe AI Integrations version
Build one PDFpdflatex -interaction=nonstopmode -halt-on-error <name>.texrebuilds a version from this folder; commit the source and PDF together
Text versionscv/text/build-full.shbuilds the plain-text versions and variables
Design buildcv/design/build-design.pybuilds the HTML design and its PDF
Dated snapshotscv/versions/2026-10-04/ and cv/versions/2026-10-04-v2/PDF, text and variables as they were on those dates
Workflowcv/WORKFLOW.mdhow a CV update moves through the folder
hermes
The Hermes agent: installed from source, with a default profile and a jobs profile on one gateway. Secrets stay in ~/.hermes, not in Git.
Launcherhermes (~/.local/bin/hermes)starts Hermes
Installenv UV_INDEX_URL=https://pypi.org/simple bash scripts/install.sh --dir /home/liel/projects/hermes-agent --non-interactive --skip-computer-usethe install command that worked on this machine
Add Telegramenv UV_INDEX_URL=https://pypi.org/simple hermes pm install --extra telegramadds Telegram support; Python environments are managed by hermes pm, not raw pip
Restore runbookhermes/RESTORE.mdsteps to restore Hermes
Example settingshermes/default.config.example.yaml and hermes/jobs.config.example.yamlsecret-free examples; real config is in ~/.hermes
PATH additionhermes/zprofile-path.zshthe PATH lines the installer added to ~/.zprofile
Backup recordhermes/BACKUP-2026-10-02.mdwhat was backed up on 2026-10-02
keepalive
A systemd timer that runs the Supabase keepalive script. Purpose is inferred from the name; no README is in the dump.
Installsupabase-keepalive/install.shinstalls the service and timer
Scriptsupabase-keepalive/supabase-keepalive.shwhat the timer runs
Timersupabase-keepalive.timerwhen it runs
Servicesupabase-keepalive.servicethe unit that runs the script
docs
Records to read, not commands to run: incidents, case studies, plans, research, design and changelog.
Incidentsreference/README.mddated machine incidents and repairs, e.g. the 2026-10-01 closed-lid test
Case studiescase-studies/archived, human-reviewed experiments, one folder each
Plansdocs/plans/one folder per plan
Researchdocs/research/ and docs/functional-research/research records
Designdocs/design/pitches and recommendations per dated folder
Changelogdocs/changelog/release notes
Intent files.idd/project.intent.md and .idd/modules/*/INTENT.mdintent and rules per module
Behavior specs.bdd/features/feature specs per area
Agent system mapREADME.md#agent-systemwhere skills, roles, rules and data live
Conventions and known issuesREADME.md#conventions-and-gotchascopy-not-link rule, the credential issue, machine-specific paths
Archive~/archive/ (not a repo, not backed up); layout in ~/archive/README.mdfiles moved out of projects
Questions
  • Retired items: Lan Mouse (retired 2026-10-05), codex/playwright-mcp and the older Codex recorders are retired. Should they appear in help? Recommendation: leave them out of help and keep them in docs with a 'retired' note.
  • Credential helpers: zsh.d/infra.zsh, zsh.d/utils.zsh (git_pull_with_creds, update-gitlab-token) embed a credential in git URLs. Should they be advertised in help? Recommendation: leave them out until the credential is rotated and moved to a credential manager, as the checklist already says.
  • Entry names: the command answers to workstation, setup and ws. Recommendation: keep workstation and ws; drop setup unless nothing else on the machine uses that name, since it is generic.
  • Windows scripts: they cannot run from Linux. Recommendation: keep them on their own windows screen, not mixed into the Linux help.
  • Dashboard concepts (port 8781) is a comparison copy. Recommendation: show it as a labeled experiment under dashboard and remove it once one version wins.
  • Source missing from the dump: workstation-cli/ (the workstation command), zsh.d/workstation.zsh, audio-share/ and zsh.d/audio-share.zsh are described in the README but not in the file list; so are the clipstack README and the resume-kvm and jev commands. Rows that depend on them are based on README text or names. Please confirm they exist and what each does before the help text describes them.
  • Hooks and plugins: claude/hooks and claude/mods run inside Claude Code, not from the shell. Recommendation: list them under claude as 'run by Claude Code' with no command to type.
  • One-off scripts: docs/plans (move-repo.py, the rules reminder), research harnesses (docs/research/.../build.py, run1.sh) and design builders are work records. Recommendation: leave them out of help and keep them in the folders.
As phone screens

Home

The main screen of the workstation command (also setup and ws): one line for each area of this kit. Each area opens its own screen. Rows with a command show that command.

Where things landwhich file in this repo is copied to which place on the machine; files are copies and nothing installs itself
›
Shell helperscommands loaded into every zsh session: git guard, infra, utilities, API keys, review-open
›
MachineLinux power profiles, network and Tailscale recovery, external display, laptop lid, repair commands
›
Browserone persistent Chrome window driven by steps; recording proof of a feature
›
Chromethe one way to start Chrome on this machine, with the recording flag
›
Jevsmoke-check a URL against a goal; consult Jev for a decision
›
Agentscheck and list the typed agent records, start a team, open the Agent Sandbox page
›
Dashboardlocal page of what waits for you: asked cases, rule changes, calls decided alone
›
OpenCoderun OpenCode with the current profile and manage the profiles
›
Rulesprint the org rules and see how they change
›
Reviewopen a review in the review pane
›
ClaudeClaude Code sessions, usage guard, team park, skills, global instructions, hooks, plugins
›
CodexCodex config, the Chrome bridge, the direct Chrome path
›
GitGit identity, credential helper, hooks and push and commit gates
›
Deskflowshare the laptop trackpad and keyboard with the Windows PC
›
Audiosend Linux audio to the Windows PC over Tailscale and restore it on pause
›
Windowsscripts run on the Windows PC: environment rebuild, skills sync, repos, user scripts, clipboard
›
Clipboard historyclipboard history: picker, watcher and server
›
CVsbuild the three CV PDFs and their text versions
›
Hermesthe Hermes agent: install, restore, profiles
›
Supabase keepalivea timer that runs the Supabase keepalive script
›
Recordsread-only records: incidents, case studies, plans, research, design, changelog
›
‹ Home

shell

Helpers loaded into zsh (some also into bash). Each row is a command or the file that holds it.

Git guardlists the files and asks [y/N] before discarding unstaged changes
›
InfraDocker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands
›
Utilitiesset-title, killport, IP aliases, lazy nvm/node/npm/npx, Android/Java and Bun setup
›
API keysedit the general-use API keys, which stay out of Git; zsh.d/api-keys.zsh exports them
›
Review openopens a review from zsh, bash or an agent
›
‹ Home

machine

Linux power, network, display, lid and repair commands. Most need sudo; the power scripts are for Intel P-state only.

Low powerpower-saver profile, turbo off, CPU capped at 8% of max
›
Normal powerbalanced profile, turbo on, cap back to 100%
›
Internet recoveryresets DNS to systemd-resolved, restarts NetworkManager, cycles networking; re-runs itself with sudo
›
Remote terminal recoveryrepairs DNS, restarts tailscaled, starts the remote-terminal user service, checks port 3500
›
External displaysets the HDMI or DP output mode with xrandr; default 1920x1080 at 59.88
›
Keep running with lid closedlogind drop-in so closing the lid does nothing; applies after reboot
›
Restore lid behaviorremoves that drop-in; applies after reboot
›
Repairsone-step repairs for the usual breakages
›
‹ Home

browser

One real Chrome window that stays open across commands. Each command runs a list of steps on the same page and prints JSON.

Run stepsruns the steps in order on the one page
›
Statusis the background server and browser up
›
Closecloses Chrome and stops the server
›
Record a featurethe one supported way to record proof of a tab; use screenshot for stills
›
Installonce per machine
›
Server portlocal port the background server answers on
›
Full referenceall actions, viewport presets, annotating, network capture, login gotchas
›
‹ Home

chrome

The single launcher for Chrome. Chrome reads its flags only when it starts, so a running Chrome must be restarted after a change.

Installlinks google-chrome commands and the menu entry to chrome.sh; quit and restart Chrome afterwards
›
Launcheradds the flags in chrome/flags and starts Chrome; never start Chrome by hand
›
Flagsthe only place the launch flags are edited
›
Check the flagconfirms a running Chrome has the recording flag
›
LimitsLinux only so far (GNOME on Wayland, Chrome 145)
›
‹ Home

jev

Behavioral browser smoke QA: a goal and optional text or URL checks go in, the supplied assertions come out. It does not prove the page looks right.

Installclones and pins jev-ultrafast, places the CLI in ~/.local/bin/jev-browser-test
›
Run a checkruns the goal against a browser and reports the assertions and exit code
›
Secrets fileAPI keys and model settings; never in Git
›
Consult Jevasks Jev to choose; -c for multi-choice, -j for confidence; the answer is guidance, not proof
›
‹ Home

agent

Agents are typed records. Check and list them, open the sandbox, or start a team from a team file.

Checkrefuses broken records (exit 1)
›
Listagents with tier, model and number of tests
›
Sandboxopens the Agent Sandbox page
›
Sandbox screenwhat each control on the sandbox page does
›
Start a team (Claude)starts a team from a file in my-skills spawn-team/teams/
›
Start a team (Codex)same team files, started from Codex
›
Agent recordthe agent's setup, situations and saved tests
›
Test resultsresults of saved tests
›
Agent memorywhat the agent keeps between sessions
›
Sandbox planproduct requirements and mockups for the sandbox
›
‹ agent

sandbox

The Agent Sandbox page: one conversation, a setup line in the header, and a judge panel for each answer.

Open the pagethe page itself
›
Setup linechange agent, model, effort, folder, rules, memory, skill versions or tools; the next message uses it
›
Asksends a message
›
Start froma ready-made first message and folder of files for one agent
›
Expectationswhat the agent must or must not do on every answer, e.g. 'must call Read'
›
Did it react right?expectations passed or failed, what it did, and failed calls
›
Answer again with another setupthe same message answered by a changed setup, side by side
›
Reply from herecontinues from that answer as if later turns never happened
›
Save as testasks the message again later; quick checks become exact checks
›
Every step, in orderthe raw steps
›
‹ Home

dashboard

A local page for its owner, read at a glance. Opens on Waiting. Desktop only, 1440 by 900.

Start the dashboardruns the page; not started by any service
›
Waiting tabcases asked, rule changes proposed and calls decided alone, newest day first
›
Overview tabcounts on the left; the running team's lanes of reads and edits on the right
›
Item readeropens an item's real file over the right column
›
Answer a caseposts the answer as a comment on its GitHub issue
›
Accept or reject a rule changesets status in that file; does not edit the rule itself
›
Review a decided-alone callsets review in the case file; no GitHub call
›
Dashboard tests199 checks against the real data and a real server
›
Concepts versionsame page with a Projects panel instead; kept apart for comparison
›
Concepts tests17 checks
›
‹ Home

opencode

Run OpenCode with the current profile, and manage the profiles it loads.

Runruns OpenCode with the current profile
›
Current profilenames the current profile
›
What each profile loadsshows the files each profile loads
›
Switchswitches every shell's new runs to that profile
›
Sign in Claude Codesigns a profile's Claude Code in
›
List fileslists the current profile's files
›
Edit a fileopens one of the profile's files
›
Helpevery profile's files, one column each; with more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it
›
Profile codethe profile logic; tests in test_profiles.py
›
Example profilea profile folder with its CLAUDE.md, Claude settings and opencode.json
›
‹ Home

rules

The rules every org follows, escalation policy among them. They change only by the owner or an accepted proposal.

Print rulesprints the rules for a folder; sessions are told to run it at startup
›
Rules sourcethe rules themselves
›
Rule metadatametadata for each rule
›
Generated referencegenerated from rules.yaml; do not edit
›
Proposalsproposed rule changes, accepted or rejected in the dashboard
›
Testschecks on the rules and folder handling
›
‹ Home

review

Open a review in the review pane.

Open a reviewopens a review from zsh
›
Wrapper for other shellsa short zsh wrapper for bash and agents
›
Review pane pluginthe plugin itself; design notes in docs/design/2026-10-18-review-pane/
›
‹ Home

claude

Claude Code setup: sessions, the usage guard, team park, skills, global rules, hooks and plugins.

Main sessioncontinue or resume the main session (runs claude/session-types/main-sessions.py)
›
Session start hookruns at each session start; run by Claude Code, not by you
›
Usage guardthe claude command with the usage guard; test files in claude/usage-guard/tests/
›
Usage guard on WindowsWindows install; Launcher.cs is the Windows launcher
›
Team parkclaude/team-park/team_park.py; purpose is in claude/team-park/README.md (not in the dump)
›
Skillsskill backups and how to install them
›
Global rules and settingsdeployed to the Windows %USERPROFILE%/.claude folder by init-windows
›
Linux instruction mirrorthe installed Linux instruction files; settings stay on the machine
›
Hookscore rules, machine history, team activity, local server guard, proof reminder; run by Claude Code
›
Pluginschangelog-pane, review-pane, scratchpad-playground, team-board
›
Desktop snapshotportable copy of the Windows desktop instructions; not installed automatically
›
‹ claude

skills

Skill backups kept here. Copy in the ones you want. Global skills come from my-skills, not from this repo.

Install a skillcopies a skill into place
›
Global skillsskills linked into ~/.claude/skills, ~/.codex/skills and ~/.config/opencode/skills
›
Skill researchskills researched on skills.sh, with what is installed
›
Planning and review skillsplanning and checking work after it is built
›
Writing and thinking skillshow to say things and analyze products; CV writing
›
Windows and session skillslaunching PowerShell, resuming work across restarts
›
Skill scriptsscripts shipped inside skills; run them directly
›
Web and tool skillsresearch server, frontend design, website cloning, Supabase, SolaraAI
›
‹ Home

codex

Codex setup: its config, the Chrome bridge that keeps the plugin link working, and the direct Chrome path.

ConfigCodex CLI config; multi_agent_v2 is on under [features]
›
Bridge install on Linuxinstalls a systemd user watcher and timer
›
Bridge install on Windowsinstalls a current-user Scheduled Task
›
Bridge repairfixes the Chrome plugin's latest link and reapplies the local file: navigation patch
›
Bridge guideinstallation and restart requirements
›
Direct Chrome pathCodex's direct Chrome command path and its live verification
›
‹ Home

git

Git identity and credential settings, and the hooks that block risky pushes and commits.

Git configauthor identity, Git LFS, store credential helper, large http.postBuffer, hooks path
›
Hook shimsLefthook shims for pre-commit, pre-push, prepare-commit-msg and commit-msg, plus scenario-gate.py
›
Push gateapproval note check; no push to main in repos marked team.gitpolicy pull-request
›
Commit gateno commit on main in a marked repo
›
Lefthook neededwithout it, every git action warns 'Can't find lefthook in PATH'; commits still go through
›
Reinstall warningoverwrites the hooks; add the hooks back by hand after running it
›
Repoint an old clonefor clones made before the rename from scripts
›
‹ Home

deskflow

Shares the laptop trackpad and keyboard with the Windows PC through Deskflow. Use the trackpad to move past the right edge into Windows.

Cross between machinesmoves control between the two machines
›
Restart after a canceled promptrestarts the Linux server and asks GNOME for input capture again (command named in deskflow/README.md)
›
Linux server servicethe Linux side; starts with the graphical session
›
Linux settingsDeskflow settings on Linux
›
Keyboard layout overrideservice override for the keyboard layout
›
USB mouse sharingforwarding of the Windows USB mouse; off since 2026-10-20; how to turn it back on
›
Keyboard follows the mousewhich machine the keyboard follows, and how to stop it
›
Windows settingsWindows client and service settings
›
Network notesnetwork audit notes and the lockdown rules file
›
‹ Home

audio

Sends all Linux audio to the Windows PC over Tailscale and restores the speakers on pause. Documented in the README only; the audio-share folder is not in the dump.

Start sendingmakes the Windows share the default output
›
Pauserestores the speakers
›
Status and test toneshows the state, or plays a test tone
›
Stream portraw PCM served to the Windows PC
›
Windows reconnect loopruns the Windows ffplay reconnect loop; you do not run it yourself
›
‹ Home

windows

Things that run on the Windows PC, from PowerShell or a double-clicked .cmd file. None of these run from Linux.

Environment rebuildrebuild and check the Windows dev environment
›
Skills syncupdates skill links from my-skills after trusted pushes to master and at startup
›
Sync statethe latest successful sync
›
Clone work reposclones the missing repos in the Betec layout; safe to re-run
›
User scriptsdo_hibernate.ps1, fix_touchpad.ps1 (1 to 3), restore-mongo.ps1
›
Windows clipboard sideinstalls the Windows half of the clipboard history; tests in clipstack/windows/tests/run-tests.ps1
›
‹ windows

init

Rebuilds the Windows dev environment from exact manifests. It is not an OS image, a personal-file backup or a credential backup.

Installinstalls programs, Node versions, VS Code extensions and settings, Git config and user scripts; then opens Chrome sign-in and Default apps
›
Checkchecks the install
›
Roll backrolls back the install using its journal
›
Capture current setupcaptures the current setup; name-based, check its header before running
›
Manifeststhe exact versions and lists the install uses
›
Inventorywhat was captured
›
Sign-ins to redoaccounts to sign in to by hand; includes the credential that must be rotated
›
Logsinstall and error logs
›
Full guideprerequisites, install steps and what is pinned
›
‹ Home

clipstack

Clipboard history with a Linux picker, a watcher and a server, plus a Windows side. Rows come from the file list; the README for this folder is not in the dump.

Pickerlets you pick from the history; how it is launched is not in the dump
›
Watcherwatches the clipboard in the background
›
Serverserves the history; tests in test_server.py
›
InstallLinux install
›
Planthe plan for the shared clipboard
›
‹ Home

cv

The CVs in three versions. Each PDF is built from its LaTeX source; text versions are generated too.

Full Stack Developerthe Full Stack Developer version
›
AI Full Stack Engineerthe AI Full Stack version
›
AI Integrationsthe AI Integrations version
›
Build one PDFrebuilds a version from this folder; commit the source and PDF together
›
Text versionsbuilds the plain-text versions and variables
›
Design buildbuilds the HTML design and its PDF
›
Dated snapshotsPDF, text and variables as they were on those dates
›
Workflowhow a CV update moves through the folder
›
‹ Home

hermes

The Hermes agent: installed from source, with a default profile and a jobs profile on one gateway. Secrets stay in ~/.hermes, not in Git.

Launcherstarts Hermes
›
Installthe install command that worked on this machine
›
Add Telegramadds Telegram support; Python environments are managed by hermes pm, not raw pip
›
Restore runbooksteps to restore Hermes
›
Example settingssecret-free examples; real config is in ~/.hermes
›
PATH additionthe PATH lines the installer added to ~/.zprofile
›
Backup recordwhat was backed up on 2026-10-02
›
‹ Home

keepalive

A systemd timer that runs the Supabase keepalive script. Purpose is inferred from the name; no README is in the dump.

Installinstalls the service and timer
›
Scriptwhat the timer runs
›
Timerwhen it runs
›
Servicethe unit that runs the script
›
‹ Home

docs

Records to read, not commands to run: incidents, case studies, plans, research, design and changelog.

Incidentsdated machine incidents and repairs, e.g. the 2026-10-01 closed-lid test
›
Case studiesarchived, human-reviewed experiments, one folder each
›
Plansone folder per plan
›
Researchresearch records
›
Designpitches and recommendations per dated folder
›
Changelogrelease notes
›
Intent filesintent and rules per module
›
Behavior specsfeature specs per area
›
Agent system mapwhere skills, roles, rules and data live
›
Conventions and known issuescopy-not-link rule, the credential issue, machine-specific paths
›
Archivefiles moved out of projects
›
Raw answer
I planned the map from the file dump only, so I could not run or check any command. Several entries rest on README text alone, and I've flagged those in the questions. The top screen is the `workstation` command, which the README says also answers to `setup` and `ws`.

```json
{"screens": [
{"path": [], "sentence": "The main screen of the workstation command (also setup and ws): one line for each area of this kit. Each area opens its own screen. Rows with a command show that command.", "rows": [
{"name": "Where things land", "form": "README.md#where-things-land", "what": "which file in this repo is copied to which place on the machine; files are copies and nothing installs itself"},
{"name": "Shell helpers", "form": "screen: shell", "what": "commands loaded into every zsh session: git guard, infra, utilities, API keys, review-open"},
{"name": "Machine", "form": "screen: machine", "what": "Linux power profiles, network and Tailscale recovery, external display, laptop lid, repair commands"},
{"name": "Browser", "form": "screen: browser (command: browser)", "what": "one persistent Chrome window driven by steps; recording proof of a feature"},
{"name": "Chrome", "form": "screen: chrome", "what": "the one way to start Chrome on this machine, with the recording flag"},
{"name": "Jev", "form": "screen: jev", "what": "smoke-check a URL against a goal; consult Jev for a decision"},
{"name": "Agents", "form": "screen: agent", "what": "check and list the typed agent records, start a team, open the Agent Sandbox page"},
{"name": "Dashboard", "form": "screen: dashboard", "what": "local page of what waits for you: asked cases, rule changes, calls decided alone"},
{"name": "OpenCode", "form": "screen: opencode", "what": "run OpenCode with the current profile and manage the profiles"},
{"name": "Rules", "form": "screen: rules", "what": "print the org rules and see how they change"},
{"name": "Review", "form": "screen: review", "what": "open a review in the review pane"},
{"name": "Claude", "form": "screen: claude", "what": "Claude Code sessions, usage guard, team park, skills, global instructions, hooks, plugins"},
{"name": "Codex", "form": "screen: codex", "what": "Codex config, the Chrome bridge, the direct Chrome path"},
{"name": "Git", "form": "screen: git", "what": "Git identity, credential helper, hooks and push and commit gates"},
{"name": "Deskflow", "form": "screen: deskflow", "what": "share the laptop trackpad and keyboard with the Windows PC"},
{"name": "Audio", "form": "screen: audio", "what": "send Linux audio to the Windows PC over Tailscale and restore it on pause"},
{"name": "Windows", "form": "screen: windows", "what": "scripts run on the Windows PC: environment rebuild, skills sync, repos, user scripts, clipboard"},
{"name": "Clipboard history", "form": "screen: clipstack", "what": "clipboard history: picker, watcher and server"},
{"name": "CVs", "form": "screen: cv", "what": "build the three CV PDFs and their text versions"},
{"name": "Hermes", "form": "screen: hermes", "what": "the Hermes agent: install, restore, profiles"},
{"name": "Supabase keepalive", "form": "screen: keepalive", "what": "a timer that runs the Supabase keepalive script"},
{"name": "Records", "form": "screen: docs", "what": "read-only records: incidents, case studies, plans, research, design, changelog"}
]},

{"path": ["shell"], "sentence": "Helpers loaded into zsh (some also into bash). Each row is a command or the file that holds it.", "rows": [
{"name": "Git guard", "form": "git checkout (wrapped by zsh.d/git-safety.zsh)", "what": "lists the files and asks [y/N] before discarding unstaged changes"},
{"name": "Infra", "form": "zsh.d/infra.zsh", "what": "Docker and Compose shortcuts, Prisma and Postgres helpers, nginx and VPN commands"},
{"name": "Utilities", "form": "zsh.d/utils.zsh", "what": "set-title, killport, IP aliases, lazy nvm/node/npm/npx, Android/Java and Bun setup"},
{"name": "API keys", "form": "api-keys-edit (opens ~/.config/api-keys/env)", "what": "edit the general-use API keys, which stay out of Git; zsh.d/api-keys.zsh exports them"},
{"name": "Review open", "form": "review-open (~/.local/bin/review-open)", "what": "opens a review from zsh, bash or an agent"}
]},

{"path": ["machine"], "sentence": "Linux power, network, display, lid and repair commands. Most need sudo; the power scripts are for Intel P-state only.", "rows": [
{"name": "Low power", "form": "cpu-min-power.sh", "what": "power-saver profile, turbo off, CPU capped at 8% of max"},
{"name": "Normal power", "form": "cpu-normal-power.sh", "what": "balanced profile, turbo on, cap back to 100%"},
{"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "resets DNS to systemd-resolved, restarts NetworkManager, cycles networking; re-runs itself with sudo"},
{"name": "Remote terminal recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "repairs DNS, restarts tailscaled, starts the remote-terminal user service, checks port 3500"},
{"name": "External display", "form": "fix_old_monitor_hdmi.sh [--output] [--mode] [--rate] [--quiet]", "what": "sets the HDMI or DP output mode with xrandr; default 1920x1080 at 59.88"},
{"name": "Keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "logind drop-in so closing the lid does nothing; applies after reboot"},
{"name": "Restore lid behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "removes that drop-in; applies after reboot"},
{"name": "Repairs", "form": "fix-keyboard, fix-mouse, fix-disk, fix-whatsapp (zsh.d/utils.zsh)", "what": "one-step repairs for the usual breakages"}
]},

{"path": ["browser"], "sentence": "One real Chrome window that stays open across commands. Each command runs a list of steps on the same page and prints JSON.", "rows": [
{"name": "Run steps", "form": "browser '<json-array-of-steps>' or browser steps.json", "what": "runs the steps in order on the one page"},
{"name": "Status", "form": "browser status", "what": "is the background server and browser up"},
{"name": "Close", "form": "browser close", "what": "closes Chrome and stops the server"},
{"name": "Record a feature", "form": "steps recordStart and recordStop", "what": "the one supported way to record proof of a tab; use screenshot for stills"},
{"name": "Install", "form": "cd browser && npm install && npm link", "what": "once per machine"},
{"name": "Server port", "form": "127.0.0.1:8848", "what": "local port the background server answers on"},
{"name": "Full reference", "form": "browser/README.md", "what": "all actions, viewport presets, annotating, network capture, login gotchas"}
]},

{"path": ["chrome"], "sentence": "The single launcher for Chrome. Chrome reads its flags only when it starts, so a running Chrome must be restarted after a change.", "rows": [
{"name": "Install", "form": "chrome/install.sh", "what": "links google-chrome commands and the menu entry to chrome.sh; quit and restart Chrome afterwards"},
{"name": "Launcher", "form": "chrome/chrome.sh", "what": "adds the flags in chrome/flags and starts Chrome; never start Chrome by hand"},
{"name": "Flags", "form": "chrome/flags", "what": "the only place the launch flags are edited"},
{"name": "Check the flag", "form": "pgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'", "what": "confirms a running Chrome has the recording flag"},
{"name": "Limits", "form": "chrome/README.md#limits", "what": "Linux only so far (GNOME on Wayland, Chrome 145)"}
]},

{"path": ["jev"], "sentence": "Behavioral browser smoke QA: a goal and optional text or URL checks go in, the supplied assertions come out. It does not prove the page looks right.", "rows": [
{"name": "Install", "form": "sh jev-browser-test/install.sh", "what": "clones and pins jev-ultrafast, places the CLI in ~/.local/bin/jev-browser-test"},
{"name": "Run a check", "form": "jev-browser-test (arguments in jev-browser-test/README.md)", "what": "runs the goal against a browser and reports the assertions and exit code"},
{"name": "Secrets file", "form": "~/.config/jev-browser-test/env (mode 600)", "what": "API keys and model settings; never in Git"},
{"name": "Consult Jev", "form": "jev \"$CONTEXT\" -c 'question' option1,option2,other_none -j", "what": "asks Jev to choose; -c for multi-choice, -j for confidence; the answer is guidance, not proof"}
]},

{"path": ["agent"], "sentence": "Agents are typed records. Check and list them, open the sandbox, or start a team from a team file.", "rows": [
{"name": "Check", "form": "agent-framework/agent check", "what": "refuses broken records (exit 1)"},
{"name": "List", "form": "agent-framework/agent list", "what": "agents with tier, model and number of tests"},
{"name": "Sandbox", "form": "agent-framework/agent serve (http://127.0.0.1:8790)", "what": "opens the Agent Sandbox page"},
{"name": "Sandbox screen", "form": "screen: agent sandbox", "what": "what each control on the sandbox page does"},
{"name": "Start a team (Claude)", "form": "/spawn-team <team>", "what": "starts a team from a file in my-skills spawn-team/teams/"},
{"name": "Start a team (Codex)", "form": "$spawn-team <team>", "what": "same team files, started from Codex"},
{"name": "Agent record", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "the agent's setup, situations and saved tests"},
{"name": "Test results", "form": "~/projects/data/<id>/eval-results/", "what": "results of saved tests"},
{"name": "Agent memory", "form": "~/projects/data/<id>/memory/", "what": "what the agent keeps between sessions"},
{"name": "Sandbox plan", "form": "docs/plans/2026-10-22-agent-sandbox/prd.html", "what": "product requirements and mockups for the sandbox"}
]},

{"path": ["agent", "sandbox"], "sentence": "The Agent Sandbox page: one conversation, a setup line in the header, and a judge panel for each answer.", "rows": [
{"name": "Open the page", "form": "http://127.0.0.1:8790 (after agent serve)", "what": "the page itself"},
{"name": "Setup line", "form": "click the header line", "what": "change agent, model, effort, folder, rules, memory, skill versions or tools; the next message uses it"},
{"name": "Ask", "form": "type in the message box and press Ask", "what": "sends a message"},
{"name": "Start from", "form": "Start from control, before the first message", "what": "a ready-made first message and folder of files for one agent"},
{"name": "Expectations", "form": "left column, Expectations", "what": "what the agent must or must not do on every answer, e.g. 'must call Read'"},
{"name": "Did it react right?", "form": "right panel", "what": "expectations passed or failed, what it did, and failed calls"},
{"name": "Answer again with another setup", "form": "control on an answer", "what": "the same message answered by a changed setup, side by side"},
{"name": "Reply from here", "form": "control on an answer", "what": "continues from that answer as if later turns never happened"},
{"name": "Save as test", "form": "control on a message", "what": "asks the message again later; quick checks become exact checks"},
{"name": "Every step, in order", "form": "closed section under the answer", "what": "the raw steps"}
]},

{"path": ["dashboard"], "sentence": "A local page for its owner, read at a glance. Opens on Waiting. Desktop only, 1440 by 900.", "rows": [
{"name": "Start the dashboard", "form": "python3 ~/projects/workstation/dashboard/server.py [port] (http://127.0.0.1:8780)", "what": "runs the page; not started by any service"},
{"name": "Waiting tab", "form": "#waiting", "what": "cases asked, rule changes proposed and calls decided alone, newest day first"},
{"name": "Overview tab", "form": "#overview", "what": "counts on the left; the running team's lanes of reads and edits on the right"},
{"name": "Item reader", "form": "/api/file?path=...&as=html", "what": "opens an item's real file over the right column"},
{"name": "Answer a case", "form": "Answer on an asked case", "what": "posts the answer as a comment on its GitHub issue"},
{"name": "Accept or reject a rule change", "form": "Accept / Reject on a rule change (~/projects/data/global/rule-proposals/)", "what": "sets status in that file; does not edit the rule itself"},
{"name": "Review a decided-alone call", "form": "Justified / Should have asked / Wrong call, plus a note", "what": "sets review in the case file; no GitHub call"},
{"name": "Dashboard tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "199 checks against the real data and a real server"},
{"name": "Concepts version", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py (http://127.0.0.1:8781)", "what": "same page with a Projects panel instead; kept apart for comparison"},
{"name": "Concepts tests", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "17 checks"}
]},

{"path": ["opencode"], "sentence": "Run OpenCode with the current profile, and manage the profiles it loads.", "rows": [
{"name": "Run", "form": "opencode or oc", "what": "runs OpenCode with the current profile"},
{"name": "Current profile", "form": "opencode-profile", "what": "names the current profile"},
{"name": "What each profile loads", "form": "opencode-profiles", "what": "shows the files each profile loads"},
{"name": "Switch", "form": "opencode-switch <name>", "what": "switches every shell's new runs to that profile"},
{"name": "Sign in Claude Code", "form": "opencode-login", "what": "signs a profile's Claude Code in"},
{"name": "List files", "form": "opencode-files", "what": "lists the current profile's files"},
{"name": "Edit a file", "form": "opencode-edit <file>", "what": "opens one of the profile's files"},
{"name": "Help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "every profile's files, one column each; with more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it"},
{"name": "Profile code", "form": "opencode-profiles/profiles.py", "what": "the profile logic; tests in test_profiles.py"},
{"name": "Example profile", "form": "opencode-profiles/private-leb-experimental/", "what": "a profile folder with its CLAUDE.md, Claude settings and opencode.json"}
]},

{"path": ["rules"], "sentence": "The rules every org follows, escalation policy among them. They change only by the owner or an accepted proposal.", "rows": [
{"name": "Print rules", "form": "rules [folder]", "what": "prints the rules for a folder; sessions are told to run it at startup"},
{"name": "Rules source", "form": "workboard/rules.yaml", "what": "the rules themselves"},
{"name": "Rule metadata", "form": "workboard/rules-meta.yaml", "what": "metadata for each rule"},
{"name": "Generated reference", "form": "~/.claude/references/rules.md", "what": "generated from rules.yaml; do not edit"},
{"name": "Proposals", "form": "~/projects/data/global/rule-proposals/", "what": "proposed rule changes, accepted or rejected in the dashboard"},
{"name": "Tests", "form": "workboard/test_rules.py, workboard/test_org_folder.py", "what": "checks on the rules and folder handling"}
]},

{"path": ["review"], "sentence": "Open a review in the review pane.", "rows": [
{"name": "Open a review", "form": "review-open", "what": "opens a review from zsh"},
{"name": "Wrapper for other shells", "form": "~/.local/bin/review-open", "what": "a short zsh wrapper for bash and agents"},
{"name": "Review pane plugin", "form": "claude/mods/review-pane/", "what": "the plugin itself; design notes in docs/design/2026-10-18-review-pane/"}
]},

{"path": ["claude"], "sentence": "Claude Code setup: sessions, the usage guard, team park, skills, global rules, hooks and plugins.", "rows": [
{"name": "Main session", "form": "claude --main -c and claude --main -r", "what": "continue or resume the main session (runs claude/session-types/main-sessions.py)"},
{"name": "Session start hook", "form": "~/.claude/hooks/session-types.sh", "what": "runs at each session start; run by Claude Code, not by you"},
{"name": "Usage guard", "form": "~/bin/claude (ahead of ~/.local/bin/claude); install: claude/usage-guard/install.sh", "what": "the claude command with the usage guard; test files in claude/usage-guard/tests/"},
{"name": "Usage guard on Windows", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Windows install; Launcher.cs is the Windows launcher"},
{"name": "Team park", "form": "team-park (~/.local/bin/team-park)", "what": "claude/team-park/team_park.py; purpose is in claude/team-park/README.md (not in the dump)"},
{"name": "Skills", "form": "screen: claude skills", "what": "skill backups and how to install them"},
{"name": "Global rules and settings", "form": "claude/CLAUDE.md, claude/AGENTS.md, claude/settings.json", "what": "deployed to the Windows %USERPROFILE%/.claude folder by init-windows"},
{"name": "Linux instruction mirror", "form": "claude/linux-global/", "what": "the installed Linux instruction files; settings stay on the machine"},
{"name": "Hooks", "form": "claude/hooks/ (copied to ~/.claude/hooks/, wired in settings.json)", "what": "core rules, machine history, team activity, local server guard, proof reminder; run by Claude Code"},
{"name": "Plugins", "form": "claude/mods/", "what": "changelog-pane, review-pane, scratchpad-playground, team-board"},
{"name": "Desktop snapshot", "form": "claude/backups/desktop-v2-2026/", "what": "portable copy of the Windows desktop instructions; not installed automatically"}
]},

{"path": ["claude", "skills"], "sentence": "Skill backups kept here. Copy in the ones you want. Global skills come from my-skills, not from this repo.", "rows": [
{"name": "Install a skill", "form": "cp -r claude/skills/<name> ~/.claude/skills/", "what": "copies a skill into place"},
{"name": "Global skills", "form": "~/projects/my-skills (linked by its install.sh)", "what": "skills linked into ~/.claude/skills, ~/.codex/skills and ~/.config/opencode/skills"},
{"name": "Skill research", "form": "claude/skills-shortlist.md", "what": "skills researched on skills.sh, with what is installed"},
{"name": "Planning and review skills", "form": "claude/skills/epic-fanout-planning/, iterative-action-review/, post-feature-cleanup/", "what": "planning and checking work after it is built"},
{"name": "Writing and thinking skills", "form": "claude/skills/tank--communication-engineering/, contextual-value-product-thinking/, tech-cv-writer/", "what": "how to say things and analyze products; CV writing"},
{"name": "Windows and session skills", "form": "claude/skills/powershell-launching/, reboot-resume/, resume-project/", "what": "launching PowerShell, resuming work across restarts"},
{"name": "Skill scripts", "form": "claude/skills/resume-project/scripts/resume_project.py, claude/skills/mentor-mode/scripts/serve_mentor.py, claude/skills/tank--skill-creator/scripts/quick_validate.py", "what": "scripts shipped inside skills; run them directly"},
{"name": "Web and tool skills", "form": "claude/skills/elad12390--web-research-assistant/, impeccable/, clone-website/, supabase/, supabase-postgres-best-practices/, solaraai-*/", "what": "research server, frontend design, website cloning, Supabase, SolaraAI"}
]},

{"path": ["codex"], "sentence": "Codex setup: its config, the Chrome bridge that keeps the plugin link working, and the direct Chrome path.", "rows": [
{"name": "Config", "form": "codex/config.toml (%USERPROFILE%/.codex/config.toml on Windows)", "what": "Codex CLI config; multi_agent_v2 is on under [features]"},
{"name": "Bridge install on Linux", "form": "codex/chrome-bridge/install.sh", "what": "installs a systemd user watcher and timer"},
{"name": "Bridge install on Windows", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "installs a current-user Scheduled Task"},
{"name": "Bridge repair", "form": "codex/chrome-bridge/repair.mjs", "what": "fixes the Chrome plugin's latest link and reapplies the local file: navigation patch"},
{"name": "Bridge guide", "form": "codex/chrome-bridge/README.md", "what": "installation and restart requirements"},
{"name": "Direct Chrome path", "form": "codex/browser/README.md", "what": "Codex's direct Chrome command path and its live verification"}
]},

{"path": ["git"], "sentence": "Git identity and credential settings, and the hooks that block risky pushes and commits.", "rows": [
{"name": "Git config", "form": "~/.gitconfig (from .gitconfig)", "what": "author identity, Git LFS, store credential helper, large http.postBuffer, hooks path"},
{"name": "Hook shims", "form": "~/.git-hooks/ (from git-hooks/)", "what": "Lefthook shims for pre-commit, pre-push, prepare-commit-msg and commit-msg, plus scenario-gate.py"},
{"name": "Push gate", "form": "pre-push hook", "what": "approval note check; no push to main in repos marked team.gitpolicy pull-request"},
{"name": "Commit gate", "form": "commit-msg hook", "what": "no commit on main in a marked repo"},
{"name": "Lefthook needed", "form": "lefthook on PATH", "what": "without it, every git action warns 'Can't find lefthook in PATH'; commits still go through"},
{"name": "Reinstall warning", "form": "lefthook install", "what": "overwrites the hooks; add the hooks back by hand after running it"},
{"name": "Repoint an old clone", "form": "git remote set-url origin https://github.com/Lebnor/workstation.git", "what": "for clones made before the rename from scripts"}
]},

{"path": ["deskflow"], "sentence": "Shares the laptop trackpad and keyboard with the Windows PC through Deskflow. Use the trackpad to move past the right edge into Windows.", "rows": [
{"name": "Cross between machines", "form": "move past the laptop's right edge; return past Windows' left edge", "what": "moves control between the two machines"},
{"name": "Restart after a canceled prompt", "form": "resume-kvm", "what": "restarts the Linux server and asks GNOME for input capture again (command named in deskflow/README.md)"},
{"name": "Linux server service", "form": "~/.config/systemd/user/deskflow.service (from deskflow/deskflow.service)", "what": "the Linux side; starts with the graphical session"},
{"name": "Linux settings", "form": "~/.config/Deskflow/Deskflow.conf and server.conf (from deskflow/linux.conf)", "what": "Deskflow settings on Linux"},
{"name": "Keyboard layout override", "form": "deskflow/deskflow.service.d/keyboard-layout.conf", "what": "service override for the keyboard layout"},
{"name": "USB mouse sharing", "form": "deskflow/usb-mouse/README.md", "what": "forwarding of the Windows USB mouse; off since 2026-10-20; how to turn it back on"},
{"name": "Keyboard follows the mouse", "form": "deskflow/usb-mouse/README.md#keyboard-follows-the-mouse", "what": "which machine the keyboard follows, and how to stop it"},
{"name": "Windows settings", "form": "deskflow/windows.conf and deskflow/windows-service.conf", "what": "Windows client and service settings"},
{"name": "Network notes", "form": "deskflow/NETWORK-AUDIT.md and deskflow/deskflow-lockdown.nft", "what": "network audit notes and the lockdown rules file"}
]},

{"path": ["audio"], "sentence": "Sends all Linux audio to the Windows PC over Tailscale and restores the speakers on pause. Documented in the README only; the audio-share folder is not in the dump.", "rows": [
{"name": "Start sending", "form": "audio-start (or audio-share on)", "what": "makes the Windows share the default output"},
{"name": "Pause", "form": "audio-pause (or audio-share off)", "what": "restores the speakers"},
{"name": "Status and test tone", "form": "audio-share status and audio-share tone", "what": "shows the state, or plays a test tone"},
{"name": "Stream port", "form": "tcp 4953 (monitor of null sink windows_share)", "what": "raw PCM served to the Windows PC"},
{"name": "Windows reconnect loop", "form": "windows-audio-share agent", "what": "runs the Windows ffplay reconnect loop; you do not run it yourself"}
]},

{"path": ["windows"], "sentence": "Things that run on the Windows PC, from PowerShell or a double-clicked .cmd file. None of these run from Linux.", "rows": [
{"name": "Environment rebuild", "form": "screen: windows init", "what": "rebuild and check the Windows dev environment"},
{"name": "Skills sync", "form": "skills-sync-windows/Sync-Skills.ps1 (catch-up task: MySkillsSync-CatchUp)", "what": "updates skill links from my-skills after trusted pushes to master and at startup"},
{"name": "Sync state", "form": "C:/ProgramData/MySkillsSync/state/last-success.json", "what": "the latest successful sync"},
{"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "clones the missing repos in the Betec layout; safe to re-run"},
{"name": "User scripts", "form": "init-windows/user-scripts/ (copied to %USERPROFILE%/Scripts/)", "what": "do_hibernate.ps1, fix_touchpad.ps1 (1 to 3), restore-mongo.ps1"},
{"name": "Windows clipboard side", "form": "clipstack/windows/install.ps1, uninstall.ps1, verify.ps1, clipstack.ahk", "what": "installs the Windows half of the clipboard history; tests in clipstack/windows/tests/run-tests.ps1"}
]},

{"path": ["windows", "init"], "sentence": "Rebuilds the Windows dev environment from exact manifests. It is not an OS image, a personal-file backup or a credential backup.", "rows": [
{"name": "Install", "form": "init-windows/Start-Install.cmd", "what": "installs programs, Node versions, VS Code extensions and settings, Git config and user scripts; then opens Chrome sign-in and Default apps"},
{"name": "Check", "form": "init-windows/Smoke-Test-Windows.ps1 and Verify-Windows.ps1", "what": "checks the install"},
{"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "rolls back the install using its journal"},
{"name": "Capture current setup", "form": "init-windows/Export-Windows.ps1", "what": "captures the current setup; name-based, check its header before running"},
{"name": "Manifests", "form": "init-windows/manifests/ (programs.json, node.json, vscode-extensions.txt, managed-files.json)", "what": "the exact versions and lists the install uses"},
{"name": "Inventory", "form": "init-windows/inventory.md", "what": "what was captured"},
{"name": "Sign-ins to redo", "form": "init-windows/secrets-checklist.md", "what": "accounts to sign in to by hand; includes the credential that must be rotated"},
{"name": "Logs", "form": "init-windows/logs/Install-Windows.log and Install-Windows.errors.log", "what": "install and error logs"},
{"name": "Full guide", "form": "init-windows/README.md", "what": "prerequisites, install steps and what is pinned"}
]},

{"path": ["clipstack"], "sentence": "Clipboard history with a Linux picker, a watcher and a server, plus a Windows side. Rows come from the file list; the README for this folder is not in the dump.", "rows": [
{"name": "Picker", "form": "clipstack/picker.py", "what": "lets you pick from the history; how it is launched is not in the dump"},
{"name": "Watcher", "form": "clipstack-watcher.service (clipstack/units/)", "what": "watches the clipboard in the background"},
{"name": "Server", "form": "clipstack-server.service (clipstack/units/) and clipstack/server.py", "what": "serves the history; tests in test_server.py"},
{"name": "Install", "form": "clipstack/install.sh", "what": "Linux install"},
{"name": "Plan", "form": "docs/plans/2026-10-26-shared-clipboard/plan.md", "what": "the plan for the shared clipboard"}
]},

{"path": ["cv"], "sentence": "The CVs in three versions. Each PDF is built from its LaTeX source; text versions are generated too.", "rows": [
{"name": "Full Stack Developer", "form": "cv/cv-full-stack.tex -> cv-full-stack.pdf", "what": "the Full Stack Developer version"},
{"name": "AI Full Stack Engineer", "form": "cv/cv-ai-full-stack.tex -> cv-ai-full-stack.pdf", "what": "the AI Full Stack version"},
{"name": "AI Integrations", "form": "cv/cv-ai-integrations.tex -> cv-ai-integrations.pdf", "what": "the AI Integrations version"},
{"name": "Build one PDF", "form": "pdflatex -interaction=nonstopmode -halt-on-error <name>.tex", "what": "rebuilds a version from this folder; commit the source and PDF together"},
{"name": "Text versions", "form": "cv/text/build-full.sh", "what": "builds the plain-text versions and variables"},
{"name": "Design build", "form": "cv/design/build-design.py", "what": "builds the HTML design and its PDF"},
{"name": "Dated snapshots", "form": "cv/versions/2026-10-04/ and cv/versions/2026-10-04-v2/", "what": "PDF, text and variables as they were on those dates"},
{"name": "Workflow", "form": "cv/WORKFLOW.md", "what": "how a CV update moves through the folder"}
]},

{"path": ["hermes"], "sentence": "The Hermes agent: installed from source, with a default profile and a jobs profile on one gateway. Secrets stay in ~/.hermes, not in Git.", "rows": [
{"name": "Launcher", "form": "hermes (~/.local/bin/hermes)", "what": "starts Hermes"},
{"name": "Install", "form": "env UV_INDEX_URL=https://pypi.org/simple bash scripts/install.sh --dir /home/liel/projects/hermes-agent --non-interactive --skip-computer-use", "what": "the install command that worked on this machine"},
{"name": "Add Telegram", "form": "env UV_INDEX_URL=https://pypi.org/simple hermes pm install --extra telegram", "what": "adds Telegram support; Python environments are managed by hermes pm, not raw pip"},
{"name": "Restore runbook", "form": "hermes/RESTORE.md", "what": "steps to restore Hermes"},
{"name": "Example settings", "form": "hermes/default.config.example.yaml and hermes/jobs.config.example.yaml", "what": "secret-free examples; real config is in ~/.hermes"},
{"name": "PATH addition", "form": "hermes/zprofile-path.zsh", "what": "the PATH lines the installer added to ~/.zprofile"},
{"name": "Backup record", "form": "hermes/BACKUP-2026-10-02.md", "what": "what was backed up on 2026-10-02"}
]},

{"path": ["keepalive"], "sentence": "A systemd timer that runs the Supabase keepalive script. Purpose is inferred from the name; no README is in the dump.", "rows": [
{"name": "Install", "form": "supabase-keepalive/install.sh", "what": "installs the service and timer"},
{"name": "Script", "form": "supabase-keepalive/supabase-keepalive.sh", "what": "what the timer runs"},
{"name": "Timer", "form": "supabase-keepalive.timer", "what": "when it runs"},
{"name": "Service", "form": "supabase-keepalive.service", "what": "the unit that runs the script"}
]},

{"path": ["docs"], "sentence": "Records to read, not commands to run: incidents, case studies, plans, research, design and changelog.", "rows": [
{"name": "Incidents", "form": "reference/README.md", "what": "dated machine incidents and repairs, e.g. the 2026-10-01 closed-lid test"},
{"name": "Case studies", "form": "case-studies/", "what": "archived, human-reviewed experiments, one folder each"},
{"name": "Plans", "form": "docs/plans/", "what": "one folder per plan"},
{"name": "Research", "form": "docs/research/ and docs/functional-research/", "what": "research records"},
{"name": "Design", "form": "docs/design/", "what": "pitches and recommendations per dated folder"},
{"name": "Changelog", "form": "docs/changelog/", "what": "release notes"},
{"name": "Intent files", "form": ".idd/project.intent.md and .idd/modules/*/INTENT.md", "what": "intent and rules per module"},
{"name": "Behavior specs", "form": ".bdd/features/", "what": "feature specs per area"},
{"name": "Agent system map", "form": "README.md#agent-system", "what": "where skills, roles, rules and data live"},
{"name": "Conventions and known issues", "form": "README.md#conventions-and-gotchas", "what": "copy-not-link rule, the credential issue, machine-specific paths"},
{"name": "Archive", "form": "~/archive/ (not a repo, not backed up); layout in ~/archive/README.md", "what": "files moved out of projects"}
]}
],
"questions": [
"Retired items: Lan Mouse (retired 2026-10-05), codex/playwright-mcp and the older Codex recorders are retired. Should they appear in help? Recommendation: leave them out of help and keep them in docs with a 'retired' note.",
"Credential helpers: zsh.d/infra.zsh, zsh.d/utils.zsh (git_pull_with_creds, update-gitlab-token) embed a credential in git URLs. Should they be advertised in help? Recommendation: leave them out until the credential is rotated and moved to a credential manager, as the checklist already says.",
"Entry names: the command answers to workstation, setup and ws. Recommendation: keep workstation and ws; drop setup unless nothing else on the machine uses that name, since it is generic.",
"Windows scripts: they cannot run from Linux. Recommendation: keep them on their own windows screen, not mixed into the Linux help.",
"Dashboard concepts (port 8781) is a comparison copy. Recommendation: show it as a labeled experiment under dashboard and remove it once one version wins.",
"Source missing from the dump: workstation-cli/ (the workstation command), zsh.d/workstation.zsh, audio-share/ and zsh.d/audio-share.zsh are described in the README but not in the file list; so are the clipstack README and the resume-kvm and jev commands. Rows that depend on them are based on README text or names. Please confirm they exist and what each does before the help text describes them.",
"Hooks and plugins: claude/hooks and claude/mods run inside Claude Code, not from the shell. Recommendation: list them under claude as 'run by Claude Code' with no command to type.",
"One-off scripts: docs/plans (move-repo.py, the rules reminder), research harnesses (docs/research/.../build.py, run1.sh) and design builders are work records. Recommendation: leave them out of help and keep them in the folders."
]}
```

Today's skills · run 4 exit=0 seconds=143 · prompt

P1 Recall: 0.571P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.319
As terminal help
The whole kit for this workstation, grouped by what you want to do; each group opens its own screen.
Shellworkstation shellPrints the shell screen: the helpers every terminal loads, for git, Docker, keys and review.
Machineworkstation machinePrints the machine screen: repair, power and background services for this Linux laptop.
Assistantworkstation assistantPrints the assistant screen: the instructions, skills and agent system behind Claude, Codex and OpenCode.
Browserworkstation browserPrints the browser screen: the browser command and the Chrome launcher.
Sharingworkstation sharingPrints the sharing screen: keyboard, mouse, clipboard and audio shared with the Windows PC.
Windowsworkstation windowsPrints the Windows screen: rebuilding the PC, its skill sync and its repo clones.
Documentsworkstation documentsPrints the documents screen: CVs, case studies, machine incidents and plans.
Toolsworkstation toolsPrints the tools screen: the dashboards, Hermes, the Supabase keep-alive and team-park.
shell
The shell helpers this workstation loads into every terminal, and the files behind them.
Git safetygit checkout (guarded by ~/.zsh.d/git-safety.zsh)Asks [y/N] before a checkout discards unstaged changes.
Git settings~/.gitconfigOpens the Git identity, LFS, credential and hooks settings.
Git hooks~/.git-hooks/Opens the Lefthook hook shims that run on every git action.
Helper files~/.zsh.d/Opens the folder of shell helpers that every terminal loads.
Repo copies of helpers~/projects/workstation/zsh.d/Opens the repo copies of the helpers; they drift from ~/.zsh.d, so diff before editing.
Docker and database helpers~/.zsh.d/infra.zshOpens the Docker, Compose, Prisma, Postgres, nginx and VPN helpers; it holds a credential, so its contents are never printed.
Terminal helpers~/.zsh.d/utils.zshOpens the terminal helpers (set-title, killport, IP aliases, lazy nvm, Android and Bun setup); it holds a credential, so its contents are never printed.
API keys~/.config/api-keys/envOpens the general API keys file, which is never in Git; api-keys-edit opens the same file.
Review a filereview-openOpens a file for review, from zsh, bash or an agent.
machine
The repair, power and background-service tools for this Linux laptop.
Repairworkstation machine repairPrints the repair screen: the fix commands and recovery scripts.
Power and lidworkstation machine powerPrints the power screen: the CPU profiles and the lid behavior scripts.
Servicesworkstation machine servicesPrints the services screen: the timers and services that run in the background.
machine › repair
The repair commands and recovery scripts for this laptop's keyboard, mouse, disk, network, Tailscale and monitor.
Fix keyboardfix-keyboardRuns the keyboard repair helper.
Fix mousefix-mouseRuns the mouse repair helper.
Fix diskfix-diskRuns the disk repair helper.
Fix WhatsAppfix-whatsappRuns the WhatsApp repair helper.
Internet recovery~/projects/workstation/linux-internet-recovery.shRuns the network recovery: points DNS at systemd-resolved, restarts NetworkManager and cycles networking; it asks for sudo.
Tailscale remote terminal~/projects/workstation/recover-tailscale-remote-terminal.shRuns the Tailscale repair: DNS, then tailscaled, then the remote-terminal service and its port check.
External monitor~/projects/workstation/fix_old_monitor_hdmi.shRuns xrandr to set the external monitor's mode and refresh rate.
machine › power
The CPU power profiles and the lid behavior for this laptop; the lid changes apply after a reboot.
Power saver~/projects/workstation/cpu-min-power.shRuns the power-saver profile: turbo off, CPU capped at 8%; it asks for sudo and works on Intel only.
Balanced~/projects/workstation/cpu-normal-power.shRuns the balanced profile: turbo on, CPU cap back to 100%; it asks for sudo.
Keep running with lid closed~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.shRuns the change so that closing the lid does nothing.
Restore lid behavior~/projects/workstation/laptop-utilities/restore-default-lid-behavior.shRuns the removal of that change, back to the default lid behavior.
machine › services
The timers and services that run in the background on this laptop, and where each one is defined.
Live timerssystemctl --user list-timersPrints each user timer and when it next runs.
Deskflow server~/projects/workstation/deskflow/deskflow.serviceOpens the unit that runs the Deskflow server with the graphical session.
Clipboard server~/projects/workstation/clipstack/units/clipstack-server.serviceOpens the unit that runs the clipboard history server.
Clipboard watcher~/projects/workstation/clipstack/units/clipstack-watcher.serviceOpens the unit that runs the clipboard watcher.
Supabase keep-alive~/projects/workstation/supabase-keepalive/supabase-keepalive.timerOpens the timer that runs the Supabase keep-alive.
Codex Chrome bridge~/projects/workstation/codex/chrome-bridge/codex-chrome-bridge.timerOpens the timer that keeps Codex's Chrome plugin link working.
Answer sync~/projects/data/systemd/Opens the timer units that pull answers every 5 minutes.
Rules reminder~/projects/workstation/docs/plans/2026-10-24-rules-per-role/reminder/rules-roles-reminder.timerOpens the timer for the rules-per-role reminder.
assistant
The instructions, skills and agent system behind Claude Code, Codex and OpenCode on this machine.
Instructionsworkstation assistant instructionsPrints the instructions screen: the global instructions, settings and rules.
Skillsworkstation assistant skillsPrints the skills screen: the global skills and their backups.
Agentsworkstation assistant agentsPrints the agents screen: agent records, the sandbox and teams.
OpenCodeopencode helpPrints the OpenCode screen with its profiles and commands; this kit links to it and does not copy it.
Claude CodeclaudeRuns Claude Code through the usage guard wrapper in ~/bin.
assistant › instructions
The global instructions, settings and rules that Claude and Codex read in this kit.
Linux Claude instructions~/projects/workstation/claude/linux-global/CLAUDE.mdOpens the mirror of this Linux machine's global Claude instructions.
Windows Claude instructions~/projects/workstation/claude/CLAUDE.mdOpens the global Claude instructions that init-windows deploys to Windows.
Claude settings~/projects/workstation/claude/settings.jsonOpens the Claude Code settings kept in this kit; the Linux settings are machine-local.
Codex config~/projects/workstation/codex/config.tomlOpens the Codex CLI config that init-windows deploys.
RulesrulesPrints the rules; rules [folder] prints the rules for one folder.
Rules file~/projects/workstation/workboard/rules.yamlOpens the file that rules reads; only the user or an accepted proposal changes it.
assistant › skills
The skills this machine uses: the global repo, the backups kept here, and the shortlist of skills under review.
Global skills~/projects/my-skillsOpens the global skills repo that install.sh links into Claude, Codex and OpenCode.
Skill backups~/projects/workstation/claude/skills/Opens the backup copies of the skills kept in this repo.
Skills shortlist~/projects/workstation/claude/skills-shortlist.mdOpens the skills researched on skills.sh and which of them are installed.
assistant › agents
The agent records, the sandbox where you ask an agent things, and the commands that start teams.
Agent records~/projects/my-skills/agents/Opens the agent records: each agent's typed record, saved tests and role skill.
Check agents~/projects/workstation/agent-framework/agent checkChecks every agent record and refuses broken ones with exit 1.
List agents~/projects/workstation/agent-framework/agent listPrints each agent with its tier, model and number of tests.
Agent Sandbox~/projects/workstation/agent-framework/agent serveStarts the Agent Sandbox page at http://127.0.0.1:8790, where you pick an agent and ask it things.
Start a team/spawn-team <team>Starts a team of agents from its team file, typed in Claude.
Main Claude sessionclaude --main -cContinues the main Claude session through the session-types wrapper.
browser
The browser command that drives one persistent Chrome window, and the Chrome launcher that makes its recordings possible.
Browser commandbrowserRuns browser steps such as goto, click, fill and screenshot in one Chrome window that stays open between calls.
Browser statusbrowser statusPrints whether the background browser server is up.
Close browserbrowser closeCloses the Chrome window and stops the server.
Browser source~/projects/workstation/browser/Opens the browser CLI's folder and its README.
Chrome launcher~/projects/workstation/chrome/chrome.shOpens the one script that starts Chrome, with the recording flag.
Chrome flags~/projects/workstation/chrome/flagsOpens the Chrome launch flags; this is the only place they are edited.
Chrome setup~/projects/workstation/chrome/install.shRuns the Chrome setup, once per machine and again after a Chrome update.
Browser smoke testjev-browser-testRuns a goal in a browser and reports only the text and URL checks you give it.
sharing
Keyboard, mouse, clipboard and audio shared between this laptop and the Windows PC.
Keyboard and mouse guide~/projects/workstation/deskflow/README.mdOpens the guide to the shared keyboard and mouse with the Windows PC.
Restart keyboard sharingresume-kvmStarts Deskflow again and asks for input access.
USB mouse notes~/projects/workstation/deskflow/usb-mouse/README.mdOpens the notes on the Windows USB mouse and how the keyboard follows it.
Lan Mouse (retired)~/projects/workstation/lan-mouse/README.mdOpens the retired Lan Mouse guide, kept only for rollback.
Clipboard history~/projects/workstation/clipstack/picker.pyOpens the clipboard history picker.
Send audio to Windowsaudio-startSends all Linux audio to the Windows PC over Tailscale.
Restore speakersaudio-pauseSends audio back to the speakers.
Audio statusaudio-share statusPrints whether audio is going to the Windows PC.
windows
Everything for the Windows PC: rebuilding it from its manifests, keeping its skills in sync, and cloning its work repos.
Rebuild the Windows PC~/projects/workstation/init-windows/Start-Install.cmdRuns the install that rebuilds the Windows environment from its manifests; it asks for admin approval.
Check the install~/projects/workstation/init-windows/Smoke-Test-Windows.ps1Runs, on the Windows PC, the checks of the installed environment.
Roll back~/projects/workstation/init-windows/Remove-WindowsPack.ps1Runs, on the Windows PC, the rollback that removes the installed pack.
Manifests~/projects/workstation/init-windows/manifests/Opens the exact lists of programs, Node versions and extensions the install uses.
Sign-ins by hand~/projects/workstation/init-windows/secrets-checklist.mdOpens the list of sign-ins to redo by hand after an install.
Skill sync guide~/projects/workstation/skills-sync-windows/README.mdOpens the guide to the skill sync that runs on pushes to master.
Clone repos~/projects/workstation/repos/Clone-BetecRepos.ps1Runs, on the Windows PC, the clone of every missing Betec repo; it is safe to run again.
documents
The working documents: CVs, case studies that record experiments, machine incidents, and the plans and designs.
CVsworkstation documents cvPrints the CV screen: the three CVs and their sources.
Case studiesworkstation documents casesPrints the case studies screen: the archived experiments.
Machine incidents~/projects/workstation/reference/incidents/Opens the dated records of machine failures and how each was fixed.
Plans and designs~/projects/workstation/docs/Opens the docs folder: plans, design pitches, research and changelog.
documents › cv
The CVs in this repo, as PDFs, and the folder and guide that build them.
CV folder~/projects/workstation/cv/Opens the CV sources, PDFs and build scripts.
Full Stack Developer CV~/projects/workstation/cv/cv-full-stack.pdfOpens the Full Stack Developer CV as a PDF.
AI Full Stack Engineer CV~/projects/workstation/cv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV as a PDF.
AI Integrations CV~/projects/workstation/cv/cv-ai-integrations.pdfOpens the AI Integrations CV as a PDF.
CV guide~/projects/workstation/cv/README.mdOpens the guide to editing, rebuilding and committing the CVs.
documents › cases
The archived experiments, each in its own folder with its own README.
Codebot return~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/README.mdOpens the case study of the same design request with and without the skill.
Signal garden~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/README.mdOpens the case study of a small documentation exhibit.
Kernel cloud browsers~/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the results of testing cloud browsers, from 2026-10-08.
tools
Small standalone tools that have their own screens: two dashboards, Hermes, the Supabase keep-alive and team-park.
Dashboardpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard at http://127.0.0.1:8780, the one screen for cases asked, rule changes and calls agents made alone.
Dashboard, concepts versionpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the second dashboard version at http://127.0.0.1:8781, to compare with the first.
HermeshermesRuns the Hermes assistant from ~/.local/bin/hermes.
Hermes guide~/projects/workstation/hermes/README.mdOpens the Hermes install notes and restore guide.
Supabase keep-alive~/projects/workstation/supabase-keepalive/supabase-keepalive.shRuns the Supabase keep-alive script; its timer runs it too.
Team parkteam-parkRuns the team-park tool from ~/.local/bin/team-park.
Questions
  • Eight top-level groups: keep all eight, or merge to fewer? Recommendation: keep eight, since each one is a different place a person goes; if you want fewer, merge tools into assistant and windows into machine.
  • What do fix-keyboard, fix-mouse, fix-disk, fix-whatsapp, team-park and zsh.d/dash-path-warn.zsh do? Their sentences are placeholders until I read the source in step 1. Recommendation: tell me the purpose of any you know, and I will read the rest before writing their sentences.
  • Are the files the README refers to but the dump does not list present (workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, resume-kvm, Start-Install.cmd, secrets-checklist.md)? Recommendation: keep their rows; the inventory step drops any that are missing.
  • Should the Lan Mouse guide stay on the map, marked retired? Recommendation: keep only that one row, for rollback, and drop the rest of the Lan Mouse items.
  • Should the Claude mods (changelog-pane, review-pane, scratchpad-playground, team-board) be reachable from the map? Recommendation: leave them out unless you start them by command; none has a README entry in the dump.
As phone screens

Home

The whole kit for this workstation, grouped by what you want to do; each group opens its own screen.

ShellPrints the shell screen: the helpers every terminal loads, for git, Docker, keys and review.
›
MachinePrints the machine screen: repair, power and background services for this Linux laptop.
›
AssistantPrints the assistant screen: the instructions, skills and agent system behind Claude, Codex and OpenCode.
›
BrowserPrints the browser screen: the browser command and the Chrome launcher.
›
SharingPrints the sharing screen: keyboard, mouse, clipboard and audio shared with the Windows PC.
›
WindowsPrints the Windows screen: rebuilding the PC, its skill sync and its repo clones.
›
DocumentsPrints the documents screen: CVs, case studies, machine incidents and plans.
›
ToolsPrints the tools screen: the dashboards, Hermes, the Supabase keep-alive and team-park.
›
‹ Home

shell

The shell helpers this workstation loads into every terminal, and the files behind them.

Git safetyAsks [y/N] before a checkout discards unstaged changes.
›
Git settingsOpens the Git identity, LFS, credential and hooks settings.
›
Git hooksOpens the Lefthook hook shims that run on every git action.
›
Helper filesOpens the folder of shell helpers that every terminal loads.
›
Repo copies of helpersOpens the repo copies of the helpers; they drift from ~/.zsh.d, so diff before editing.
›
Docker and database helpersOpens the Docker, Compose, Prisma, Postgres, nginx and VPN helpers; it holds a credential, so its contents are never printed.
›
Terminal helpersOpens the terminal helpers (set-title, killport, IP aliases, lazy nvm, Android and Bun setup); it holds a credential, so its contents are never printed.
›
API keysOpens the general API keys file, which is never in Git; api-keys-edit opens the same file.
›
Review a fileOpens a file for review, from zsh, bash or an agent.
›
‹ Home

machine

The repair, power and background-service tools for this Linux laptop.

RepairPrints the repair screen: the fix commands and recovery scripts.
›
Power and lidPrints the power screen: the CPU profiles and the lid behavior scripts.
›
ServicesPrints the services screen: the timers and services that run in the background.
›
‹ machine

repair

The repair commands and recovery scripts for this laptop's keyboard, mouse, disk, network, Tailscale and monitor.

Fix keyboardRuns the keyboard repair helper.
›
Fix mouseRuns the mouse repair helper.
›
Fix diskRuns the disk repair helper.
›
Fix WhatsAppRuns the WhatsApp repair helper.
›
Internet recoveryRuns the network recovery: points DNS at systemd-resolved, restarts NetworkManager and cycles networking; it asks for sudo.
›
Tailscale remote terminalRuns the Tailscale repair: DNS, then tailscaled, then the remote-terminal service and its port check.
›
External monitorRuns xrandr to set the external monitor's mode and refresh rate.
›
‹ machine

power

The CPU power profiles and the lid behavior for this laptop; the lid changes apply after a reboot.

Power saverRuns the power-saver profile: turbo off, CPU capped at 8%; it asks for sudo and works on Intel only.
›
BalancedRuns the balanced profile: turbo on, CPU cap back to 100%; it asks for sudo.
›
Keep running with lid closedRuns the change so that closing the lid does nothing.
›
Restore lid behaviorRuns the removal of that change, back to the default lid behavior.
›
‹ machine

services

The timers and services that run in the background on this laptop, and where each one is defined.

Live timersPrints each user timer and when it next runs.
›
Deskflow serverOpens the unit that runs the Deskflow server with the graphical session.
›
Clipboard serverOpens the unit that runs the clipboard history server.
›
Clipboard watcherOpens the unit that runs the clipboard watcher.
›
Supabase keep-aliveOpens the timer that runs the Supabase keep-alive.
›
Codex Chrome bridgeOpens the timer that keeps Codex's Chrome plugin link working.
›
Answer syncOpens the timer units that pull answers every 5 minutes.
›
Rules reminderOpens the timer for the rules-per-role reminder.
›
‹ Home

assistant

The instructions, skills and agent system behind Claude Code, Codex and OpenCode on this machine.

InstructionsPrints the instructions screen: the global instructions, settings and rules.
›
SkillsPrints the skills screen: the global skills and their backups.
›
AgentsPrints the agents screen: agent records, the sandbox and teams.
›
OpenCodePrints the OpenCode screen with its profiles and commands; this kit links to it and does not copy it.
›
Claude CodeRuns Claude Code through the usage guard wrapper in ~/bin.
›
‹ assistant

instructions

The global instructions, settings and rules that Claude and Codex read in this kit.

Linux Claude instructionsOpens the mirror of this Linux machine's global Claude instructions.
›
Windows Claude instructionsOpens the global Claude instructions that init-windows deploys to Windows.
›
Claude settingsOpens the Claude Code settings kept in this kit; the Linux settings are machine-local.
›
Codex configOpens the Codex CLI config that init-windows deploys.
›
RulesPrints the rules; rules [folder] prints the rules for one folder.
›
Rules fileOpens the file that rules reads; only the user or an accepted proposal changes it.
›
‹ assistant

skills

The skills this machine uses: the global repo, the backups kept here, and the shortlist of skills under review.

Global skillsOpens the global skills repo that install.sh links into Claude, Codex and OpenCode.
›
Skill backupsOpens the backup copies of the skills kept in this repo.
›
Skills shortlistOpens the skills researched on skills.sh and which of them are installed.
›
‹ assistant

agents

The agent records, the sandbox where you ask an agent things, and the commands that start teams.

Agent recordsOpens the agent records: each agent's typed record, saved tests and role skill.
›
Check agentsChecks every agent record and refuses broken ones with exit 1.
›
List agentsPrints each agent with its tier, model and number of tests.
›
Agent SandboxStarts the Agent Sandbox page at http://127.0.0.1:8790, where you pick an agent and ask it things.
›
Start a teamStarts a team of agents from its team file, typed in Claude.
›
Main Claude sessionContinues the main Claude session through the session-types wrapper.
›
‹ Home

browser

The browser command that drives one persistent Chrome window, and the Chrome launcher that makes its recordings possible.

Browser commandRuns browser steps such as goto, click, fill and screenshot in one Chrome window that stays open between calls.
›
Browser statusPrints whether the background browser server is up.
›
Close browserCloses the Chrome window and stops the server.
›
Browser sourceOpens the browser CLI's folder and its README.
›
Chrome launcherOpens the one script that starts Chrome, with the recording flag.
›
Chrome flagsOpens the Chrome launch flags; this is the only place they are edited.
›
Chrome setupRuns the Chrome setup, once per machine and again after a Chrome update.
›
Browser smoke testRuns a goal in a browser and reports only the text and URL checks you give it.
›
‹ Home

sharing

Keyboard, mouse, clipboard and audio shared between this laptop and the Windows PC.

Keyboard and mouse guideOpens the guide to the shared keyboard and mouse with the Windows PC.
›
Restart keyboard sharingStarts Deskflow again and asks for input access.
›
USB mouse notesOpens the notes on the Windows USB mouse and how the keyboard follows it.
›
Lan Mouse (retired)Opens the retired Lan Mouse guide, kept only for rollback.
›
Clipboard historyOpens the clipboard history picker.
›
Send audio to WindowsSends all Linux audio to the Windows PC over Tailscale.
›
Restore speakersSends audio back to the speakers.
›
Audio statusPrints whether audio is going to the Windows PC.
›
‹ Home

windows

Everything for the Windows PC: rebuilding it from its manifests, keeping its skills in sync, and cloning its work repos.

Rebuild the Windows PCRuns the install that rebuilds the Windows environment from its manifests; it asks for admin approval.
›
Check the installRuns, on the Windows PC, the checks of the installed environment.
›
Roll backRuns, on the Windows PC, the rollback that removes the installed pack.
›
ManifestsOpens the exact lists of programs, Node versions and extensions the install uses.
›
Sign-ins by handOpens the list of sign-ins to redo by hand after an install.
›
Skill sync guideOpens the guide to the skill sync that runs on pushes to master.
›
Clone reposRuns, on the Windows PC, the clone of every missing Betec repo; it is safe to run again.
›
‹ Home

documents

The working documents: CVs, case studies that record experiments, machine incidents, and the plans and designs.

CVsPrints the CV screen: the three CVs and their sources.
›
Case studiesPrints the case studies screen: the archived experiments.
›
Machine incidentsOpens the dated records of machine failures and how each was fixed.
›
Plans and designsOpens the docs folder: plans, design pitches, research and changelog.
›
‹ documents

cv

The CVs in this repo, as PDFs, and the folder and guide that build them.

CV folderOpens the CV sources, PDFs and build scripts.
›
Full Stack Developer CVOpens the Full Stack Developer CV as a PDF.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV as a PDF.
›
AI Integrations CVOpens the AI Integrations CV as a PDF.
›
CV guideOpens the guide to editing, rebuilding and committing the CVs.
›
‹ documents

cases

The archived experiments, each in its own folder with its own README.

Codebot returnOpens the case study of the same design request with and without the skill.
›
Signal gardenOpens the case study of a small documentation exhibit.
›
Kernel cloud browsersOpens the results of testing cloud browsers, from 2026-10-08.
›
‹ Home

tools

Small standalone tools that have their own screens: two dashboards, Hermes, the Supabase keep-alive and team-park.

DashboardStarts the dashboard at http://127.0.0.1:8780, the one screen for cases asked, rule changes and calls agents made alone.
›
Dashboard, concepts versionStarts the second dashboard version at http://127.0.0.1:8781, to compare with the first.
›
HermesRuns the Hermes assistant from ~/.local/bin/hermes.
›
Hermes guideOpens the Hermes install notes and restore guide.
›
Supabase keep-aliveRuns the Supabase keep-alive script; its timer runs it too.
›
Team parkRuns the team-park tool from ~/.local/bin/team-park.
›
Raw answer
The map below covers the reachable things in the workstation repo, grouped into eight top-level screens. Nested screens hold the larger groups. I could only read the file dump, so each sentence describes what the file name and README say. Step 1 of the skill will check them against the source before anything is built.

Judgment calls:
- **Groups follow what a person wants to do**, not the repo's folders: shell, machine, assistant, browser, sharing, windows, documents, tools.
- **OpenCode is linked, not copied.** `opencode help` already exists, so the assistant screen points to it.
- **Credentials stay out of the output.** `infra.zsh` and `utils.zsh` embed credentials in git URLs. Their rows link to the file, and the screen never prints its contents.
- **Windows scripts** are listed by their repo path. They run on the Windows PC, so the row describes running them there.
- **Gaps in the dump.** The README refers to `workstation-cli/`, `zsh.d/workstation.zsh`, `zsh.d/audio-share.zsh`, `audio-share/`, `resume-kvm`, `Start-Install.cmd` and `secrets-checklist.md`, but none appear in the file list. I kept their rows; the inventory step has to confirm each one exists.
- **Left out on purpose:** git-hook internals, the Claude `mods/` plugins (see the questions), the retired Codex recorders and Playwright.

```json
{"screens": [
 {"path": [], "sentence": "The whole kit for this workstation, grouped by what you want to do; each group opens its own screen.", "rows": [
  {"name": "Shell", "form": "workstation shell", "what": "Prints the shell screen: the helpers every terminal loads, for git, Docker, keys and review."},
  {"name": "Machine", "form": "workstation machine", "what": "Prints the machine screen: repair, power and background services for this Linux laptop."},
  {"name": "Assistant", "form": "workstation assistant", "what": "Prints the assistant screen: the instructions, skills and agent system behind Claude, Codex and OpenCode."},
  {"name": "Browser", "form": "workstation browser", "what": "Prints the browser screen: the browser command and the Chrome launcher."},
  {"name": "Sharing", "form": "workstation sharing", "what": "Prints the sharing screen: keyboard, mouse, clipboard and audio shared with the Windows PC."},
  {"name": "Windows", "form": "workstation windows", "what": "Prints the Windows screen: rebuilding the PC, its skill sync and its repo clones."},
  {"name": "Documents", "form": "workstation documents", "what": "Prints the documents screen: CVs, case studies, machine incidents and plans."},
  {"name": "Tools", "form": "workstation tools", "what": "Prints the tools screen: the dashboards, Hermes, the Supabase keep-alive and team-park."}
 ]},
 {"path": ["shell"], "sentence": "The shell helpers this workstation loads into every terminal, and the files behind them.", "rows": [
  {"name": "Git safety", "form": "git checkout (guarded by ~/.zsh.d/git-safety.zsh)", "what": "Asks [y/N] before a checkout discards unstaged changes."},
  {"name": "Git settings", "form": "~/.gitconfig", "what": "Opens the Git identity, LFS, credential and hooks settings."},
  {"name": "Git hooks", "form": "~/.git-hooks/", "what": "Opens the Lefthook hook shims that run on every git action."},
  {"name": "Helper files", "form": "~/.zsh.d/", "what": "Opens the folder of shell helpers that every terminal loads."},
  {"name": "Repo copies of helpers", "form": "~/projects/workstation/zsh.d/", "what": "Opens the repo copies of the helpers; they drift from ~/.zsh.d, so diff before editing."},
  {"name": "Docker and database helpers", "form": "~/.zsh.d/infra.zsh", "what": "Opens the Docker, Compose, Prisma, Postgres, nginx and VPN helpers; it holds a credential, so its contents are never printed."},
  {"name": "Terminal helpers", "form": "~/.zsh.d/utils.zsh", "what": "Opens the terminal helpers (set-title, killport, IP aliases, lazy nvm, Android and Bun setup); it holds a credential, so its contents are never printed."},
  {"name": "API keys", "form": "~/.config/api-keys/env", "what": "Opens the general API keys file, which is never in Git; api-keys-edit opens the same file."},
  {"name": "Review a file", "form": "review-open", "what": "Opens a file for review, from zsh, bash or an agent."}
 ]},
 {"path": ["machine"], "sentence": "The repair, power and background-service tools for this Linux laptop.", "rows": [
  {"name": "Repair", "form": "workstation machine repair", "what": "Prints the repair screen: the fix commands and recovery scripts."},
  {"name": "Power and lid", "form": "workstation machine power", "what": "Prints the power screen: the CPU profiles and the lid behavior scripts."},
  {"name": "Services", "form": "workstation machine services", "what": "Prints the services screen: the timers and services that run in the background."}
 ]},
 {"path": ["machine", "repair"], "sentence": "The repair commands and recovery scripts for this laptop's keyboard, mouse, disk, network, Tailscale and monitor.", "rows": [
  {"name": "Fix keyboard", "form": "fix-keyboard", "what": "Runs the keyboard repair helper."},
  {"name": "Fix mouse", "form": "fix-mouse", "what": "Runs the mouse repair helper."},
  {"name": "Fix disk", "form": "fix-disk", "what": "Runs the disk repair helper."},
  {"name": "Fix WhatsApp", "form": "fix-whatsapp", "what": "Runs the WhatsApp repair helper."},
  {"name": "Internet recovery", "form": "~/projects/workstation/linux-internet-recovery.sh", "what": "Runs the network recovery: points DNS at systemd-resolved, restarts NetworkManager and cycles networking; it asks for sudo."},
  {"name": "Tailscale remote terminal", "form": "~/projects/workstation/recover-tailscale-remote-terminal.sh", "what": "Runs the Tailscale repair: DNS, then tailscaled, then the remote-terminal service and its port check."},
  {"name": "External monitor", "form": "~/projects/workstation/fix_old_monitor_hdmi.sh", "what": "Runs xrandr to set the external monitor's mode and refresh rate."}
 ]},
 {"path": ["machine", "power"], "sentence": "The CPU power profiles and the lid behavior for this laptop; the lid changes apply after a reboot.", "rows": [
  {"name": "Power saver", "form": "~/projects/workstation/cpu-min-power.sh", "what": "Runs the power-saver profile: turbo off, CPU capped at 8%; it asks for sudo and works on Intel only."},
  {"name": "Balanced", "form": "~/projects/workstation/cpu-normal-power.sh", "what": "Runs the balanced profile: turbo on, CPU cap back to 100%; it asks for sudo."},
  {"name": "Keep running with lid closed", "form": "~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.sh", "what": "Runs the change so that closing the lid does nothing."},
  {"name": "Restore lid behavior", "form": "~/projects/workstation/laptop-utilities/restore-default-lid-behavior.sh", "what": "Runs the removal of that change, back to the default lid behavior."}
 ]},
 {"path": ["machine", "services"], "sentence": "The timers and services that run in the background on this laptop, and where each one is defined.", "rows": [
  {"name": "Live timers", "form": "systemctl --user list-timers", "what": "Prints each user timer and when it next runs."},
  {"name": "Deskflow server", "form": "~/projects/workstation/deskflow/deskflow.service", "what": "Opens the unit that runs the Deskflow server with the graphical session."},
  {"name": "Clipboard server", "form": "~/projects/workstation/clipstack/units/clipstack-server.service", "what": "Opens the unit that runs the clipboard history server."},
  {"name": "Clipboard watcher", "form": "~/projects/workstation/clipstack/units/clipstack-watcher.service", "what": "Opens the unit that runs the clipboard watcher."},
  {"name": "Supabase keep-alive", "form": "~/projects/workstation/supabase-keepalive/supabase-keepalive.timer", "what": "Opens the timer that runs the Supabase keep-alive."},
  {"name": "Codex Chrome bridge", "form": "~/projects/workstation/codex/chrome-bridge/codex-chrome-bridge.timer", "what": "Opens the timer that keeps Codex's Chrome plugin link working."},
  {"name": "Answer sync", "form": "~/projects/data/systemd/", "what": "Opens the timer units that pull answers every 5 minutes."},
  {"name": "Rules reminder", "form": "~/projects/workstation/docs/plans/2026-10-24-rules-per-role/reminder/rules-roles-reminder.timer", "what": "Opens the timer for the rules-per-role reminder."}
 ]},
 {"path": ["assistant"], "sentence": "The instructions, skills and agent system behind Claude Code, Codex and OpenCode on this machine.", "rows": [
  {"name": "Instructions", "form": "workstation assistant instructions", "what": "Prints the instructions screen: the global instructions, settings and rules."},
  {"name": "Skills", "form": "workstation assistant skills", "what": "Prints the skills screen: the global skills and their backups."},
  {"name": "Agents", "form": "workstation assistant agents", "what": "Prints the agents screen: agent records, the sandbox and teams."},
  {"name": "OpenCode", "form": "opencode help", "what": "Prints the OpenCode screen with its profiles and commands; this kit links to it and does not copy it."},
  {"name": "Claude Code", "form": "claude", "what": "Runs Claude Code through the usage guard wrapper in ~/bin."}
 ]},
 {"path": ["assistant", "instructions"], "sentence": "The global instructions, settings and rules that Claude and Codex read in this kit.", "rows": [
  {"name": "Linux Claude instructions", "form": "~/projects/workstation/claude/linux-global/CLAUDE.md", "what": "Opens the mirror of this Linux machine's global Claude instructions."},
  {"name": "Windows Claude instructions", "form": "~/projects/workstation/claude/CLAUDE.md", "what": "Opens the global Claude instructions that init-windows deploys to Windows."},
  {"name": "Claude settings", "form": "~/projects/workstation/claude/settings.json", "what": "Opens the Claude Code settings kept in this kit; the Linux settings are machine-local."},
  {"name": "Codex config", "form": "~/projects/workstation/codex/config.toml", "what": "Opens the Codex CLI config that init-windows deploys."},
  {"name": "Rules", "form": "rules", "what": "Prints the rules; rules [folder] prints the rules for one folder."},
  {"name": "Rules file", "form": "~/projects/workstation/workboard/rules.yaml", "what": "Opens the file that rules reads; only the user or an accepted proposal changes it."}
 ]},
 {"path": ["assistant", "skills"], "sentence": "The skills this machine uses: the global repo, the backups kept here, and the shortlist of skills under review.", "rows": [
  {"name": "Global skills", "form": "~/projects/my-skills", "what": "Opens the global skills repo that install.sh links into Claude, Codex and OpenCode."},
  {"name": "Skill backups", "form": "~/projects/workstation/claude/skills/", "what": "Opens the backup copies of the skills kept in this repo."},
  {"name": "Skills shortlist", "form": "~/projects/workstation/claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and which of them are installed."}
 ]},
 {"path": ["assistant", "agents"], "sentence": "The agent records, the sandbox where you ask an agent things, and the commands that start teams.", "rows": [
  {"name": "Agent records", "form": "~/projects/my-skills/agents/", "what": "Opens the agent records: each agent's typed record, saved tests and role skill."},
  {"name": "Check agents", "form": "~/projects/workstation/agent-framework/agent check", "what": "Checks every agent record and refuses broken ones with exit 1."},
  {"name": "List agents", "form": "~/projects/workstation/agent-framework/agent list", "what": "Prints each agent with its tier, model and number of tests."},
  {"name": "Agent Sandbox", "form": "~/projects/workstation/agent-framework/agent serve", "what": "Starts the Agent Sandbox page at http://127.0.0.1:8790, where you pick an agent and ask it things."},
  {"name": "Start a team", "form": "/spawn-team <team>", "what": "Starts a team of agents from its team file, typed in Claude."},
  {"name": "Main Claude session", "form": "claude --main -c", "what": "Continues the main Claude session through the session-types wrapper."}
 ]},
 {"path": ["browser"], "sentence": "The browser command that drives one persistent Chrome window, and the Chrome launcher that makes its recordings possible.", "rows": [
  {"name": "Browser command", "form": "browser", "what": "Runs browser steps such as goto, click, fill and screenshot in one Chrome window that stays open between calls."},
  {"name": "Browser status", "form": "browser status", "what": "Prints whether the background browser server is up."},
  {"name": "Close browser", "form": "browser close", "what": "Closes the Chrome window and stops the server."},
  {"name": "Browser source", "form": "~/projects/workstation/browser/", "what": "Opens the browser CLI's folder and its README."},
  {"name": "Chrome launcher", "form": "~/projects/workstation/chrome/chrome.sh", "what": "Opens the one script that starts Chrome, with the recording flag."},
  {"name": "Chrome flags", "form": "~/projects/workstation/chrome/flags", "what": "Opens the Chrome launch flags; this is the only place they are edited."},
  {"name": "Chrome setup", "form": "~/projects/workstation/chrome/install.sh", "what": "Runs the Chrome setup, once per machine and again after a Chrome update."},
  {"name": "Browser smoke test", "form": "jev-browser-test", "what": "Runs a goal in a browser and reports only the text and URL checks you give it."}
 ]},
 {"path": ["sharing"], "sentence": "Keyboard, mouse, clipboard and audio shared between this laptop and the Windows PC.", "rows": [
  {"name": "Keyboard and mouse guide", "form": "~/projects/workstation/deskflow/README.md", "what": "Opens the guide to the shared keyboard and mouse with the Windows PC."},
  {"name": "Restart keyboard sharing", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input access."},
  {"name": "USB mouse notes", "form": "~/projects/workstation/deskflow/usb-mouse/README.md", "what": "Opens the notes on the Windows USB mouse and how the keyboard follows it."},
  {"name": "Lan Mouse (retired)", "form": "~/projects/workstation/lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide, kept only for rollback."},
  {"name": "Clipboard history", "form": "~/projects/workstation/clipstack/picker.py", "what": "Opens the clipboard history picker."},
  {"name": "Send audio to Windows", "form": "audio-start", "what": "Sends all Linux audio to the Windows PC over Tailscale."},
  {"name": "Restore speakers", "form": "audio-pause", "what": "Sends audio back to the speakers."},
  {"name": "Audio status", "form": "audio-share status", "what": "Prints whether audio is going to the Windows PC."}
 ]},
 {"path": ["windows"], "sentence": "Everything for the Windows PC: rebuilding it from its manifests, keeping its skills in sync, and cloning its work repos.", "rows": [
  {"name": "Rebuild the Windows PC", "form": "~/projects/workstation/init-windows/Start-Install.cmd", "what": "Runs the install that rebuilds the Windows environment from its manifests; it asks for admin approval."},
  {"name": "Check the install", "form": "~/projects/workstation/init-windows/Smoke-Test-Windows.ps1", "what": "Runs, on the Windows PC, the checks of the installed environment."},
  {"name": "Roll back", "form": "~/projects/workstation/init-windows/Remove-WindowsPack.ps1", "what": "Runs, on the Windows PC, the rollback that removes the installed pack."},
  {"name": "Manifests", "form": "~/projects/workstation/init-windows/manifests/", "what": "Opens the exact lists of programs, Node versions and extensions the install uses."},
  {"name": "Sign-ins by hand", "form": "~/projects/workstation/init-windows/secrets-checklist.md", "what": "Opens the list of sign-ins to redo by hand after an install."},
  {"name": "Skill sync guide", "form": "~/projects/workstation/skills-sync-windows/README.md", "what": "Opens the guide to the skill sync that runs on pushes to master."},
  {"name": "Clone repos", "form": "~/projects/workstation/repos/Clone-BetecRepos.ps1", "what": "Runs, on the Windows PC, the clone of every missing Betec repo; it is safe to run again."}
 ]},
 {"path": ["documents"], "sentence": "The working documents: CVs, case studies that record experiments, machine incidents, and the plans and designs.", "rows": [
  {"name": "CVs", "form": "workstation documents cv", "what": "Prints the CV screen: the three CVs and their sources."},
  {"name": "Case studies", "form": "workstation documents cases", "what": "Prints the case studies screen: the archived experiments."},
  {"name": "Machine incidents", "form": "~/projects/workstation/reference/incidents/", "what": "Opens the dated records of machine failures and how each was fixed."},
  {"name": "Plans and designs", "form": "~/projects/workstation/docs/", "what": "Opens the docs folder: plans, design pitches, research and changelog."}
 ]},
 {"path": ["documents", "cv"], "sentence": "The CVs in this repo, as PDFs, and the folder and guide that build them.", "rows": [
  {"name": "CV folder", "form": "~/projects/workstation/cv/", "what": "Opens the CV sources, PDFs and build scripts."},
  {"name": "Full Stack Developer CV", "form": "~/projects/workstation/cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV as a PDF."},
  {"name": "AI Full Stack Engineer CV", "form": "~/projects/workstation/cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV as a PDF."},
  {"name": "AI Integrations CV", "form": "~/projects/workstation/cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV as a PDF."},
  {"name": "CV guide", "form": "~/projects/workstation/cv/README.md", "what": "Opens the guide to editing, rebuilding and committing the CVs."}
 ]},
 {"path": ["documents", "cases"], "sentence": "The archived experiments, each in its own folder with its own README.", "rows": [
  {"name": "Codebot return", "form": "~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/README.md", "what": "Opens the case study of the same design request with and without the skill."},
  {"name": "Signal garden", "form": "~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "Opens the case study of a small documentation exhibit."},
  {"name": "Kernel cloud browsers", "form": "~/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the results of testing cloud browsers, from 2026-10-08."}
 ]},
 {"path": ["tools"], "sentence": "Small standalone tools that have their own screens: two dashboards, Hermes, the Supabase keep-alive and team-park.", "rows": [
  {"name": "Dashboard", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard at http://127.0.0.1:8780, the one screen for cases asked, rule changes and calls agents made alone."},
  {"name": "Dashboard, concepts version", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the second dashboard version at http://127.0.0.1:8781, to compare with the first."},
  {"name": "Hermes", "form": "hermes", "what": "Runs the Hermes assistant from ~/.local/bin/hermes."},
  {"name": "Hermes guide", "form": "~/projects/workstation/hermes/README.md", "what": "Opens the Hermes install notes and restore guide."},
  {"name": "Supabase keep-alive", "form": "~/projects/workstation/supabase-keepalive/supabase-keepalive.sh", "what": "Runs the Supabase keep-alive script; its timer runs it too."},
  {"name": "Team park", "form": "team-park", "what": "Runs the team-park tool from ~/.local/bin/team-park."}
 ]}
],
"questions": [
 "Eight top-level groups: keep all eight, or merge to fewer? Recommendation: keep eight, since each one is a different place a person goes; if you want fewer, merge tools into assistant and windows into machine.",
 "What do fix-keyboard, fix-mouse, fix-disk, fix-whatsapp, team-park and zsh.d/dash-path-warn.zsh do? Their sentences are placeholders until I read the source in step 1. Recommendation: tell me the purpose of any you know, and I will read the rest before writing their sentences.",
 "Are the files the README refers to but the dump does not list present (workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, resume-kvm, Start-Install.cmd, secrets-checklist.md)? Recommendation: keep their rows; the inventory step drops any that are missing.",
 "Should the Lan Mouse guide stay on the map, marked retired? Recommendation: keep only that one row, for rollback, and drop the rest of the Lan Mouse items.",
 "Should the Claude mods (changelog-pane, review-pane, scratchpad-playground, team-board) be reachable from the map? Recommendation: leave them out unless you start them by command; none has a README entry in the dump."
]}
```

screen-decomposition, first draft · run 4 exit=0 seconds=158 · prompt

P1 Recall: 0.771P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.993P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.301
As terminal help
Everything this workstation keeps, grouped by what you are trying to do.
Shell and git (Linux)workstation shellOpens the shell screen: the zsh helper files and the git settings and hooks on this Linux machine.
Machine utilities (Linux)workstation machineOpens the machine screen: power, network, display, lid, audio, background services and repairs.
AI assistant setupworkstation assistantOpens the assistant screen: the rules, instructions and settings Claude and Codex run with, plus agents, skills, OpenCode, Hermes and hooks.
Browser CLIworkstation browserOpens the browser screen: the persistent Chrome command, Chrome itself, and the behavioral browser QA.
Dashboardworkstation dashboardOpens the dashboard screen: the at-a-glance screen on this machine and its concepts version.
Deskflow (shared mouse and keyboard)workstation deskflowOpens the Deskflow screen: sharing the laptop keyboard and mouse with the Windows PC.
Windows bootstrapworkstation windowsOpens the Windows screen: rebuilding the Windows setup, cloning the work repos and syncing skills.
Documentsworkstation documentsOpens the documents screen: CVs, case studies, plans, design research and the notes on where things land.
shell
The shell and git on this Linux machine: the zsh helper files and the git settings and hooks.
zsh helpersworkstation shell zshOpens the zsh screen: the helper files sourced from ~/.zshrc, one topic each.
Gitworkstation shell gitOpens the git screen: the git identity, credential helper and hooks for every repo.
shell › zsh
The zsh helper files, one per topic, sourced from ~/.zshrc through copies in ~/.zsh.d/.
git-safety.zshzsh.d/git-safety.zshWraps git checkout: lists the files and asks [y/N] before discarding unstaged changes.
infra.zshzsh.d/infra.zshRuns the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
utils.zshzsh.d/utils.zshRuns terminal helpers (set-title, killport), IP aliases, lazy-loaded nvm and node, and Android, Java and Bun setup.
api-keys.zshzsh.d/api-keys.zshExports the general API keys from ~/.config/api-keys/env, which is never in Git; api-keys-edit opens that file.
opencode-profiles.zshzsh.d/opencode-profiles.zshRuns opencode and oc with the current OpenCode profile.
review-open.zshzsh.d/review-open.zshOpens a file for review; ~/.local/bin/review-open runs it for bash and agents.
rules.zshzsh.d/rules.zshPrints the rules that apply to a folder; the rules themselves are on the assistant screen.
dash-path-warn.zshzsh.d/dash-path-warn.zshWarns about a path by its name; the README does not describe it, so read the file.
workstation.zshzsh.d/workstation.zshRuns the workstation facade (workstation, setup, ws) that prints this kit's help. File not in the list; verify.
shell › git
The git settings and hooks on this Linux machine.
.gitconfig~/.gitconfig (copy of .gitconfig)Sets the author, Git LFS, the store credential helper, the post buffer and the hooks folder for every repo.
git hooks~/.git-hooks/ (copies of git-hooks/)Runs on every git action in every repo: pre-push holds the push gates, commit-msg the commit gate.
lefthooklefthook on PATHRuns the hook manager the hook shims call; without it each git action prints a warning.
machine
The utilities for this Linux machine: power, network, display, lid, audio, background services, repairs, and incident records.
cpu-min-power.shcpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8%; Intel P-state only, asks for sudo.
cpu-normal-power.shcpu-normal-power.shSets the balanced profile, turns turbo on and removes the cap; same requirements.
keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shWrites a logind drop-in so closing the lid does nothing; applies after a reboot.
restore default lid behaviorlaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in; applies after a reboot.
supabase keep-alivesupabase-keepalive/ (systemd timer)Runs the Supabase keep-alive script on a systemd timer.
fix_old_monitor_hdmi.shfix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output with xrandr (default 1920x1080 at 59.88).
linux-internet-recovery.shlinux-internet-recovery.shRepairs DNS through systemd-resolved, restarts NetworkManager and cycles networking; runs itself with sudo.
recover-tailscale-remote-terminal.shrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, waits up to 30 s for reconnect, then starts remote-terminal and checks port 3500.
fix-keyboardfix-keyboard (zsh.d/utils.zsh)Repairs the keyboard.
fix-mousefix-mouse (zsh.d/utils.zsh)Repairs the mouse.
fix-diskfix-disk (zsh.d/utils.zsh)Repairs the disk.
fix-whatsappfix-whatsapp (zsh.d/utils.zsh)Repairs WhatsApp.
audio-startaudio-start (zsh.d/audio-share.zsh)Starts sending all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers.
clipstack server and watcherclipstack/units/ (systemd user services)Runs the clipboard server and watcher as user services; see clipstack/install.sh.
clipstack pickerclipstack/picker.pyRuns the clipboard picker; clipstack/ says how it is opened.
incident recordsreference/incidents/Opens the dated machine incident records, with the repairs and what was verified.
assistant
The AI assistants on this machine: their rules, instructions and settings, and the agents, skills, OpenCode, Hermes and hooks.
rulesrulesPrints the rules every session follows, from workboard/rules.yaml.
global instructionsclaude/linux-global/Opens the mirror of the global instructions Claude and Codex read first on this machine.
settings and Codex configclaude/settings.json and codex/config.tomlOpens the Claude Code settings and the Codex CLI config; both are machine-local copies.
agentsworkstation assistant agentsOpens the agents screen: agent records, roles, team starts, results and the Agent Sandbox.
skillsworkstation assistant skillsOpens the skills screen: the global skills and the backups kept in this repo.
OpenCode profilesworkstation assistant opencodeOpens the OpenCode screen: the profiles, what each one loads, and how to switch them.
Hermesworkstation assistant hermesOpens the Hermes screen: the source install, its example configs and the restore steps.
hooksworkstation assistant hooksOpens the hooks screen: the Claude hooks, session types, mods and the usage guard.
assistant › agents
The agent system: agent records, roles, team starts, saved results and memory, and the Agent Sandbox.
Agent Sandboxagent-framework/agent serve (http://127.0.0.1:8790)Starts the sandbox server at http://127.0.0.1:8790, where you pick an agent and ask it things.
agent checkagent-framework/agent checkChecks every agent record and refuses broken ones with exit 1.
agent listagent-framework/agent listLists agents with their tier, model and number of tests.
agent records~/projects/my-skills/agents/<id>/agent.yamlOpens an agent's record: its typed setup, situations and saved tests.
roles~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.mdOpens the role skills each team member starts with.
team files~/projects/my-skills/spawn-team/teams/Opens the team files that /spawn-team starts.
eval results and memory~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/Opens an agent's saved eval results and memory.
answer sync~/projects/data/bin/sync (systemd user timer)Syncs answers between the data repo and this machine every five minutes.
team-park~/.local/bin/team-park (claude/team-park/team_park.py)Runs team_park.py; its README says what it parks.
supervision backlog~/projects/betec/workboard/docs/supervision-backlog.mdOpens the supervision backlog.
archive~/archive/Opens the archive of files moved out of projects, including agents' test evidence.
assistant › skills
The skills: the global skills in my-skills, and the backups kept in this repo.
global skills~/projects/my-skills (linked into ~/.claude/skills, ~/.codex/skills, ~/.config/opencode/skills)Opens the global skills; install.sh links them into the three skill folders.
skill backupsclaude/skills/<name>/Opens one skill backup's folder: its SKILL.md and references; copy the ones you want into ~/.claude/skills/.
skill shortlistclaude/skills-shortlist.mdOpens the skills researched on skills.sh and which ones are installed.
assistant › opencode
The OpenCode profiles: what each one loads, and the commands that name, switch and edit them.
current profileopencode-profilePrints the name of the current profile.
profile listopencode-profilesLists what each profile loads.
switch profileopencode-switch <name>Switches the profile that every shell's new runs use.
sign in a profileopencode-loginSigns the profile's Claude Code in.
profile filesopencode-filesLists the current profile's files.
edit a profile fileopencode-edit <file>Opens one of the current profile's files for editing.
opencode helpopencode help (also oc help, opencode-help, oc-help)Prints each profile's files, one column per profile, and the commands; with more than 3 profiles it writes and opens ~/.opencode-profiles/help.md.
profile foldersopencode-profiles/Opens the profile folders kept in this repo, such as the experimental profile's CLAUDE.md and settings.
assistant › hermes
The Hermes source install: its launcher, example configs, restore steps and backup record.
Hermes launcher~/.local/bin/hermes (checkout ~/projects/hermes-agent)Starts Hermes from the source checkout.
default config examplehermes/default.config.example.yamlOpens the default profile's settings, with no secrets.
jobs config examplehermes/jobs.config.example.yamlOpens the jobs profile's settings, with no secrets.
restore runbookhermes/RESTORE.mdOpens the steps to restore Hermes on a new machine.
backup recordhermes/BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
PATH fragmenthermes/zprofile-path.zshOpens the PATH lines the installer added to ~/.zprofile.
state and secrets~/.hermes (not in Git)Opens Hermes's state and secrets folder, which is not backed up in this repo.
assistant › hooks
The Claude hooks, session types, mods and the usage guard wrapper.
machine-history hookclaude/hooks/machine-history.sh (~/.claude/hooks/)Runs as a hook wired in ~/.claude/settings.json; the README table gives its event.
core-rules hookclaude/hooks/core-rules.sh (~/.claude/hooks/)Runs at SessionStart and before each Bash call.
team-activity hookclaude/hooks/team-activity.sh (~/.claude/hooks/)Runs as a hook wired in ~/.claude/settings.json; the README table gives its event.
local-server guardclaude/hooks/local-server-guard.py (~/.claude/hooks/)Runs before each Bash call and guards local servers.
proof reminderclaude/hooks/proof-reminder.sh (~/.claude/hooks/)Runs after each Edit, MultiEdit, Write and Bash call and reminds you to show proof.
session typesclaude/session-types/session-types.shRuns at SessionStart as the session types hook.
main sessionsclaude/session-types/main-sessions.pyRuns for claude --main -c and claude --main -r, starting or resuming the main session.
claude modsclaude/mods/Opens the Claude Code mods: the changelog, review, scratchpad and team-board panes.
usage-guard wrapperclaude/usage-guard/claude (~/bin/claude)Runs claude through the usage guard, ahead of the native ~/.local/bin/claude.
usage-guard install (Linux)claude/usage-guard/install.shInstalls the native claude that the wrapper runs.
usage-guard install (Windows)claude/usage-guard/Install-Windows.cmdInstalls the usage guard on Windows.
browser
The browser tools: the persistent Chrome command, Chrome itself, the older Codex path, and the behavioral browser QA.
browser commandbrowser '<steps>'Runs browser steps in one Chrome window that stays open across calls.
browser statusbrowser statusPrints whether the background server and Chrome are up.
browser closebrowser closeCloses Chrome and stops the background server.
recording proofrecordStart and recordStop (browser command)Starts or stops a tab recording as proof that a feature works.
browser guidebrowser/README.mdOpens the browser guide: every action, viewport preset, network capture and login gotcha.
Chrome launcherchrome/chrome.sh (run as google-chrome)Starts Chrome with the recording flag from chrome/flags; the only way to start Chrome here.
Chrome installchrome/install.shLinks google-chrome to chrome.sh and rewrites the menu entry; run once per machine and after a Chrome update.
Chrome flagschrome/flagsOpens the flags Chrome starts with; edit only this file, since browser reads it too.
Chrome guidechrome/README.mdOpens the Chrome guide: why the flag exists, its limits and the setup.
Codex direct Chrome pathcodex/browser/README.mdOpens the older Codex Chrome path; for recording, use recordStart and recordStop instead.
Codex Chrome bridgecodex/chrome-bridge/Repairs the Codex Chrome plugin's latest link and reapplies its local file: navigation patch.
jev-browser-testjev-browser-testRuns a goal against a browser and reports only the text and URL you assert.
jev-browser-test installjev-browser-test/install.shInstalls the CLI: clones the pinned upstream and places the command in ~/.local/bin.
jev-browser-test guidejev-browser-test/README.mdOpens its guide: the secrets file, the Jev loop and the exit codes.
jev-browser-test settings~/.config/jev-browser-test/env (mode 600)Opens the private settings file that holds the API keys; it stays out of Git.
dashboard
The dashboard on this machine and its concepts version.
dashboard serverpython3 ~/projects/workstation/dashboard/server.py (http://127.0.0.1:8780)Starts the dashboard on http://127.0.0.1:8780; nothing else starts it.
dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns its 199 checks against the real data and a real server.
dashboard guidedashboard/README.mdOpens its guide: the tabs, what it writes and how hot reload works.
concepts serverpython3 ~/projects/workstation/dashboard-concepts/server.py (http://127.0.0.1:8781)Starts the concepts version on http://127.0.0.1:8781, with a Projects panel in place of the bottom-right panel.
concepts checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns its 17 checks.
concepts guidedashboard-concepts/README.mdOpens its guide and how the two versions differ.
dashboard designdocs/design/2026-10-17-dashboard/Opens the design research, pitches and recommendation behind the dashboard's look.
dashboard data modeldocs/flows/2026-10-17/data-model.mdOpens the data model: what contains what, and the kinds the dashboard reads.
deskflow
Sharing the laptop keyboard and mouse with the Windows PC: Deskflow, its guides, and the retired Lan Mouse.
Deskflow serverdeskflow/deskflow.service (~/.config/systemd/user/)Runs the Deskflow server with the graphical session; GNOME asks to allow input capture on each start.
resume Deskflowresume-kvmStarts Deskflow again and asks for input capture, after a Cancel.
Deskflow guidedeskflow/README.mdOpens the everyday use, recovery and restore boundaries.
network auditdeskflow/NETWORK-AUDIT.mdOpens the audit of what Deskflow connects to.
lockdown rulesdeskflow/deskflow-lockdown.nftSets the nftables rules that lock down Deskflow's network; the dump does not say how they load.
Linux Deskflow settingsdeskflow/linux.conf (~/.config/Deskflow/Deskflow.conf)Sets Deskflow's settings for this Linux machine.
USB mouse notesdeskflow/usb-mouse/README.mdOpens the USB sharing notes, including how to turn the forwarded Windows USB mouse back on.
USB mouse servicedeskflow/usb-mouse/deskflow-usb-mouse.serviceForwards the Windows USB mouse over USB/IP; disabled since 2026-10-20.
retired Lan Mouse guidelan-mouse/README.mdOpens the retired Lan Mouse guide, kept for rollback; do not run it next to Deskflow.
retired Lan Mouse controller~/.local/bin/lan-mouse-controllerOpens the retired Lan Mouse controller: KVM now, start at login, retry input access.
windows
Rebuilding and syncing the Windows machine: the bootstrap, the cloned work repos, the skill sync and the clipboard script.
install Windowsinit-windows/Start-Install.cmdInstalls the pinned programs, Node versions, VS Code extensions and user scripts; approve the admin prompt.
verify Windowsinit-windows/Verify-Windows.ps1 (also Smoke-Test-Windows.ps1)Checks that the install matches the manifests.
remove Windows packinit-windows/Remove-WindowsPack.ps1Rolls back the install using its journal.
init-windows guideinit-windows/README.mdOpens the full guide to the Windows bootstrap.
captured inventoryinit-windows/inventory.mdOpens the list of what was captured.
sign-ins to redoinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand and the credentials to rotate.
Windows user scriptsinit-windows/user-scripts/Opens the Windows user scripts (hibernate, touchpad fixes), copied to %USERPROFILE%\Scripts.
clone work reposrepos/Clone-BetecRepos.ps1Clones every missing Betec repo into the workspace layout; existing folders are left alone.
skill syncskills-sync-windows/Sync-Skills.ps1Fast-forwards the Windows my-skills checkout and relinks the three skill folders; runs when master is pushed.
skill sync guideskills-sync-windows/README.mdOpens the sync guide: the runner, the install and what it may touch.
skill sync testsskills-sync-windows/Test-Sync.ps1Runs the sync tests.
Windows global instructionsclaude/windows-global/Opens the mirror of the Windows desktop's global Claude instructions.
Windows desktop snapshotclaude/backups/desktop-v2-2026/Opens the portable snapshot of the Windows desktop's instructions and skills; it is not loaded automatically.
Windows config deployclaude/CLAUDE.md, claude/settings.json, codex/config.tomlDeploys the Claude and Codex config files to Windows through init-windows.
clipstack Windows installclipstack/windows/install.ps1Installs the Windows clipboard script, clipstack.ahk.
documents
The documents kept here: CVs, case studies, plans, design research, and the notes on where things land.
CV guidecv/README.mdOpens the CV guide: the three versions, their sources and the pdflatex rebuild.
CV versionscv/versions/Opens the dated CV versions.
case studiescase-studies/Opens the archived experiments, one folder each.
codebot-return casecase-studies/conceptual-modeling/2026-09-15-codebot-return/README.mdOpens the codebot-return case: the same request with and without the skill.
signal-garden casecase-studies/blume-astryx/2026-09-16-signal-garden/README.mdOpens the signal-garden exhibit: durable explanation apart from the live interface.
plansdocs/plans/Opens the dated plans for each change.
itemsdocs/items/Opens the planned, urgent and work items.
incident indexreference/README.mdOpens the index of dated incident records.
where things landREADME.md#where-things-landOpens the table of which repo file lands on which machine path.
conventions and gotchasREADME.md#conventions-and-gotchasOpens the copy, machine-path and credential conventions, including the known issue in zsh.d.
Questions
  • Split the Machine screen (13 rows) into 'power' and 'repairs' screens? Recommend yes: power = CPU, lid and keep-alive; repairs = the four fix-* commands plus the network and display scripts. Audio, clipstack and incidents stay on Machine.
  • Which name do you type? The README uses workstation, ws and setup. Recommend ws as the typed name, workstation as the full name, and dropping setup as too generic. I will check each against whence -a at build time.
  • Show the retired items (Lan Mouse, older Codex browser path) inline, or behind a 'retired' screen? Recommend a retired screen under Deskflow for Lan Mouse, with the Codex path noted on the Browser screen.
  • May I read the files missing from the dump at build time: workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, and the clipstack README? Recommend yes; their rows are marked as taken from the README until then.
  • What do dash-path-warn.zsh, team-park, and the core-rules and team-activity hooks actually do? Recommend you describe them, or I read the files at build time. Until then their rows say only what the name or README shows.
As phone screens

Home

Everything this workstation keeps, grouped by what you are trying to do.

Shell and git (Linux)Opens the shell screen: the zsh helper files and the git settings and hooks on this Linux machine.
›
Machine utilities (Linux)Opens the machine screen: power, network, display, lid, audio, background services and repairs.
›
AI assistant setupOpens the assistant screen: the rules, instructions and settings Claude and Codex run with, plus agents, skills, OpenCode, Hermes and hooks.
›
Browser CLIOpens the browser screen: the persistent Chrome command, Chrome itself, and the behavioral browser QA.
›
DashboardOpens the dashboard screen: the at-a-glance screen on this machine and its concepts version.
›
Deskflow (shared mouse and keyboard)Opens the Deskflow screen: sharing the laptop keyboard and mouse with the Windows PC.
›
Windows bootstrapOpens the Windows screen: rebuilding the Windows setup, cloning the work repos and syncing skills.
›
DocumentsOpens the documents screen: CVs, case studies, plans, design research and the notes on where things land.
›
‹ Home

shell

The shell and git on this Linux machine: the zsh helper files and the git settings and hooks.

zsh helpersOpens the zsh screen: the helper files sourced from ~/.zshrc, one topic each.
›
GitOpens the git screen: the git identity, credential helper and hooks for every repo.
›
‹ shell

zsh

The zsh helper files, one per topic, sourced from ~/.zshrc through copies in ~/.zsh.d/.

git-safety.zshWraps git checkout: lists the files and asks [y/N] before discarding unstaged changes.
›
infra.zshRuns the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
›
utils.zshRuns terminal helpers (set-title, killport), IP aliases, lazy-loaded nvm and node, and Android, Java and Bun setup.
›
api-keys.zshExports the general API keys from ~/.config/api-keys/env, which is never in Git; api-keys-edit opens that file.
›
opencode-profiles.zshRuns opencode and oc with the current OpenCode profile.
›
review-open.zshOpens a file for review; ~/.local/bin/review-open runs it for bash and agents.
›
rules.zshPrints the rules that apply to a folder; the rules themselves are on the assistant screen.
›
dash-path-warn.zshWarns about a path by its name; the README does not describe it, so read the file.
›
workstation.zshRuns the workstation facade (workstation, setup, ws) that prints this kit's help. File not in the list; verify.
›
‹ shell

git

The git settings and hooks on this Linux machine.

.gitconfigSets the author, Git LFS, the store credential helper, the post buffer and the hooks folder for every repo.
›
git hooksRuns on every git action in every repo: pre-push holds the push gates, commit-msg the commit gate.
›
lefthookRuns the hook manager the hook shims call; without it each git action prints a warning.
›
‹ Home

machine

The utilities for this Linux machine: power, network, display, lid, audio, background services, repairs, and incident records.

cpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8%; Intel P-state only, asks for sudo.
›
cpu-normal-power.shSets the balanced profile, turns turbo on and removes the cap; same requirements.
›
keep running with lid closedWrites a logind drop-in so closing the lid does nothing; applies after a reboot.
›
restore default lid behaviorRemoves that drop-in; applies after a reboot.
›
supabase keep-aliveRuns the Supabase keep-alive script on a systemd timer.
›
fix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output with xrandr (default 1920x1080 at 59.88).
›
linux-internet-recovery.shRepairs DNS through systemd-resolved, restarts NetworkManager and cycles networking; runs itself with sudo.
›
recover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, waits up to 30 s for reconnect, then starts remote-terminal and checks port 3500.
›
fix-keyboardRepairs the keyboard.
›
fix-mouseRepairs the mouse.
›
fix-diskRepairs the disk.
›
fix-whatsappRepairs WhatsApp.
›
audio-startStarts sending all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers.
›
clipstack server and watcherRuns the clipboard server and watcher as user services; see clipstack/install.sh.
›
clipstack pickerRuns the clipboard picker; clipstack/ says how it is opened.
›
incident recordsOpens the dated machine incident records, with the repairs and what was verified.
›
‹ Home

assistant

The AI assistants on this machine: their rules, instructions and settings, and the agents, skills, OpenCode, Hermes and hooks.

rulesPrints the rules every session follows, from workboard/rules.yaml.
›
global instructionsOpens the mirror of the global instructions Claude and Codex read first on this machine.
›
settings and Codex configOpens the Claude Code settings and the Codex CLI config; both are machine-local copies.
›
agentsOpens the agents screen: agent records, roles, team starts, results and the Agent Sandbox.
›
skillsOpens the skills screen: the global skills and the backups kept in this repo.
›
OpenCode profilesOpens the OpenCode screen: the profiles, what each one loads, and how to switch them.
›
HermesOpens the Hermes screen: the source install, its example configs and the restore steps.
›
hooksOpens the hooks screen: the Claude hooks, session types, mods and the usage guard.
›
‹ assistant

agents

The agent system: agent records, roles, team starts, saved results and memory, and the Agent Sandbox.

Agent SandboxStarts the sandbox server at http://127.0.0.1:8790, where you pick an agent and ask it things.
›
agent checkChecks every agent record and refuses broken ones with exit 1.
›
agent listLists agents with their tier, model and number of tests.
›
agent recordsOpens an agent's record: its typed setup, situations and saved tests.
›
rolesOpens the role skills each team member starts with.
›
team filesOpens the team files that /spawn-team starts.
›
eval results and memoryOpens an agent's saved eval results and memory.
›
answer syncSyncs answers between the data repo and this machine every five minutes.
›
team-parkRuns team_park.py; its README says what it parks.
›
supervision backlogOpens the supervision backlog.
›
archiveOpens the archive of files moved out of projects, including agents' test evidence.
›
‹ assistant

skills

The skills: the global skills in my-skills, and the backups kept in this repo.

global skillsOpens the global skills; install.sh links them into the three skill folders.
›
skill backupsOpens one skill backup's folder: its SKILL.md and references; copy the ones you want into ~/.claude/skills/.
›
skill shortlistOpens the skills researched on skills.sh and which ones are installed.
›
‹ assistant

opencode

The OpenCode profiles: what each one loads, and the commands that name, switch and edit them.

current profilePrints the name of the current profile.
›
profile listLists what each profile loads.
›
switch profileSwitches the profile that every shell's new runs use.
›
sign in a profileSigns the profile's Claude Code in.
›
profile filesLists the current profile's files.
›
edit a profile fileOpens one of the current profile's files for editing.
›
opencode helpPrints each profile's files, one column per profile, and the commands; with more than 3 profiles it writes and opens ~/.opencode-profiles/help.md.
›
profile foldersOpens the profile folders kept in this repo, such as the experimental profile's CLAUDE.md and settings.
›
‹ assistant

hermes

The Hermes source install: its launcher, example configs, restore steps and backup record.

Hermes launcherStarts Hermes from the source checkout.
›
default config exampleOpens the default profile's settings, with no secrets.
›
jobs config exampleOpens the jobs profile's settings, with no secrets.
›
restore runbookOpens the steps to restore Hermes on a new machine.
›
backup recordOpens the record of the 2026-10-02 backup.
›
PATH fragmentOpens the PATH lines the installer added to ~/.zprofile.
›
state and secretsOpens Hermes's state and secrets folder, which is not backed up in this repo.
›
‹ assistant

hooks

The Claude hooks, session types, mods and the usage guard wrapper.

machine-history hookRuns as a hook wired in ~/.claude/settings.json; the README table gives its event.
›
core-rules hookRuns at SessionStart and before each Bash call.
›
team-activity hookRuns as a hook wired in ~/.claude/settings.json; the README table gives its event.
›
local-server guardRuns before each Bash call and guards local servers.
›
proof reminderRuns after each Edit, MultiEdit, Write and Bash call and reminds you to show proof.
›
session typesRuns at SessionStart as the session types hook.
›
main sessionsRuns for claude --main -c and claude --main -r, starting or resuming the main session.
›
claude modsOpens the Claude Code mods: the changelog, review, scratchpad and team-board panes.
›
usage-guard wrapperRuns claude through the usage guard, ahead of the native ~/.local/bin/claude.
›
usage-guard install (Linux)Installs the native claude that the wrapper runs.
›
usage-guard install (Windows)Installs the usage guard on Windows.
›
‹ Home

browser

The browser tools: the persistent Chrome command, Chrome itself, the older Codex path, and the behavioral browser QA.

browser commandRuns browser steps in one Chrome window that stays open across calls.
›
browser statusPrints whether the background server and Chrome are up.
›
browser closeCloses Chrome and stops the background server.
›
recording proofStarts or stops a tab recording as proof that a feature works.
›
browser guideOpens the browser guide: every action, viewport preset, network capture and login gotcha.
›
Chrome launcherStarts Chrome with the recording flag from chrome/flags; the only way to start Chrome here.
›
Chrome installLinks google-chrome to chrome.sh and rewrites the menu entry; run once per machine and after a Chrome update.
›
Chrome flagsOpens the flags Chrome starts with; edit only this file, since browser reads it too.
›
Chrome guideOpens the Chrome guide: why the flag exists, its limits and the setup.
›
Codex direct Chrome pathOpens the older Codex Chrome path; for recording, use recordStart and recordStop instead.
›
Codex Chrome bridgeRepairs the Codex Chrome plugin's latest link and reapplies its local file: navigation patch.
›
jev-browser-testRuns a goal against a browser and reports only the text and URL you assert.
›
jev-browser-test installInstalls the CLI: clones the pinned upstream and places the command in ~/.local/bin.
›
jev-browser-test guideOpens its guide: the secrets file, the Jev loop and the exit codes.
›
jev-browser-test settingsOpens the private settings file that holds the API keys; it stays out of Git.
›
‹ Home

dashboard

The dashboard on this machine and its concepts version.

dashboard serverStarts the dashboard on http://127.0.0.1:8780; nothing else starts it.
›
dashboard checksRuns its 199 checks against the real data and a real server.
›
dashboard guideOpens its guide: the tabs, what it writes and how hot reload works.
›
concepts serverStarts the concepts version on http://127.0.0.1:8781, with a Projects panel in place of the bottom-right panel.
›
concepts checksRuns its 17 checks.
›
concepts guideOpens its guide and how the two versions differ.
›
dashboard designOpens the design research, pitches and recommendation behind the dashboard's look.
›
dashboard data modelOpens the data model: what contains what, and the kinds the dashboard reads.
›
‹ Home

deskflow

Sharing the laptop keyboard and mouse with the Windows PC: Deskflow, its guides, and the retired Lan Mouse.

Deskflow serverRuns the Deskflow server with the graphical session; GNOME asks to allow input capture on each start.
›
resume DeskflowStarts Deskflow again and asks for input capture, after a Cancel.
›
Deskflow guideOpens the everyday use, recovery and restore boundaries.
›
network auditOpens the audit of what Deskflow connects to.
›
lockdown rulesSets the nftables rules that lock down Deskflow's network; the dump does not say how they load.
›
Linux Deskflow settingsSets Deskflow's settings for this Linux machine.
›
USB mouse notesOpens the USB sharing notes, including how to turn the forwarded Windows USB mouse back on.
›
USB mouse serviceForwards the Windows USB mouse over USB/IP; disabled since 2026-10-20.
›
retired Lan Mouse guideOpens the retired Lan Mouse guide, kept for rollback; do not run it next to Deskflow.
›
retired Lan Mouse controllerOpens the retired Lan Mouse controller: KVM now, start at login, retry input access.
›
‹ Home

windows

Rebuilding and syncing the Windows machine: the bootstrap, the cloned work repos, the skill sync and the clipboard script.

install WindowsInstalls the pinned programs, Node versions, VS Code extensions and user scripts; approve the admin prompt.
›
verify WindowsChecks that the install matches the manifests.
›
remove Windows packRolls back the install using its journal.
›
init-windows guideOpens the full guide to the Windows bootstrap.
›
captured inventoryOpens the list of what was captured.
›
sign-ins to redoOpens the sign-ins to redo by hand and the credentials to rotate.
›
Windows user scriptsOpens the Windows user scripts (hibernate, touchpad fixes), copied to %USERPROFILE%\Scripts.
›
clone work reposClones every missing Betec repo into the workspace layout; existing folders are left alone.
›
skill syncFast-forwards the Windows my-skills checkout and relinks the three skill folders; runs when master is pushed.
›
skill sync guideOpens the sync guide: the runner, the install and what it may touch.
›
skill sync testsRuns the sync tests.
›
Windows global instructionsOpens the mirror of the Windows desktop's global Claude instructions.
›
Windows desktop snapshotOpens the portable snapshot of the Windows desktop's instructions and skills; it is not loaded automatically.
›
Windows config deployDeploys the Claude and Codex config files to Windows through init-windows.
›
clipstack Windows installInstalls the Windows clipboard script, clipstack.ahk.
›
‹ Home

documents

The documents kept here: CVs, case studies, plans, design research, and the notes on where things land.

CV guideOpens the CV guide: the three versions, their sources and the pdflatex rebuild.
›
CV versionsOpens the dated CV versions.
›
case studiesOpens the archived experiments, one folder each.
›
codebot-return caseOpens the codebot-return case: the same request with and without the skill.
›
signal-garden caseOpens the signal-garden exhibit: durable explanation apart from the live interface.
›
plansOpens the dated plans for each change.
›
itemsOpens the planned, urgent and work items.
›
incident indexOpens the index of dated incident records.
›
where things landOpens the table of which repo file lands on which machine path.
›
conventions and gotchasOpens the copy, machine-path and credential conventions, including the known issue in zsh.d.
›
Raw answer
**Scenario (reasoning from experience, not observed):** Liel sits at the Linux laptop, sometimes with the lid closed while CodeBot runs, or at the Windows PC. They reach for a repair when the network, keyboard or mouse misbehaves, the dashboard to see waiting cases, the browser command to check a feature, and the agent and OpenCode tools while working with assistants. Documents and CVs come up less often. Each time they want the command, what it does, and where its file lives.

**Shape of the map:** eight top groups, named with the README's own headings. Each has a screen of its own, and a few have sub-screens (`shell zsh`, `shell git`, and `assistant agents / skills / opencode / hermes / hooks`).

**Inventory notes:**
- The descriptions come from the README and the file list. I have not read the script bodies, so the build step must check each `what` line against its file.
- Left off the map as agent or build internals, not user reach: `.bdd/` and `.idd/` specs, test files, fixtures, fonts, screenshot folders, `docs/research/` run output, and the skill reference documents.
- Kept, marked retired or disabled where that applies: Lan Mouse, the older Codex browser path, and USB mouse forwarding. Rollback is a reach.
- The credential problem in `zsh.d/` is a convention, so it is a line under Documents, not a command.

## Questions for you

1. **Split the Machine screen?** It has 13 rows. **Recommend:** yes, into `power` (CPU, lid, keep-alive) and `repairs` (the four `fix-*` commands plus the network and display scripts). Audio and incidents stay on Machine.
2. **Which name do you type?** The README uses `workstation`, `ws` and `setup`. **Recommend:** `ws` as the typed name, `workstation` as the full name, and drop `setup` because it is too generic. I will check it for clashes with `whence -a` at build time.
3. **Retired items:** show them inline or behind a `retired` screen? **Recommend:** a `retired` screen under Deskflow for Lan Mouse, with the older Codex browser path noted on the Browser screen.
4. **Files missing from the dump:** `workstation-cli/`, `zsh.d/workstation.zsh`, `zsh.d/audio-share.zsh`, `audio-share/`, and `clipstack/`'s own README. **Recommend:** let me read them at build time. Their rows are marked as taken from the README until then.
5. **Unclear purposes:** `dash-path-warn.zsh`, `team-park`, and the details of `machine-history.sh` and `team-activity.sh`. **Recommend:** you describe them, or I read them at build time. Until then the rows say only what the file name or README shows.

## Judgment calls

- **Top groups:** eight, from the README headings, to keep the top screen short.
- **One row per skill folder:** the skill backups are one pattern row, not one row each. Reason: the list is long and changes often. The build step can expand it from the file tree.
- **Screen-opening rows use `workstation <nouns>`** until question 2 is settled.
- **Clipstack and the Windows user scripts** are included even though the README does not list them, because a user reaches them.

```json
{"screens": [
{"path": [], "sentence": "Everything this workstation keeps, grouped by what you are trying to do.", "rows": [
{"name": "Shell and git (Linux)", "form": "workstation shell", "what": "Opens the shell screen: the zsh helper files and the git settings and hooks on this Linux machine."},
{"name": "Machine utilities (Linux)", "form": "workstation machine", "what": "Opens the machine screen: power, network, display, lid, audio, background services and repairs."},
{"name": "AI assistant setup", "form": "workstation assistant", "what": "Opens the assistant screen: the rules, instructions and settings Claude and Codex run with, plus agents, skills, OpenCode, Hermes and hooks."},
{"name": "Browser CLI", "form": "workstation browser", "what": "Opens the browser screen: the persistent Chrome command, Chrome itself, and the behavioral browser QA."},
{"name": "Dashboard", "form": "workstation dashboard", "what": "Opens the dashboard screen: the at-a-glance screen on this machine and its concepts version."},
{"name": "Deskflow (shared mouse and keyboard)", "form": "workstation deskflow", "what": "Opens the Deskflow screen: sharing the laptop keyboard and mouse with the Windows PC."},
{"name": "Windows bootstrap", "form": "workstation windows", "what": "Opens the Windows screen: rebuilding the Windows setup, cloning the work repos and syncing skills."},
{"name": "Documents", "form": "workstation documents", "what": "Opens the documents screen: CVs, case studies, plans, design research and the notes on where things land."}
]},
{"path": ["shell"], "sentence": "The shell and git on this Linux machine: the zsh helper files and the git settings and hooks.", "rows": [
{"name": "zsh helpers", "form": "workstation shell zsh", "what": "Opens the zsh screen: the helper files sourced from ~/.zshrc, one topic each."},
{"name": "Git", "form": "workstation shell git", "what": "Opens the git screen: the git identity, credential helper and hooks for every repo."}
]},
{"path": ["shell", "zsh"], "sentence": "The zsh helper files, one per topic, sourced from ~/.zshrc through copies in ~/.zsh.d/.", "rows": [
{"name": "git-safety.zsh", "form": "zsh.d/git-safety.zsh", "what": "Wraps git checkout: lists the files and asks [y/N] before discarding unstaged changes."},
{"name": "infra.zsh", "form": "zsh.d/infra.zsh", "what": "Runs the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts."},
{"name": "utils.zsh", "form": "zsh.d/utils.zsh", "what": "Runs terminal helpers (set-title, killport), IP aliases, lazy-loaded nvm and node, and Android, Java and Bun setup."},
{"name": "api-keys.zsh", "form": "zsh.d/api-keys.zsh", "what": "Exports the general API keys from ~/.config/api-keys/env, which is never in Git; api-keys-edit opens that file."},
{"name": "opencode-profiles.zsh", "form": "zsh.d/opencode-profiles.zsh", "what": "Runs opencode and oc with the current OpenCode profile."},
{"name": "review-open.zsh", "form": "zsh.d/review-open.zsh", "what": "Opens a file for review; ~/.local/bin/review-open runs it for bash and agents."},
{"name": "rules.zsh", "form": "zsh.d/rules.zsh", "what": "Prints the rules that apply to a folder; the rules themselves are on the assistant screen."},
{"name": "dash-path-warn.zsh", "form": "zsh.d/dash-path-warn.zsh", "what": "Warns about a path by its name; the README does not describe it, so read the file."},
{"name": "workstation.zsh", "form": "zsh.d/workstation.zsh", "what": "Runs the workstation facade (workstation, setup, ws) that prints this kit's help. File not in the list; verify."}
]},
{"path": ["shell", "git"], "sentence": "The git settings and hooks on this Linux machine.", "rows": [
{"name": ".gitconfig", "form": "~/.gitconfig (copy of .gitconfig)", "what": "Sets the author, Git LFS, the store credential helper, the post buffer and the hooks folder for every repo."},
{"name": "git hooks", "form": "~/.git-hooks/ (copies of git-hooks/)", "what": "Runs on every git action in every repo: pre-push holds the push gates, commit-msg the commit gate."},
{"name": "lefthook", "form": "lefthook on PATH", "what": "Runs the hook manager the hook shims call; without it each git action prints a warning."}
]},
{"path": ["machine"], "sentence": "The utilities for this Linux machine: power, network, display, lid, audio, background services, repairs, and incident records.", "rows": [
{"name": "cpu-min-power.sh", "form": "cpu-min-power.sh", "what": "Sets the power-saver profile, turns turbo off and caps the CPU at 8%; Intel P-state only, asks for sudo."},
{"name": "cpu-normal-power.sh", "form": "cpu-normal-power.sh", "what": "Sets the balanced profile, turns turbo on and removes the cap; same requirements."},
{"name": "keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind drop-in so closing the lid does nothing; applies after a reboot."},
{"name": "restore default lid behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in; applies after a reboot."},
{"name": "supabase keep-alive", "form": "supabase-keepalive/ (systemd timer)", "what": "Runs the Supabase keep-alive script on a systemd timer."},
{"name": "fix_old_monitor_hdmi.sh", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output with xrandr (default 1920x1080 at 59.88)."},
{"name": "linux-internet-recovery.sh", "form": "linux-internet-recovery.sh", "what": "Repairs DNS through systemd-resolved, restarts NetworkManager and cycles networking; runs itself with sudo."},
{"name": "recover-tailscale-remote-terminal.sh", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, waits up to 30 s for reconnect, then starts remote-terminal and checks port 3500."},
{"name": "fix-keyboard", "form": "fix-keyboard (zsh.d/utils.zsh)", "what": "Repairs the keyboard."},
{"name": "fix-mouse", "form": "fix-mouse (zsh.d/utils.zsh)", "what": "Repairs the mouse."},
{"name": "fix-disk", "form": "fix-disk (zsh.d/utils.zsh)", "what": "Repairs the disk."},
{"name": "fix-whatsapp", "form": "fix-whatsapp (zsh.d/utils.zsh)", "what": "Repairs WhatsApp."},
{"name": "audio-start", "form": "audio-start (zsh.d/audio-share.zsh)", "what": "Starts sending all Linux audio to the Windows machine over Tailscale; audio-pause restores the speakers."},
{"name": "clipstack server and watcher", "form": "clipstack/units/ (systemd user services)", "what": "Runs the clipboard server and watcher as user services; see clipstack/install.sh."},
{"name": "clipstack picker", "form": "clipstack/picker.py", "what": "Runs the clipboard picker; clipstack/ says how it is opened."},
{"name": "incident records", "form": "reference/incidents/", "what": "Opens the dated machine incident records, with the repairs and what was verified."}
]},
{"path": ["assistant"], "sentence": "The AI assistants on this machine: their rules, instructions and settings, and the agents, skills, OpenCode, Hermes and hooks.", "rows": [
{"name": "rules", "form": "rules", "what": "Prints the rules every session follows, from workboard/rules.yaml."},
{"name": "global instructions", "form": "claude/linux-global/", "what": "Opens the mirror of the global instructions Claude and Codex read first on this machine."},
{"name": "settings and Codex config", "form": "claude/settings.json and codex/config.toml", "what": "Opens the Claude Code settings and the Codex CLI config; both are machine-local copies."},
{"name": "agents", "form": "workstation assistant agents", "what": "Opens the agents screen: agent records, roles, team starts, results and the Agent Sandbox."},
{"name": "skills", "form": "workstation assistant skills", "what": "Opens the skills screen: the global skills and the backups kept in this repo."},
{"name": "OpenCode profiles", "form": "workstation assistant opencode", "what": "Opens the OpenCode screen: the profiles, what each one loads, and how to switch them."},
{"name": "Hermes", "form": "workstation assistant hermes", "what": "Opens the Hermes screen: the source install, its example configs and the restore steps."},
{"name": "hooks", "form": "workstation assistant hooks", "what": "Opens the hooks screen: the Claude hooks, session types, mods and the usage guard."}
]},
{"path": ["assistant", "agents"], "sentence": "The agent system: agent records, roles, team starts, saved results and memory, and the Agent Sandbox.", "rows": [
{"name": "Agent Sandbox", "form": "agent-framework/agent serve (http://127.0.0.1:8790)", "what": "Starts the sandbox server at http://127.0.0.1:8790, where you pick an agent and ask it things."},
{"name": "agent check", "form": "agent-framework/agent check", "what": "Checks every agent record and refuses broken ones with exit 1."},
{"name": "agent list", "form": "agent-framework/agent list", "what": "Lists agents with their tier, model and number of tests."},
{"name": "agent records", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "Opens an agent's record: its typed setup, situations and saved tests."},
{"name": "roles", "form": "~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.md", "what": "Opens the role skills each team member starts with."},
{"name": "team files", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files that /spawn-team starts."},
{"name": "eval results and memory", "form": "~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/", "what": "Opens an agent's saved eval results and memory."},
{"name": "answer sync", "form": "~/projects/data/bin/sync (systemd user timer)", "what": "Syncs answers between the data repo and this machine every five minutes."},
{"name": "team-park", "form": "~/.local/bin/team-park (claude/team-park/team_park.py)", "what": "Runs team_park.py; its README says what it parks."},
{"name": "supervision backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "Opens the supervision backlog."},
{"name": "archive", "form": "~/archive/", "what": "Opens the archive of files moved out of projects, including agents' test evidence."}
]},
{"path": ["assistant", "skills"], "sentence": "The skills: the global skills in my-skills, and the backups kept in this repo.", "rows": [
{"name": "global skills", "form": "~/projects/my-skills (linked into ~/.claude/skills, ~/.codex/skills, ~/.config/opencode/skills)", "what": "Opens the global skills; install.sh links them into the three skill folders."},
{"name": "skill backups", "form": "claude/skills/<name>/", "what": "Opens one skill backup's folder: its SKILL.md and references; copy the ones you want into ~/.claude/skills/."},
{"name": "skill shortlist", "form": "claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and which ones are installed."}
]},
{"path": ["assistant", "opencode"], "sentence": "The OpenCode profiles: what each one loads, and the commands that name, switch and edit them.", "rows": [
{"name": "current profile", "form": "opencode-profile", "what": "Prints the name of the current profile."},
{"name": "profile list", "form": "opencode-profiles", "what": "Lists what each profile loads."},
{"name": "switch profile", "form": "opencode-switch <name>", "what": "Switches the profile that every shell's new runs use."},
{"name": "sign in a profile", "form": "opencode-login", "what": "Signs the profile's Claude Code in."},
{"name": "profile files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "edit a profile file", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files for editing."},
{"name": "opencode help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints each profile's files, one column per profile, and the commands; with more than 3 profiles it writes and opens ~/.opencode-profiles/help.md."},
{"name": "profile folders", "form": "opencode-profiles/", "what": "Opens the profile folders kept in this repo, such as the experimental profile's CLAUDE.md and settings."}
]},
{"path": ["assistant", "hermes"], "sentence": "The Hermes source install: its launcher, example configs, restore steps and backup record.", "rows": [
{"name": "Hermes launcher", "form": "~/.local/bin/hermes (checkout ~/projects/hermes-agent)", "what": "Starts Hermes from the source checkout."},
{"name": "default config example", "form": "hermes/default.config.example.yaml", "what": "Opens the default profile's settings, with no secrets."},
{"name": "jobs config example", "form": "hermes/jobs.config.example.yaml", "what": "Opens the jobs profile's settings, with no secrets."},
{"name": "restore runbook", "form": "hermes/RESTORE.md", "what": "Opens the steps to restore Hermes on a new machine."},
{"name": "backup record", "form": "hermes/BACKUP-2026-10-02.md", "what": "Opens the record of the 2026-10-02 backup."},
{"name": "PATH fragment", "form": "hermes/zprofile-path.zsh", "what": "Opens the PATH lines the installer added to ~/.zprofile."},
{"name": "state and secrets", "form": "~/.hermes (not in Git)", "what": "Opens Hermes's state and secrets folder, which is not backed up in this repo."}
]},
{"path": ["assistant", "hooks"], "sentence": "The Claude hooks, session types, mods and the usage guard wrapper.", "rows": [
{"name": "machine-history hook", "form": "claude/hooks/machine-history.sh (~/.claude/hooks/)", "what": "Runs as a hook wired in ~/.claude/settings.json; the README table gives its event."},
{"name": "core-rules hook", "form": "claude/hooks/core-rules.sh (~/.claude/hooks/)", "what": "Runs at SessionStart and before each Bash call."},
{"name": "team-activity hook", "form": "claude/hooks/team-activity.sh (~/.claude/hooks/)", "what": "Runs as a hook wired in ~/.claude/settings.json; the README table gives its event."},
{"name": "local-server guard", "form": "claude/hooks/local-server-guard.py (~/.claude/hooks/)", "what": "Runs before each Bash call and guards local servers."},
{"name": "proof reminder", "form": "claude/hooks/proof-reminder.sh (~/.claude/hooks/)", "what": "Runs after each Edit, MultiEdit, Write and Bash call and reminds you to show proof."},
{"name": "session types", "form": "claude/session-types/session-types.sh", "what": "Runs at SessionStart as the session types hook."},
{"name": "main sessions", "form": "claude/session-types/main-sessions.py", "what": "Runs for claude --main -c and claude --main -r, starting or resuming the main session."},
{"name": "claude mods", "form": "claude/mods/", "what": "Opens the Claude Code mods: the changelog, review, scratchpad and team-board panes."},
{"name": "usage-guard wrapper", "form": "claude/usage-guard/claude (~/bin/claude)", "what": "Runs claude through the usage guard, ahead of the native ~/.local/bin/claude."},
{"name": "usage-guard install (Linux)", "form": "claude/usage-guard/install.sh", "what": "Installs the native claude that the wrapper runs."},
{"name": "usage-guard install (Windows)", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the usage guard on Windows."}
]},
{"path": ["browser"], "sentence": "The browser tools: the persistent Chrome command, Chrome itself, the older Codex path, and the behavioral browser QA.", "rows": [
{"name": "browser command", "form": "browser '<steps>'", "what": "Runs browser steps in one Chrome window that stays open across calls."},
{"name": "browser status", "form": "browser status", "what": "Prints whether the background server and Chrome are up."},
{"name": "browser close", "form": "browser close", "what": "Closes Chrome and stops the background server."},
{"name": "recording proof", "form": "recordStart and recordStop (browser command)", "what": "Starts or stops a tab recording as proof that a feature works."},
{"name": "browser guide", "form": "browser/README.md", "what": "Opens the browser guide: every action, viewport preset, network capture and login gotcha."},
{"name": "Chrome launcher", "form": "chrome/chrome.sh (run as google-chrome)", "what": "Starts Chrome with the recording flag from chrome/flags; the only way to start Chrome here."},
{"name": "Chrome install", "form": "chrome/install.sh", "what": "Links google-chrome to chrome.sh and rewrites the menu entry; run once per machine and after a Chrome update."},
{"name": "Chrome flags", "form": "chrome/flags", "what": "Opens the flags Chrome starts with; edit only this file, since browser reads it too."},
{"name": "Chrome guide", "form": "chrome/README.md", "what": "Opens the Chrome guide: why the flag exists, its limits and the setup."},
{"name": "Codex direct Chrome path", "form": "codex/browser/README.md", "what": "Opens the older Codex Chrome path; for recording, use recordStart and recordStop instead."},
{"name": "Codex Chrome bridge", "form": "codex/chrome-bridge/", "what": "Repairs the Codex Chrome plugin's latest link and reapplies its local file: navigation patch."},
{"name": "jev-browser-test", "form": "jev-browser-test", "what": "Runs a goal against a browser and reports only the text and URL you assert."},
{"name": "jev-browser-test install", "form": "jev-browser-test/install.sh", "what": "Installs the CLI: clones the pinned upstream and places the command in ~/.local/bin."},
{"name": "jev-browser-test guide", "form": "jev-browser-test/README.md", "what": "Opens its guide: the secrets file, the Jev loop and the exit codes."},
{"name": "jev-browser-test settings", "form": "~/.config/jev-browser-test/env (mode 600)", "what": "Opens the private settings file that holds the API keys; it stays out of Git."}
]},
{"path": ["dashboard"], "sentence": "The dashboard on this machine and its concepts version.", "rows": [
{"name": "dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py (http://127.0.0.1:8780)", "what": "Starts the dashboard on http://127.0.0.1:8780; nothing else starts it."},
{"name": "dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs its 199 checks against the real data and a real server."},
{"name": "dashboard guide", "form": "dashboard/README.md", "what": "Opens its guide: the tabs, what it writes and how hot reload works."},
{"name": "concepts server", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py (http://127.0.0.1:8781)", "what": "Starts the concepts version on http://127.0.0.1:8781, with a Projects panel in place of the bottom-right panel."},
{"name": "concepts checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs its 17 checks."},
{"name": "concepts guide", "form": "dashboard-concepts/README.md", "what": "Opens its guide and how the two versions differ."},
{"name": "dashboard design", "form": "docs/design/2026-10-17-dashboard/", "what": "Opens the design research, pitches and recommendation behind the dashboard's look."},
{"name": "dashboard data model", "form": "docs/flows/2026-10-17/data-model.md", "what": "Opens the data model: what contains what, and the kinds the dashboard reads."}
]},
{"path": ["deskflow"], "sentence": "Sharing the laptop keyboard and mouse with the Windows PC: Deskflow, its guides, and the retired Lan Mouse.", "rows": [
{"name": "Deskflow server", "form": "deskflow/deskflow.service (~/.config/systemd/user/)", "what": "Runs the Deskflow server with the graphical session; GNOME asks to allow input capture on each start."},
{"name": "resume Deskflow", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input capture, after a Cancel."},
{"name": "Deskflow guide", "form": "deskflow/README.md", "what": "Opens the everyday use, recovery and restore boundaries."},
{"name": "network audit", "form": "deskflow/NETWORK-AUDIT.md", "what": "Opens the audit of what Deskflow connects to."},
{"name": "lockdown rules", "form": "deskflow/deskflow-lockdown.nft", "what": "Sets the nftables rules that lock down Deskflow's network; the dump does not say how they load."},
{"name": "Linux Deskflow settings", "form": "deskflow/linux.conf (~/.config/Deskflow/Deskflow.conf)", "what": "Sets Deskflow's settings for this Linux machine."},
{"name": "USB mouse notes", "form": "deskflow/usb-mouse/README.md", "what": "Opens the USB sharing notes, including how to turn the forwarded Windows USB mouse back on."},
{"name": "USB mouse service", "form": "deskflow/usb-mouse/deskflow-usb-mouse.service", "what": "Forwards the Windows USB mouse over USB/IP; disabled since 2026-10-20."},
{"name": "retired Lan Mouse guide", "form": "lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide, kept for rollback; do not run it next to Deskflow."},
{"name": "retired Lan Mouse controller", "form": "~/.local/bin/lan-mouse-controller", "what": "Opens the retired Lan Mouse controller: KVM now, start at login, retry input access."}
]},
{"path": ["windows"], "sentence": "Rebuilding and syncing the Windows machine: the bootstrap, the cloned work repos, the skill sync and the clipboard script.", "rows": [
{"name": "install Windows", "form": "init-windows/Start-Install.cmd", "what": "Installs the pinned programs, Node versions, VS Code extensions and user scripts; approve the admin prompt."},
{"name": "verify Windows", "form": "init-windows/Verify-Windows.ps1 (also Smoke-Test-Windows.ps1)", "what": "Checks that the install matches the manifests."},
{"name": "remove Windows pack", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Rolls back the install using its journal."},
{"name": "init-windows guide", "form": "init-windows/README.md", "what": "Opens the full guide to the Windows bootstrap."},
{"name": "captured inventory", "form": "init-windows/inventory.md", "what": "Opens the list of what was captured."},
{"name": "sign-ins to redo", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand and the credentials to rotate."},
{"name": "Windows user scripts", "form": "init-windows/user-scripts/", "what": "Opens the Windows user scripts (hibernate, touchpad fixes), copied to %USERPROFILE%\\Scripts."},
{"name": "clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones every missing Betec repo into the workspace layout; existing folders are left alone."},
{"name": "skill sync", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Fast-forwards the Windows my-skills checkout and relinks the three skill folders; runs when master is pushed."},
{"name": "skill sync guide", "form": "skills-sync-windows/README.md", "what": "Opens the sync guide: the runner, the install and what it may touch."},
{"name": "skill sync tests", "form": "skills-sync-windows/Test-Sync.ps1", "what": "Runs the sync tests."},
{"name": "Windows global instructions", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows desktop's global Claude instructions."},
{"name": "Windows desktop snapshot", "form": "claude/backups/desktop-v2-2026/", "what": "Opens the portable snapshot of the Windows desktop's instructions and skills; it is not loaded automatically."},
{"name": "Windows config deploy", "form": "claude/CLAUDE.md, claude/settings.json, codex/config.toml", "what": "Deploys the Claude and Codex config files to Windows through init-windows."},
{"name": "clipstack Windows install", "form": "clipstack/windows/install.ps1", "what": "Installs the Windows clipboard script, clipstack.ahk."}
]},
{"path": ["documents"], "sentence": "The documents kept here: CVs, case studies, plans, design research, and the notes on where things land.", "rows": [
{"name": "CV guide", "form": "cv/README.md", "what": "Opens the CV guide: the three versions, their sources and the pdflatex rebuild."},
{"name": "CV versions", "form": "cv/versions/", "what": "Opens the dated CV versions."},
{"name": "case studies", "form": "case-studies/", "what": "Opens the archived experiments, one folder each."},
{"name": "codebot-return case", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/README.md", "what": "Opens the codebot-return case: the same request with and without the skill."},
{"name": "signal-garden case", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "Opens the signal-garden exhibit: durable explanation apart from the live interface."},
{"name": "plans", "form": "docs/plans/", "what": "Opens the dated plans for each change."},
{"name": "items", "form": "docs/items/", "what": "Opens the planned, urgent and work items."},
{"name": "incident index", "form": "reference/README.md", "what": "Opens the index of dated incident records."},
{"name": "where things land", "form": "README.md#where-things-land", "what": "Opens the table of which repo file lands on which machine path."},
{"name": "conventions and gotchas", "form": "README.md#conventions-and-gotchas", "what": "Opens the copy, machine-path and credential conventions, including the known issue in zsh.d."}
]}
],
"questions": [
"Split the Machine screen (13 rows) into 'power' and 'repairs' screens? Recommend yes: power = CPU, lid and keep-alive; repairs = the four fix-* commands plus the network and display scripts. Audio, clipstack and incidents stay on Machine.",
"Which name do you type? The README uses workstation, ws and setup. Recommend ws as the typed name, workstation as the full name, and dropping setup as too generic. I will check each against whence -a at build time.",
"Show the retired items (Lan Mouse, older Codex browser path) inline, or behind a 'retired' screen? Recommend a retired screen under Deskflow for Lan Mouse, with the Codex path noted on the Browser screen.",
"May I read the files missing from the dump at build time: workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, and the clipstack README? Recommend yes; their rows are marked as taken from the README until then.",
"What do dash-path-warn.zsh, team-park, and the core-rules and team-activity hooks actually do? Recommend you describe them, or I read the files at build time. Until then their rows say only what the name or README shows."
]}
```

screen-decomposition, final · run 4 exit=0 seconds=260 · prompt

P1 Recall: 0.971P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.334
As terminal help
The map of everything this workstation holds, grouped by what you are trying to do.
Shell and git (Linux)workstation shellOpens the shell screen: zsh helpers, git settings and git hooks.
Machine utilities (Linux)workstation machineOpens the machine screen: power, display, network, laptop and repair scripts, and the incident records.
Services on this machineworkstation servicesOpens the services screen: the dashboards, Deskflow, Hermes, Clipstack and the other background services.
Browser CLIworkstation browserOpens the browser screen: Chrome, the browser command and the smoke test.
AI assistant setupworkstation assistantOpens the assistant screen: global Claude and Codex settings, hooks, plugins, usage guard and OpenCode profiles.
Agent systemworkstation agentsOpens the agents screen: rules, the agent framework, roles, teams, skills and data.
Windows bootstrapworkstation windowsOpens the windows screen: the Windows install, skill sync and cloning the work repos.
Working documentsworkstation documentsOpens the documents screen: CVs, case studies, plans, designs and intents.
shell
The zsh helpers, git settings and git hooks this kit puts on this Linux machine.
git safetyzsh.d/git-safety.zsh (~/.zsh.d/)Asks [y/N] before a git checkout throws away unstaged changes.
infra helperszsh.d/infra.zsh (~/.zsh.d/)Loads the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
utils helperszsh.d/utils.zsh (~/.zsh.d/)Loads the terminal helpers (set-title, killport), IP aliases, lazy nvm, node, npm and npx, and Android, Java and Bun setup.
api keyszsh.d/api-keys.zsh (~/.zsh.d/)Exports the general-use keys from ~/.config/api-keys/env; that file stays out of Git.
api-keys-editapi-keys-editOpens ~/.config/api-keys/env in the editor.
review-openzsh.d/review-open.zsh (also ~/.local/bin/review-open)Opens a file for review, from zsh or from an agent.
dash-path-warnzsh.d/dash-path-warn.zsh (~/.zsh.d/)Warns about the PATH problem its check looks for; the README does not say more.
git config.gitconfig (~/.gitconfig)Sets the author identity, Git LFS, the credential store, http.postBuffer and core.hooksPath.
git hooksgit-hooks/ (~/.git-hooks/)Runs the Lefthook gates in every repo: approval note, no commits to main in a marked repo, and the scenario gate (scenario-gate.py).
workstationworkstation help (aliases ws, setup)Prints this map: the top screen, and a screen for each group.
Credentials known issueREADME.md, Conventions and gotchasReads the warning that the git URLs in infra.zsh and utils.zsh embed a credential to rotate.
machine
The power, display, network, laptop and repair scripts for this Linux machine, and its incident records.
cpu-min-powercpu-min-power.shSets the power-saver profile, turbo off and the CPU capped at 8%; asks for sudo.
cpu-normal-powercpu-normal-power.shSets the balanced profile, turbo on and the CPU cap back to 100%.
fix_old_monitor_hdmifix_old_monitor_hdmi.shSets the mode and refresh rate of the external HDMI or DP output with xrandr (defaults 1920x1080 at 59.88).
linux-internet-recoverylinux-internet-recovery.shRepairs DNS, restarts NetworkManager and cycles networking; reruns itself with sudo.
recover-tailscale-remote-terminalrecover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, then starts remote-terminal and checks port 3500.
keep-running-with-lid-closedlaptop-utilities/keep-running-with-lid-closed.shWrites the logind drop-in so closing the lid does nothing; applies after reboot.
restore-default-lid-behaviorlaptop-utilities/restore-default-lid-behavior.shRemoves that drop-in; applies after reboot.
fix-keyboardfix-keyboard (zsh.d/utils.zsh)Runs the keyboard repair.
fix-mousefix-mouse (zsh.d/utils.zsh)Runs the mouse repair.
fix-diskfix-disk (zsh.d/utils.zsh)Runs the disk repair.
fix-whatsappfix-whatsapp (zsh.d/utils.zsh)Runs the WhatsApp repair.
Incidentsworkstation machine incidentsOpens the incident records: dated machine failures and their verified fixes.
machine › incidents
The dated incident records for this machine, each with the state it was verified in.
2026-10-01 CodeBot with lid closedreference/incidents/2026-10-01-codebot-lid-closed.mdReads the closed-lid test: it passed for 1 minute 46 seconds with Wi-Fi, CodeBot and Tailscale healthy.
Reference indexreference/README.mdOpens the index of incident cases and their outcomes.
services
The services and tools that run on this machine: their folders, what they serve, and how to start them.
Dashboardworkstation services dashboardOpens the dashboard screen: both dashboard versions, their servers and checks.
Deskflowworkstation services deskflowOpens the Deskflow screen: the shared mouse and laptop keyboard setup.
Hermesworkstation services hermesOpens the Hermes screen: its launcher, example settings and restore steps.
Clipstackworkstation services clipstackOpens the clipstack screen: the clipboard server, picker and Windows side.
Supabase keepalivesupabase-keepalive/install.shInstalls the timer and service that run supabase-keepalive.sh.
audio-startaudio-start (zsh.d/audio-share.zsh)Starts sending all Linux audio to the Windows machine over Tailscale.
audio-pauseaudio-pause (zsh.d/audio-share.zsh)Pauses that sending and restores the speakers.
audio-shareaudio-share on|off|status|toneSets the audio share on or off, shows its status, or plays a test tone.
services › dashboard
The two dashboard versions on this machine: their servers, page, checks, fonts and screenshots.
dashboard serverpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard at http://127.0.0.1:8780, or on the port you pass.
dashboard pagedashboard/index.htmlOpens the page the server serves; the open page reloads when it or server.py changes.
dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the 199 dashboard checks against the real data and a real server.
dashboard snapshotdashboard/snapshot.pyRuns snapshot.py; the README does not say what it writes.
dashboard fonts and screenshotsdashboard/fonts/ and dashboard/shots/Opens the IBM Plex fonts the page uses and the screenshots of its views.
Dashboard, concepts versionpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the second version at http://127.0.0.1:8781, with its Projects panel in the bottom-right corner.
concepts checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the 17 concepts checks.
services › deskflow
The Deskflow setup that shares one mouse and the laptop keyboard between this laptop and the Windows PC.
Deskflow serverdeskflow/deskflow.service (~/.config/systemd/user/)Runs the Linux Deskflow server with the graphical session; GNOME asks for input capture at each start.
Linux configdeskflow/linux.conf (~/.config/Deskflow/Deskflow.conf)Sets the Linux server's Deskflow configuration.
server configdeskflow/server.conf (~/.config/Deskflow/server.conf)Sets the server settings.
keyboard layoutdeskflow/deskflow.service.d/keyboard-layout.confSets the keyboard layout for the Deskflow service.
resume-kvmresume-kvm (location not in this dump)Starts Deskflow again and asks for input capture permission.
USB mouse sharingdeskflow/usb-mouse/README.mdOpens the notes for turning USB mouse sharing back on; it has been off since 2026-10-20.
network auditdeskflow/NETWORK-AUDIT.mdReads the Deskflow network audit.
lockdown rulesdeskflow/deskflow-lockdown.nftReads the lockdown rules; deskflow/README.md says how they apply (not in this dump).
Windows configsdeskflow/windows.conf and deskflow/windows-service.confSets the Windows client and service settings; copied by hand, see deskflow/README.md.
services › hermes
The Hermes agent on this machine: its launcher, example settings, backup record and restore steps.
hermes launcher~/.local/bin/hermes (source ~/projects/hermes-agent)Starts the Hermes agent.
PATH fragmenthermes/zprofile-path.zshAdds the Hermes launcher to PATH in ~/.zprofile, guarded.
default config examplehermes/default.config.example.yamlShows the default profile's settings, with no secrets.
jobs config examplehermes/jobs.config.example.yamlShows the jobs profile's settings, with no secrets.
restore runbookhermes/RESTORE.mdReads the steps to restore Hermes.
backup recordhermes/BACKUP-2026-10-02.mdReads the 2026-10-02 backup record.
install recordhermes/README.mdOpens the install and configuration record.
services › clipstack
The clipboard tool: its server, picker and watcher on Linux, and its AutoHotkey side on Windows.
clipstack serverclipstack/server.pyRuns the clipboard server.
pickerclipstack/picker.pyOpens the picker to choose an earlier clipboard item.
watcherclipstack/watcher.pyRuns the watcher that records clipboard changes.
installclipstack/install.shInstalls the server and watcher units.
unitsclipstack/units/ (clipstack-server.service, clipstack-watcher.service)Defines the server and watcher as user services.
Windows sideclipstack/windows/ (clipstack.ahk and its install, uninstall and verify scripts)Opens the Windows side: the AutoHotkey script and its scripts.
Windows testsclipstack/windows/tests/run-tests.ps1Runs the Windows clipstack tests.
server testsclipstack/test_server.pyRuns the server tests.
browser
Chrome, the browser command and the smoke test, for driving a browser or checking a page.
Chromechrome/chrome.sh (via ~/.local/bin/google-chrome)Starts Chrome with the flags in chrome/flags; the only way to start it.
Chrome installchrome/install.shLinks the Chrome commands to chrome.sh and rewrites the menu entry; run once per machine.
Chrome flagschrome/flagsSets the flags that chrome.sh and the browser command both read.
browserbrowser '<json steps>' (browser/browser.sh)Drives the one persistent Chrome window with a list of steps.
browser statusbrowser statusPrints whether the background server and Chrome are up.
browser closebrowser closeCloses Chrome and stops the server.
record proofbrowser recordStart and recordStop stepsStarts a tab recording as proof of a feature; recordStop ends it.
browser referencebrowser/README.mdOpens the full command reference: actions, viewports, network capture and login notes.
browser sourcebrowser/Opens the browser folder: cli.mjs and the server and step code it shares.
open-logged-inbrowser/open-logged-in.mjsOpens a page with the logged-in profile; not described in this dump, so the name is the only evidence.
smoke testjev-browser-test (command)Runs a goal against a browser and checks only the text and URL you give.
smoke test installjev-browser-test/install.shInstalls the CLI to ~/.local/bin, pinned to revision 1231850, and applies jev-ultrafast.patch.
smoke test keys~/.config/jev-browser-test/env (example: jev-browser-test/env.example)Sets the API keys the smoke test reads; the file stays out of Git.
smoke test instructionsjev-browser-test/instructions.mdReads the CLI's instructions.
assistant
The global Claude and Codex settings, their hooks, plugins and usage guard, and the OpenCode profiles.
Claude rulesclaude/CLAUDE.mdSets the global Claude instructions that init-windows deploys to Windows.
Claude agent notesclaude/AGENTS.mdSets the shorter global agent notes deployed to Windows.
Claude settingsclaude/settings.jsonSets Claude Code's settings, deployed to Windows.
Linux global mirrorclaude/linux-global/Opens the copies of the Linux machine's global instruction files.
Windows global mirrorclaude/windows-global/Opens the copies of the Windows Claude folder.
Backupsclaude/backups/Opens the dated snapshots of the instruction package; nothing installs them.
Communication draftclaude/communication-framework.mdReads the draft communication design; it is not enforced anywhere yet.
Skills shortlistclaude/skills-shortlist.mdReads the skills researched on skills.sh and what is installed.
Hooksworkstation assistant hooksOpens the hooks screen: the Claude hook scripts and where they are wired.
Modsworkstation assistant modsOpens the mods screen: the four Claude plugins kept here.
Session typesworkstation assistant session-typesOpens the session types screen: the start hook, the main session command and its design notes.
Usage guardworkstation assistant usage-guardOpens the usage guard screen: the wrapper that runs claude, its installers and tests.
Codexworkstation assistant codexOpens the Codex screen: its config, its direct Chrome path and the Chrome bridge.
OpenCode profilesworkstation assistant opencodeOpens the OpenCode screen: the commands that run and switch profiles, and their files.
assistant › hooks
The Claude hook scripts kept here, what runs each one, and their test.
core rules hookclaude/hooks/core-rules.sh (~/.claude/hooks/)Runs at session start and before each Bash call, as wired in settings.json.
machine history hookclaude/hooks/machine-history.sh (~/.claude/hooks/)Runs from settings.json.
team activity hookclaude/hooks/team-activity.sh (~/.claude/hooks/)Runs from settings.json.
local server guardclaude/hooks/local-server-guard.py (~/.claude/hooks/)Runs before each Bash call, as wired in settings.json.
proof reminderclaude/hooks/proof-reminder.sh (~/.claude/hooks/)Runs after Edit, MultiEdit, Write and Bash calls, as a reminder.
core rules testsclaude/hooks/test_core_rules.shRuns the core-rules tests.
hook wiring~/.claude/settings.jsonOpens Claude's settings file, where these hooks are wired.
assistant › mods
The four Claude plugins kept here, each with its hooks, types, tests and design notes.
changelog paneclaude/mods/changelog-pane/Opens the changelog pane plugin: its hooks, types and tests.
review paneclaude/mods/review-pane/Opens the review pane plugin, with its design and flow notes in docs/.
scratchpad playgroundclaude/mods/scratchpad-playground/Opens the scratchpad plugin.
team boardclaude/mods/team-board/Opens the team board plugin and its tests.
assistant › session-types
Claude's session types: the start hook, the main session command, its tests and design notes.
session types hookclaude/session-types/session-types.sh (~/.claude/hooks/)Runs at session start, as a SessionStart hook.
main sessionsclaude/session-types/main-sessions.py (~/.claude/hooks/main-sessions.py)Continues or resumes the main session for claude --main -c and -r.
session types testsclaude/session-types/tests/run.shRuns the session-types tests.
session types guideclaude/session-types/README.mdOpens the session types guide.
design notesclaude/session-types/docs/design/Opens the design pitches for the changelog on the timeline and the picker views.
assistant › usage-guard
The usage guard: the wrapper that runs claude, its installers, its plugin, its tests and its resolved cases.
claude wrapper~/bin/claude (claude/usage-guard/claude)Starts Claude Code through the usage guard, ahead of the native claude.
installclaude/usage-guard/install.shInstalls the native Claude Code that the wrapper runs.
Windows installclaude/usage-guard/Install-Windows.cmdInstalls the Windows launcher (Install-Windows.ps1 and Launcher.cs).
pluginclaude/usage-guard/plugin/Opens the plugin's hooks and register.js, which use shared-usage.py.
usage guard testsclaude/usage-guard/tests/Runs test_request_budget.py and live-refresh.py.
usage guard guideclaude/usage-guard/README.mdOpens the usage guard guide.
resolved casesclaude/usage-guard/.bdd/qa/resolutions/Opens the two resolved QA cases: stale usage and request budget.
assistant › codex
Codex's config, its direct Chrome path, and the Chrome bridge that keeps it working.
Codex configcodex/config.toml (%USERPROFILE%/.codex/config.toml on Windows)Sets the Codex CLI config that init-windows deploys to Windows.
Codex Chrome pathcodex/browser/README.mdOpens the notes on Codex's direct Chrome command path and its live check.
tab recordercodex/browser/tab-recorder.mjsRecords a tab on Codex's path; for proof, use the browser command's recordStart instead.
tab recorder extensioncodex/browser/tab-recorder-extension/Opens the Chrome extension for the tab recorder.
Chrome bridge repaircodex/chrome-bridge/repair.mjsRepairs the Chrome plugin's latest link and reapplies the local file: patch.
bridge install (Linux)codex/chrome-bridge/install.shInstalls the systemd watcher and timer that run the repair.
bridge install (Windows)codex/chrome-bridge/Install-CodexChromeBridge.cmdInstalls a current-user Scheduled Task that runs the repair.
bridge notescodex/chrome-bridge/README.mdOpens the bridge's install and restart notes.
assistant › opencode
The OpenCode profiles: the commands that run and switch them, their help, files, tests and wiring.
opencodeopencode (alias oc)Runs opencode with the current profile.
opencode-profileopencode-profile <name>Names the current profile.
opencode-profilesopencode-profilesPrints what each profile loads.
opencode-switchopencode-switch <name>Switches every shell's new runs to that profile.
opencode-loginopencode-loginSigns a profile's Claude Code in.
opencode-filesopencode-filesLists the current profile's files.
opencode-editopencode-edit <file>Opens one of the current profile's files in the editor.
opencode helpopencode help (also oc help, opencode-help, oc-help)Prints every profile's files, one column per profile, and the commands; with more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it.
profile logicopencode-profiles/profiles.pyRuns the profile logic these commands call.
profile testsopencode-profiles/test_profiles.pyRuns the profile tests.
experimental profileopencode-profiles/private-leb-experimental/Opens the experimental profile's CLAUDE.md, settings and opencode.json.
OpenCode zsh wiringzsh.d/opencode-profiles.zshLoads these commands into zsh; ~/.bashrc sources it too.
agents
The agent system: the rules every session follows, the agent framework, roles and teams, skills and data.
rules commandrules [folder] (~/.local/bin/rules)Prints the rules that apply to a folder.
rules fileworkboard/rules.yamlOpens the rules; only the user or an accepted proposal (R43) changes them.
rule metadataworkboard/rules-meta.yamlOpens the metadata for each rule.
rules testsworkboard/test_rules.py and workboard/test_org_folder.pyRuns the rules checks.
rules shell helperszsh.d/rules.zshLoads the rules helpers into zsh.
Agent frameworkworkstation agents agent-frameworkOpens the agent framework screen: check, list, serve and its tests.
Roles~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.mdOpens the role skills each team member starts with.
Personas~/projects/my-skills/agents/<id>/claude.md and opencode.mdOpens an agent's Claude persona or OpenCode agent; my-skills/install.sh links them.
Teams~/projects/my-skills/spawn-team/SKILL.mdStarts a team: /spawn-team <team> in Claude, or $spawn-team in Codex.
Team messages~/projects/my-skills/coordinated-agentic-session/Opens how team members message each other.
team-parkclaude/team-park/team_park.py (~/.local/bin/team-park)Runs the team-park tool; its README says what it parks.
team-park testsclaude/team-park/test_team_park.pyRuns the team-park tests.
Skillsworkstation agents skillsOpens the skills screen: the global skills and the backups kept here.
Data~/projects/data/Opens the cases, rule proposals, verdicts and designs the agents write.
Answer sync~/projects/data/bin/{issue,pull,sync}Runs the answer sync; a timer runs it every 5 minutes.
Supervision backlog~/projects/betec/workboard/docs/supervision-backlog.mdOpens the supervision backlog.
Archive~/archive/Opens the archive of moved files and test evidence; it is not backed up.
agents › agent-framework
The agent framework: its check, list and serve commands, its tests, and the Agent Sandbox page.
agent checkagent-framework/agent checkRefuses broken agent records, with exit 1.
agent listagent-framework/agent listPrints the agents, their tier, model and number of tests.
agent serveagent-framework/agent serveStarts the Agent Sandbox page at http://127.0.0.1:8790.
agent codeagent-framework/agentkit.pyRuns the code behind check, list and serve.
sandbox pageagent-framework/sandbox/ (index.html, server.py)Opens the Agent Sandbox page's files.
saved runagent-framework/fixtures/run-prd-writer-qa-agent.jsonOpens a saved run of the PRD writer QA agent.
framework testsagent-framework/test_agentkit.py and agent-framework/test_server.pyRuns the agent framework tests.
framework guideagent-framework/README.mdOpens the framework guide: the sandbox, its modes and its words.
agent records~/projects/my-skills/agents/<id>/agent.yamlOpens an agent's record: its setup, situations and tests.
agent results and memory~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/Opens an agent's eval results and memory.
agents › skills
The skills this machine uses: the global skills from my-skills and the backups kept in this repo.
supabase~/projects/my-skills/supabase/Opens the skill for Supabase Auth, RLS, migrations and debugging.
supabase-postgres-best-practices~/projects/my-skills/supabase-postgres-best-practices/Opens the skill with Supabase's Postgres performance rules.
clone-website~/projects/my-skills/clone-website/Opens the skill for cloning a website with parallel builder agents.
lab-experiment~/projects/my-skills/lab-experiment/Opens the skill for running an experiment in ai-lab.
coding-guidelines~/projects/my-skills/coding-guidelines/Opens the house coding rules.
volatility-based-decomposition~/projects/my-skills/volatility-based-decomposition/Opens the skill for decomposing systems around independently changing decisions.
working-with-windows~/projects/my-skills/working-with-windows/Opens the Windows gotchas for Node MCP servers that call PowerShell.
solaraai skills~/projects/my-skills/solaraai-content-calendar, solaraai-deployment, solaraai-design, solaraai-formsOpens the four SolaraAI skills: content calendar, deployment, design system and form behavior.
skill backupsclaude/skills/ (23 skill folders)Opens the folder of skill backups; copy the wanted one into ~/.claude/skills.
windows
The Windows setup: the bootstrap that rebuilds the environment, the skill sync, and cloning the work repos.
Installinit-windows/Start-Install.cmdInstalls the environment from the manifests; asks for administrator approval.
Checksinit-windows/Smoke-Test-Windows.ps1 and init-windows/Verify-Windows.ps1Runs the checks on the installed environment.
Roll backinit-windows/Remove-WindowsPack.ps1Removes what the install added, using its journal.
Exportinit-windows/Export-Windows.ps1Exports the current machine's state into the manifests.
Manifestsinit-windows/manifests/Opens the exact versions: programs, Node, VS Code extensions and managed files.
Configsinit-windows/configs/Opens the git and VS Code configs that get copied in.
User scriptsinit-windows/user-scripts/Opens the user scripts that get copied to %USERPROFILE%/Scripts.
Install codeinit-windows/lib/Opens the install code, one file per program or area.
Inventoryinit-windows/inventory.mdOpens the list of what the first capture found.
Sign-insinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand, and the credential to rotate.
Install logsinit-windows/logs/Opens the install and error logs.
Install guideinit-windows/README.mdOpens the full install guide.
Skill syncworkstation windows skills-syncOpens the skill sync screen.
Cloning the work reposrepos/Clone-BetecRepos.ps1Clones each missing Betec repo; leaves existing folders alone.
windows › skills-sync
The Windows skill sync: the runner, the scheduled catch-up, its scripts, and the last success record.
sync scriptskills-sync-windows/Sync-Skills.ps1Updates the Windows skill checkout from master and relinks; runs on each push.
runner serviceactions.runner.Lebnor-my-skills.my-skills-liel-windowsRuns the GitHub runner that starts a sync on each trusted push to master.
catch-up taskMySkillsSync-CatchUp (Windows scheduled task)Runs the sync once after startup, with three retries on failure.
last successC:/ProgramData/MySkillsSync/state/last-success.jsonReads when the last sync succeeded.
account testskills-sync-windows/Test-Account.ps1Checks the runner account's rights.
sync testskills-sync-windows/Test-Sync.ps1Tests the sync script.
verificationskills-sync-windows/verification.mdReads how the sync was verified.
sync guideskills-sync-windows/README.mdOpens the sync's components, permissions and risks.
documents
The working documents: CVs, case studies, plans and designs, intents, features, and the research behind them.
CVsworkstation documents cvOpens the CV screen: the three CVs, their sources and rebuilds.
Case studiesworkstation documents case-studiesOpens the case studies screen: the archived, reviewed experiments.
Working documentsworkstation documents docsOpens the docs screen: plans, designs, flows, research, roles, items and changelog.
Project intent.idd/project.intent.mdReads the project's own intent.
Module intents.idd/modules/Opens each module's intent: what it must do, and the checks for it.
Features.bdd/features/Opens the feature files: the behavior the checks follow, in Given, When, Then.
QA findings.bdd/qa/findings/Opens the QA findings from the 2026-10-25 say-the-thing check.
Screenshotscopy/ (1-today.webp, 2-subsystems.webp, 3-reviews.webp)Opens three screenshots: today, subsystems and reviews.
documents › cv
The three CVs: their PDFs, their sources, the shared parts, and how they are rebuilt.
Full Stack Developer CVcv/cv-full-stack.pdf (source cv/cv-full-stack.tex)Opens the Full Stack Developer CV as a PDF.
AI Full Stack Engineer CVcv/cv-ai-full-stack.pdf (source cv/cv-ai-full-stack.tex)Opens the AI Full Stack Engineer CV as a PDF.
AI Integrations CVcv/cv-ai-integrations.pdf (source cv/cv-ai-integrations.tex)Opens the AI Integrations CV as a PDF.
rebuild a CVpdflatex -interaction=nonstopmode -halt-on-error <name>.tex (in cv/)Rebuilds one CV PDF from its .tex source.
shared partscv/cv-details.tex, cv-work-experience.tex, cv-codebot.tex, cv-layout.texOpens the parts that all three CVs share.
factual inputcv/experience-notes.mdOpens the facts the CVs are built from.
readable mastercv/cv-master.mdOpens the readable master copy of the CV.
drafting decisionscv/cv-material-draft.mdOpens the drafting decisions.
CV workflowcv/WORKFLOW.mdOpens the CV workflow.
plain-text versionscv/text/build-full.shBuilds the plain-text versions of the CVs.
HTML designcv/design/build-design.pyBuilds the HTML design of the CV.
dated versionscv/versions/ (2026-10-04 and 2026-10-04-v2)Opens the dated CV versions.
old CV path~/projects/tech-cv-workspace/Opens the CVs through their old path, which Hermes still uses through compatibility symlinks.
documents › case-studies
The archived, human-reviewed experiments, each in its own dated folder.
CodeBot returncase-studies/conceptual-modeling/2026-09-15-codebot-return/Opens the same design request run with and without the conceptual-modeling skill, with runs, images and the skill snapshot.
Signal gardencase-studies/blume-astryx/2026-09-16-signal-garden/README.mdOpens the exhibit's notes: durable explanation apart from the live interface.
Kernel cloud browser results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the results on cloud browser use cases, speed against local Chrome, and session recording.
documents › docs
The project's working documents by kind: plans, designs, flows, research, roles, items and changelog.
plansdocs/plans/Opens the dated plans, one folder per change.
designsdocs/design/Opens the dated design pitches, research and recommendations.
design referencesdocs/design-references/Opens the dashboard design mockups kept as references.
flowsdocs/flows/Opens the dated flow cards and data models.
researchdocs/research/Opens the dated research, including the phase-1 check test.
functional researchdocs/functional-research/2026-10-21/Opens the comparisons of agent frameworks and subagent tools.
rolesdocs/roles/Opens the qa-agent role and the 2026-10-23 role drafts.
itemsdocs/items/Opens the planned, urgent and work items.
changelogdocs/changelog/Opens the dated changelog entries.
playbooksdocs/playbooks/Opens the playbook for talking while the team builds.
Superpowers plansdocs/superpowers/plans/Opens the older Superpowers plan for the usage guard.
Questions
  • Several things the README describes are not in the file list: workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, resume-kvm, browser/server.mjs, steps.mjs and recorder.mjs, cv/experience-notes.md, cv/cv-master.md, cv/cv-material-draft.md, init-windows/inventory.md, and the remote-terminal service. Are they untracked, moved, or gone? Recommendation: check each on disk before the build; keep the rows as the README describes them until then.
  • Skill backups: keep one folder row for claude/skills/ (23 folders), or one row per skill? The README table lists only 12 of them. Recommendation: keep the folder row now, and go per skill only once you say which backups you keep.
  • Dashboard and dashboard-concepts: one screen holding both versions, or two screens? Recommendation: one screen, since the README calls the second a comparison of the first.
  • Confirm the retirements stay off the map: lan-mouse (retired 2026-10-05), codex/playwright-mcp (retired), and docs/roles/drafts-2026-10-23/.old. Recommendation: keep them off, as your own notes retire them.
  • The alias setup is generic and may clash with another command. Keep it? Recommendation: keep workstation and ws; keep setup only if whence -a setup shows no clash in zsh and bash.
As phone screens

Home

The map of everything this workstation holds, grouped by what you are trying to do.

Shell and git (Linux)Opens the shell screen: zsh helpers, git settings and git hooks.
›
Machine utilities (Linux)Opens the machine screen: power, display, network, laptop and repair scripts, and the incident records.
›
Services on this machineOpens the services screen: the dashboards, Deskflow, Hermes, Clipstack and the other background services.
›
Browser CLIOpens the browser screen: Chrome, the browser command and the smoke test.
›
AI assistant setupOpens the assistant screen: global Claude and Codex settings, hooks, plugins, usage guard and OpenCode profiles.
›
Agent systemOpens the agents screen: rules, the agent framework, roles, teams, skills and data.
›
Windows bootstrapOpens the windows screen: the Windows install, skill sync and cloning the work repos.
›
Working documentsOpens the documents screen: CVs, case studies, plans, designs and intents.
›
‹ Home

shell

The zsh helpers, git settings and git hooks this kit puts on this Linux machine.

git safetyAsks [y/N] before a git checkout throws away unstaged changes.
›
infra helpersLoads the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
›
utils helpersLoads the terminal helpers (set-title, killport), IP aliases, lazy nvm, node, npm and npx, and Android, Java and Bun setup.
›
api keysExports the general-use keys from ~/.config/api-keys/env; that file stays out of Git.
›
api-keys-editOpens ~/.config/api-keys/env in the editor.
›
review-openOpens a file for review, from zsh or from an agent.
›
dash-path-warnWarns about the PATH problem its check looks for; the README does not say more.
›
git configSets the author identity, Git LFS, the credential store, http.postBuffer and core.hooksPath.
›
git hooksRuns the Lefthook gates in every repo: approval note, no commits to main in a marked repo, and the scenario gate (scenario-gate.py).
›
workstationPrints this map: the top screen, and a screen for each group.
›
Credentials known issueReads the warning that the git URLs in infra.zsh and utils.zsh embed a credential to rotate.
›
‹ Home

machine

The power, display, network, laptop and repair scripts for this Linux machine, and its incident records.

cpu-min-powerSets the power-saver profile, turbo off and the CPU capped at 8%; asks for sudo.
›
cpu-normal-powerSets the balanced profile, turbo on and the CPU cap back to 100%.
›
fix_old_monitor_hdmiSets the mode and refresh rate of the external HDMI or DP output with xrandr (defaults 1920x1080 at 59.88).
›
linux-internet-recoveryRepairs DNS, restarts NetworkManager and cycles networking; reruns itself with sudo.
›
recover-tailscale-remote-terminalRepairs DNS, restarts tailscaled, then starts remote-terminal and checks port 3500.
›
keep-running-with-lid-closedWrites the logind drop-in so closing the lid does nothing; applies after reboot.
›
restore-default-lid-behaviorRemoves that drop-in; applies after reboot.
›
fix-keyboardRuns the keyboard repair.
›
fix-mouseRuns the mouse repair.
›
fix-diskRuns the disk repair.
›
fix-whatsappRuns the WhatsApp repair.
›
IncidentsOpens the incident records: dated machine failures and their verified fixes.
›
‹ machine

incidents

The dated incident records for this machine, each with the state it was verified in.

2026-10-01 CodeBot with lid closedReads the closed-lid test: it passed for 1 minute 46 seconds with Wi-Fi, CodeBot and Tailscale healthy.
›
Reference indexOpens the index of incident cases and their outcomes.
›
‹ Home

services

The services and tools that run on this machine: their folders, what they serve, and how to start them.

DashboardOpens the dashboard screen: both dashboard versions, their servers and checks.
›
DeskflowOpens the Deskflow screen: the shared mouse and laptop keyboard setup.
›
HermesOpens the Hermes screen: its launcher, example settings and restore steps.
›
ClipstackOpens the clipstack screen: the clipboard server, picker and Windows side.
›
Supabase keepaliveInstalls the timer and service that run supabase-keepalive.sh.
›
audio-startStarts sending all Linux audio to the Windows machine over Tailscale.
›
audio-pausePauses that sending and restores the speakers.
›
audio-shareSets the audio share on or off, shows its status, or plays a test tone.
›
‹ services

dashboard

The two dashboard versions on this machine: their servers, page, checks, fonts and screenshots.

dashboard serverStarts the dashboard at http://127.0.0.1:8780, or on the port you pass.
›
dashboard pageOpens the page the server serves; the open page reloads when it or server.py changes.
›
dashboard checksRuns the 199 dashboard checks against the real data and a real server.
›
dashboard snapshotRuns snapshot.py; the README does not say what it writes.
›
dashboard fonts and screenshotsOpens the IBM Plex fonts the page uses and the screenshots of its views.
›
Dashboard, concepts versionStarts the second version at http://127.0.0.1:8781, with its Projects panel in the bottom-right corner.
›
concepts checksRuns the 17 concepts checks.
›
‹ services

deskflow

The Deskflow setup that shares one mouse and the laptop keyboard between this laptop and the Windows PC.

Deskflow serverRuns the Linux Deskflow server with the graphical session; GNOME asks for input capture at each start.
›
Linux configSets the Linux server's Deskflow configuration.
›
server configSets the server settings.
›
keyboard layoutSets the keyboard layout for the Deskflow service.
›
resume-kvmStarts Deskflow again and asks for input capture permission.
›
USB mouse sharingOpens the notes for turning USB mouse sharing back on; it has been off since 2026-10-20.
›
network auditReads the Deskflow network audit.
›
lockdown rulesReads the lockdown rules; deskflow/README.md says how they apply (not in this dump).
›
Windows configsSets the Windows client and service settings; copied by hand, see deskflow/README.md.
›
‹ services

hermes

The Hermes agent on this machine: its launcher, example settings, backup record and restore steps.

hermes launcherStarts the Hermes agent.
›
PATH fragmentAdds the Hermes launcher to PATH in ~/.zprofile, guarded.
›
default config exampleShows the default profile's settings, with no secrets.
›
jobs config exampleShows the jobs profile's settings, with no secrets.
›
restore runbookReads the steps to restore Hermes.
›
backup recordReads the 2026-10-02 backup record.
›
install recordOpens the install and configuration record.
›
‹ services

clipstack

The clipboard tool: its server, picker and watcher on Linux, and its AutoHotkey side on Windows.

clipstack serverRuns the clipboard server.
›
pickerOpens the picker to choose an earlier clipboard item.
›
watcherRuns the watcher that records clipboard changes.
›
installInstalls the server and watcher units.
›
unitsDefines the server and watcher as user services.
›
Windows sideOpens the Windows side: the AutoHotkey script and its scripts.
›
Windows testsRuns the Windows clipstack tests.
›
server testsRuns the server tests.
›
‹ Home

browser

Chrome, the browser command and the smoke test, for driving a browser or checking a page.

ChromeStarts Chrome with the flags in chrome/flags; the only way to start it.
›
Chrome installLinks the Chrome commands to chrome.sh and rewrites the menu entry; run once per machine.
›
Chrome flagsSets the flags that chrome.sh and the browser command both read.
›
browserDrives the one persistent Chrome window with a list of steps.
›
browser statusPrints whether the background server and Chrome are up.
›
browser closeCloses Chrome and stops the server.
›
record proofStarts a tab recording as proof of a feature; recordStop ends it.
›
browser referenceOpens the full command reference: actions, viewports, network capture and login notes.
›
browser sourceOpens the browser folder: cli.mjs and the server and step code it shares.
›
open-logged-inOpens a page with the logged-in profile; not described in this dump, so the name is the only evidence.
›
smoke testRuns a goal against a browser and checks only the text and URL you give.
›
smoke test installInstalls the CLI to ~/.local/bin, pinned to revision 1231850, and applies jev-ultrafast.patch.
›
smoke test keysSets the API keys the smoke test reads; the file stays out of Git.
›
smoke test instructionsReads the CLI's instructions.
›
‹ Home

assistant

The global Claude and Codex settings, their hooks, plugins and usage guard, and the OpenCode profiles.

Claude rulesSets the global Claude instructions that init-windows deploys to Windows.
›
Claude agent notesSets the shorter global agent notes deployed to Windows.
›
Claude settingsSets Claude Code's settings, deployed to Windows.
›
Linux global mirrorOpens the copies of the Linux machine's global instruction files.
›
Windows global mirrorOpens the copies of the Windows Claude folder.
›
BackupsOpens the dated snapshots of the instruction package; nothing installs them.
›
Communication draftReads the draft communication design; it is not enforced anywhere yet.
›
Skills shortlistReads the skills researched on skills.sh and what is installed.
›
HooksOpens the hooks screen: the Claude hook scripts and where they are wired.
›
ModsOpens the mods screen: the four Claude plugins kept here.
›
Session typesOpens the session types screen: the start hook, the main session command and its design notes.
›
Usage guardOpens the usage guard screen: the wrapper that runs claude, its installers and tests.
›
CodexOpens the Codex screen: its config, its direct Chrome path and the Chrome bridge.
›
OpenCode profilesOpens the OpenCode screen: the commands that run and switch profiles, and their files.
›
‹ assistant

hooks

The Claude hook scripts kept here, what runs each one, and their test.

core rules hookRuns at session start and before each Bash call, as wired in settings.json.
›
machine history hookRuns from settings.json.
›
team activity hookRuns from settings.json.
›
local server guardRuns before each Bash call, as wired in settings.json.
›
proof reminderRuns after Edit, MultiEdit, Write and Bash calls, as a reminder.
›
core rules testsRuns the core-rules tests.
›
hook wiringOpens Claude's settings file, where these hooks are wired.
›
‹ assistant

mods

The four Claude plugins kept here, each with its hooks, types, tests and design notes.

changelog paneOpens the changelog pane plugin: its hooks, types and tests.
›
review paneOpens the review pane plugin, with its design and flow notes in docs/.
›
scratchpad playgroundOpens the scratchpad plugin.
›
team boardOpens the team board plugin and its tests.
›
‹ assistant

session-types

Claude's session types: the start hook, the main session command, its tests and design notes.

session types hookRuns at session start, as a SessionStart hook.
›
main sessionsContinues or resumes the main session for claude --main -c and -r.
›
session types testsRuns the session-types tests.
›
session types guideOpens the session types guide.
›
design notesOpens the design pitches for the changelog on the timeline and the picker views.
›
‹ assistant

usage-guard

The usage guard: the wrapper that runs claude, its installers, its plugin, its tests and its resolved cases.

claude wrapperStarts Claude Code through the usage guard, ahead of the native claude.
›
installInstalls the native Claude Code that the wrapper runs.
›
Windows installInstalls the Windows launcher (Install-Windows.ps1 and Launcher.cs).
›
pluginOpens the plugin's hooks and register.js, which use shared-usage.py.
›
usage guard testsRuns test_request_budget.py and live-refresh.py.
›
usage guard guideOpens the usage guard guide.
›
resolved casesOpens the two resolved QA cases: stale usage and request budget.
›
‹ assistant

codex

Codex's config, its direct Chrome path, and the Chrome bridge that keeps it working.

Codex configSets the Codex CLI config that init-windows deploys to Windows.
›
Codex Chrome pathOpens the notes on Codex's direct Chrome command path and its live check.
›
tab recorderRecords a tab on Codex's path; for proof, use the browser command's recordStart instead.
›
tab recorder extensionOpens the Chrome extension for the tab recorder.
›
Chrome bridge repairRepairs the Chrome plugin's latest link and reapplies the local file: patch.
›
bridge install (Linux)Installs the systemd watcher and timer that run the repair.
›
bridge install (Windows)Installs a current-user Scheduled Task that runs the repair.
›
bridge notesOpens the bridge's install and restart notes.
›
‹ assistant

opencode

The OpenCode profiles: the commands that run and switch them, their help, files, tests and wiring.

opencodeRuns opencode with the current profile.
›
opencode-profileNames the current profile.
›
opencode-profilesPrints what each profile loads.
›
opencode-switchSwitches every shell's new runs to that profile.
›
opencode-loginSigns a profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editOpens one of the current profile's files in the editor.
›
opencode helpPrints every profile's files, one column per profile, and the commands; with more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it.
›
profile logicRuns the profile logic these commands call.
›
profile testsRuns the profile tests.
›
experimental profileOpens the experimental profile's CLAUDE.md, settings and opencode.json.
›
OpenCode zsh wiringLoads these commands into zsh; ~/.bashrc sources it too.
›
‹ Home

agents

The agent system: the rules every session follows, the agent framework, roles and teams, skills and data.

rules commandPrints the rules that apply to a folder.
›
rules fileOpens the rules; only the user or an accepted proposal (R43) changes them.
›
rule metadataOpens the metadata for each rule.
›
rules testsRuns the rules checks.
›
rules shell helpersLoads the rules helpers into zsh.
›
Agent frameworkOpens the agent framework screen: check, list, serve and its tests.
›
RolesOpens the role skills each team member starts with.
›
PersonasOpens an agent's Claude persona or OpenCode agent; my-skills/install.sh links them.
›
TeamsStarts a team: /spawn-team <team> in Claude, or $spawn-team in Codex.
›
Team messagesOpens how team members message each other.
›
team-parkRuns the team-park tool; its README says what it parks.
›
team-park testsRuns the team-park tests.
›
SkillsOpens the skills screen: the global skills and the backups kept here.
›
DataOpens the cases, rule proposals, verdicts and designs the agents write.
›
Answer syncRuns the answer sync; a timer runs it every 5 minutes.
›
Supervision backlogOpens the supervision backlog.
›
ArchiveOpens the archive of moved files and test evidence; it is not backed up.
›
‹ agents

agent-framework

The agent framework: its check, list and serve commands, its tests, and the Agent Sandbox page.

agent checkRefuses broken agent records, with exit 1.
›
agent listPrints the agents, their tier, model and number of tests.
›
agent serveStarts the Agent Sandbox page at http://127.0.0.1:8790.
›
agent codeRuns the code behind check, list and serve.
›
sandbox pageOpens the Agent Sandbox page's files.
›
saved runOpens a saved run of the PRD writer QA agent.
›
framework testsRuns the agent framework tests.
›
framework guideOpens the framework guide: the sandbox, its modes and its words.
›
agent recordsOpens an agent's record: its setup, situations and tests.
›
agent results and memoryOpens an agent's eval results and memory.
›
‹ agents

skills

The skills this machine uses: the global skills from my-skills and the backups kept in this repo.

supabaseOpens the skill for Supabase Auth, RLS, migrations and debugging.
›
supabase-postgres-best-practicesOpens the skill with Supabase's Postgres performance rules.
›
clone-websiteOpens the skill for cloning a website with parallel builder agents.
›
lab-experimentOpens the skill for running an experiment in ai-lab.
›
coding-guidelinesOpens the house coding rules.
›
volatility-based-decompositionOpens the skill for decomposing systems around independently changing decisions.
›
working-with-windowsOpens the Windows gotchas for Node MCP servers that call PowerShell.
›
solaraai skillsOpens the four SolaraAI skills: content calendar, deployment, design system and form behavior.
›
skill backupsOpens the folder of skill backups; copy the wanted one into ~/.claude/skills.
›
‹ Home

windows

The Windows setup: the bootstrap that rebuilds the environment, the skill sync, and cloning the work repos.

InstallInstalls the environment from the manifests; asks for administrator approval.
›
ChecksRuns the checks on the installed environment.
›
Roll backRemoves what the install added, using its journal.
›
ExportExports the current machine's state into the manifests.
›
ManifestsOpens the exact versions: programs, Node, VS Code extensions and managed files.
›
ConfigsOpens the git and VS Code configs that get copied in.
›
User scriptsOpens the user scripts that get copied to %USERPROFILE%/Scripts.
›
Install codeOpens the install code, one file per program or area.
›
InventoryOpens the list of what the first capture found.
›
Sign-insOpens the sign-ins to redo by hand, and the credential to rotate.
›
Install logsOpens the install and error logs.
›
Install guideOpens the full install guide.
›
Skill syncOpens the skill sync screen.
›
Cloning the work reposClones each missing Betec repo; leaves existing folders alone.
›
‹ windows

skills-sync

The Windows skill sync: the runner, the scheduled catch-up, its scripts, and the last success record.

sync scriptUpdates the Windows skill checkout from master and relinks; runs on each push.
›
runner serviceRuns the GitHub runner that starts a sync on each trusted push to master.
›
catch-up taskRuns the sync once after startup, with three retries on failure.
›
last successReads when the last sync succeeded.
›
account testChecks the runner account's rights.
›
sync testTests the sync script.
›
verificationReads how the sync was verified.
›
sync guideOpens the sync's components, permissions and risks.
›
‹ Home

documents

The working documents: CVs, case studies, plans and designs, intents, features, and the research behind them.

CVsOpens the CV screen: the three CVs, their sources and rebuilds.
›
Case studiesOpens the case studies screen: the archived, reviewed experiments.
›
Working documentsOpens the docs screen: plans, designs, flows, research, roles, items and changelog.
›
Project intentReads the project's own intent.
›
Module intentsOpens each module's intent: what it must do, and the checks for it.
›
FeaturesOpens the feature files: the behavior the checks follow, in Given, When, Then.
›
QA findingsOpens the QA findings from the 2026-10-25 say-the-thing check.
›
ScreenshotsOpens three screenshots: today, subsystems and reviews.
›
‹ documents

cv

The three CVs: their PDFs, their sources, the shared parts, and how they are rebuilt.

Full Stack Developer CVOpens the Full Stack Developer CV as a PDF.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV as a PDF.
›
AI Integrations CVOpens the AI Integrations CV as a PDF.
›
rebuild a CVRebuilds one CV PDF from its .tex source.
›
shared partsOpens the parts that all three CVs share.
›
factual inputOpens the facts the CVs are built from.
›
readable masterOpens the readable master copy of the CV.
›
drafting decisionsOpens the drafting decisions.
›
CV workflowOpens the CV workflow.
›
plain-text versionsBuilds the plain-text versions of the CVs.
›
HTML designBuilds the HTML design of the CV.
›
dated versionsOpens the dated CV versions.
›
old CV pathOpens the CVs through their old path, which Hermes still uses through compatibility symlinks.
›
‹ documents

case-studies

The archived, human-reviewed experiments, each in its own dated folder.

CodeBot returnOpens the same design request run with and without the conceptual-modeling skill, with runs, images and the skill snapshot.
›
Signal gardenOpens the exhibit's notes: durable explanation apart from the live interface.
›
Kernel cloud browser resultsOpens the results on cloud browser use cases, speed against local Chrome, and session recording.
›
‹ documents

docs

The project's working documents by kind: plans, designs, flows, research, roles, items and changelog.

plansOpens the dated plans, one folder per change.
›
designsOpens the dated design pitches, research and recommendations.
›
design referencesOpens the dashboard design mockups kept as references.
›
flowsOpens the dated flow cards and data models.
›
researchOpens the dated research, including the phase-1 check test.
›
functional researchOpens the comparisons of agent frameworks and subagent tools.
›
rolesOpens the qa-agent role and the 2026-10-23 role drafts.
›
itemsOpens the planned, urgent and work items.
›
changelogOpens the dated changelog entries.
›
playbooksOpens the playbook for talking while the team builds.
›
Superpowers plansOpens the older Superpowers plan for the usage guard.
›
Raw answer
## Map plan: workstation

**Scenario** (from the README, not from a user report): the owner works on the Linux laptop. They reach for this kit when something on the machine breaks or needs setting up (display, power, network, mouse, lid, a git checkout mistake), or when they need an agent's rules, a CV PDF, or a plan.

**Judgment calls**
- **Eight top groups**, named from the README's own headings and words ("Services", "Working documents", "AI assistant setup").
- **Grouped by job**, not file type: machine fixes, services that run, agent setup, and so on.
- **Evidence and output folders** (`shots/`, `out/`, `prompts/`, run records, fonts) get one folder row each, not one row per file.
- **Off the map, as the owner left them:** `lan-mouse/` (retired 2026-10-05, superseded by Deskflow), `codex/playwright-mcp/` (retired; "does not install a browser server anymore"), and `docs/roles/drafts-2026-10-23/.old/` (the owner's own "old" drafts). Their files stay in the repo.
- **The lid-closed scripts** appear on the machine screen (to run) and in the incident record (to read). The two lines differ, since the reasons differ.
- **The facade** is `workstation`, with `ws` and `setup` as aliases, per the README. It is listed as an item on the shell screen, not as a group, so the top screen stays short.
- **Skill backups** are one folder row. The README's table covers 12 of the 23 folders, so per-skill rows need the owner's call (question 2).
- **Named but missing from the file list:** `workstation-cli/`, `zsh.d/workstation.zsh`, `audio-share/`, and others. I kept their rows as the README describes them and flagged them (question 1). The build step must check them on disk.

```json
{"screens": [
{"path": [], "sentence": "The map of everything this workstation holds, grouped by what you are trying to do.", "rows": [
{"name": "Shell and git (Linux)", "form": "workstation shell", "what": "Opens the shell screen: zsh helpers, git settings and git hooks."},
{"name": "Machine utilities (Linux)", "form": "workstation machine", "what": "Opens the machine screen: power, display, network, laptop and repair scripts, and the incident records."},
{"name": "Services on this machine", "form": "workstation services", "what": "Opens the services screen: the dashboards, Deskflow, Hermes, Clipstack and the other background services."},
{"name": "Browser CLI", "form": "workstation browser", "what": "Opens the browser screen: Chrome, the browser command and the smoke test."},
{"name": "AI assistant setup", "form": "workstation assistant", "what": "Opens the assistant screen: global Claude and Codex settings, hooks, plugins, usage guard and OpenCode profiles."},
{"name": "Agent system", "form": "workstation agents", "what": "Opens the agents screen: rules, the agent framework, roles, teams, skills and data."},
{"name": "Windows bootstrap", "form": "workstation windows", "what": "Opens the windows screen: the Windows install, skill sync and cloning the work repos."},
{"name": "Working documents", "form": "workstation documents", "what": "Opens the documents screen: CVs, case studies, plans, designs and intents."}
]},

{"path": ["shell"], "sentence": "The zsh helpers, git settings and git hooks this kit puts on this Linux machine.", "rows": [
{"name": "git safety", "form": "zsh.d/git-safety.zsh (~/.zsh.d/)", "what": "Asks [y/N] before a git checkout throws away unstaged changes."},
{"name": "infra helpers", "form": "zsh.d/infra.zsh (~/.zsh.d/)", "what": "Loads the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts."},
{"name": "utils helpers", "form": "zsh.d/utils.zsh (~/.zsh.d/)", "what": "Loads the terminal helpers (set-title, killport), IP aliases, lazy nvm, node, npm and npx, and Android, Java and Bun setup."},
{"name": "api keys", "form": "zsh.d/api-keys.zsh (~/.zsh.d/)", "what": "Exports the general-use keys from ~/.config/api-keys/env; that file stays out of Git."},
{"name": "api-keys-edit", "form": "api-keys-edit", "what": "Opens ~/.config/api-keys/env in the editor."},
{"name": "review-open", "form": "zsh.d/review-open.zsh (also ~/.local/bin/review-open)", "what": "Opens a file for review, from zsh or from an agent."},
{"name": "dash-path-warn", "form": "zsh.d/dash-path-warn.zsh (~/.zsh.d/)", "what": "Warns about the PATH problem its check looks for; the README does not say more."},
{"name": "git config", "form": ".gitconfig (~/.gitconfig)", "what": "Sets the author identity, Git LFS, the credential store, http.postBuffer and core.hooksPath."},
{"name": "git hooks", "form": "git-hooks/ (~/.git-hooks/)", "what": "Runs the Lefthook gates in every repo: approval note, no commits to main in a marked repo, and the scenario gate (scenario-gate.py)."},
{"name": "workstation", "form": "workstation help (aliases ws, setup)", "what": "Prints this map: the top screen, and a screen for each group."},
{"name": "Credentials known issue", "form": "README.md, Conventions and gotchas", "what": "Reads the warning that the git URLs in infra.zsh and utils.zsh embed a credential to rotate."}
]},

{"path": ["machine"], "sentence": "The power, display, network, laptop and repair scripts for this Linux machine, and its incident records.", "rows": [
{"name": "cpu-min-power", "form": "cpu-min-power.sh", "what": "Sets the power-saver profile, turbo off and the CPU capped at 8%; asks for sudo."},
{"name": "cpu-normal-power", "form": "cpu-normal-power.sh", "what": "Sets the balanced profile, turbo on and the CPU cap back to 100%."},
{"name": "fix_old_monitor_hdmi", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the mode and refresh rate of the external HDMI or DP output with xrandr (defaults 1920x1080 at 59.88)."},
{"name": "linux-internet-recovery", "form": "linux-internet-recovery.sh", "what": "Repairs DNS, restarts NetworkManager and cycles networking; reruns itself with sudo."},
{"name": "recover-tailscale-remote-terminal", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, then starts remote-terminal and checks port 3500."},
{"name": "keep-running-with-lid-closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes the logind drop-in so closing the lid does nothing; applies after reboot."},
{"name": "restore-default-lid-behavior", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that drop-in; applies after reboot."},
{"name": "fix-keyboard", "form": "fix-keyboard (zsh.d/utils.zsh)", "what": "Runs the keyboard repair."},
{"name": "fix-mouse", "form": "fix-mouse (zsh.d/utils.zsh)", "what": "Runs the mouse repair."},
{"name": "fix-disk", "form": "fix-disk (zsh.d/utils.zsh)", "what": "Runs the disk repair."},
{"name": "fix-whatsapp", "form": "fix-whatsapp (zsh.d/utils.zsh)", "what": "Runs the WhatsApp repair."},
{"name": "Incidents", "form": "workstation machine incidents", "what": "Opens the incident records: dated machine failures and their verified fixes."}
]},

{"path": ["machine", "incidents"], "sentence": "The dated incident records for this machine, each with the state it was verified in.", "rows": [
{"name": "2026-10-01 CodeBot with lid closed", "form": "reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "Reads the closed-lid test: it passed for 1 minute 46 seconds with Wi-Fi, CodeBot and Tailscale healthy."},
{"name": "Reference index", "form": "reference/README.md", "what": "Opens the index of incident cases and their outcomes."}
]},

{"path": ["services"], "sentence": "The services and tools that run on this machine: their folders, what they serve, and how to start them.", "rows": [
{"name": "Dashboard", "form": "workstation services dashboard", "what": "Opens the dashboard screen: both dashboard versions, their servers and checks."},
{"name": "Deskflow", "form": "workstation services deskflow", "what": "Opens the Deskflow screen: the shared mouse and laptop keyboard setup."},
{"name": "Hermes", "form": "workstation services hermes", "what": "Opens the Hermes screen: its launcher, example settings and restore steps."},
{"name": "Clipstack", "form": "workstation services clipstack", "what": "Opens the clipstack screen: the clipboard server, picker and Windows side."},
{"name": "Supabase keepalive", "form": "supabase-keepalive/install.sh", "what": "Installs the timer and service that run supabase-keepalive.sh."},
{"name": "audio-start", "form": "audio-start (zsh.d/audio-share.zsh)", "what": "Starts sending all Linux audio to the Windows machine over Tailscale."},
{"name": "audio-pause", "form": "audio-pause (zsh.d/audio-share.zsh)", "what": "Pauses that sending and restores the speakers."},
{"name": "audio-share", "form": "audio-share on|off|status|tone", "what": "Sets the audio share on or off, shows its status, or plays a test tone."}
]},

{"path": ["services", "dashboard"], "sentence": "The two dashboard versions on this machine: their servers, page, checks, fonts and screenshots.", "rows": [
{"name": "dashboard server", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard at http://127.0.0.1:8780, or on the port you pass."},
{"name": "dashboard page", "form": "dashboard/index.html", "what": "Opens the page the server serves; the open page reloads when it or server.py changes."},
{"name": "dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the 199 dashboard checks against the real data and a real server."},
{"name": "dashboard snapshot", "form": "dashboard/snapshot.py", "what": "Runs snapshot.py; the README does not say what it writes."},
{"name": "dashboard fonts and screenshots", "form": "dashboard/fonts/ and dashboard/shots/", "what": "Opens the IBM Plex fonts the page uses and the screenshots of its views."},
{"name": "Dashboard, concepts version", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the second version at http://127.0.0.1:8781, with its Projects panel in the bottom-right corner."},
{"name": "concepts checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the 17 concepts checks."}
]},

{"path": ["services", "deskflow"], "sentence": "The Deskflow setup that shares one mouse and the laptop keyboard between this laptop and the Windows PC.", "rows": [
{"name": "Deskflow server", "form": "deskflow/deskflow.service (~/.config/systemd/user/)", "what": "Runs the Linux Deskflow server with the graphical session; GNOME asks for input capture at each start."},
{"name": "Linux config", "form": "deskflow/linux.conf (~/.config/Deskflow/Deskflow.conf)", "what": "Sets the Linux server's Deskflow configuration."},
{"name": "server config", "form": "deskflow/server.conf (~/.config/Deskflow/server.conf)", "what": "Sets the server settings."},
{"name": "keyboard layout", "form": "deskflow/deskflow.service.d/keyboard-layout.conf", "what": "Sets the keyboard layout for the Deskflow service."},
{"name": "resume-kvm", "form": "resume-kvm (location not in this dump)", "what": "Starts Deskflow again and asks for input capture permission."},
{"name": "USB mouse sharing", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes for turning USB mouse sharing back on; it has been off since 2026-10-20."},
{"name": "network audit", "form": "deskflow/NETWORK-AUDIT.md", "what": "Reads the Deskflow network audit."},
{"name": "lockdown rules", "form": "deskflow/deskflow-lockdown.nft", "what": "Reads the lockdown rules; deskflow/README.md says how they apply (not in this dump)."},
{"name": "Windows configs", "form": "deskflow/windows.conf and deskflow/windows-service.conf", "what": "Sets the Windows client and service settings; copied by hand, see deskflow/README.md."}
]},

{"path": ["services", "hermes"], "sentence": "The Hermes agent on this machine: its launcher, example settings, backup record and restore steps.", "rows": [
{"name": "hermes launcher", "form": "~/.local/bin/hermes (source ~/projects/hermes-agent)", "what": "Starts the Hermes agent."},
{"name": "PATH fragment", "form": "hermes/zprofile-path.zsh", "what": "Adds the Hermes launcher to PATH in ~/.zprofile, guarded."},
{"name": "default config example", "form": "hermes/default.config.example.yaml", "what": "Shows the default profile's settings, with no secrets."},
{"name": "jobs config example", "form": "hermes/jobs.config.example.yaml", "what": "Shows the jobs profile's settings, with no secrets."},
{"name": "restore runbook", "form": "hermes/RESTORE.md", "what": "Reads the steps to restore Hermes."},
{"name": "backup record", "form": "hermes/BACKUP-2026-10-02.md", "what": "Reads the 2026-10-02 backup record."},
{"name": "install record", "form": "hermes/README.md", "what": "Opens the install and configuration record."}
]},

{"path": ["services", "clipstack"], "sentence": "The clipboard tool: its server, picker and watcher on Linux, and its AutoHotkey side on Windows.", "rows": [
{"name": "clipstack server", "form": "clipstack/server.py", "what": "Runs the clipboard server."},
{"name": "picker", "form": "clipstack/picker.py", "what": "Opens the picker to choose an earlier clipboard item."},
{"name": "watcher", "form": "clipstack/watcher.py", "what": "Runs the watcher that records clipboard changes."},
{"name": "install", "form": "clipstack/install.sh", "what": "Installs the server and watcher units."},
{"name": "units", "form": "clipstack/units/ (clipstack-server.service, clipstack-watcher.service)", "what": "Defines the server and watcher as user services."},
{"name": "Windows side", "form": "clipstack/windows/ (clipstack.ahk and its install, uninstall and verify scripts)", "what": "Opens the Windows side: the AutoHotkey script and its scripts."},
{"name": "Windows tests", "form": "clipstack/windows/tests/run-tests.ps1", "what": "Runs the Windows clipstack tests."},
{"name": "server tests", "form": "clipstack/test_server.py", "what": "Runs the server tests."}
]},

{"path": ["browser"], "sentence": "Chrome, the browser command and the smoke test, for driving a browser or checking a page.", "rows": [
{"name": "Chrome", "form": "chrome/chrome.sh (via ~/.local/bin/google-chrome)", "what": "Starts Chrome with the flags in chrome/flags; the only way to start it."},
{"name": "Chrome install", "form": "chrome/install.sh", "what": "Links the Chrome commands to chrome.sh and rewrites the menu entry; run once per machine."},
{"name": "Chrome flags", "form": "chrome/flags", "what": "Sets the flags that chrome.sh and the browser command both read."},
{"name": "browser", "form": "browser '<json steps>' (browser/browser.sh)", "what": "Drives the one persistent Chrome window with a list of steps."},
{"name": "browser status", "form": "browser status", "what": "Prints whether the background server and Chrome are up."},
{"name": "browser close", "form": "browser close", "what": "Closes Chrome and stops the server."},
{"name": "record proof", "form": "browser recordStart and recordStop steps", "what": "Starts a tab recording as proof of a feature; recordStop ends it."},
{"name": "browser reference", "form": "browser/README.md", "what": "Opens the full command reference: actions, viewports, network capture and login notes."},
{"name": "browser source", "form": "browser/", "what": "Opens the browser folder: cli.mjs and the server and step code it shares."},
{"name": "open-logged-in", "form": "browser/open-logged-in.mjs", "what": "Opens a page with the logged-in profile; not described in this dump, so the name is the only evidence."},
{"name": "smoke test", "form": "jev-browser-test (command)", "what": "Runs a goal against a browser and checks only the text and URL you give."},
{"name": "smoke test install", "form": "jev-browser-test/install.sh", "what": "Installs the CLI to ~/.local/bin, pinned to revision 1231850, and applies jev-ultrafast.patch."},
{"name": "smoke test keys", "form": "~/.config/jev-browser-test/env (example: jev-browser-test/env.example)", "what": "Sets the API keys the smoke test reads; the file stays out of Git."},
{"name": "smoke test instructions", "form": "jev-browser-test/instructions.md", "what": "Reads the CLI's instructions."}
]},

{"path": ["assistant"], "sentence": "The global Claude and Codex settings, their hooks, plugins and usage guard, and the OpenCode profiles.", "rows": [
{"name": "Claude rules", "form": "claude/CLAUDE.md", "what": "Sets the global Claude instructions that init-windows deploys to Windows."},
{"name": "Claude agent notes", "form": "claude/AGENTS.md", "what": "Sets the shorter global agent notes deployed to Windows."},
{"name": "Claude settings", "form": "claude/settings.json", "what": "Sets Claude Code's settings, deployed to Windows."},
{"name": "Linux global mirror", "form": "claude/linux-global/", "what": "Opens the copies of the Linux machine's global instruction files."},
{"name": "Windows global mirror", "form": "claude/windows-global/", "what": "Opens the copies of the Windows Claude folder."},
{"name": "Backups", "form": "claude/backups/", "what": "Opens the dated snapshots of the instruction package; nothing installs them."},
{"name": "Communication draft", "form": "claude/communication-framework.md", "what": "Reads the draft communication design; it is not enforced anywhere yet."},
{"name": "Skills shortlist", "form": "claude/skills-shortlist.md", "what": "Reads the skills researched on skills.sh and what is installed."},
{"name": "Hooks", "form": "workstation assistant hooks", "what": "Opens the hooks screen: the Claude hook scripts and where they are wired."},
{"name": "Mods", "form": "workstation assistant mods", "what": "Opens the mods screen: the four Claude plugins kept here."},
{"name": "Session types", "form": "workstation assistant session-types", "what": "Opens the session types screen: the start hook, the main session command and its design notes."},
{"name": "Usage guard", "form": "workstation assistant usage-guard", "what": "Opens the usage guard screen: the wrapper that runs claude, its installers and tests."},
{"name": "Codex", "form": "workstation assistant codex", "what": "Opens the Codex screen: its config, its direct Chrome path and the Chrome bridge."},
{"name": "OpenCode profiles", "form": "workstation assistant opencode", "what": "Opens the OpenCode screen: the commands that run and switch profiles, and their files."}
]},

{"path": ["assistant", "hooks"], "sentence": "The Claude hook scripts kept here, what runs each one, and their test.", "rows": [
{"name": "core rules hook", "form": "claude/hooks/core-rules.sh (~/.claude/hooks/)", "what": "Runs at session start and before each Bash call, as wired in settings.json."},
{"name": "machine history hook", "form": "claude/hooks/machine-history.sh (~/.claude/hooks/)", "what": "Runs from settings.json."},
{"name": "team activity hook", "form": "claude/hooks/team-activity.sh (~/.claude/hooks/)", "what": "Runs from settings.json."},
{"name": "local server guard", "form": "claude/hooks/local-server-guard.py (~/.claude/hooks/)", "what": "Runs before each Bash call, as wired in settings.json."},
{"name": "proof reminder", "form": "claude/hooks/proof-reminder.sh (~/.claude/hooks/)", "what": "Runs after Edit, MultiEdit, Write and Bash calls, as a reminder."},
{"name": "core rules tests", "form": "claude/hooks/test_core_rules.sh", "what": "Runs the core-rules tests."},
{"name": "hook wiring", "form": "~/.claude/settings.json", "what": "Opens Claude's settings file, where these hooks are wired."}
]},

{"path": ["assistant", "mods"], "sentence": "The four Claude plugins kept here, each with its hooks, types, tests and design notes.", "rows": [
{"name": "changelog pane", "form": "claude/mods/changelog-pane/", "what": "Opens the changelog pane plugin: its hooks, types and tests."},
{"name": "review pane", "form": "claude/mods/review-pane/", "what": "Opens the review pane plugin, with its design and flow notes in docs/."},
{"name": "scratchpad playground", "form": "claude/mods/scratchpad-playground/", "what": "Opens the scratchpad plugin."},
{"name": "team board", "form": "claude/mods/team-board/", "what": "Opens the team board plugin and its tests."}
]},

{"path": ["assistant", "session-types"], "sentence": "Claude's session types: the start hook, the main session command, its tests and design notes.", "rows": [
{"name": "session types hook", "form": "claude/session-types/session-types.sh (~/.claude/hooks/)", "what": "Runs at session start, as a SessionStart hook."},
{"name": "main sessions", "form": "claude/session-types/main-sessions.py (~/.claude/hooks/main-sessions.py)", "what": "Continues or resumes the main session for claude --main -c and -r."},
{"name": "session types tests", "form": "claude/session-types/tests/run.sh", "what": "Runs the session-types tests."},
{"name": "session types guide", "form": "claude/session-types/README.md", "what": "Opens the session types guide."},
{"name": "design notes", "form": "claude/session-types/docs/design/", "what": "Opens the design pitches for the changelog on the timeline and the picker views."}
]},

{"path": ["assistant", "usage-guard"], "sentence": "The usage guard: the wrapper that runs claude, its installers, its plugin, its tests and its resolved cases.", "rows": [
{"name": "claude wrapper", "form": "~/bin/claude (claude/usage-guard/claude)", "what": "Starts Claude Code through the usage guard, ahead of the native claude."},
{"name": "install", "form": "claude/usage-guard/install.sh", "what": "Installs the native Claude Code that the wrapper runs."},
{"name": "Windows install", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the Windows launcher (Install-Windows.ps1 and Launcher.cs)."},
{"name": "plugin", "form": "claude/usage-guard/plugin/", "what": "Opens the plugin's hooks and register.js, which use shared-usage.py."},
{"name": "usage guard tests", "form": "claude/usage-guard/tests/", "what": "Runs test_request_budget.py and live-refresh.py."},
{"name": "usage guard guide", "form": "claude/usage-guard/README.md", "what": "Opens the usage guard guide."},
{"name": "resolved cases", "form": "claude/usage-guard/.bdd/qa/resolutions/", "what": "Opens the two resolved QA cases: stale usage and request budget."}
]},

{"path": ["assistant", "codex"], "sentence": "Codex's config, its direct Chrome path, and the Chrome bridge that keeps it working.", "rows": [
{"name": "Codex config", "form": "codex/config.toml (%USERPROFILE%/.codex/config.toml on Windows)", "what": "Sets the Codex CLI config that init-windows deploys to Windows."},
{"name": "Codex Chrome path", "form": "codex/browser/README.md", "what": "Opens the notes on Codex's direct Chrome command path and its live check."},
{"name": "tab recorder", "form": "codex/browser/tab-recorder.mjs", "what": "Records a tab on Codex's path; for proof, use the browser command's recordStart instead."},
{"name": "tab recorder extension", "form": "codex/browser/tab-recorder-extension/", "what": "Opens the Chrome extension for the tab recorder."},
{"name": "Chrome bridge repair", "form": "codex/chrome-bridge/repair.mjs", "what": "Repairs the Chrome plugin's latest link and reapplies the local file: patch."},
{"name": "bridge install (Linux)", "form": "codex/chrome-bridge/install.sh", "what": "Installs the systemd watcher and timer that run the repair."},
{"name": "bridge install (Windows)", "form": "codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "Installs a current-user Scheduled Task that runs the repair."},
{"name": "bridge notes", "form": "codex/chrome-bridge/README.md", "what": "Opens the bridge's install and restart notes."}
]},

{"path": ["assistant", "opencode"], "sentence": "The OpenCode profiles: the commands that run and switch them, their help, files, tests and wiring.", "rows": [
{"name": "opencode", "form": "opencode (alias oc)", "what": "Runs opencode with the current profile."},
{"name": "opencode-profile", "form": "opencode-profile <name>", "what": "Names the current profile."},
{"name": "opencode-profiles", "form": "opencode-profiles", "what": "Prints what each profile loads."},
{"name": "opencode-switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to that profile."},
{"name": "opencode-login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "opencode-files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "opencode-edit", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files in the editor."},
{"name": "opencode help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints every profile's files, one column per profile, and the commands; with more than 3 profiles, writes ~/.opencode-profiles/help.md and opens it."},
{"name": "profile logic", "form": "opencode-profiles/profiles.py", "what": "Runs the profile logic these commands call."},
{"name": "profile tests", "form": "opencode-profiles/test_profiles.py", "what": "Runs the profile tests."},
{"name": "experimental profile", "form": "opencode-profiles/private-leb-experimental/", "what": "Opens the experimental profile's CLAUDE.md, settings and opencode.json."},
{"name": "OpenCode zsh wiring", "form": "zsh.d/opencode-profiles.zsh", "what": "Loads these commands into zsh; ~/.bashrc sources it too."}
]},

{"path": ["agents"], "sentence": "The agent system: the rules every session follows, the agent framework, roles and teams, skills and data.", "rows": [
{"name": "rules command", "form": "rules [folder] (~/.local/bin/rules)", "what": "Prints the rules that apply to a folder."},
{"name": "rules file", "form": "workboard/rules.yaml", "what": "Opens the rules; only the user or an accepted proposal (R43) changes them."},
{"name": "rule metadata", "form": "workboard/rules-meta.yaml", "what": "Opens the metadata for each rule."},
{"name": "rules tests", "form": "workboard/test_rules.py and workboard/test_org_folder.py", "what": "Runs the rules checks."},
{"name": "rules shell helpers", "form": "zsh.d/rules.zsh", "what": "Loads the rules helpers into zsh."},
{"name": "Agent framework", "form": "workstation agents agent-framework", "what": "Opens the agent framework screen: check, list, serve and its tests."},
{"name": "Roles", "form": "~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.md", "what": "Opens the role skills each team member starts with."},
{"name": "Personas", "form": "~/projects/my-skills/agents/<id>/claude.md and opencode.md", "what": "Opens an agent's Claude persona or OpenCode agent; my-skills/install.sh links them."},
{"name": "Teams", "form": "~/projects/my-skills/spawn-team/SKILL.md", "what": "Starts a team: /spawn-team <team> in Claude, or $spawn-team in Codex."},
{"name": "Team messages", "form": "~/projects/my-skills/coordinated-agentic-session/", "what": "Opens how team members message each other."},
{"name": "team-park", "form": "claude/team-park/team_park.py (~/.local/bin/team-park)", "what": "Runs the team-park tool; its README says what it parks."},
{"name": "team-park tests", "form": "claude/team-park/test_team_park.py", "what": "Runs the team-park tests."},
{"name": "Skills", "form": "workstation agents skills", "what": "Opens the skills screen: the global skills and the backups kept here."},
{"name": "Data", "form": "~/projects/data/", "what": "Opens the cases, rule proposals, verdicts and designs the agents write."},
{"name": "Answer sync", "form": "~/projects/data/bin/{issue,pull,sync}", "what": "Runs the answer sync; a timer runs it every 5 minutes."},
{"name": "Supervision backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "Opens the supervision backlog."},
{"name": "Archive", "form": "~/archive/", "what": "Opens the archive of moved files and test evidence; it is not backed up."}
]},

{"path": ["agents", "agent-framework"], "sentence": "The agent framework: its check, list and serve commands, its tests, and the Agent Sandbox page.", "rows": [
{"name": "agent check", "form": "agent-framework/agent check", "what": "Refuses broken agent records, with exit 1."},
{"name": "agent list", "form": "agent-framework/agent list", "what": "Prints the agents, their tier, model and number of tests."},
{"name": "agent serve", "form": "agent-framework/agent serve", "what": "Starts the Agent Sandbox page at http://127.0.0.1:8790."},
{"name": "agent code", "form": "agent-framework/agentkit.py", "what": "Runs the code behind check, list and serve."},
{"name": "sandbox page", "form": "agent-framework/sandbox/ (index.html, server.py)", "what": "Opens the Agent Sandbox page's files."},
{"name": "saved run", "form": "agent-framework/fixtures/run-prd-writer-qa-agent.json", "what": "Opens a saved run of the PRD writer QA agent."},
{"name": "framework tests", "form": "agent-framework/test_agentkit.py and agent-framework/test_server.py", "what": "Runs the agent framework tests."},
{"name": "framework guide", "form": "agent-framework/README.md", "what": "Opens the framework guide: the sandbox, its modes and its words."},
{"name": "agent records", "form": "~/projects/my-skills/agents/<id>/agent.yaml", "what": "Opens an agent's record: its setup, situations and tests."},
{"name": "agent results and memory", "form": "~/projects/data/<id>/eval-results/ and ~/projects/data/<id>/memory/", "what": "Opens an agent's eval results and memory."}
]},

{"path": ["agents", "skills"], "sentence": "The skills this machine uses: the global skills from my-skills and the backups kept in this repo.", "rows": [
{"name": "supabase", "form": "~/projects/my-skills/supabase/", "what": "Opens the skill for Supabase Auth, RLS, migrations and debugging."},
{"name": "supabase-postgres-best-practices", "form": "~/projects/my-skills/supabase-postgres-best-practices/", "what": "Opens the skill with Supabase's Postgres performance rules."},
{"name": "clone-website", "form": "~/projects/my-skills/clone-website/", "what": "Opens the skill for cloning a website with parallel builder agents."},
{"name": "lab-experiment", "form": "~/projects/my-skills/lab-experiment/", "what": "Opens the skill for running an experiment in ai-lab."},
{"name": "coding-guidelines", "form": "~/projects/my-skills/coding-guidelines/", "what": "Opens the house coding rules."},
{"name": "volatility-based-decomposition", "form": "~/projects/my-skills/volatility-based-decomposition/", "what": "Opens the skill for decomposing systems around independently changing decisions."},
{"name": "working-with-windows", "form": "~/projects/my-skills/working-with-windows/", "what": "Opens the Windows gotchas for Node MCP servers that call PowerShell."},
{"name": "solaraai skills", "form": "~/projects/my-skills/solaraai-content-calendar, solaraai-deployment, solaraai-design, solaraai-forms", "what": "Opens the four SolaraAI skills: content calendar, deployment, design system and form behavior."},
{"name": "skill backups", "form": "claude/skills/ (23 skill folders)", "what": "Opens the folder of skill backups; copy the wanted one into ~/.claude/skills."}
]},

{"path": ["windows"], "sentence": "The Windows setup: the bootstrap that rebuilds the environment, the skill sync, and cloning the work repos.", "rows": [
{"name": "Install", "form": "init-windows/Start-Install.cmd", "what": "Installs the environment from the manifests; asks for administrator approval."},
{"name": "Checks", "form": "init-windows/Smoke-Test-Windows.ps1 and init-windows/Verify-Windows.ps1", "what": "Runs the checks on the installed environment."},
{"name": "Roll back", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes what the install added, using its journal."},
{"name": "Export", "form": "init-windows/Export-Windows.ps1", "what": "Exports the current machine's state into the manifests."},
{"name": "Manifests", "form": "init-windows/manifests/", "what": "Opens the exact versions: programs, Node, VS Code extensions and managed files."},
{"name": "Configs", "form": "init-windows/configs/", "what": "Opens the git and VS Code configs that get copied in."},
{"name": "User scripts", "form": "init-windows/user-scripts/", "what": "Opens the user scripts that get copied to %USERPROFILE%/Scripts."},
{"name": "Install code", "form": "init-windows/lib/", "what": "Opens the install code, one file per program or area."},
{"name": "Inventory", "form": "init-windows/inventory.md", "what": "Opens the list of what the first capture found."},
{"name": "Sign-ins", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand, and the credential to rotate."},
{"name": "Install logs", "form": "init-windows/logs/", "what": "Opens the install and error logs."},
{"name": "Install guide", "form": "init-windows/README.md", "what": "Opens the full install guide."},
{"name": "Skill sync", "form": "workstation windows skills-sync", "what": "Opens the skill sync screen."},
{"name": "Cloning the work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones each missing Betec repo; leaves existing folders alone."}
]},

{"path": ["windows", "skills-sync"], "sentence": "The Windows skill sync: the runner, the scheduled catch-up, its scripts, and the last success record.", "rows": [
{"name": "sync script", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Updates the Windows skill checkout from master and relinks; runs on each push."},
{"name": "runner service", "form": "actions.runner.Lebnor-my-skills.my-skills-liel-windows", "what": "Runs the GitHub runner that starts a sync on each trusted push to master."},
{"name": "catch-up task", "form": "MySkillsSync-CatchUp (Windows scheduled task)", "what": "Runs the sync once after startup, with three retries on failure."},
{"name": "last success", "form": "C:/ProgramData/MySkillsSync/state/last-success.json", "what": "Reads when the last sync succeeded."},
{"name": "account test", "form": "skills-sync-windows/Test-Account.ps1", "what": "Checks the runner account's rights."},
{"name": "sync test", "form": "skills-sync-windows/Test-Sync.ps1", "what": "Tests the sync script."},
{"name": "verification", "form": "skills-sync-windows/verification.md", "what": "Reads how the sync was verified."},
{"name": "sync guide", "form": "skills-sync-windows/README.md", "what": "Opens the sync's components, permissions and risks."}
]},

{"path": ["documents"], "sentence": "The working documents: CVs, case studies, plans and designs, intents, features, and the research behind them.", "rows": [
{"name": "CVs", "form": "workstation documents cv", "what": "Opens the CV screen: the three CVs, their sources and rebuilds."},
{"name": "Case studies", "form": "workstation documents case-studies", "what": "Opens the case studies screen: the archived, reviewed experiments."},
{"name": "Working documents", "form": "workstation documents docs", "what": "Opens the docs screen: plans, designs, flows, research, roles, items and changelog."},
{"name": "Project intent", "form": ".idd/project.intent.md", "what": "Reads the project's own intent."},
{"name": "Module intents", "form": ".idd/modules/", "what": "Opens each module's intent: what it must do, and the checks for it."},
{"name": "Features", "form": ".bdd/features/", "what": "Opens the feature files: the behavior the checks follow, in Given, When, Then."},
{"name": "QA findings", "form": ".bdd/qa/findings/", "what": "Opens the QA findings from the 2026-10-25 say-the-thing check."},
{"name": "Screenshots", "form": "copy/ (1-today.webp, 2-subsystems.webp, 3-reviews.webp)", "what": "Opens three screenshots: today, subsystems and reviews."}
]},

{"path": ["documents", "cv"], "sentence": "The three CVs: their PDFs, their sources, the shared parts, and how they are rebuilt.", "rows": [
{"name": "Full Stack Developer CV", "form": "cv/cv-full-stack.pdf (source cv/cv-full-stack.tex)", "what": "Opens the Full Stack Developer CV as a PDF."},
{"name": "AI Full Stack Engineer CV", "form": "cv/cv-ai-full-stack.pdf (source cv/cv-ai-full-stack.tex)", "what": "Opens the AI Full Stack Engineer CV as a PDF."},
{"name": "AI Integrations CV", "form": "cv/cv-ai-integrations.pdf (source cv/cv-ai-integrations.tex)", "what": "Opens the AI Integrations CV as a PDF."},
{"name": "rebuild a CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error <name>.tex (in cv/)", "what": "Rebuilds one CV PDF from its .tex source."},
{"name": "shared parts", "form": "cv/cv-details.tex, cv-work-experience.tex, cv-codebot.tex, cv-layout.tex", "what": "Opens the parts that all three CVs share."},
{"name": "factual input", "form": "cv/experience-notes.md", "what": "Opens the facts the CVs are built from."},
{"name": "readable master", "form": "cv/cv-master.md", "what": "Opens the readable master copy of the CV."},
{"name": "drafting decisions", "form": "cv/cv-material-draft.md", "what": "Opens the drafting decisions."},
{"name": "CV workflow", "form": "cv/WORKFLOW.md", "what": "Opens the CV workflow."},
{"name": "plain-text versions", "form": "cv/text/build-full.sh", "what": "Builds the plain-text versions of the CVs."},
{"name": "HTML design", "form": "cv/design/build-design.py", "what": "Builds the HTML design of the CV."},
{"name": "dated versions", "form": "cv/versions/ (2026-10-04 and 2026-10-04-v2)", "what": "Opens the dated CV versions."},
{"name": "old CV path", "form": "~/projects/tech-cv-workspace/", "what": "Opens the CVs through their old path, which Hermes still uses through compatibility symlinks."}
]},

{"path": ["documents", "case-studies"], "sentence": "The archived, human-reviewed experiments, each in its own dated folder.", "rows": [
{"name": "CodeBot return", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/", "what": "Opens the same design request run with and without the conceptual-modeling skill, with runs, images and the skill snapshot."},
{"name": "Signal garden", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "Opens the exhibit's notes: durable explanation apart from the live interface."},
{"name": "Kernel cloud browser results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the results on cloud browser use cases, speed against local Chrome, and session recording."}
]},

{"path": ["documents", "docs"], "sentence": "The project's working documents by kind: plans, designs, flows, research, roles, items and changelog.", "rows": [
{"name": "plans", "form": "docs/plans/", "what": "Opens the dated plans, one folder per change."},
{"name": "designs", "form": "docs/design/", "what": "Opens the dated design pitches, research and recommendations."},
{"name": "design references", "form": "docs/design-references/", "what": "Opens the dashboard design mockups kept as references."},
{"name": "flows", "form": "docs/flows/", "what": "Opens the dated flow cards and data models."},
{"name": "research", "form": "docs/research/", "what": "Opens the dated research, including the phase-1 check test."},
{"name": "functional research", "form": "docs/functional-research/2026-10-21/", "what": "Opens the comparisons of agent frameworks and subagent tools."},
{"name": "roles", "form": "docs/roles/", "what": "Opens the qa-agent role and the 2026-10-23 role drafts."},
{"name": "items", "form": "docs/items/", "what": "Opens the planned, urgent and work items."},
{"name": "changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "playbooks", "form": "docs/playbooks/", "what": "Opens the playbook for talking while the team builds."},
{"name": "Superpowers plans", "form": "docs/superpowers/plans/", "what": "Opens the older Superpowers plan for the usage guard."}
]}
],
"questions": [
"Several things the README describes are not in the file list: workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, resume-kvm, browser/server.mjs, steps.mjs and recorder.mjs, cv/experience-notes.md, cv/cv-master.md, cv/cv-material-draft.md, init-windows/inventory.md, and the remote-terminal service. Are they untracked, moved, or gone? Recommendation: check each on disk before the build; keep the rows as the README describes them until then.",
"Skill backups: keep one folder row for claude/skills/ (23 folders), or one row per skill? The README table lists only 12 of them. Recommendation: keep the folder row now, and go per skill only once you say which backups you keep.",
"Dashboard and dashboard-concepts: one screen holding both versions, or two screens? Recommendation: one screen, since the README calls the second a comparison of the first.",
"Confirm the retirements stay off the map: lan-mouse (retired 2026-10-05), codex/playwright-mcp (retired), and docs/roles/drafts-2026-10-23/.old. Recommendation: keep them off, as your own notes retire them.",
"The alias setup is generic and may clash with another command. Keep it? Recommendation: keep workstation and ws; keep setup only if whence -a setup shows no clash in zsh and bash."
]}
```

No skill · run 5 exit=0 seconds=82 · prompt

P1 Recall: 0.586P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.348P5 Short top: 22P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.128
As terminal help
The front door: every area of this workstation, one line each. Type an area name to open its screen; the help is grouped by these areas.
Browsercommand: browserdrive one persistent Chrome window and record proof
Agentscommand: agentcheck, list and open the Agent Sandbox
Dashboardhttp://127.0.0.1:8780today's waiting items and team overview; started by hand
Rulescommand: rulesthe rules every agent session follows
OpenCode profilescommand: opencode-profilewhich OpenCode profile runs, its files and switching
Claudecommand: claude (usage-guard wrapper)Claude Code wrapper, sessions, team park, plugins, usage guard
Shellfiles: zsh.d/*.zshgit safety, infra, terminal utilities, API keys, review-open
Gitfiles: .gitconfig and git-hooks/git config, hooks and the push and commit gates
Machine (Linux)scripts in the repo root and laptop-utilities/power, display, network, lid and repair helpers
Chromecommand: chrome/chrome.shthe one way to start Chrome on this machine
Windowsscripts in init-windows/ and skills-sync-windows/rebuild, check and sync the Windows machine; runs on Windows
CVsfolder cv/ (pdflatex)build and find the three CV versions
Audiocommand: audio-startsend Linux audio to the Windows machine and back
Deskflowcommand: resume-kvmshared mouse and keyboard between Linux and Windows
Clipboardsystemd units clipstack-server and clipstack-watcherclipboard history and its picker
Hermescommand: hermesthe Hermes agent, its configs and restore runbook
Jevcommand: jev-browser-testbehavioral browser smoke tests and asking Jev a question
Skillsrepo Lebnor/my-skills, linked into ~/.claude/skillsthe agent skill catalog and its backups here
Keep-alivesystemd timer supabase-keepalivekeeps the Supabase project awake
Workfolder docs/items/ and docs/plans/urgent, planned and work items, and dated plans
Referencefolder reference/incidents/dated machine incidents and verified fixes
Case studiesfolder case-studies/reviewed experiments with their evidence
browser
One Chrome window kept open between commands; send it a list of steps and read the JSON result.
Statuscommand: browser statusis the background server and Chrome up
Closecommand: browser closeclose Chrome and stop the server
Run stepscommand: browser '<json steps>' (goto, screenshot, click, fill and others)drive the page
Record proofsteps recordStart and recordStoprecord a feature as proof; the one supported way
Browser READMEfile browser/README.mdall actions, presets and login notes
agent
Agent records are checked before any session starts; the sandbox page runs them for real.
Checkcommand: agent checkrefuse broken records; exits 1 on failure
Listcommand: agent listagents with tier, model and number of tests
Sandbox pagecommand: agent serve, then http://127.0.0.1:8790pick an agent, change its setup, send a message
Agent recordsfile ~/projects/my-skills/agents/<id>/agent.yamlthe typed record of each agent
Agent framework READMEfile agent-framework/README.mdhow the sandbox page works and its words
dashboard
One screen for the owner, read at a glance: what waits, what the team is doing.
Opencommand: python3 dashboard/server.py, then http://127.0.0.1:8780start and open the dashboard; a port can be passed
Waiting tabpage tab #waiting (default)cases asked, rule changes proposed and calls made alone
Overview tabpage tab on http://127.0.0.1:8780cases and proposals counts, running team lanes
Testscommand: python3 -I -m unittest discover -s dashboard199 checks against real data and a real server
Concepts versioncommand: python3 dashboard-concepts/server.py, then http://127.0.0.1:8781the second dashboard, kept to compare the two
rules
The rules every agent follows; only you or an accepted proposal can change them.
Print rulescommand: rules [folder]print the rules that apply, optionally for a folder
Rules sourcefile workboard/rules.yamlthe rules themselves
Rule metadatafile workboard/rules-meta.yamldetails kept beside each rule
Rule proposalsfolder ~/projects/data/global/rule-proposals/proposed changes waiting for accept or reject
Generated copyfile ~/.claude/references/rules.mdgenerated from rules.yaml; do not edit by hand
opencode
Which OpenCode profile runs, what each loads, and how to switch or edit them.
Current profilecommand: opencode-profilename the profile in use
Profilescommand: opencode-profilesshow what each profile loads
Switchcommand: opencode-switch <name>switch every shell's new runs to a profile
Sign incommand: opencode-loginsign a profile's Claude Code in
Filescommand: opencode-fileslist the current profile's files
Edit a filecommand: opencode-edit <file>open one profile file
Helpcommand: opencode help (also oc help, opencode-help, oc-help)every profile's files and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it
claude
The Claude Code wrapper, its sessions, its usage guard and its team tools.
Claude wrappercommand: claude (file ~/bin/claude, ahead of ~/.local/bin/claude)the usage-guard wrapper that runs Claude Code
Usage guard installcommand: claude/usage-guard/install.shinstall the wrapper on Linux
Usage guard on Windowsfile claude/usage-guard/Install-Windows.cmdinstall the wrapper on Windows; runs there
Main sessionscommand: claude --main -c, or claude --main -rcontinue or resume the main session
Team parkcommand: team-park (file ~/.local/bin/team-park)park and manage team work
Pluginsfolders claude/mods/changelog-pane, review-pane, scratchpad-playground, team-boardClaude Code plugins kept here
Global instructionsfiles claude/CLAUDE.md and claude/AGENTS.mdthe global rules and agent notes
shell
Helpers loaded by zsh from ~/.zsh.d/; each one is a command you type.
Git safetyzsh.d/git-safety.zsh: git checkoutlists the files and asks [y/N] before discarding changes
Infrazsh.d/infra.zshDocker, Compose, Prisma, Postgres, nginx and VPN shortcuts
Utilitieszsh.d/utils.zshset-title, killport, IP aliases, lazy nvm and node, Android, Java and Bun
API keyscommand: api-keys-edit (file ~/.config/api-keys/env)general-use API keys, kept out of Git
Review opencommand: review-open (file ~/.local/bin/review-open)open a review from bash or an agent
Workstationcommand: workstation, setup or wsthis kit's own help and commands
Audio sharezsh.d/audio-share.zsh, also sourced by ~/.bashrcthe audio commands on the Audio screen
git
Git settings and the hooks that gate pushes and commits in every repo.
Git configfile .gitconfig (copied to ~/.gitconfig)author, LFS, credential store, hooks path
Hooksfolder git-hooks/ (copied to ~/.git-hooks/)Lefthook shims; need lefthook on PATH
Push gateshook pre-pushapproval note; no push to main in a repo marked team.gitpolicy pull-request
Commit gatehook commit-msgno commit on main in a marked repo
Repoint old clonecommand: git remote set-url origin https://github.com/Lebnor/workstation.gitfix a clone made before the rename
machine
Linux machine settings and repairs; some need sudo or a reboot, as noted.
Minimum powercommand: cpu-min-power.sh (sudo)power-saver profile, turbo off, CPU capped at 8%; Intel P-state only
Normal powercommand: cpu-normal-power.sh (sudo)balanced profile, turbo on, cap back to 100%
External monitorcommand: fix_old_monitor_hdmi.sh [--output] [--mode] [--rate] [--quiet]set mode and refresh on the HDMI or DP output; default 1920x1080 at 59.88
Internet recoverycommand: linux-internet-recovery.sh (re-runs with sudo)fix DNS and restart networking
Remote terminal recoverycommand: recover-tailscale-remote-terminal.sh; checks port 3500repair DNS and Tailscale, then start the remote terminal service
Keep running with lid closedcommand: laptop-utilities/keep-running-with-lid-closed.shclosing the lid does nothing; applies after reboot
Restore lid behaviorcommand: laptop-utilities/restore-default-lid-behavior.shremove that setting; applies after reboot
Repair keyboardcommand: fix-keyboardrepair helper from zsh.d/utils.zsh
Repair mousecommand: fix-mouserepair helper from zsh.d/utils.zsh
Repair diskcommand: fix-diskrepair helper from zsh.d/utils.zsh
Repair WhatsAppcommand: fix-whatsapprepair helper from zsh.d/utils.zsh
chrome
The one way to start Chrome here, so recording works without a prompt.
Start Chromecommand: chrome/chrome.sh (also google-chrome)start Chrome with the flags in chrome/flags
Installcommand: chrome/install.sh (run once, and after a Chrome update)link the launchers and the menu entry to chrome.sh
Flagsfile chrome/flagsthe one list of Chrome flags; edit only here
Check the flagcommand: pgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'confirm a running Chrome has the recording flag
Chrome READMEfile chrome/README.mdwhy it starts this way and its limits
windows
Work done on the Windows machine. None of these run from this shell; copy them there.
Installfile init-windows/Start-Install.cmd (runs on Windows)rebuild the Windows dev environment from the manifests
Checkfiles init-windows/Smoke-Test-Windows.ps1 and Verify-Windows.ps1check the install
Roll backfile init-windows/Remove-WindowsPack.ps1remove what the install added
Inventoryfile init-windows/inventory.mdwhat was captured
Sign-ins to redofile init-windows/secrets-checklist.mdsign-ins you must do by hand
Clone work reposfile repos/Clone-BetecRepos.ps1clone the missing Betec repos; safe to re-run
Skill syncfile skills-sync-windows/Sync-Skills.ps1, run by the runner on each pushkeep Windows skill links current
Skill sync statusfile state/last-success.json under ProgramData/MySkillsSyncwhen the last sync succeeded
Chrome bridgefile codex/chrome-bridge/Install-CodexChromeBridge.cmdkeep the Codex Chrome link and patch in place
cv
The CVs: three versions, their sources and their text, all built from this folder.
Full Stack CVfile cv/cv-full-stack.pdf (source cv-full-stack.tex)the full stack version
AI Full Stack CVfile cv/cv-ai-full-stack.pdf (source cv-ai-full-stack.tex)the AI full stack version
AI Integrations CVfile cv/cv-ai-integrations.pdf (source cv-ai-integrations.tex)the AI integrations version
Rebuildcommand: pdflatex -interaction=nonstopmode -halt-on-error <file>.tex, run in cv/rebuild a changed version, then commit the sources and PDFs together
Past versionsfolders cv/versions/2026-10-04 and 2026-10-04-v2dated copies kept for reference
Text outputscommand: cv/text/build-full.shplain-text versions for applications
audio
Send all Linux audio to the Windows machine over Tailscale, and take it back.
Startcommand: audio-startsend audio to the Windows machine
Pausecommand: audio-pauserestore the laptop speakers
Share controlcommand: audio-share on|off|status|toneturn sharing on or off, check it, or play a test tone
Stream porttcp port 4953where the raw audio is served
Windows siderun by the windows-audio-share agent (ffplay reconnect loop)the Windows playback loop; not run from here
deskflow
One shared mouse and keyboard between the laptop and Windows. Deskflow replaced Lan Mouse.
Resumecommand: resume-kvmrestart Deskflow and ask GNOME for input capture again
Everyday usefile deskflow/README.mdhow to cross edges, the keyboard follow rule and recovery
USB mouse sharingfile usb-mouse/README.md; service deskflow-usb-mouse.service (disabled)forwarding of the Windows USB mouse, off since 2026-10-20; how to turn it back on
Network auditfile deskflow/NETWORK-AUDIT.mdwhat the setup connects to
clipboard
Clipboard history shared with Windows: a server, a watcher, a picker and a Windows script.
Serversystemd unit clipstack-server.service (clipstack/server.py)keeps the history
Watchersystemd unit clipstack-watcher.service (clipstack/watcher.py)records new copies
Pickercommand: clipstack/picker.pychoose an item from the history
Windows installfile clipstack/windows/install.ps1 (runs on Windows)install the Windows side; verify.ps1 checks it
Windows scriptfile clipstack/windows/clipstack.ahkthe AutoHotkey hook on Windows
Shared clipboard planfile docs/plans/2026-10-26-shared-clipboard/plan.mdthe plan for the shared clipboard
hermes
The Hermes agent installed from source; its state is kept out of this repo.
Launchercommand: hermes (file ~/.local/bin/hermes)start Hermes
Restore runbookfile hermes/RESTORE.mdhow to restore it on a new machine
Default config examplefile hermes/default.config.example.yamlsecret-free settings for the default profile
Jobs config examplefile hermes/jobs.config.example.yamlsecret-free settings for the jobs profile
Statefolder ~/.hermes (not in Git)keys and profile state; kept on the machine
jev
Browser smoke tests against a goal, and asking Jev a question with options.
Browser smoke testcommand: jev-browser-test (with a URL and a goal)run a goal in a browser and report the supplied checks
Ask Jevcommand: jev '<context>' -c 'question' option1,option2,other_none -jget a choice; a confidence of 0.85 or more can count as approved
Installcommand: sh jev-browser-test/install.shinstall the pinned upstream and the CLI
Secretsfile ~/.config/jev-browser-test/env (mode 600)API keys; never in Git
Instructionsfile jev-browser-test/instructions.mdhow to use it and what it proves
skills
The agent skill catalog: where it lives, where it is linked, and the copies kept here.
Catalogrepo Lebnor/my-skills (/home/liel/projects/my-skills)the source of every global skill
Linked foldersfolders ~/.claude/skills, ~/.codex/skills, ~/.config/opencode/skillswhere install.sh links the skills
Skill tablesection of README.mdthe main skills and their purpose
Backups kept herefolder claude/skills/copies of skills kept in this repo
Shortlistfile claude/skills-shortlist.mdskills researched on skills.sh and what is installed
keepalive
A timer that keeps the Supabase project from going idle.
Installcommand: supabase-keepalive/install.shinstall the service and timer
Timersystemd timer supabase-keepalive.timerwhen it runs
Scriptfile supabase-keepalive/supabase-keepalive.shwhat each run does
work
Items and dated plans for ongoing work.
Urgent itemsfile docs/items/urgent.item.mdwhat needs attention first
Planned itemsfile docs/items/planned.item.mdscheduled work
Work itemsfile docs/items/work.item.mdeverything else in progress
Plansfolder docs/plans/ (dated subfolders)each plan, by date
reference
Dated incident records for machine failures and the verified fixes.
Incident indexfile reference/README.mdevery incident with its outcome
Closed-lid incidentfile reference/incidents/2026-10-01-codebot-lid-closed.mdCodeBot kept serving with the lid closed; test passed
case-studies
Archived, human-reviewed experiments with their evidence.
Codebot returnfile case-studies/conceptual-modeling/2026-09-15-codebot-return/README.mdthe same design run with and without a skill; the skill run was better
Signal gardenfile case-studies/blume-astryx/2026-09-16-signal-garden/README.mda documentation exhibit splitting explanation from the live interface
Kernel browsers resultsfile /home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md (outside this repo)cloud browser use cases, speed and recording, tested 2026-10-08
Questions
  • Should workstation, setup and ws stay the one front door, with every existing command (browser, agent, rules, opencode-profile and so on) still working and listed under its area? Recommendation: yes. Rename nothing; the help only points at the names that already exist.
  • Should the Windows steps appear in the Linux help? Recommendation: yes, under the Windows screen, marked 'runs on Windows' and printed as text to copy, never run from zsh, because they cannot run here.
  • Should retired items (Lan Mouse, codex/playwright-mcp, the old Codex recorders) be left out of the help? Recommendation: yes; they stay in their READMEs and the help does not mention them.
  • Should machine scripts that need sudo or a reboot appear in the help? Recommendation: yes, each marked 'needs sudo' or 'after reboot'; the help prints the command and never runs it.
  • Should helpers that embed a credential in git URLs (git_pull_with_creds, update-gitlab-token) appear? Recommendation: no. Leave them out until the credential is rotated and moved to a credential manager, as the checklist asks.
  • Should the concepts dashboard (port 8781) appear beside the main dashboard? Recommendation: only under Dashboard, labelled as a comparison, not on the top screen.
  • How much of the skill catalog should the help list? Recommendation: the README's skill table and a link to my-skills; the full catalog lives in another repo and would swamp the help.
  • Should the top screen show services that are not on by default (dashboard, agent sandbox, clipboard, keep-alive)? Recommendation: yes, each with its command and whether it runs by default; the help shows them and never starts them.
  • Can you add workstation-cli/ (workstation.py and terminal_links.py) to the dump? Recommendation: yes, before the top screen is finalized. Its current help text is not visible here, so the top screen and its existing text are inferred from the README.
  • Should the workstation help open the link pages in the terminal, or print plain text? Recommendation: keep what the README describes: links on a terminal, plain markdown when piped.
As phone screens

Home

The front door: every area of this workstation, one line each. Type an area name to open its screen; the help is grouped by these areas.

Browserdrive one persistent Chrome window and record proof
›
Agentscheck, list and open the Agent Sandbox
›
Dashboardtoday's waiting items and team overview; started by hand
›
Rulesthe rules every agent session follows
›
OpenCode profileswhich OpenCode profile runs, its files and switching
›
ClaudeClaude Code wrapper, sessions, team park, plugins, usage guard
›
Shellgit safety, infra, terminal utilities, API keys, review-open
›
Gitgit config, hooks and the push and commit gates
›
Machine (Linux)power, display, network, lid and repair helpers
›
Chromethe one way to start Chrome on this machine
›
Windowsrebuild, check and sync the Windows machine; runs on Windows
›
CVsbuild and find the three CV versions
›
Audiosend Linux audio to the Windows machine and back
›
Deskflowshared mouse and keyboard between Linux and Windows
›
Clipboardclipboard history and its picker
›
Hermesthe Hermes agent, its configs and restore runbook
›
Jevbehavioral browser smoke tests and asking Jev a question
›
Skillsthe agent skill catalog and its backups here
›
Keep-alivekeeps the Supabase project awake
›
Workurgent, planned and work items, and dated plans
›
Referencedated machine incidents and verified fixes
›
Case studiesreviewed experiments with their evidence
›
‹ Home

browser

One Chrome window kept open between commands; send it a list of steps and read the JSON result.

Statusis the background server and Chrome up
›
Closeclose Chrome and stop the server
›
Run stepsdrive the page
›
Record proofrecord a feature as proof; the one supported way
›
Browser READMEall actions, presets and login notes
›
‹ Home

agent

Agent records are checked before any session starts; the sandbox page runs them for real.

Checkrefuse broken records; exits 1 on failure
›
Listagents with tier, model and number of tests
›
Sandbox pagepick an agent, change its setup, send a message
›
Agent recordsthe typed record of each agent
›
Agent framework READMEhow the sandbox page works and its words
›
‹ Home

dashboard

One screen for the owner, read at a glance: what waits, what the team is doing.

Openstart and open the dashboard; a port can be passed
›
Waiting tabcases asked, rule changes proposed and calls made alone
›
Overview tabcases and proposals counts, running team lanes
›
Tests199 checks against real data and a real server
›
Concepts versionthe second dashboard, kept to compare the two
›
‹ Home

rules

The rules every agent follows; only you or an accepted proposal can change them.

Print rulesprint the rules that apply, optionally for a folder
›
Rules sourcethe rules themselves
›
Rule metadatadetails kept beside each rule
›
Rule proposalsproposed changes waiting for accept or reject
›
Generated copygenerated from rules.yaml; do not edit by hand
›
‹ Home

opencode

Which OpenCode profile runs, what each loads, and how to switch or edit them.

Current profilename the profile in use
›
Profilesshow what each profile loads
›
Switchswitch every shell's new runs to a profile
›
Sign insign a profile's Claude Code in
›
Fileslist the current profile's files
›
Edit a fileopen one profile file
›
Helpevery profile's files and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it
›
‹ Home

claude

The Claude Code wrapper, its sessions, its usage guard and its team tools.

Claude wrapperthe usage-guard wrapper that runs Claude Code
›
Usage guard installinstall the wrapper on Linux
›
Usage guard on Windowsinstall the wrapper on Windows; runs there
›
Main sessionscontinue or resume the main session
›
Team parkpark and manage team work
›
PluginsClaude Code plugins kept here
›
Global instructionsthe global rules and agent notes
›
‹ Home

shell

Helpers loaded by zsh from ~/.zsh.d/; each one is a command you type.

Git safetylists the files and asks [y/N] before discarding changes
›
InfraDocker, Compose, Prisma, Postgres, nginx and VPN shortcuts
›
Utilitiesset-title, killport, IP aliases, lazy nvm and node, Android, Java and Bun
›
API keysgeneral-use API keys, kept out of Git
›
Review openopen a review from bash or an agent
›
Workstationthis kit's own help and commands
›
Audio sharethe audio commands on the Audio screen
›
‹ Home

git

Git settings and the hooks that gate pushes and commits in every repo.

Git configauthor, LFS, credential store, hooks path
›
HooksLefthook shims; need lefthook on PATH
›
Push gatesapproval note; no push to main in a repo marked team.gitpolicy pull-request
›
Commit gateno commit on main in a marked repo
›
Repoint old clonefix a clone made before the rename
›
‹ Home

machine

Linux machine settings and repairs; some need sudo or a reboot, as noted.

Minimum powerpower-saver profile, turbo off, CPU capped at 8%; Intel P-state only
›
Normal powerbalanced profile, turbo on, cap back to 100%
›
External monitorset mode and refresh on the HDMI or DP output; default 1920x1080 at 59.88
›
Internet recoveryfix DNS and restart networking
›
Remote terminal recoveryrepair DNS and Tailscale, then start the remote terminal service
›
Keep running with lid closedclosing the lid does nothing; applies after reboot
›
Restore lid behaviorremove that setting; applies after reboot
›
Repair keyboardrepair helper from zsh.d/utils.zsh
›
Repair mouserepair helper from zsh.d/utils.zsh
›
Repair diskrepair helper from zsh.d/utils.zsh
›
Repair WhatsApprepair helper from zsh.d/utils.zsh
›
‹ Home

chrome

The one way to start Chrome here, so recording works without a prompt.

Start Chromestart Chrome with the flags in chrome/flags
›
Installlink the launchers and the menu entry to chrome.sh
›
Flagsthe one list of Chrome flags; edit only here
›
Check the flagconfirm a running Chrome has the recording flag
›
Chrome READMEwhy it starts this way and its limits
›
‹ Home

windows

Work done on the Windows machine. None of these run from this shell; copy them there.

Installrebuild the Windows dev environment from the manifests
›
Checkcheck the install
›
Roll backremove what the install added
›
Inventorywhat was captured
›
Sign-ins to redosign-ins you must do by hand
›
Clone work reposclone the missing Betec repos; safe to re-run
›
Skill synckeep Windows skill links current
›
Skill sync statuswhen the last sync succeeded
›
Chrome bridgekeep the Codex Chrome link and patch in place
›
‹ Home

cv

The CVs: three versions, their sources and their text, all built from this folder.

Full Stack CVthe full stack version
›
AI Full Stack CVthe AI full stack version
›
AI Integrations CVthe AI integrations version
›
Rebuildrebuild a changed version, then commit the sources and PDFs together
›
Past versionsdated copies kept for reference
›
Text outputsplain-text versions for applications
›
‹ Home

audio

Send all Linux audio to the Windows machine over Tailscale, and take it back.

Startsend audio to the Windows machine
›
Pauserestore the laptop speakers
›
Share controlturn sharing on or off, check it, or play a test tone
›
Stream portwhere the raw audio is served
›
Windows sidethe Windows playback loop; not run from here
›
‹ Home

deskflow

One shared mouse and keyboard between the laptop and Windows. Deskflow replaced Lan Mouse.

Resumerestart Deskflow and ask GNOME for input capture again
›
Everyday usehow to cross edges, the keyboard follow rule and recovery
›
USB mouse sharingforwarding of the Windows USB mouse, off since 2026-10-20; how to turn it back on
›
Network auditwhat the setup connects to
›
‹ Home

clipboard

Clipboard history shared with Windows: a server, a watcher, a picker and a Windows script.

Serverkeeps the history
›
Watcherrecords new copies
›
Pickerchoose an item from the history
›
Windows installinstall the Windows side; verify.ps1 checks it
›
Windows scriptthe AutoHotkey hook on Windows
›
Shared clipboard planthe plan for the shared clipboard
›
‹ Home

hermes

The Hermes agent installed from source; its state is kept out of this repo.

Launcherstart Hermes
›
Restore runbookhow to restore it on a new machine
›
Default config examplesecret-free settings for the default profile
›
Jobs config examplesecret-free settings for the jobs profile
›
Statekeys and profile state; kept on the machine
›
‹ Home

jev

Browser smoke tests against a goal, and asking Jev a question with options.

Browser smoke testrun a goal in a browser and report the supplied checks
›
Ask Jevget a choice; a confidence of 0.85 or more can count as approved
›
Installinstall the pinned upstream and the CLI
›
SecretsAPI keys; never in Git
›
Instructionshow to use it and what it proves
›
‹ Home

skills

The agent skill catalog: where it lives, where it is linked, and the copies kept here.

Catalogthe source of every global skill
›
Linked folderswhere install.sh links the skills
›
Skill tablethe main skills and their purpose
›
Backups kept herecopies of skills kept in this repo
›
Shortlistskills researched on skills.sh and what is installed
›
‹ Home

keepalive

A timer that keeps the Supabase project from going idle.

Installinstall the service and timer
›
Timerwhen it runs
›
Scriptwhat each run does
›
‹ Home

work

Items and dated plans for ongoing work.

Urgent itemswhat needs attention first
›
Planned itemsscheduled work
›
Work itemseverything else in progress
›
Planseach plan, by date
›
‹ Home

reference

Dated incident records for machine failures and the verified fixes.

Incident indexevery incident with its outcome
›
Closed-lid incidentCodeBot kept serving with the lid closed; test passed
›
‹ Home

case-studies

Archived, human-reviewed experiments with their evidence.

Codebot returnthe same design run with and without a skill; the skill run was better
›
Signal gardena documentation exhibit splitting explanation from the live interface
›
Kernel browsers resultscloud browser use cases, speed and recording, tested 2026-10-08
›
Raw answer
I planned the map without building anything. The dump has gaps, so some rows may be incomplete:

- The `workstation` command's own source (`workstation-cli/`) is not in the dump. The top screen is inferred from the README.
- Several READMEs are cut at 2500 characters (agent-framework, browser, chrome, dashboard, deskflow, hermes, init-windows, jev-browser-test, lan-mouse, skills-sync-windows), so their rows may be incomplete.
- I ran no commands and did not check that any listed command or port exists on the machine.

```json
{"screens": [
 {"path": [], "sentence": "The front door: every area of this workstation, one line each. Type an area name to open its screen; the help is grouped by these areas.", "rows": [
  {"name": "Browser", "form": "command: browser", "what": "drive one persistent Chrome window and record proof"},
  {"name": "Agents", "form": "command: agent", "what": "check, list and open the Agent Sandbox"},
  {"name": "Dashboard", "form": "http://127.0.0.1:8780", "what": "today's waiting items and team overview; started by hand"},
  {"name": "Rules", "form": "command: rules", "what": "the rules every agent session follows"},
  {"name": "OpenCode profiles", "form": "command: opencode-profile", "what": "which OpenCode profile runs, its files and switching"},
  {"name": "Claude", "form": "command: claude (usage-guard wrapper)", "what": "Claude Code wrapper, sessions, team park, plugins, usage guard"},
  {"name": "Shell", "form": "files: zsh.d/*.zsh", "what": "git safety, infra, terminal utilities, API keys, review-open"},
  {"name": "Git", "form": "files: .gitconfig and git-hooks/", "what": "git config, hooks and the push and commit gates"},
  {"name": "Machine (Linux)", "form": "scripts in the repo root and laptop-utilities/", "what": "power, display, network, lid and repair helpers"},
  {"name": "Chrome", "form": "command: chrome/chrome.sh", "what": "the one way to start Chrome on this machine"},
  {"name": "Windows", "form": "scripts in init-windows/ and skills-sync-windows/", "what": "rebuild, check and sync the Windows machine; runs on Windows"},
  {"name": "CVs", "form": "folder cv/ (pdflatex)", "what": "build and find the three CV versions"},
  {"name": "Audio", "form": "command: audio-start", "what": "send Linux audio to the Windows machine and back"},
  {"name": "Deskflow", "form": "command: resume-kvm", "what": "shared mouse and keyboard between Linux and Windows"},
  {"name": "Clipboard", "form": "systemd units clipstack-server and clipstack-watcher", "what": "clipboard history and its picker"},
  {"name": "Hermes", "form": "command: hermes", "what": "the Hermes agent, its configs and restore runbook"},
  {"name": "Jev", "form": "command: jev-browser-test", "what": "behavioral browser smoke tests and asking Jev a question"},
  {"name": "Skills", "form": "repo Lebnor/my-skills, linked into ~/.claude/skills", "what": "the agent skill catalog and its backups here"},
  {"name": "Keep-alive", "form": "systemd timer supabase-keepalive", "what": "keeps the Supabase project awake"},
  {"name": "Work", "form": "folder docs/items/ and docs/plans/", "what": "urgent, planned and work items, and dated plans"},
  {"name": "Reference", "form": "folder reference/incidents/", "what": "dated machine incidents and verified fixes"},
  {"name": "Case studies", "form": "folder case-studies/", "what": "reviewed experiments with their evidence"}
 ]},
 {"path": ["browser"], "sentence": "One Chrome window kept open between commands; send it a list of steps and read the JSON result.", "rows": [
  {"name": "Status", "form": "command: browser status", "what": "is the background server and Chrome up"},
  {"name": "Close", "form": "command: browser close", "what": "close Chrome and stop the server"},
  {"name": "Run steps", "form": "command: browser '<json steps>' (goto, screenshot, click, fill and others)", "what": "drive the page"},
  {"name": "Record proof", "form": "steps recordStart and recordStop", "what": "record a feature as proof; the one supported way"},
  {"name": "Browser README", "form": "file browser/README.md", "what": "all actions, presets and login notes"}
 ]},
 {"path": ["agent"], "sentence": "Agent records are checked before any session starts; the sandbox page runs them for real.", "rows": [
  {"name": "Check", "form": "command: agent check", "what": "refuse broken records; exits 1 on failure"},
  {"name": "List", "form": "command: agent list", "what": "agents with tier, model and number of tests"},
  {"name": "Sandbox page", "form": "command: agent serve, then http://127.0.0.1:8790", "what": "pick an agent, change its setup, send a message"},
  {"name": "Agent records", "form": "file ~/projects/my-skills/agents/<id>/agent.yaml", "what": "the typed record of each agent"},
  {"name": "Agent framework README", "form": "file agent-framework/README.md", "what": "how the sandbox page works and its words"}
 ]},
 {"path": ["dashboard"], "sentence": "One screen for the owner, read at a glance: what waits, what the team is doing.", "rows": [
  {"name": "Open", "form": "command: python3 dashboard/server.py, then http://127.0.0.1:8780", "what": "start and open the dashboard; a port can be passed"},
  {"name": "Waiting tab", "form": "page tab #waiting (default)", "what": "cases asked, rule changes proposed and calls made alone"},
  {"name": "Overview tab", "form": "page tab on http://127.0.0.1:8780", "what": "cases and proposals counts, running team lanes"},
  {"name": "Tests", "form": "command: python3 -I -m unittest discover -s dashboard", "what": "199 checks against real data and a real server"},
  {"name": "Concepts version", "form": "command: python3 dashboard-concepts/server.py, then http://127.0.0.1:8781", "what": "the second dashboard, kept to compare the two"}
 ]},
 {"path": ["rules"], "sentence": "The rules every agent follows; only you or an accepted proposal can change them.", "rows": [
  {"name": "Print rules", "form": "command: rules [folder]", "what": "print the rules that apply, optionally for a folder"},
  {"name": "Rules source", "form": "file workboard/rules.yaml", "what": "the rules themselves"},
  {"name": "Rule metadata", "form": "file workboard/rules-meta.yaml", "what": "details kept beside each rule"},
  {"name": "Rule proposals", "form": "folder ~/projects/data/global/rule-proposals/", "what": "proposed changes waiting for accept or reject"},
  {"name": "Generated copy", "form": "file ~/.claude/references/rules.md", "what": "generated from rules.yaml; do not edit by hand"}
 ]},
 {"path": ["opencode"], "sentence": "Which OpenCode profile runs, what each loads, and how to switch or edit them.", "rows": [
  {"name": "Current profile", "form": "command: opencode-profile", "what": "name the profile in use"},
  {"name": "Profiles", "form": "command: opencode-profiles", "what": "show what each profile loads"},
  {"name": "Switch", "form": "command: opencode-switch <name>", "what": "switch every shell's new runs to a profile"},
  {"name": "Sign in", "form": "command: opencode-login", "what": "sign a profile's Claude Code in"},
  {"name": "Files", "form": "command: opencode-files", "what": "list the current profile's files"},
  {"name": "Edit a file", "form": "command: opencode-edit <file>", "what": "open one profile file"},
  {"name": "Help", "form": "command: opencode help (also oc help, opencode-help, oc-help)", "what": "every profile's files and the commands; with more than 3 profiles it writes ~/.opencode-profiles/help.md and opens it"}
 ]},
 {"path": ["claude"], "sentence": "The Claude Code wrapper, its sessions, its usage guard and its team tools.", "rows": [
  {"name": "Claude wrapper", "form": "command: claude (file ~/bin/claude, ahead of ~/.local/bin/claude)", "what": "the usage-guard wrapper that runs Claude Code"},
  {"name": "Usage guard install", "form": "command: claude/usage-guard/install.sh", "what": "install the wrapper on Linux"},
  {"name": "Usage guard on Windows", "form": "file claude/usage-guard/Install-Windows.cmd", "what": "install the wrapper on Windows; runs there"},
  {"name": "Main sessions", "form": "command: claude --main -c, or claude --main -r", "what": "continue or resume the main session"},
  {"name": "Team park", "form": "command: team-park (file ~/.local/bin/team-park)", "what": "park and manage team work"},
  {"name": "Plugins", "form": "folders claude/mods/changelog-pane, review-pane, scratchpad-playground, team-board", "what": "Claude Code plugins kept here"},
  {"name": "Global instructions", "form": "files claude/CLAUDE.md and claude/AGENTS.md", "what": "the global rules and agent notes"}
 ]},
 {"path": ["shell"], "sentence": "Helpers loaded by zsh from ~/.zsh.d/; each one is a command you type.", "rows": [
  {"name": "Git safety", "form": "zsh.d/git-safety.zsh: git checkout", "what": "lists the files and asks [y/N] before discarding changes"},
  {"name": "Infra", "form": "zsh.d/infra.zsh", "what": "Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts"},
  {"name": "Utilities", "form": "zsh.d/utils.zsh", "what": "set-title, killport, IP aliases, lazy nvm and node, Android, Java and Bun"},
  {"name": "API keys", "form": "command: api-keys-edit (file ~/.config/api-keys/env)", "what": "general-use API keys, kept out of Git"},
  {"name": "Review open", "form": "command: review-open (file ~/.local/bin/review-open)", "what": "open a review from bash or an agent"},
  {"name": "Workstation", "form": "command: workstation, setup or ws", "what": "this kit's own help and commands"},
  {"name": "Audio share", "form": "zsh.d/audio-share.zsh, also sourced by ~/.bashrc", "what": "the audio commands on the Audio screen"}
 ]},
 {"path": ["git"], "sentence": "Git settings and the hooks that gate pushes and commits in every repo.", "rows": [
  {"name": "Git config", "form": "file .gitconfig (copied to ~/.gitconfig)", "what": "author, LFS, credential store, hooks path"},
  {"name": "Hooks", "form": "folder git-hooks/ (copied to ~/.git-hooks/)", "what": "Lefthook shims; need lefthook on PATH"},
  {"name": "Push gates", "form": "hook pre-push", "what": "approval note; no push to main in a repo marked team.gitpolicy pull-request"},
  {"name": "Commit gate", "form": "hook commit-msg", "what": "no commit on main in a marked repo"},
  {"name": "Repoint old clone", "form": "command: git remote set-url origin https://github.com/Lebnor/workstation.git", "what": "fix a clone made before the rename"}
 ]},
 {"path": ["machine"], "sentence": "Linux machine settings and repairs; some need sudo or a reboot, as noted.", "rows": [
  {"name": "Minimum power", "form": "command: cpu-min-power.sh (sudo)", "what": "power-saver profile, turbo off, CPU capped at 8%; Intel P-state only"},
  {"name": "Normal power", "form": "command: cpu-normal-power.sh (sudo)", "what": "balanced profile, turbo on, cap back to 100%"},
  {"name": "External monitor", "form": "command: fix_old_monitor_hdmi.sh [--output] [--mode] [--rate] [--quiet]", "what": "set mode and refresh on the HDMI or DP output; default 1920x1080 at 59.88"},
  {"name": "Internet recovery", "form": "command: linux-internet-recovery.sh (re-runs with sudo)", "what": "fix DNS and restart networking"},
  {"name": "Remote terminal recovery", "form": "command: recover-tailscale-remote-terminal.sh; checks port 3500", "what": "repair DNS and Tailscale, then start the remote terminal service"},
  {"name": "Keep running with lid closed", "form": "command: laptop-utilities/keep-running-with-lid-closed.sh", "what": "closing the lid does nothing; applies after reboot"},
  {"name": "Restore lid behavior", "form": "command: laptop-utilities/restore-default-lid-behavior.sh", "what": "remove that setting; applies after reboot"},
  {"name": "Repair keyboard", "form": "command: fix-keyboard", "what": "repair helper from zsh.d/utils.zsh"},
  {"name": "Repair mouse", "form": "command: fix-mouse", "what": "repair helper from zsh.d/utils.zsh"},
  {"name": "Repair disk", "form": "command: fix-disk", "what": "repair helper from zsh.d/utils.zsh"},
  {"name": "Repair WhatsApp", "form": "command: fix-whatsapp", "what": "repair helper from zsh.d/utils.zsh"}
 ]},
 {"path": ["chrome"], "sentence": "The one way to start Chrome here, so recording works without a prompt.", "rows": [
  {"name": "Start Chrome", "form": "command: chrome/chrome.sh (also google-chrome)", "what": "start Chrome with the flags in chrome/flags"},
  {"name": "Install", "form": "command: chrome/install.sh (run once, and after a Chrome update)", "what": "link the launchers and the menu entry to chrome.sh"},
  {"name": "Flags", "form": "file chrome/flags", "what": "the one list of Chrome flags; edit only here"},
  {"name": "Check the flag", "form": "command: pgrep -af chrome | grep -o 'auto-select-desktop-capture-source=[A-Z-]*'", "what": "confirm a running Chrome has the recording flag"},
  {"name": "Chrome README", "form": "file chrome/README.md", "what": "why it starts this way and its limits"}
 ]},
 {"path": ["windows"], "sentence": "Work done on the Windows machine. None of these run from this shell; copy them there.", "rows": [
  {"name": "Install", "form": "file init-windows/Start-Install.cmd (runs on Windows)", "what": "rebuild the Windows dev environment from the manifests"},
  {"name": "Check", "form": "files init-windows/Smoke-Test-Windows.ps1 and Verify-Windows.ps1", "what": "check the install"},
  {"name": "Roll back", "form": "file init-windows/Remove-WindowsPack.ps1", "what": "remove what the install added"},
  {"name": "Inventory", "form": "file init-windows/inventory.md", "what": "what was captured"},
  {"name": "Sign-ins to redo", "form": "file init-windows/secrets-checklist.md", "what": "sign-ins you must do by hand"},
  {"name": "Clone work repos", "form": "file repos/Clone-BetecRepos.ps1", "what": "clone the missing Betec repos; safe to re-run"},
  {"name": "Skill sync", "form": "file skills-sync-windows/Sync-Skills.ps1, run by the runner on each push", "what": "keep Windows skill links current"},
  {"name": "Skill sync status", "form": "file state/last-success.json under ProgramData/MySkillsSync", "what": "when the last sync succeeded"},
  {"name": "Chrome bridge", "form": "file codex/chrome-bridge/Install-CodexChromeBridge.cmd", "what": "keep the Codex Chrome link and patch in place"}
 ]},
 {"path": ["cv"], "sentence": "The CVs: three versions, their sources and their text, all built from this folder.", "rows": [
  {"name": "Full Stack CV", "form": "file cv/cv-full-stack.pdf (source cv-full-stack.tex)", "what": "the full stack version"},
  {"name": "AI Full Stack CV", "form": "file cv/cv-ai-full-stack.pdf (source cv-ai-full-stack.tex)", "what": "the AI full stack version"},
  {"name": "AI Integrations CV", "form": "file cv/cv-ai-integrations.pdf (source cv-ai-integrations.tex)", "what": "the AI integrations version"},
  {"name": "Rebuild", "form": "command: pdflatex -interaction=nonstopmode -halt-on-error <file>.tex, run in cv/", "what": "rebuild a changed version, then commit the sources and PDFs together"},
  {"name": "Past versions", "form": "folders cv/versions/2026-10-04 and 2026-10-04-v2", "what": "dated copies kept for reference"},
  {"name": "Text outputs", "form": "command: cv/text/build-full.sh", "what": "plain-text versions for applications"}
 ]},
 {"path": ["audio"], "sentence": "Send all Linux audio to the Windows machine over Tailscale, and take it back.", "rows": [
  {"name": "Start", "form": "command: audio-start", "what": "send audio to the Windows machine"},
  {"name": "Pause", "form": "command: audio-pause", "what": "restore the laptop speakers"},
  {"name": "Share control", "form": "command: audio-share on|off|status|tone", "what": "turn sharing on or off, check it, or play a test tone"},
  {"name": "Stream port", "form": "tcp port 4953", "what": "where the raw audio is served"},
  {"name": "Windows side", "form": "run by the windows-audio-share agent (ffplay reconnect loop)", "what": "the Windows playback loop; not run from here"}
 ]},
 {"path": ["deskflow"], "sentence": "One shared mouse and keyboard between the laptop and Windows. Deskflow replaced Lan Mouse.", "rows": [
  {"name": "Resume", "form": "command: resume-kvm", "what": "restart Deskflow and ask GNOME for input capture again"},
  {"name": "Everyday use", "form": "file deskflow/README.md", "what": "how to cross edges, the keyboard follow rule and recovery"},
  {"name": "USB mouse sharing", "form": "file usb-mouse/README.md; service deskflow-usb-mouse.service (disabled)", "what": "forwarding of the Windows USB mouse, off since 2026-10-20; how to turn it back on"},
  {"name": "Network audit", "form": "file deskflow/NETWORK-AUDIT.md", "what": "what the setup connects to"}
 ]},
 {"path": ["clipboard"], "sentence": "Clipboard history shared with Windows: a server, a watcher, a picker and a Windows script.", "rows": [
  {"name": "Server", "form": "systemd unit clipstack-server.service (clipstack/server.py)", "what": "keeps the history"},
  {"name": "Watcher", "form": "systemd unit clipstack-watcher.service (clipstack/watcher.py)", "what": "records new copies"},
  {"name": "Picker", "form": "command: clipstack/picker.py", "what": "choose an item from the history"},
  {"name": "Windows install", "form": "file clipstack/windows/install.ps1 (runs on Windows)", "what": "install the Windows side; verify.ps1 checks it"},
  {"name": "Windows script", "form": "file clipstack/windows/clipstack.ahk", "what": "the AutoHotkey hook on Windows"},
  {"name": "Shared clipboard plan", "form": "file docs/plans/2026-10-26-shared-clipboard/plan.md", "what": "the plan for the shared clipboard"}
 ]},
 {"path": ["hermes"], "sentence": "The Hermes agent installed from source; its state is kept out of this repo.", "rows": [
  {"name": "Launcher", "form": "command: hermes (file ~/.local/bin/hermes)", "what": "start Hermes"},
  {"name": "Restore runbook", "form": "file hermes/RESTORE.md", "what": "how to restore it on a new machine"},
  {"name": "Default config example", "form": "file hermes/default.config.example.yaml", "what": "secret-free settings for the default profile"},
  {"name": "Jobs config example", "form": "file hermes/jobs.config.example.yaml", "what": "secret-free settings for the jobs profile"},
  {"name": "State", "form": "folder ~/.hermes (not in Git)", "what": "keys and profile state; kept on the machine"}
 ]},
 {"path": ["jev"], "sentence": "Browser smoke tests against a goal, and asking Jev a question with options.", "rows": [
  {"name": "Browser smoke test", "form": "command: jev-browser-test (with a URL and a goal)", "what": "run a goal in a browser and report the supplied checks"},
  {"name": "Ask Jev", "form": "command: jev '<context>' -c 'question' option1,option2,other_none -j", "what": "get a choice; a confidence of 0.85 or more can count as approved"},
  {"name": "Install", "form": "command: sh jev-browser-test/install.sh", "what": "install the pinned upstream and the CLI"},
  {"name": "Secrets", "form": "file ~/.config/jev-browser-test/env (mode 600)", "what": "API keys; never in Git"},
  {"name": "Instructions", "form": "file jev-browser-test/instructions.md", "what": "how to use it and what it proves"}
 ]},
 {"path": ["skills"], "sentence": "The agent skill catalog: where it lives, where it is linked, and the copies kept here.", "rows": [
  {"name": "Catalog", "form": "repo Lebnor/my-skills (/home/liel/projects/my-skills)", "what": "the source of every global skill"},
  {"name": "Linked folders", "form": "folders ~/.claude/skills, ~/.codex/skills, ~/.config/opencode/skills", "what": "where install.sh links the skills"},
  {"name": "Skill table", "form": "section of README.md", "what": "the main skills and their purpose"},
  {"name": "Backups kept here", "form": "folder claude/skills/", "what": "copies of skills kept in this repo"},
  {"name": "Shortlist", "form": "file claude/skills-shortlist.md", "what": "skills researched on skills.sh and what is installed"}
 ]},
 {"path": ["keepalive"], "sentence": "A timer that keeps the Supabase project from going idle.", "rows": [
  {"name": "Install", "form": "command: supabase-keepalive/install.sh", "what": "install the service and timer"},
  {"name": "Timer", "form": "systemd timer supabase-keepalive.timer", "what": "when it runs"},
  {"name": "Script", "form": "file supabase-keepalive/supabase-keepalive.sh", "what": "what each run does"}
 ]},
 {"path": ["work"], "sentence": "Items and dated plans for ongoing work.", "rows": [
  {"name": "Urgent items", "form": "file docs/items/urgent.item.md", "what": "what needs attention first"},
  {"name": "Planned items", "form": "file docs/items/planned.item.md", "what": "scheduled work"},
  {"name": "Work items", "form": "file docs/items/work.item.md", "what": "everything else in progress"},
  {"name": "Plans", "form": "folder docs/plans/ (dated subfolders)", "what": "each plan, by date"}
 ]},
 {"path": ["reference"], "sentence": "Dated incident records for machine failures and the verified fixes.", "rows": [
  {"name": "Incident index", "form": "file reference/README.md", "what": "every incident with its outcome"},
  {"name": "Closed-lid incident", "form": "file reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "CodeBot kept serving with the lid closed; test passed"}
 ]},
 {"path": ["case-studies"], "sentence": "Archived, human-reviewed experiments with their evidence.", "rows": [
  {"name": "Codebot return", "form": "file case-studies/conceptual-modeling/2026-09-15-codebot-return/README.md", "what": "the same design run with and without a skill; the skill run was better"},
  {"name": "Signal garden", "form": "file case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "a documentation exhibit splitting explanation from the live interface"},
  {"name": "Kernel browsers results", "form": "file /home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md (outside this repo)", "what": "cloud browser use cases, speed and recording, tested 2026-10-08"}
 ]}
],
 "questions": [
  "Should workstation, setup and ws stay the one front door, with every existing command (browser, agent, rules, opencode-profile and so on) still working and listed under its area? Recommendation: yes. Rename nothing; the help only points at the names that already exist.",
  "Should the Windows steps appear in the Linux help? Recommendation: yes, under the Windows screen, marked 'runs on Windows' and printed as text to copy, never run from zsh, because they cannot run here.",
  "Should retired items (Lan Mouse, codex/playwright-mcp, the old Codex recorders) be left out of the help? Recommendation: yes; they stay in their READMEs and the help does not mention them.",
  "Should machine scripts that need sudo or a reboot appear in the help? Recommendation: yes, each marked 'needs sudo' or 'after reboot'; the help prints the command and never runs it.",
  "Should helpers that embed a credential in git URLs (git_pull_with_creds, update-gitlab-token) appear? Recommendation: no. Leave them out until the credential is rotated and moved to a credential manager, as the checklist asks.",
  "Should the concepts dashboard (port 8781) appear beside the main dashboard? Recommendation: only under Dashboard, labelled as a comparison, not on the top screen.",
  "How much of the skill catalog should the help list? Recommendation: the README's skill table and a link to my-skills; the full catalog lives in another repo and would swamp the help.",
  "Should the top screen show services that are not on by default (dashboard, agent sandbox, clipboard, keep-alive)? Recommendation: yes, each with its command and whether it runs by default; the help shows them and never starts them.",
  "Can you add workstation-cli/ (workstation.py and terminal_links.py) to the dump? Recommendation: yes, before the top screen is finalized. Its current help text is not visible here, so the top screen and its existing text are inferred from the README.",
  "Should the workstation help open the link pages in the terminal, or print plain text? Recommendation: keep what the README describes: links on a terminal, plain markdown when piped."
 ]}
```

Today's skills · run 5 exit=0 seconds=171 · prompt

P1 Recall: 0.871P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 9P6 Own words: 0.958P8 Worded per screen: 0P9 Grouping (ARI): 0.392
As terminal help
Everything this machine's kit keeps and runs, grouped by what you come here to do.
Dashboardworkstation dashboardPrints the dashboard screen: what waits for you and the team running now.
Agentsworkstation agentsPrints the agents screen: the sandbox, rules, skills, teams, Hermes and data.
Assistantsworkstation assistantsPrints the assistants screen: how Claude Code and Codex are set up here.
Browserworkstation browserPrints the browser screen: the browser command, Chrome and the Codex Chrome bridge.
Machineworkstation machinePrints the machine screen: power, network, screen, lid, sound, clipboard and services.
Inputworkstation inputPrints the input screen: sharing the laptop keyboard and mouse with Windows.
Windowsworkstation windowsPrints the Windows screen: its setup, skill sync, repo clones and kept copies.
Shellworkstation shellPrints the shell screen: the zsh helpers, Git settings and OpenCode commands.
Documentsworkstation documentsPrints the documents screen: CVs, plans, designs, case studies and incidents.
dashboard
The dashboard: what waits for you (decisions, rule changes, calls made alone) and the team running now.
Start the dashboardpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard on http://127.0.0.1:8780 and keeps it running until you stop it.
Dashboard pagehttp://127.0.0.1:8780Opens the dashboard page in your browser, once it is started.
Concepts versionpython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts variant on http://127.0.0.1:8781 to compare with the dashboard.
Dashboard checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the 199 dashboard checks against the real data and a real server.
Dashboard guidedashboard/README.mdOpens the dashboard guide.
agents
The agents: the sandbox where you run them, the rules and skills they follow, the teams they form, Hermes, and the data they keep.
Sandboxworkstation agents sandboxPrints the sandbox screen: the agent records and how to check and run them.
Rulesworkstation agents rulesPrints the rules screen: the rules every org follows and where they are kept.
Skillsworkstation agents skillsPrints the skills screen: the reusable instructions agents load.
Teamsworkstation agents teamsPrints the teams screen: how a team is started, its files and its roles.
Hermesworkstation agents hermesPrints the Hermes screen: the separate agent runtime, its config and its restore notes.
Dataworkstation agents dataPrints the data screen: the answers, cases and verdicts the agents keep.
Agent framework guideagent-framework/README.mdOpens the guide to the agent records and the sandbox.
agents › sandbox
The agent records and the Agent Sandbox: which agents exist, whether their records are sound, and the page where you run them.
List agentsagent listLists the agents with their tier, model and number of tests.
Check agentsagent checkChecks every agent record and refuses broken ones (exit 1).
Agent Sandbox pageagent serveStarts the Agent Sandbox page on http://127.0.0.1:8790.
Agent records~/projects/my-skills/agents/Opens the agent records, one agent.yaml per agent.
Results and memory~/projects/data/Opens each agent's test results and memory.
Framework intent.idd/modules/agent-framework/INTENT.mdOpens the intent and rules of the agent framework.
agents › rules
The rules every org follows: the file they are written in, the tool that prints them, and the copy Claude reads.
Print rulesrulesPrints the rules for the current folder, or the folder you give.
Rules fileworkboard/rules.yamlOpens the rules; they change only by your decision or an accepted proposal.
Rule metadataworkboard/rules-meta.yamlOpens the metadata for each rule.
Generated copy~/.claude/references/rules.mdOpens the copy Claude reads, rebuilt from rules.yaml; do not edit it by hand.
Rules testsworkboard/test_rules.pyOpens the rules tests.
Rules helperzsh.d/rules.zshOpens the zsh helper for the rules tool.
agents › skills
The skills: reusable instructions agents load, where the global ones come from, and the backups kept here.
Global skills repo~/projects/my-skillsOpens the repo that holds the global skills.
Link skills~/projects/my-skills/install.shLinks the global skills into Claude, Codex and OpenCode.
Skill backupsclaude/skills/Opens the skills backed up in this repo; copy in the ones you want.
Skill shortlistclaude/skills-shortlist.mdOpens the skills researched on skills.sh and what is installed.
agents › teams
The teams: how one is started, its team files, the roles its members play, and how they talk to each other.
Start a team/spawn-team <team> in Claude, $spawn-team <team> in CodexStarts a team inside the chat, from its team file.
Team files~/projects/my-skills/spawn-team/teams/Opens the team files, such as worker-pair and research-team.
Role instructions~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.mdOpens the instructions for each role.
Claude personas~/projects/my-skills/agents/<id>/claude.mdOpens an agent's persona for Claude.
Handoff rules~/projects/my-skills/coordinated-agentic-session/references/handoff.mdOpens the rules for how team members hand work to each other.
QA agent role notesdocs/roles/qa-agent.mdOpens the QA agent's role notes in this repo.
agents › hermes
Hermes, a separate agent runtime installed from source, with its launcher, example configs and restore notes.
Launch HermeshermesStarts Hermes, the agent runtime.
Hermes guidehermes/README.mdOpens the Hermes guide: installation, configuration and status.
Restore stepshermes/RESTORE.mdOpens the steps to restore Hermes.
Default config examplehermes/default.config.example.yamlOpens the example config for the default profile, without secrets.
Jobs config examplehermes/jobs.config.example.yamlOpens the example config for the jobs profile, without secrets.
State and secrets~/.hermesOpens Hermes's state and secrets folder, which is not in Git.
Source checkout~/projects/hermes-agentOpens the Hermes source checkout.
agents › data
The data repository: the answers, cases, rule proposals and verdicts the agents keep, and the scripts that move them.
Data repo~/projects/dataOpens the private data repository.
Sync scripts~/projects/data/bin/Opens the scripts that issue, pull and sync cases and answers.
Sync timersystemctl --user status data-pull.timerShows the timer that syncs answers every 5 minutes.
Supervision backlog~/projects/betec/workboard/docs/supervision-backlog.mdOpens the supervision backlog in the betec workspace.
assistants
How Claude Code and Codex are set up on this machine: their global rules, settings, hooks, usage guard and plugins.
Global rules for Claudeclaude/CLAUDE.mdOpens the global rules every Claude session reads.
Short agent notesclaude/AGENTS.mdOpens the shorter global notes for agents.
Claude settingsclaude/settings.jsonOpens Claude Code's settings, which Windows deploys too.
Codex configcodex/config.tomlOpens the Codex CLI config.
Hooksworkstation assistants hooksPrints the hooks screen: the scripts Claude runs at set points.
Session typesworkstation assistants sessionsPrints the sessions screen: main sessions and how to continue them.
Usage guardworkstation assistants usage-guardPrints the usage guard screen: the wrapper that checks Claude usage before it runs.
Pluginsworkstation assistants pluginsPrints the plugins screen: the Claude plugins kept here.
Linux instructions copyclaude/linux-global/Opens the copy of this machine's installed global instructions.
Windows instructions copyclaude/windows-global/Opens the copy of the Windows Claude instructions.
Communication draftclaude/communication-framework.mdOpens a draft on how agents should communicate; it is not enforced anywhere yet.
assistants › hooks
The hook scripts Claude Code runs at set points in a session, installed in ~/.claude/hooks.
Core rules~/.claude/hooks/core-rules.shApplies the core rules at session start and before each Bash call.
Local server guard~/.claude/hooks/local-server-guard.pyChecks Bash calls before they run, to guard local servers.
Machine history~/.claude/hooks/machine-history.shRecords the machine's history when a session runs (see its header).
Proof reminder~/.claude/hooks/proof-reminder.shReminds you to prove a change after edits and Bash runs.
Team activity~/.claude/hooks/team-activity.shRecords what the team is doing (see its header).
Core-rules testsclaude/hooks/test_core_rules.shOpens the core-rules tests.
assistants › sessions
The session types: the main session and the picker that chooses how a session starts.
Continue main sessionclaude --main -cContinues the last main session.
Resume main sessionclaude --main -rPicks a main session to resume.
Session-type hook~/.claude/hooks/session-types.shRuns at session start as the SessionStart hook for session types.
Session-type testsclaude/session-types/tests/run.shRuns the session-types tests.
Picker design workclaude/session-types/docs/design/2026-10-21-picker-views/Opens the picker-views design work.
assistants › usage-guard
The usage guard: the wrapper that runs Claude Code with a usage check, how it installs, and its tests.
Claude wrapperclaudeRuns Claude Code through the usage guard.
Install on Linuxclaude/usage-guard/install.shInstalls the usage guard on this Linux machine.
Install on Windowsclaude/usage-guard/Install-Windows.cmdInstalls the usage guard on Windows.
Shared usage readerclaude/usage-guard/plugin/hooks/shared-usage.pyOpens the script that reads usage for the plugin hooks.
Request-budget testsclaude/usage-guard/tests/test_request_budget.pyOpens the request-budget tests.
Logged resolutionsclaude/usage-guard/.bdd/qa/resolutions/Opens the logged resolutions of stale-usage and budget problems.
assistants › plugins
The Claude plugins kept in this repo, one folder each.
Changelog paneclaude/mods/changelog-pane/Opens the changelog pane plugin.
Review paneclaude/mods/review-pane/Opens the review pane plugin and its design notes.
Scratchpadclaude/mods/scratchpad-playground/Opens the scratchpad plugin.
Team boardclaude/mods/team-board/Opens the team board plugin.
browser
The browser: the one Chrome window the agents and you share, the command that drives it, and the tools around it.
Browser commandbrowser '<steps>'Runs browser steps in the one Chrome window kept open.
Browser statusbrowser statusShows whether the browser server is up.
Close browserbrowser closeCloses Chrome and stops the browser server.
Browser guidebrowser/README.mdOpens the browser guide, including how to record proof.
Chrome launcherchrome/chrome.shOpens the Chrome launcher, the only way to start Chrome here.
Chrome flagschrome/flagsOpens the Chrome launch flags; edit them here only.
Chrome guidechrome/README.mdOpens the Chrome guide and why it starts this way.
Smoke QAjev-browser-testRuns a goal in a browser and checks the text and URL you give it.
Codex Chrome bridgecodex/chrome-bridge/install.shInstalls the watcher that keeps the Codex Chrome bridge working.
Codex browser path (retired)codex/browser/README.mdOpens the old Codex browser path; the browser command replaces it for what it can drive.
machine
This Linux machine: its power, network, screen, laptop lid, sound, repairs, clipboard and background services.
Power savercpu-min-power.shSwitches the CPU to power-saver with turbo off (Intel only; asks for sudo).
Balanced powercpu-normal-power.shSwitches the CPU back to balanced with turbo on.
Internet recoverylinux-internet-recovery.shResets DNS and restarts networking (re-runs itself with sudo).
Tailscale recoveryrecover-tailscale-remote-terminal.shRepairs DNS, restarts Tailscale and checks the remote terminal on port 3500.
External monitorfix_old_monitor_hdmi.shSets the external monitor's mode and refresh rate with xrandr.
Keep running with lid closedlaptop-utilities/keep-running-with-lid-closed.shMakes closing the lid keep the laptop running (applies after reboot).
Restore lid defaultlaptop-utilities/restore-default-lid-behavior.shRestores the default lid behavior (applies after reboot).
Repair helpersfix-keyboard, fix-mouse, fix-disk, fix-whatsappRuns one repair helper for the keyboard, mouse, disk or WhatsApp.
Send audio to Windowsaudio-startSends all Linux audio to the Windows machine over Tailscale.
Restore speakersaudio-pauseRestores the speakers and stops sending audio to Windows.
Clipboardworkstation machine clipboardPrints the clipboard screen: the picker, its services and the Windows script.
Servicesworkstation machine servicesPrints the services screen: the background timers and services.
machine › clipboard
The clipboard history: what you copied earlier, its picker, and the parts that keep it running.
Clipboard pickerpython3 ~/projects/workstation/clipstack/picker.pyOpens the picker to paste something copied earlier.
Clipboard serverclipstack/server.pyServes the clipboard history, run by the clipstack-server service.
Clipboard watcherclipstack/watcher.pyWatches the clipboard for new copies, run by the clipstack-watcher service.
Install clipboardclipstack/install.shInstalls the clipboard server and watcher as user services.
Windows clipboard scriptclipstack/windows/clipstack.ahkOpens the Windows clipboard script.
Clipboard testsclipstack/test_server.pyOpens the clipboard server tests.
machine › services
The background timers and services that run on this machine, and how to check each one.
List timerssystemctl --user list-timersLists the timers that run in the background.
Clipboard server statussystemctl --user status clipstack-serverShows whether the clipboard server is running.
Clipboard watcher statussystemctl --user status clipstack-watcherShows whether the clipboard watcher is running.
Deskflow statussystemctl --user status deskflowShows whether Deskflow, the keyboard and mouse sharing, is running.
Remote terminal statussystemctl --user status remote-terminalShows whether the remote terminal on port 3500 is running.
Codex bridge timersystemctl --user status codex-chrome-bridge.timerShows the timer that keeps the Codex Chrome bridge working.
Supabase keep-alivesupabase-keepalive/supabase-keepalive.timerKeeps the Supabase project awake on a timer.
Answer sync timersystemctl --user status data-pull.timerShows the timer that pulls answers every 5 minutes.
Rules reminder timerdocs/plans/2026-10-24-rules-per-role/reminder/Opens the rules reminder timer and its unit.
input
Sharing one keyboard and mouse between this laptop and the Windows PC: the current setup and the retired one.
Deskflow guidedeskflow/README.mdOpens the Deskflow guide: everyday use and recovery.
Deskflow settingsdeskflow/linux.confOpens the Deskflow settings copied to the laptop.
Deskflow servicedeskflow/deskflow.serviceOpens the unit that runs Deskflow at graphical login.
Resume inputresume-kvmStarts Deskflow again and asks for input access.
Windows USB mouse notesdeskflow/usb-mouse/README.mdOpens the notes on forwarding the Windows USB mouse, off since 2026-10-20.
Firewall lockdowndeskflow/deskflow-lockdown.nftOpens the firewall rules for Deskflow's lockdown.
Network auditdeskflow/NETWORK-AUDIT.mdOpens the network audit of Deskflow.
Lan Mouse (retired)lan-mouse/README.mdOpens the retired Lan Mouse guide; do not run it alongside Deskflow.
windows
The Windows PC: its setup and checks, its skill sync, the work repos cloned onto it, and the copies of its files kept here.
Install Windows setupinit-windows/Start-Install.cmdInstalls the Windows setup from its manifests (asks for administrator).
Check Windows setupinit-windows/Smoke-Test-Windows.ps1Checks the Windows setup against its manifests.
Remove Windows packinit-windows/Remove-WindowsPack.ps1Removes the packs the install added (rollback).
Setup guideinit-windows/README.mdOpens the Windows setup guide.
Sign-ins to redoinit-windows/secrets-checklist.mdOpens the list of sign-ins to redo by hand.
Captured inventoryinit-windows/inventory.mdOpens what the setup captured.
Windows user scriptsinit-windows/user-scripts/Opens the scripts copied to the Windows Scripts folder.
Skill sync guideskills-sync-windows/README.mdOpens the guide to the Windows skill sync, which runs on each push to master.
Clone work reposrepos/Clone-BetecRepos.ps1Clones the missing work repositories into the standard layout.
shell
The shell helpers in ~/.zsh.d: the commands you type in a terminal and the files they read.
Gitworkstation shell gitPrints the Git screen: checkout safety, Git settings and hooks.
OpenCodeworkstation shell opencodePrints the OpenCode screen: the profiles and the commands that run OpenCode.
Terminal helperszsh.d/utils.zshOpens the terminal helpers: set-title, killport, IP aliases and lazy node loaders.
Docker and database helperszsh.d/infra.zshOpens the Docker, Prisma, Postgres, nginx and VPN helpers (holds a credential to rotate).
API keysapi-keys-editOpens the API keys file, which is never in Git.
Review openreview-openOpens a file for review, from zsh, bash or an agent.
Dash path warningzsh.d/dash-path-warn.zshOpens the helper that warns about dash paths.
shell › git
Git here: the checkout safety wrapper, the Git settings, and the hooks that run in every repo.
Checkout safetyzsh.d/git-safety.zshOpens the wrapper that lists files and asks before git checkout discards changes.
Git settings.gitconfigOpens the Git identity, LFS and hooks-path settings.
Hook shimsgit-hooks/Opens the Lefthook shims that run in every repo.
Push gatesgit-hooks/pre-pushOpens the push gates: the approval note and no pushes to main in marked repos.
shell › opencode
The OpenCode profiles: which files each profile loads, and the commands that run OpenCode with the current one.
Profiles tableopencode helpPrints every profile's files, one column per profile, and the commands.
Current profileopencode-profilePrints the name of the current profile.
All profilesopencode-profilesPrints what each profile loads.
Switch profileopencode-switch <name>Switches every shell's new runs to the named profile.
Sign in a profileopencode-loginSigns a profile's Claude Code in.
Current profile filesopencode-filesPrints the current profile's files.
Edit a profile fileopencode-edit <file>Opens one of the current profile's files in the editor.
Profile folderopencode-profiles/Opens the profile folder and its tests.
documents
The written things: CVs, dated plans and designs, case studies, machine incidents and the archive of moved files.
CVsworkstation documents cvPrints the CVs screen: three versions, each as PDF and LaTeX.
Papersworkstation documents papersPrints the papers screen: plans, designs, research, flows and work items.
Case studiescase-studies/Opens the archived experiments, each with its own README.
Machine incidentsreference/Opens the dated machine incident records and their index.
Changelogdocs/changelog/Opens the dated changelog entries.
Archive~/archive/Opens the archive of moved files; it is not backed up (see its README).
documents › cv
The CVs: three versions, each as a PDF and as the LaTeX it is built from.
Full Stack Developer CVcv/cv-full-stack.pdfOpens the Full Stack Developer CV.
Full Stack LaTeXcv/cv-full-stack.texOpens the LaTeX source of that CV.
AI Full Stack Engineer CVcv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
AI Integrations CVcv/cv-ai-integrations.pdfOpens the AI Integrations CV.
Rebuild a CVpdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex (run in cv/)Rebuilds one CV's PDF from its LaTeX source.
Dated versionscv/versions/Opens the dated CV versions, as PDF and text.
CV workflowcv/WORKFLOW.mdOpens the steps for updating a CV.
documents › papers
The dated working papers: plans, designs, research, flows, work items, and playbooks.
Plansdocs/plans/Opens the dated plans, one folder each.
Designsdocs/design/Opens the design pitches and recommendations.
Researchdocs/research/Opens the research notes behind the plans.
Flowsdocs/flows/Opens the flow cards and data models.
Work itemsdocs/items/Opens the planned, urgent and work item lists.
Playbooksdocs/playbooks/Opens the working playbooks.
Functional researchdocs/functional-research/Opens the research on other agent frameworks.
Questions
  • Keep `setup` as a second alias for the facade? The README lists `workstation`, `setup` and `ws`, but `setup` is a common word and probably clashes. Recommendation: keep `workstation` and `ws` only, after `whence -a setup` shows what else owns the name.
  • Keep `opencode-profile` (prints the current profile) next to `opencode-profiles` (prints every profile)? They differ by one letter. Recommendation: keep the names, since scripts and habits use them, and label the rows 'current' and 'all' in the help screen.
  • Should the map start the dashboard and the Agent Sandbox servers, or only show their addresses? Recommendation: include the start rows. Both are thin commands over existing scripts, and each runs in the foreground until you stop it.
As phone screens

Home

Everything this machine's kit keeps and runs, grouped by what you come here to do.

DashboardPrints the dashboard screen: what waits for you and the team running now.
›
AgentsPrints the agents screen: the sandbox, rules, skills, teams, Hermes and data.
›
AssistantsPrints the assistants screen: how Claude Code and Codex are set up here.
›
BrowserPrints the browser screen: the browser command, Chrome and the Codex Chrome bridge.
›
MachinePrints the machine screen: power, network, screen, lid, sound, clipboard and services.
›
InputPrints the input screen: sharing the laptop keyboard and mouse with Windows.
›
WindowsPrints the Windows screen: its setup, skill sync, repo clones and kept copies.
›
ShellPrints the shell screen: the zsh helpers, Git settings and OpenCode commands.
›
DocumentsPrints the documents screen: CVs, plans, designs, case studies and incidents.
›
‹ Home

dashboard

The dashboard: what waits for you (decisions, rule changes, calls made alone) and the team running now.

Start the dashboardStarts the dashboard on http://127.0.0.1:8780 and keeps it running until you stop it.
›
Dashboard pageOpens the dashboard page in your browser, once it is started.
›
Concepts versionStarts the concepts variant on http://127.0.0.1:8781 to compare with the dashboard.
›
Dashboard checksRuns the 199 dashboard checks against the real data and a real server.
›
Dashboard guideOpens the dashboard guide.
›
‹ Home

agents

The agents: the sandbox where you run them, the rules and skills they follow, the teams they form, Hermes, and the data they keep.

SandboxPrints the sandbox screen: the agent records and how to check and run them.
›
RulesPrints the rules screen: the rules every org follows and where they are kept.
›
SkillsPrints the skills screen: the reusable instructions agents load.
›
TeamsPrints the teams screen: how a team is started, its files and its roles.
›
HermesPrints the Hermes screen: the separate agent runtime, its config and its restore notes.
›
DataPrints the data screen: the answers, cases and verdicts the agents keep.
›
Agent framework guideOpens the guide to the agent records and the sandbox.
›
‹ agents

sandbox

The agent records and the Agent Sandbox: which agents exist, whether their records are sound, and the page where you run them.

List agentsLists the agents with their tier, model and number of tests.
›
Check agentsChecks every agent record and refuses broken ones (exit 1).
›
Agent Sandbox pageStarts the Agent Sandbox page on http://127.0.0.1:8790.
›
Agent recordsOpens the agent records, one agent.yaml per agent.
›
Results and memoryOpens each agent's test results and memory.
›
Framework intentOpens the intent and rules of the agent framework.
›
‹ agents

rules

The rules every org follows: the file they are written in, the tool that prints them, and the copy Claude reads.

Print rulesPrints the rules for the current folder, or the folder you give.
›
Rules fileOpens the rules; they change only by your decision or an accepted proposal.
›
Rule metadataOpens the metadata for each rule.
›
Generated copyOpens the copy Claude reads, rebuilt from rules.yaml; do not edit it by hand.
›
Rules testsOpens the rules tests.
›
Rules helperOpens the zsh helper for the rules tool.
›
‹ agents

skills

The skills: reusable instructions agents load, where the global ones come from, and the backups kept here.

Global skills repoOpens the repo that holds the global skills.
›
Link skillsLinks the global skills into Claude, Codex and OpenCode.
›
Skill backupsOpens the skills backed up in this repo; copy in the ones you want.
›
Skill shortlistOpens the skills researched on skills.sh and what is installed.
›
‹ agents

teams

The teams: how one is started, its team files, the roles its members play, and how they talk to each other.

Start a teamStarts a team inside the chat, from its team file.
›
Team filesOpens the team files, such as worker-pair and research-team.
›
Role instructionsOpens the instructions for each role.
›
Claude personasOpens an agent's persona for Claude.
›
Handoff rulesOpens the rules for how team members hand work to each other.
›
QA agent role notesOpens the QA agent's role notes in this repo.
›
‹ agents

hermes

Hermes, a separate agent runtime installed from source, with its launcher, example configs and restore notes.

Launch HermesStarts Hermes, the agent runtime.
›
Hermes guideOpens the Hermes guide: installation, configuration and status.
›
Restore stepsOpens the steps to restore Hermes.
›
Default config exampleOpens the example config for the default profile, without secrets.
›
Jobs config exampleOpens the example config for the jobs profile, without secrets.
›
State and secretsOpens Hermes's state and secrets folder, which is not in Git.
›
Source checkoutOpens the Hermes source checkout.
›
‹ agents

data

The data repository: the answers, cases, rule proposals and verdicts the agents keep, and the scripts that move them.

Data repoOpens the private data repository.
›
Sync scriptsOpens the scripts that issue, pull and sync cases and answers.
›
Sync timerShows the timer that syncs answers every 5 minutes.
›
Supervision backlogOpens the supervision backlog in the betec workspace.
›
‹ Home

assistants

How Claude Code and Codex are set up on this machine: their global rules, settings, hooks, usage guard and plugins.

Global rules for ClaudeOpens the global rules every Claude session reads.
›
Short agent notesOpens the shorter global notes for agents.
›
Claude settingsOpens Claude Code's settings, which Windows deploys too.
›
Codex configOpens the Codex CLI config.
›
HooksPrints the hooks screen: the scripts Claude runs at set points.
›
Session typesPrints the sessions screen: main sessions and how to continue them.
›
Usage guardPrints the usage guard screen: the wrapper that checks Claude usage before it runs.
›
PluginsPrints the plugins screen: the Claude plugins kept here.
›
Linux instructions copyOpens the copy of this machine's installed global instructions.
›
Windows instructions copyOpens the copy of the Windows Claude instructions.
›
Communication draftOpens a draft on how agents should communicate; it is not enforced anywhere yet.
›
‹ assistants

hooks

The hook scripts Claude Code runs at set points in a session, installed in ~/.claude/hooks.

Core rulesApplies the core rules at session start and before each Bash call.
›
Local server guardChecks Bash calls before they run, to guard local servers.
›
Machine historyRecords the machine's history when a session runs (see its header).
›
Proof reminderReminds you to prove a change after edits and Bash runs.
›
Team activityRecords what the team is doing (see its header).
›
Core-rules testsOpens the core-rules tests.
›
‹ assistants

sessions

The session types: the main session and the picker that chooses how a session starts.

Continue main sessionContinues the last main session.
›
Resume main sessionPicks a main session to resume.
›
Session-type hookRuns at session start as the SessionStart hook for session types.
›
Session-type testsRuns the session-types tests.
›
Picker design workOpens the picker-views design work.
›
‹ assistants

usage-guard

The usage guard: the wrapper that runs Claude Code with a usage check, how it installs, and its tests.

Claude wrapperRuns Claude Code through the usage guard.
›
Install on LinuxInstalls the usage guard on this Linux machine.
›
Install on WindowsInstalls the usage guard on Windows.
›
Shared usage readerOpens the script that reads usage for the plugin hooks.
›
Request-budget testsOpens the request-budget tests.
›
Logged resolutionsOpens the logged resolutions of stale-usage and budget problems.
›
‹ assistants

plugins

The Claude plugins kept in this repo, one folder each.

Changelog paneOpens the changelog pane plugin.
›
Review paneOpens the review pane plugin and its design notes.
›
ScratchpadOpens the scratchpad plugin.
›
Team boardOpens the team board plugin.
›
‹ Home

browser

The browser: the one Chrome window the agents and you share, the command that drives it, and the tools around it.

Browser commandRuns browser steps in the one Chrome window kept open.
›
Browser statusShows whether the browser server is up.
›
Close browserCloses Chrome and stops the browser server.
›
Browser guideOpens the browser guide, including how to record proof.
›
Chrome launcherOpens the Chrome launcher, the only way to start Chrome here.
›
Chrome flagsOpens the Chrome launch flags; edit them here only.
›
Chrome guideOpens the Chrome guide and why it starts this way.
›
Smoke QARuns a goal in a browser and checks the text and URL you give it.
›
Codex Chrome bridgeInstalls the watcher that keeps the Codex Chrome bridge working.
›
Codex browser path (retired)Opens the old Codex browser path; the browser command replaces it for what it can drive.
›
‹ Home

machine

This Linux machine: its power, network, screen, laptop lid, sound, repairs, clipboard and background services.

Power saverSwitches the CPU to power-saver with turbo off (Intel only; asks for sudo).
›
Balanced powerSwitches the CPU back to balanced with turbo on.
›
Internet recoveryResets DNS and restarts networking (re-runs itself with sudo).
›
Tailscale recoveryRepairs DNS, restarts Tailscale and checks the remote terminal on port 3500.
›
External monitorSets the external monitor's mode and refresh rate with xrandr.
›
Keep running with lid closedMakes closing the lid keep the laptop running (applies after reboot).
›
Restore lid defaultRestores the default lid behavior (applies after reboot).
›
Repair helpersRuns one repair helper for the keyboard, mouse, disk or WhatsApp.
›
Send audio to WindowsSends all Linux audio to the Windows machine over Tailscale.
›
Restore speakersRestores the speakers and stops sending audio to Windows.
›
ClipboardPrints the clipboard screen: the picker, its services and the Windows script.
›
ServicesPrints the services screen: the background timers and services.
›
‹ machine

clipboard

The clipboard history: what you copied earlier, its picker, and the parts that keep it running.

Clipboard pickerOpens the picker to paste something copied earlier.
›
Clipboard serverServes the clipboard history, run by the clipstack-server service.
›
Clipboard watcherWatches the clipboard for new copies, run by the clipstack-watcher service.
›
Install clipboardInstalls the clipboard server and watcher as user services.
›
Windows clipboard scriptOpens the Windows clipboard script.
›
Clipboard testsOpens the clipboard server tests.
›
‹ machine

services

The background timers and services that run on this machine, and how to check each one.

List timersLists the timers that run in the background.
›
Clipboard server statusShows whether the clipboard server is running.
›
Clipboard watcher statusShows whether the clipboard watcher is running.
›
Deskflow statusShows whether Deskflow, the keyboard and mouse sharing, is running.
›
Remote terminal statusShows whether the remote terminal on port 3500 is running.
›
Codex bridge timerShows the timer that keeps the Codex Chrome bridge working.
›
Supabase keep-aliveKeeps the Supabase project awake on a timer.
›
Answer sync timerShows the timer that pulls answers every 5 minutes.
›
Rules reminder timerOpens the rules reminder timer and its unit.
›
‹ Home

input

Sharing one keyboard and mouse between this laptop and the Windows PC: the current setup and the retired one.

Deskflow guideOpens the Deskflow guide: everyday use and recovery.
›
Deskflow settingsOpens the Deskflow settings copied to the laptop.
›
Deskflow serviceOpens the unit that runs Deskflow at graphical login.
›
Resume inputStarts Deskflow again and asks for input access.
›
Windows USB mouse notesOpens the notes on forwarding the Windows USB mouse, off since 2026-10-20.
›
Firewall lockdownOpens the firewall rules for Deskflow's lockdown.
›
Network auditOpens the network audit of Deskflow.
›
Lan Mouse (retired)Opens the retired Lan Mouse guide; do not run it alongside Deskflow.
›
‹ Home

windows

The Windows PC: its setup and checks, its skill sync, the work repos cloned onto it, and the copies of its files kept here.

Install Windows setupInstalls the Windows setup from its manifests (asks for administrator).
›
Check Windows setupChecks the Windows setup against its manifests.
›
Remove Windows packRemoves the packs the install added (rollback).
›
Setup guideOpens the Windows setup guide.
›
Sign-ins to redoOpens the list of sign-ins to redo by hand.
›
Captured inventoryOpens what the setup captured.
›
Windows user scriptsOpens the scripts copied to the Windows Scripts folder.
›
Skill sync guideOpens the guide to the Windows skill sync, which runs on each push to master.
›
Clone work reposClones the missing work repositories into the standard layout.
›
‹ Home

shell

The shell helpers in ~/.zsh.d: the commands you type in a terminal and the files they read.

GitPrints the Git screen: checkout safety, Git settings and hooks.
›
OpenCodePrints the OpenCode screen: the profiles and the commands that run OpenCode.
›
Terminal helpersOpens the terminal helpers: set-title, killport, IP aliases and lazy node loaders.
›
Docker and database helpersOpens the Docker, Prisma, Postgres, nginx and VPN helpers (holds a credential to rotate).
›
API keysOpens the API keys file, which is never in Git.
›
Review openOpens a file for review, from zsh, bash or an agent.
›
Dash path warningOpens the helper that warns about dash paths.
›
‹ shell

git

Git here: the checkout safety wrapper, the Git settings, and the hooks that run in every repo.

Checkout safetyOpens the wrapper that lists files and asks before git checkout discards changes.
›
Git settingsOpens the Git identity, LFS and hooks-path settings.
›
Hook shimsOpens the Lefthook shims that run in every repo.
›
Push gatesOpens the push gates: the approval note and no pushes to main in marked repos.
›
‹ shell

opencode

The OpenCode profiles: which files each profile loads, and the commands that run OpenCode with the current one.

Profiles tablePrints every profile's files, one column per profile, and the commands.
›
Current profilePrints the name of the current profile.
›
All profilesPrints what each profile loads.
›
Switch profileSwitches every shell's new runs to the named profile.
›
Sign in a profileSigns a profile's Claude Code in.
›
Current profile filesPrints the current profile's files.
›
Edit a profile fileOpens one of the current profile's files in the editor.
›
Profile folderOpens the profile folder and its tests.
›
‹ Home

documents

The written things: CVs, dated plans and designs, case studies, machine incidents and the archive of moved files.

CVsPrints the CVs screen: three versions, each as PDF and LaTeX.
›
PapersPrints the papers screen: plans, designs, research, flows and work items.
›
Case studiesOpens the archived experiments, each with its own README.
›
Machine incidentsOpens the dated machine incident records and their index.
›
ChangelogOpens the dated changelog entries.
›
ArchiveOpens the archive of moved files; it is not backed up (see its README).
›
‹ documents

cv

The CVs: three versions, each as a PDF and as the LaTeX it is built from.

Full Stack Developer CVOpens the Full Stack Developer CV.
›
Full Stack LaTeXOpens the LaTeX source of that CV.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV.
›
AI Integrations CVOpens the AI Integrations CV.
›
Rebuild a CVRebuilds one CV's PDF from its LaTeX source.
›
Dated versionsOpens the dated CV versions, as PDF and text.
›
CV workflowOpens the steps for updating a CV.
›
‹ documents

papers

The dated working papers: plans, designs, research, flows, work items, and playbooks.

PlansOpens the dated plans, one folder each.
›
DesignsOpens the design pitches and recommendations.
›
ResearchOpens the research notes behind the plans.
›
FlowsOpens the flow cards and data models.
›
Work itemsOpens the planned, urgent and work item lists.
›
PlaybooksOpens the working playbooks.
›
Functional researchOpens the research on other agent frameworks.
›
Raw answer
# Workstation CLI map

**What I used:** only the dump. I could not read `workstation-cli/`, `zsh.d/workstation.zsh`, `resume-kvm`, or the house-conventions reference, so the map comes from the README and file tree. Check it against the current `workstation help`, `ws`, and `setup` output before building. Forms are relative to `~/projects/workstation` unless they start with `~` or are commands.

**Judgment calls**

- **Nine groups at the top**, sorted by what you come to do, not by file type. Each group is a screen with its own menu.
- **Agents and Assistants are separate.** Agents are the things that run, with their rules, skills, teams, Hermes, and data. Assistants are how Claude Code and Codex are configured on this machine.
- **No command appears twice.** `rules` lives under Agents only. The `data-pull` timer appears under Machine only as a status row.
- **Retired things stay visible** (Lan Mouse, the Codex browser recorders, USB mouse forwarding), labelled as retired, because the README documents them for rollback.
- **Credentials:** `infra.zsh` and `utils.zsh` embed a credential. Their rows say so. The screens never print file contents.
- **Unclear purposes:** `dash-path-warn.zsh`, `dashboard/snapshot.py`, `team-park`, `machine-history.sh`, and `team-activity.sh` are described from their names. Confirm them before the help text is final.

**Questions** are in the JSON below, each with my recommendation.

```json
{"screens": [
{"path": [], "sentence": "Everything this machine's kit keeps and runs, grouped by what you come here to do.", "rows": [
{"name": "Dashboard", "form": "workstation dashboard", "what": "Prints the dashboard screen: what waits for you and the team running now."},
{"name": "Agents", "form": "workstation agents", "what": "Prints the agents screen: the sandbox, rules, skills, teams, Hermes and data."},
{"name": "Assistants", "form": "workstation assistants", "what": "Prints the assistants screen: how Claude Code and Codex are set up here."},
{"name": "Browser", "form": "workstation browser", "what": "Prints the browser screen: the browser command, Chrome and the Codex Chrome bridge."},
{"name": "Machine", "form": "workstation machine", "what": "Prints the machine screen: power, network, screen, lid, sound, clipboard and services."},
{"name": "Input", "form": "workstation input", "what": "Prints the input screen: sharing the laptop keyboard and mouse with Windows."},
{"name": "Windows", "form": "workstation windows", "what": "Prints the Windows screen: its setup, skill sync, repo clones and kept copies."},
{"name": "Shell", "form": "workstation shell", "what": "Prints the shell screen: the zsh helpers, Git settings and OpenCode commands."},
{"name": "Documents", "form": "workstation documents", "what": "Prints the documents screen: CVs, plans, designs, case studies and incidents."}
]},
{"path": ["dashboard"], "sentence": "The dashboard: what waits for you (decisions, rule changes, calls made alone) and the team running now.", "rows": [
{"name": "Start the dashboard", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard on http://127.0.0.1:8780 and keeps it running until you stop it."},
{"name": "Dashboard page", "form": "http://127.0.0.1:8780", "what": "Opens the dashboard page in your browser, once it is started."},
{"name": "Concepts version", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts variant on http://127.0.0.1:8781 to compare with the dashboard."},
{"name": "Dashboard checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the 199 dashboard checks against the real data and a real server."},
{"name": "Dashboard guide", "form": "dashboard/README.md", "what": "Opens the dashboard guide."}
]},
{"path": ["agents"], "sentence": "The agents: the sandbox where you run them, the rules and skills they follow, the teams they form, Hermes, and the data they keep.", "rows": [
{"name": "Sandbox", "form": "workstation agents sandbox", "what": "Prints the sandbox screen: the agent records and how to check and run them."},
{"name": "Rules", "form": "workstation agents rules", "what": "Prints the rules screen: the rules every org follows and where they are kept."},
{"name": "Skills", "form": "workstation agents skills", "what": "Prints the skills screen: the reusable instructions agents load."},
{"name": "Teams", "form": "workstation agents teams", "what": "Prints the teams screen: how a team is started, its files and its roles."},
{"name": "Hermes", "form": "workstation agents hermes", "what": "Prints the Hermes screen: the separate agent runtime, its config and its restore notes."},
{"name": "Data", "form": "workstation agents data", "what": "Prints the data screen: the answers, cases and verdicts the agents keep."},
{"name": "Agent framework guide", "form": "agent-framework/README.md", "what": "Opens the guide to the agent records and the sandbox."}
]},
{"path": ["agents", "sandbox"], "sentence": "The agent records and the Agent Sandbox: which agents exist, whether their records are sound, and the page where you run them.", "rows": [
{"name": "List agents", "form": "agent list", "what": "Lists the agents with their tier, model and number of tests."},
{"name": "Check agents", "form": "agent check", "what": "Checks every agent record and refuses broken ones (exit 1)."},
{"name": "Agent Sandbox page", "form": "agent serve", "what": "Starts the Agent Sandbox page on http://127.0.0.1:8790."},
{"name": "Agent records", "form": "~/projects/my-skills/agents/", "what": "Opens the agent records, one agent.yaml per agent."},
{"name": "Results and memory", "form": "~/projects/data/", "what": "Opens each agent's test results and memory."},
{"name": "Framework intent", "form": ".idd/modules/agent-framework/INTENT.md", "what": "Opens the intent and rules of the agent framework."}
]},
{"path": ["agents", "rules"], "sentence": "The rules every org follows: the file they are written in, the tool that prints them, and the copy Claude reads.", "rows": [
{"name": "Print rules", "form": "rules", "what": "Prints the rules for the current folder, or the folder you give."},
{"name": "Rules file", "form": "workboard/rules.yaml", "what": "Opens the rules; they change only by your decision or an accepted proposal."},
{"name": "Rule metadata", "form": "workboard/rules-meta.yaml", "what": "Opens the metadata for each rule."},
{"name": "Generated copy", "form": "~/.claude/references/rules.md", "what": "Opens the copy Claude reads, rebuilt from rules.yaml; do not edit it by hand."},
{"name": "Rules tests", "form": "workboard/test_rules.py", "what": "Opens the rules tests."},
{"name": "Rules helper", "form": "zsh.d/rules.zsh", "what": "Opens the zsh helper for the rules tool."}
]},
{"path": ["agents", "skills"], "sentence": "The skills: reusable instructions agents load, where the global ones come from, and the backups kept here.", "rows": [
{"name": "Global skills repo", "form": "~/projects/my-skills", "what": "Opens the repo that holds the global skills."},
{"name": "Link skills", "form": "~/projects/my-skills/install.sh", "what": "Links the global skills into Claude, Codex and OpenCode."},
{"name": "Skill backups", "form": "claude/skills/", "what": "Opens the skills backed up in this repo; copy in the ones you want."},
{"name": "Skill shortlist", "form": "claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and what is installed."}
]},
{"path": ["agents", "teams"], "sentence": "The teams: how one is started, its team files, the roles its members play, and how they talk to each other.", "rows": [
{"name": "Start a team", "form": "/spawn-team <team> in Claude, $spawn-team <team> in Codex", "what": "Starts a team inside the chat, from its team file."},
{"name": "Team files", "form": "~/projects/my-skills/spawn-team/teams/", "what": "Opens the team files, such as worker-pair and research-team."},
{"name": "Role instructions", "form": "~/projects/my-skills/{worker,supervisor,admin,qa-agent}/SKILL.md", "what": "Opens the instructions for each role."},
{"name": "Claude personas", "form": "~/projects/my-skills/agents/<id>/claude.md", "what": "Opens an agent's persona for Claude."},
{"name": "Handoff rules", "form": "~/projects/my-skills/coordinated-agentic-session/references/handoff.md", "what": "Opens the rules for how team members hand work to each other."},
{"name": "QA agent role notes", "form": "docs/roles/qa-agent.md", "what": "Opens the QA agent's role notes in this repo."}
]},
{"path": ["agents", "hermes"], "sentence": "Hermes, a separate agent runtime installed from source, with its launcher, example configs and restore notes.", "rows": [
{"name": "Launch Hermes", "form": "hermes", "what": "Starts Hermes, the agent runtime."},
{"name": "Hermes guide", "form": "hermes/README.md", "what": "Opens the Hermes guide: installation, configuration and status."},
{"name": "Restore steps", "form": "hermes/RESTORE.md", "what": "Opens the steps to restore Hermes."},
{"name": "Default config example", "form": "hermes/default.config.example.yaml", "what": "Opens the example config for the default profile, without secrets."},
{"name": "Jobs config example", "form": "hermes/jobs.config.example.yaml", "what": "Opens the example config for the jobs profile, without secrets."},
{"name": "State and secrets", "form": "~/.hermes", "what": "Opens Hermes's state and secrets folder, which is not in Git."},
{"name": "Source checkout", "form": "~/projects/hermes-agent", "what": "Opens the Hermes source checkout."}
]},
{"path": ["agents", "data"], "sentence": "The data repository: the answers, cases, rule proposals and verdicts the agents keep, and the scripts that move them.", "rows": [
{"name": "Data repo", "form": "~/projects/data", "what": "Opens the private data repository."},
{"name": "Sync scripts", "form": "~/projects/data/bin/", "what": "Opens the scripts that issue, pull and sync cases and answers."},
{"name": "Sync timer", "form": "systemctl --user status data-pull.timer", "what": "Shows the timer that syncs answers every 5 minutes."},
{"name": "Supervision backlog", "form": "~/projects/betec/workboard/docs/supervision-backlog.md", "what": "Opens the supervision backlog in the betec workspace."}
]},
{"path": ["assistants"], "sentence": "How Claude Code and Codex are set up on this machine: their global rules, settings, hooks, usage guard and plugins.", "rows": [
{"name": "Global rules for Claude", "form": "claude/CLAUDE.md", "what": "Opens the global rules every Claude session reads."},
{"name": "Short agent notes", "form": "claude/AGENTS.md", "what": "Opens the shorter global notes for agents."},
{"name": "Claude settings", "form": "claude/settings.json", "what": "Opens Claude Code's settings, which Windows deploys too."},
{"name": "Codex config", "form": "codex/config.toml", "what": "Opens the Codex CLI config."},
{"name": "Hooks", "form": "workstation assistants hooks", "what": "Prints the hooks screen: the scripts Claude runs at set points."},
{"name": "Session types", "form": "workstation assistants sessions", "what": "Prints the sessions screen: main sessions and how to continue them."},
{"name": "Usage guard", "form": "workstation assistants usage-guard", "what": "Prints the usage guard screen: the wrapper that checks Claude usage before it runs."},
{"name": "Plugins", "form": "workstation assistants plugins", "what": "Prints the plugins screen: the Claude plugins kept here."},
{"name": "Linux instructions copy", "form": "claude/linux-global/", "what": "Opens the copy of this machine's installed global instructions."},
{"name": "Windows instructions copy", "form": "claude/windows-global/", "what": "Opens the copy of the Windows Claude instructions."},
{"name": "Communication draft", "form": "claude/communication-framework.md", "what": "Opens a draft on how agents should communicate; it is not enforced anywhere yet."}
]},
{"path": ["assistants", "hooks"], "sentence": "The hook scripts Claude Code runs at set points in a session, installed in ~/.claude/hooks.", "rows": [
{"name": "Core rules", "form": "~/.claude/hooks/core-rules.sh", "what": "Applies the core rules at session start and before each Bash call."},
{"name": "Local server guard", "form": "~/.claude/hooks/local-server-guard.py", "what": "Checks Bash calls before they run, to guard local servers."},
{"name": "Machine history", "form": "~/.claude/hooks/machine-history.sh", "what": "Records the machine's history when a session runs (see its header)."},
{"name": "Proof reminder", "form": "~/.claude/hooks/proof-reminder.sh", "what": "Reminds you to prove a change after edits and Bash runs."},
{"name": "Team activity", "form": "~/.claude/hooks/team-activity.sh", "what": "Records what the team is doing (see its header)."},
{"name": "Core-rules tests", "form": "claude/hooks/test_core_rules.sh", "what": "Opens the core-rules tests."}
]},
{"path": ["assistants", "sessions"], "sentence": "The session types: the main session and the picker that chooses how a session starts.", "rows": [
{"name": "Continue main session", "form": "claude --main -c", "what": "Continues the last main session."},
{"name": "Resume main session", "form": "claude --main -r", "what": "Picks a main session to resume."},
{"name": "Session-type hook", "form": "~/.claude/hooks/session-types.sh", "what": "Runs at session start as the SessionStart hook for session types."},
{"name": "Session-type tests", "form": "claude/session-types/tests/run.sh", "what": "Runs the session-types tests."},
{"name": "Picker design work", "form": "claude/session-types/docs/design/2026-10-21-picker-views/", "what": "Opens the picker-views design work."}
]},
{"path": ["assistants", "usage-guard"], "sentence": "The usage guard: the wrapper that runs Claude Code with a usage check, how it installs, and its tests.", "rows": [
{"name": "Claude wrapper", "form": "claude", "what": "Runs Claude Code through the usage guard."},
{"name": "Install on Linux", "form": "claude/usage-guard/install.sh", "what": "Installs the usage guard on this Linux machine."},
{"name": "Install on Windows", "form": "claude/usage-guard/Install-Windows.cmd", "what": "Installs the usage guard on Windows."},
{"name": "Shared usage reader", "form": "claude/usage-guard/plugin/hooks/shared-usage.py", "what": "Opens the script that reads usage for the plugin hooks."},
{"name": "Request-budget tests", "form": "claude/usage-guard/tests/test_request_budget.py", "what": "Opens the request-budget tests."},
{"name": "Logged resolutions", "form": "claude/usage-guard/.bdd/qa/resolutions/", "what": "Opens the logged resolutions of stale-usage and budget problems."}
]},
{"path": ["assistants", "plugins"], "sentence": "The Claude plugins kept in this repo, one folder each.", "rows": [
{"name": "Changelog pane", "form": "claude/mods/changelog-pane/", "what": "Opens the changelog pane plugin."},
{"name": "Review pane", "form": "claude/mods/review-pane/", "what": "Opens the review pane plugin and its design notes."},
{"name": "Scratchpad", "form": "claude/mods/scratchpad-playground/", "what": "Opens the scratchpad plugin."},
{"name": "Team board", "form": "claude/mods/team-board/", "what": "Opens the team board plugin."}
]},
{"path": ["browser"], "sentence": "The browser: the one Chrome window the agents and you share, the command that drives it, and the tools around it.", "rows": [
{"name": "Browser command", "form": "browser '<steps>'", "what": "Runs browser steps in the one Chrome window kept open."},
{"name": "Browser status", "form": "browser status", "what": "Shows whether the browser server is up."},
{"name": "Close browser", "form": "browser close", "what": "Closes Chrome and stops the browser server."},
{"name": "Browser guide", "form": "browser/README.md", "what": "Opens the browser guide, including how to record proof."},
{"name": "Chrome launcher", "form": "chrome/chrome.sh", "what": "Opens the Chrome launcher, the only way to start Chrome here."},
{"name": "Chrome flags", "form": "chrome/flags", "what": "Opens the Chrome launch flags; edit them here only."},
{"name": "Chrome guide", "form": "chrome/README.md", "what": "Opens the Chrome guide and why it starts this way."},
{"name": "Smoke QA", "form": "jev-browser-test", "what": "Runs a goal in a browser and checks the text and URL you give it."},
{"name": "Codex Chrome bridge", "form": "codex/chrome-bridge/install.sh", "what": "Installs the watcher that keeps the Codex Chrome bridge working."},
{"name": "Codex browser path (retired)", "form": "codex/browser/README.md", "what": "Opens the old Codex browser path; the browser command replaces it for what it can drive."}
]},
{"path": ["machine"], "sentence": "This Linux machine: its power, network, screen, laptop lid, sound, repairs, clipboard and background services.", "rows": [
{"name": "Power saver", "form": "cpu-min-power.sh", "what": "Switches the CPU to power-saver with turbo off (Intel only; asks for sudo)."},
{"name": "Balanced power", "form": "cpu-normal-power.sh", "what": "Switches the CPU back to balanced with turbo on."},
{"name": "Internet recovery", "form": "linux-internet-recovery.sh", "what": "Resets DNS and restarts networking (re-runs itself with sudo)."},
{"name": "Tailscale recovery", "form": "recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts Tailscale and checks the remote terminal on port 3500."},
{"name": "External monitor", "form": "fix_old_monitor_hdmi.sh", "what": "Sets the external monitor's mode and refresh rate with xrandr."},
{"name": "Keep running with lid closed", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Makes closing the lid keep the laptop running (applies after reboot)."},
{"name": "Restore lid default", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Restores the default lid behavior (applies after reboot)."},
{"name": "Repair helpers", "form": "fix-keyboard, fix-mouse, fix-disk, fix-whatsapp", "what": "Runs one repair helper for the keyboard, mouse, disk or WhatsApp."},
{"name": "Send audio to Windows", "form": "audio-start", "what": "Sends all Linux audio to the Windows machine over Tailscale."},
{"name": "Restore speakers", "form": "audio-pause", "what": "Restores the speakers and stops sending audio to Windows."},
{"name": "Clipboard", "form": "workstation machine clipboard", "what": "Prints the clipboard screen: the picker, its services and the Windows script."},
{"name": "Services", "form": "workstation machine services", "what": "Prints the services screen: the background timers and services."}
]},
{"path": ["machine", "clipboard"], "sentence": "The clipboard history: what you copied earlier, its picker, and the parts that keep it running.", "rows": [
{"name": "Clipboard picker", "form": "python3 ~/projects/workstation/clipstack/picker.py", "what": "Opens the picker to paste something copied earlier."},
{"name": "Clipboard server", "form": "clipstack/server.py", "what": "Serves the clipboard history, run by the clipstack-server service."},
{"name": "Clipboard watcher", "form": "clipstack/watcher.py", "what": "Watches the clipboard for new copies, run by the clipstack-watcher service."},
{"name": "Install clipboard", "form": "clipstack/install.sh", "what": "Installs the clipboard server and watcher as user services."},
{"name": "Windows clipboard script", "form": "clipstack/windows/clipstack.ahk", "what": "Opens the Windows clipboard script."},
{"name": "Clipboard tests", "form": "clipstack/test_server.py", "what": "Opens the clipboard server tests."}
]},
{"path": ["machine", "services"], "sentence": "The background timers and services that run on this machine, and how to check each one.", "rows": [
{"name": "List timers", "form": "systemctl --user list-timers", "what": "Lists the timers that run in the background."},
{"name": "Clipboard server status", "form": "systemctl --user status clipstack-server", "what": "Shows whether the clipboard server is running."},
{"name": "Clipboard watcher status", "form": "systemctl --user status clipstack-watcher", "what": "Shows whether the clipboard watcher is running."},
{"name": "Deskflow status", "form": "systemctl --user status deskflow", "what": "Shows whether Deskflow, the keyboard and mouse sharing, is running."},
{"name": "Remote terminal status", "form": "systemctl --user status remote-terminal", "what": "Shows whether the remote terminal on port 3500 is running."},
{"name": "Codex bridge timer", "form": "systemctl --user status codex-chrome-bridge.timer", "what": "Shows the timer that keeps the Codex Chrome bridge working."},
{"name": "Supabase keep-alive", "form": "supabase-keepalive/supabase-keepalive.timer", "what": "Keeps the Supabase project awake on a timer."},
{"name": "Answer sync timer", "form": "systemctl --user status data-pull.timer", "what": "Shows the timer that pulls answers every 5 minutes."},
{"name": "Rules reminder timer", "form": "docs/plans/2026-10-24-rules-per-role/reminder/", "what": "Opens the rules reminder timer and its unit."}
]},
{"path": ["input"], "sentence": "Sharing one keyboard and mouse between this laptop and the Windows PC: the current setup and the retired one.", "rows": [
{"name": "Deskflow guide", "form": "deskflow/README.md", "what": "Opens the Deskflow guide: everyday use and recovery."},
{"name": "Deskflow settings", "form": "deskflow/linux.conf", "what": "Opens the Deskflow settings copied to the laptop."},
{"name": "Deskflow service", "form": "deskflow/deskflow.service", "what": "Opens the unit that runs Deskflow at graphical login."},
{"name": "Resume input", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input access."},
{"name": "Windows USB mouse notes", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes on forwarding the Windows USB mouse, off since 2026-10-20."},
{"name": "Firewall lockdown", "form": "deskflow/deskflow-lockdown.nft", "what": "Opens the firewall rules for Deskflow's lockdown."},
{"name": "Network audit", "form": "deskflow/NETWORK-AUDIT.md", "what": "Opens the network audit of Deskflow."},
{"name": "Lan Mouse (retired)", "form": "lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide; do not run it alongside Deskflow."}
]},
{"path": ["windows"], "sentence": "The Windows PC: its setup and checks, its skill sync, the work repos cloned onto it, and the copies of its files kept here.", "rows": [
{"name": "Install Windows setup", "form": "init-windows/Start-Install.cmd", "what": "Installs the Windows setup from its manifests (asks for administrator)."},
{"name": "Check Windows setup", "form": "init-windows/Smoke-Test-Windows.ps1", "what": "Checks the Windows setup against its manifests."},
{"name": "Remove Windows pack", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes the packs the install added (rollback)."},
{"name": "Setup guide", "form": "init-windows/README.md", "what": "Opens the Windows setup guide."},
{"name": "Sign-ins to redo", "form": "init-windows/secrets-checklist.md", "what": "Opens the list of sign-ins to redo by hand."},
{"name": "Captured inventory", "form": "init-windows/inventory.md", "what": "Opens what the setup captured."},
{"name": "Windows user scripts", "form": "init-windows/user-scripts/", "what": "Opens the scripts copied to the Windows Scripts folder."},
{"name": "Skill sync guide", "form": "skills-sync-windows/README.md", "what": "Opens the guide to the Windows skill sync, which runs on each push to master."},
{"name": "Clone work repos", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing work repositories into the standard layout."}
]},
{"path": ["shell"], "sentence": "The shell helpers in ~/.zsh.d: the commands you type in a terminal and the files they read.", "rows": [
{"name": "Git", "form": "workstation shell git", "what": "Prints the Git screen: checkout safety, Git settings and hooks."},
{"name": "OpenCode", "form": "workstation shell opencode", "what": "Prints the OpenCode screen: the profiles and the commands that run OpenCode."},
{"name": "Terminal helpers", "form": "zsh.d/utils.zsh", "what": "Opens the terminal helpers: set-title, killport, IP aliases and lazy node loaders."},
{"name": "Docker and database helpers", "form": "zsh.d/infra.zsh", "what": "Opens the Docker, Prisma, Postgres, nginx and VPN helpers (holds a credential to rotate)."},
{"name": "API keys", "form": "api-keys-edit", "what": "Opens the API keys file, which is never in Git."},
{"name": "Review open", "form": "review-open", "what": "Opens a file for review, from zsh, bash or an agent."},
{"name": "Dash path warning", "form": "zsh.d/dash-path-warn.zsh", "what": "Opens the helper that warns about dash paths."}
]},
{"path": ["shell", "git"], "sentence": "Git here: the checkout safety wrapper, the Git settings, and the hooks that run in every repo.", "rows": [
{"name": "Checkout safety", "form": "zsh.d/git-safety.zsh", "what": "Opens the wrapper that lists files and asks before git checkout discards changes."},
{"name": "Git settings", "form": ".gitconfig", "what": "Opens the Git identity, LFS and hooks-path settings."},
{"name": "Hook shims", "form": "git-hooks/", "what": "Opens the Lefthook shims that run in every repo."},
{"name": "Push gates", "form": "git-hooks/pre-push", "what": "Opens the push gates: the approval note and no pushes to main in marked repos."}
]},
{"path": ["shell", "opencode"], "sentence": "The OpenCode profiles: which files each profile loads, and the commands that run OpenCode with the current one.", "rows": [
{"name": "Profiles table", "form": "opencode help", "what": "Prints every profile's files, one column per profile, and the commands."},
{"name": "Current profile", "form": "opencode-profile", "what": "Prints the name of the current profile."},
{"name": "All profiles", "form": "opencode-profiles", "what": "Prints what each profile loads."},
{"name": "Switch profile", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "Sign in a profile", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "Current profile files", "form": "opencode-files", "what": "Prints the current profile's files."},
{"name": "Edit a profile file", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files in the editor."},
{"name": "Profile folder", "form": "opencode-profiles/", "what": "Opens the profile folder and its tests."}
]},
{"path": ["documents"], "sentence": "The written things: CVs, dated plans and designs, case studies, machine incidents and the archive of moved files.", "rows": [
{"name": "CVs", "form": "workstation documents cv", "what": "Prints the CVs screen: three versions, each as PDF and LaTeX."},
{"name": "Papers", "form": "workstation documents papers", "what": "Prints the papers screen: plans, designs, research, flows and work items."},
{"name": "Case studies", "form": "case-studies/", "what": "Opens the archived experiments, each with its own README."},
{"name": "Machine incidents", "form": "reference/", "what": "Opens the dated machine incident records and their index."},
{"name": "Changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "Archive", "form": "~/archive/", "what": "Opens the archive of moved files; it is not backed up (see its README)."}
]},
{"path": ["documents", "cv"], "sentence": "The CVs: three versions, each as a PDF and as the LaTeX it is built from.", "rows": [
{"name": "Full Stack Developer CV", "form": "cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
{"name": "Full Stack LaTeX", "form": "cv/cv-full-stack.tex", "what": "Opens the LaTeX source of that CV."},
{"name": "AI Full Stack Engineer CV", "form": "cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
{"name": "AI Integrations CV", "form": "cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
{"name": "Rebuild a CV", "form": "pdflatex -interaction=nonstopmode -halt-on-error cv-full-stack.tex (run in cv/)", "what": "Rebuilds one CV's PDF from its LaTeX source."},
{"name": "Dated versions", "form": "cv/versions/", "what": "Opens the dated CV versions, as PDF and text."},
{"name": "CV workflow", "form": "cv/WORKFLOW.md", "what": "Opens the steps for updating a CV."}
]},
{"path": ["documents", "papers"], "sentence": "The dated working papers: plans, designs, research, flows, work items, and playbooks.", "rows": [
{"name": "Plans", "form": "docs/plans/", "what": "Opens the dated plans, one folder each."},
{"name": "Designs", "form": "docs/design/", "what": "Opens the design pitches and recommendations."},
{"name": "Research", "form": "docs/research/", "what": "Opens the research notes behind the plans."},
{"name": "Flows", "form": "docs/flows/", "what": "Opens the flow cards and data models."},
{"name": "Work items", "form": "docs/items/", "what": "Opens the planned, urgent and work item lists."},
{"name": "Playbooks", "form": "docs/playbooks/", "what": "Opens the working playbooks."},
{"name": "Functional research", "form": "docs/functional-research/", "what": "Opens the research on other agent frameworks."}
]}
],
"questions": [
"Keep `setup` as a second alias for the facade? The README lists `workstation`, `setup` and `ws`, but `setup` is a common word and probably clashes. Recommendation: keep `workstation` and `ws` only, after `whence -a setup` shows what else owns the name.",
"Keep `opencode-profile` (prints the current profile) next to `opencode-profiles` (prints every profile)? They differ by one letter. Recommendation: keep the names, since scripts and habits use them, and label the rows 'current' and 'all' in the help screen.",
"Should the map start the dashboard and the Agent Sandbox servers, or only show their addresses? Recommendation: include the start rows. Both are thin commands over existing scripts, and each runs in the foreground until you stop it."
]}
```

screen-decomposition, first draft · run 5 exit=0 seconds=169 · prompt

P1 Recall: 0.8P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.322
As terminal help
The groups of this workstation, each one a place to reach one part of it.
dashboardworkstation dashboardPrints the dashboard screen: its page, server and checks.
machineworkstation machinePrints the machine screen: the Linux machine's power, display, internet, lid, Deskflow, audio, clipboard and repairs.
shellworkstation shellPrints the shell screen: git, OpenCode profiles and the helpers in zsh.d.
assistantsworkstation assistantsPrints the assistants screen: rules, Claude, Codex, skills, agents, usage guard, mods and Hermes.
browserworkstation browserPrints the browser screen: the browser command, Chrome and browser QA.
windowsworkstation windowsPrints the windows screen: the Windows bootstrap, skill sync, repo clone and desktop mirror.
documentsworkstation documentsPrints the documents screen: the CVs, case studies, incident records and project docs.
dashboard
The dashboard on this machine: its page, its server, its checks and the concepts version beside it.
pagehttp://127.0.0.1:8780Opens the dashboard page, where asked cases, rule changes and decided-alone calls wait for you. The server must be running.
serverpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard server on port 8780, which serves the page and writes your answers to GitHub and the rule-proposal files.
checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboardRuns the dashboard's 199 checks against the real data and a real server.
conceptspython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts dashboard on port 8781, to compare with the main one by its output.
concepts checkspython3 -I -m unittest discover -s ~/projects/workstation/dashboard-conceptsRuns the concepts dashboard's 17 checks.
shotsdashboard/shots/Opens the screenshots of the dashboard's screens.
guidedashboard/README.mdOpens the dashboard guide: what it reads, what it writes and how it reloads.
machine
The Linux machine's own utilities: power, display, internet, the lid, Deskflow, audio, clipboard and repairs.
powerworkstation machine powerPrints the power screen: the two CPU power profiles.
fix_old_monitor_hdmi.shfix_old_monitor_hdmi.shRuns xrandr to set the external HDMI or DP output's mode and refresh rate, default 1920x1080 at 59.88.
internetworkstation machine internetPrints the internet screen: the two repairs for a lost connection.
lidworkstation machine lidPrints the lid screen: what closing the laptop lid does, and the closed-lid record.
deskflowworkstation machine deskflowPrints the deskflow screen: the shared keyboard and trackpad with the Windows machine.
audioworkstation machine audioPrints the audio screen: sending Linux audio to the Windows machine.
clipboardworkstation machine clipboardPrints the clipboard screen: the clipboard history picker, server and watcher.
repairworkstation machine repairPrints the repair screen: the fix helpers for keyboard, mouse, disk and WhatsApp.
supabase-keepalivesupabase-keepalive/supabase-keepalive.shRuns the Supabase keepalive; its timer is supabase-keepalive.timer.
machine › power
The two CPU power profiles, for the Intel machine only.
cpu-min-power.shcpu-min-power.shRuns the power-saver profile: turbo off and the CPU capped at 8% of max. Asks for sudo.
cpu-normal-power.shcpu-normal-power.shRuns the balanced profile: turbo on and the cap back to 100%. Asks for sudo.
machine › internet
The two repairs for a machine that lost its internet connection.
linux-internet-recovery.shlinux-internet-recovery.shRuns the DNS and network repair: systemd-resolved, resolv.conf, a NetworkManager restart and a DNS flush. Re-runs itself with sudo.
recover-tailscale-remote-terminal.shrecover-tailscale-remote-terminal.shRuns the Tailscale repair, starts the remote-terminal service and checks port 3500.
machine › lid
The settings for what closing the laptop lid does, and the record of the closed-lid test.
keep-running-with-lid-closed.shlaptop-utilities/keep-running-with-lid-closed.shRuns the logind change so closing the lid does nothing. It applies after a reboot.
restore-default-lid-behavior.shlaptop-utilities/restore-default-lid-behavior.shRuns the removal of that change. It applies after a reboot.
closed-lid incidentreference/incidents/2026-10-01-codebot-lid-closed.mdOpens the record of the closed-lid test that kept CodeBot serving.
machine › deskflow
Deskflow, which shares the laptop's keyboard and trackpad with the Windows machine.
resume-kvmresume-kvmStarts Deskflow again and asks for input access when that was cancelled.
deskflow.service~/.config/systemd/user/deskflow.serviceStarts the Deskflow server with the graphical session.
guidedeskflow/README.mdOpens the Deskflow guide: everyday use, recovery and the setup.
usb-mouse notesdeskflow/usb-mouse/README.mdOpens the notes on keyboard following the mouse and on USB sharing, which has been off since 2026-10-20.
lan-mouse (retired)lan-mouse/README.mdOpens the retired Lan Mouse guide, kept only for rollback.
machine › audio
Sending the Linux machine's audio to the Windows machine over Tailscale.
audio-startaudio-startStarts sending all Linux audio to the Windows machine, which becomes the default output.
audio-pauseaudio-pausePauses the share and restores the speakers.
audio-share statusaudio-share statusPrints whether audio is being sent to the Windows machine.
audio-share toneaudio-share tonePlays a test tone to the Windows machine.
machine › clipboard
The clipboard history: its picker, its server, its watcher and its Windows script.
pickerclipstack/picker.pyRuns the clipboard history picker.
serverclipstack/server.pyStarts the clipboard server, run by clipstack-server.service.
watcherclipstack/watcher.pyStarts the clipboard watcher, run by clipstack-watcher.service.
clipstack.ahkclipstack/windows/clipstack.ahkOpens the Windows clipboard script.
installclipstack/install.shInstalls the clipboard services on this machine.
machine › repair
The repair helpers in zsh.d/utils.zsh, for a keyboard, mouse, disk or WhatsApp that stopped working.
fix-keyboardfix-keyboardRuns the keyboard repair.
fix-mousefix-mouseRuns the mouse repair.
fix-diskfix-diskRuns the disk repair.
fix-whatsappfix-whatsappRuns the WhatsApp repair.
shell
The shell on this machine: git, the OpenCode profiles, and the helpers in zsh.d.
gitworkstation shell gitPrints the git screen: the checkout guard, the git settings and the hooks.
opencodeworkstation shell opencodePrints the OpenCode screen: the profiles and their commands.
utilszsh.d/utils.zshOpens the terminal helpers: set-title, killport, IP aliases, lazy nvm and node, Android, Java and Bun.
infrazsh.d/infra.zshOpens the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
api-keys-editapi-keys-editEdits the general-use API keys in ~/.config/api-keys/env. They are never kept in Git.
review-openreview-openOpens a file for review. It also works from bash and from agents.
shell › git
The git setup: the guard on checkout, the git settings and the hooks that run in every repo.
git-safetyzsh.d/git-safety.zshRuns git checkout through the wrapper that lists the files and asks [y/N] before discarding unstaged changes.
gitconfig~/.gitconfigEdits the author identity, Git LFS, the credential helper and the hooks path.
git-hooks~/.git-hooks/Opens the Lefthook shims that run in every repo, including the push and commit gates.
shell › opencode
The OpenCode profiles, and the commands that run and switch them.
opencodeopencodeRuns OpenCode with the current profile. The oc command does the same.
opencode helpopencode helpPrints every profile's files, one column each, and the commands. With more than 3 profiles it writes them to ~/.opencode-profiles/help.md and opens it.
opencode-profileopencode-profileSets the name of the current profile.
opencode-profilesopencode-profilesLists each profile and what it loads.
opencode-switchopencode-switch <name>Switches every shell's new runs to the named profile.
opencode-loginopencode-loginSigns the current profile's Claude Code in.
opencode-filesopencode-filesLists the current profile's files.
opencode-editopencode-edit <file>Edits one of the current profile's files.
profile filesopencode-profiles/Opens the profile files: profiles.py and its tests.
assistants
The AI assistant setup: the rules, the Claude and Codex settings, skills, agents, the usage guard, the mods and Hermes.
rulesrules [folder]Prints the rules, or the rules of one folder.
claudeworkstation assistants claudePrints the Claude screen: its global instructions, settings, hooks and session types.
codexworkstation assistants codexPrints the Codex screen: its config and the Chrome bridge.
skillsworkstation assistants skillsPrints the skills screen: the shortlist, the backups and the source repo.
agentsworkstation assistants agentsPrints the agents screen: the Agent Sandbox, the agent records, the roles and the teams.
usage-guardworkstation assistants usage-guardPrints the usage guard screen: the claude wrapper and its install.
modsworkstation assistants modsPrints the mods screen: the Claude Code plugins kept here.
hermesworkstation assistants hermesPrints the Hermes screen: running it, its configs and its restore runbook.
assistants › claude
Claude's global instructions, settings, hooks and session types.
CLAUDE.mdclaude/CLAUDE.mdEdits the global rules: browser automation, communication style, research and how to present work.
AGENTS.mdclaude/AGENTS.mdEdits the shorter global agent notes.
settings.jsonclaude/settings.jsonEdits the Claude Code settings that init-windows deploys.
hooksworkstation assistants claude hooksPrints the hooks screen: the five hooks wired into Claude's settings.
session typesclaude/session-types/README.mdOpens the session types guide: how claude --main -c and -r pick a session.
assistants › claude › hooks
The five hooks in claude/hooks, wired into the Claude settings.
core-rules.shclaude/hooks/core-rules.shPrints the rules at session start and before Bash calls.
local-server-guard.pyclaude/hooks/local-server-guard.pyRuns before each Bash call as the local server guard.
machine-history.shclaude/hooks/machine-history.shRuns as a hook that keeps the machine history.
proof-reminder.shclaude/hooks/proof-reminder.shReminds you to record proof after edits and Bash calls.
team-activity.shclaude/hooks/team-activity.shRuns as a hook that records team activity.
assistants › codex
Codex's CLI config and the Chrome bridge that keeps its Chrome plugin working.
config.tomlcodex/config.tomlEdits the Codex CLI config that init-windows deploys.
chrome-bridge guidecodex/chrome-bridge/README.mdOpens the Chrome bridge guide: installing it and the restarts it needs.
chrome-bridge installcodex/chrome-bridge/install.shInstalls the bridge's systemd watcher and timer on Linux.
repair.mjscodex/chrome-bridge/repair.mjsRuns the repair that restores the Chrome plugin's latest link and reapplies the file navigation patch.
playwright-mcp (retired)codex/playwright-mcp/README.mdOpens the retired Playwright setup. It installs no browser server now.
assistants › skills
The skills: which are installed, the backups kept here and the source repo.
shortlistclaude/skills-shortlist.mdOpens the skills researched on skills.sh and what is installed.
skill backupsclaude/skills/Opens the skill backups kept here. Copy in the ones you want installed.
my-skills repo~/projects/my-skillsOpens the global skills repo that every installed skill is linked from.
skill syncworkstation windows skills-syncPrints the Windows skill sync screen.
assistants › agents
The agents: the Agent Sandbox that tests them, their records, the roles and the teams.
agent serveagent-framework/agent serveStarts the Agent Sandbox page on port 8790, where agents are tested in real sessions.
agent checkagent-framework/agent checkChecks every agent record and refuses broken ones with exit 1.
agent listagent-framework/agent listLists the agents with their tier, model and number of tests.
agent framework guideagent-framework/README.mdOpens the agent framework guide: how the sandbox works and the words it uses.
agent records~/projects/my-skills/agents/Opens the agent records, one folder per agent with its agent.yaml.
rolesdocs/roles/Opens the draft role files: worker, supervisor, admin and qa-agent.
spawn-team/spawn-team <team>Starts a team from its team file in Claude. In Codex, $spawn-team does the same.
team-park~/.local/bin/team-parkRuns team-park. Its guide is claude/team-park/README.md.
assistants › usage-guard
The usage guard: the wrapper that stands in front of the claude command.
claude wrapper~/bin/claudeRuns claude through the usage guard, ahead of the native claude.
install.shclaude/usage-guard/install.shInstalls the native claude and the wrapper on this machine.
Install-Windows.ps1claude/usage-guard/Install-Windows.ps1Installs the usage guard on Windows.
guideclaude/usage-guard/README.mdOpens the usage guard guide.
testsclaude/usage-guard/tests/Opens the usage guard tests: the request budget and the live refresh.
assistants › mods
The Claude Code plugins kept here: the changelog pane, the review pane, the scratchpad playground and the team board.
changelog-paneclaude/mods/changelog-pane/Opens the changelog pane plugin: its hooks, types and tests.
review-paneclaude/mods/review-pane/README.mdOpens the review pane plugin's guide, with its design and flow notes.
scratchpad-playgroundclaude/mods/scratchpad-playground/Opens the scratchpad playground plugin: its hooks and types.
team-boardclaude/mods/team-board/Opens the team board plugin: its hooks, types and tests.
assistants › hermes
The Hermes agent: its launcher, its example settings and how to restore it.
hermeshermesRuns the Hermes agent from its source checkout in ~/projects/hermes-agent.
RESTORE.mdhermes/RESTORE.mdOpens the restore runbook for Hermes and its profiles.
BACKUP-2026-10-02.mdhermes/BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
default config examplehermes/default.config.example.yamlOpens the example settings for the default profile, with no secrets.
jobs config examplehermes/jobs.config.example.yamlOpens the example settings for the jobs profile, with no secrets.
guidehermes/README.mdOpens the Hermes setup guide: installation, current configuration and history.
browser
Chrome automation: the browser command, the Chrome launcher and the behavioral browser QA.
browser statusbrowser statusPrints whether the background server and its Chrome are up.
browser closebrowser closeCloses the Chrome window and stops the background server.
browser stepsbrowser '<json-array-of-steps>'Runs the steps in the one open Chrome window and prints the results as JSON.
browser guidebrowser/README.mdOpens the browser command guide: actions, viewports, annotating, network capture and logins.
recording proofbrowser/README.md#recording-proofOpens how to record proof of a feature with recordStart and recordStop.
chrome.shchrome/chrome.shStarts Chrome with the flags in chrome/flags. It is the only correct way to start Chrome here.
chrome installchrome/install.shInstalls the Chrome links and menu entry that route to chrome.sh. Run once per machine.
chrome flagschrome/flagsEdits the Chrome flags, read at every start and by the browser command.
chrome guidechrome/README.mdOpens the Chrome guide: why the capture flag exists and its limits.
jev-browser-testjev-browser-testRuns a goal in a browser and reports only the text and URL checks you give it.
jev installsh jev-browser-test/install.shInstalls jev-browser-test and its pinned jev-ultrafast checkout.
jev guidejev-browser-test/README.mdOpens the browser QA guide: config, exit codes and the Jev loop.
codex browser notescodex/browser/README.mdOpens the notes on Codex's direct Chrome path. For recording, the browser command now replaces it.
windows
The Windows machine: the bootstrap, the skill sync, the repo clone and the desktop mirror.
init-windows guideinit-windows/README.mdOpens the Windows bootstrap guide: prerequisites, install, check and rollback.
Start-Install.cmdinit-windows/Start-Install.cmdInstalls the pinned programs, Node versions, VS Code settings, Git config and user scripts. Needs the administrator prompt approved.
Smoke-Test-Windows.ps1init-windows/Smoke-Test-Windows.ps1Runs the smoke test that checks the install.
Remove-WindowsPack.ps1init-windows/Remove-WindowsPack.ps1Removes the install, rolling it back from its journal.
secrets checklistinit-windows/secrets-checklist.mdOpens the sign-ins to redo by hand after the install.
inventoryinit-windows/inventory.mdOpens what the capture contains.
skills-syncworkstation windows skills-syncPrints the skills sync screen: the runner that syncs skills after each push.
Clone-BetecRepos.ps1repos/Clone-BetecRepos.ps1Clones the missing Betec repositories into the standard layout. Safe to re-run.
desktop mirrorclaude/windows-global/Opens the mirror of the Windows desktop's global Claude folder.
desktop backupclaude/backups/desktop-v2-2026/Opens the portable snapshot of the desktop's instructions and two skills, for manual restore.
windows › skills-sync
The Windows skill sync: the runner, its scripts, the catch-up task and its last success.
runner serviceactions.runner.Lebnor-my-skills.my-skills-liel-windowsRuns the self-hosted runner that starts a sync after each trusted push to master.
Sync-Skills.ps1skills-sync-windows/Sync-Skills.ps1Runs the sync: fast-forwards the checkout and links the skills into the three skill folders.
Test-Sync.ps1skills-sync-windows/Test-Sync.ps1Runs the sync test.
Test-Account.ps1skills-sync-windows/Test-Account.ps1Runs the account check for the sync's Windows account.
catch-up taskMySkillsSync-CatchUpRuns the sync once after startup, retried three times if an attempt fails.
last successC:/ProgramData/MySkillsSync/state/last-success.jsonOpens the record of the last successful sync.
sync guideskills-sync-windows/README.mdOpens the sync guide: installed parts, permissions and the trust boundary.
verificationskills-sync-windows/verification.mdOpens how the sync was verified.
documents
The documents: the CVs, the case studies, the incident records and the project's own docs.
cvworkstation documents cvPrints the cv screen: the three CVs and how to rebuild them.
codebot return casecase-studies/conceptual-modeling/2026-09-15-codebot-return/README.mdOpens the case study of one design request run with and without the conceptual-modeling skill.
signal garden casecase-studies/blume-astryx/2026-09-16-signal-garden/README.mdOpens the case study of a doc exhibit that separates durable explanation from the live interface.
kernel results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the results of testing Kernel cloud browsers against local Chrome, including session recording.
incidentsreference/README.mdOpens the list of dated incident records and their outcomes.
docsworkstation documents docsPrints the docs screen: changelog, plans, designs, flows, items, research, specs and playbooks.
documents › cv
The three CVs and the tools that rebuild them.
cv-full-stack.pdfcv/cv-full-stack.pdfOpens the Full Stack Developer CV.
cv-ai-full-stack.pdfcv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
cv-ai-integrations.pdfcv/cv-ai-integrations.pdfOpens the AI Integrations CV.
pdflatex rebuildpdflatex -interaction=nonstopmode -halt-on-error <cv>.texRuns pdflatex to rebuild one CV from its LaTeX source. Run it in cv/.
text buildcv/text/build-full.shRuns the build of the plain-text CV versions.
versionscv/versions/Opens the dated CV versions, 2026-10-04 and 2026-10-04-v2.
cv guidecv/README.mdOpens the CV guide: sources, shared content and the update steps.
cv workflowcv/WORKFLOW.mdOpens the CV workflow.
documents › docs
The project's own docs: changelog, plans, designs, flows, items, research, the intent and feature specs, and the playbooks.
changelogdocs/changelog/Opens the dated changelog entries.
plansdocs/plans/Opens the dated plans, one folder each.
designdocs/design/Opens the dated design pitches and recommendations.
flowsdocs/flows/Opens the flow cards, one per screen change.
itemsdocs/items/Opens the planned, urgent and work items.
researchdocs/research/Opens the dated research notes.
playbooksdocs/playbooks/Opens the playbooks, such as how to talk while a team builds.
project intent.idd/project.intent.mdOpens the project intent that the per-module specs follow.
feature specs.bdd/features/Opens the behavior specs, one feature file per area.
Questions
  • Top screen has seven groups (dashboard, machine, shell, assistants, browser, windows, documents). Recommendation: keep them. If you want fewer, fold browser into assistants, since most of its use is by agents.
  • Which facade name do you type? The README names workstation, setup and ws. Recommendation: ws as the short alias, workstation help as the map, and setup kept as it is.
  • These are named in the README but are not in git ls-files: workstation-cli/workstation.py, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, init-windows/Start-Install.cmd, init-windows/inventory.md, resume-kvm, and the ~/.local/bin rules and review-open wrappers. Recommendation: confirm which exist on the machine, track them, and keep their rows. Otherwise drop the rows, because a thing with no row is what the map's test catches.
  • These row descriptions come from names and README wiring, not from reading the files: killport, the fix-keyboard/mouse/disk/whatsapp helpers, team-park, the five Claude hooks, clipstack, supabase-keepalive, and Test-Account.ps1. Recommendation: confirm each in its file before the what-lines are final.
  • zsh.d/dash-path-warn.zsh has no row because I cannot tell its purpose from the file name. Recommendation: tell me what it does, and I will add its row.
  • rules: under assistants (it prints agent rules) or under shell (it is a command)? Recommendation: assistants, with the command in its row.
  • The repair helpers live in zsh.d/utils.zsh but do machine repair. Recommendation: put them under machine.repair, not shell.utils.
  • The retired Lan Mouse and Playwright setups have rows, marked retired, so their rollback paths stay findable. Recommendation: keep them until rollback is no longer needed, then delete the rows.
  • The helpers update-gitlab-token and git_pull_with_creds carry a credential in their URLs, which the README says to rotate. They have no rows. Recommendation: rotate the credential, then add rows that name the command only.
  • dashboard-concepts is a comparison version. Recommendation: keep its rows until the comparison is decided, then remove the one you do not choose. Which one stays?
As phone screens

Home

The groups of this workstation, each one a place to reach one part of it.

dashboardPrints the dashboard screen: its page, server and checks.
›
machinePrints the machine screen: the Linux machine's power, display, internet, lid, Deskflow, audio, clipboard and repairs.
›
shellPrints the shell screen: git, OpenCode profiles and the helpers in zsh.d.
›
assistantsPrints the assistants screen: rules, Claude, Codex, skills, agents, usage guard, mods and Hermes.
›
browserPrints the browser screen: the browser command, Chrome and browser QA.
›
windowsPrints the windows screen: the Windows bootstrap, skill sync, repo clone and desktop mirror.
›
documentsPrints the documents screen: the CVs, case studies, incident records and project docs.
›
‹ Home

dashboard

The dashboard on this machine: its page, its server, its checks and the concepts version beside it.

pageOpens the dashboard page, where asked cases, rule changes and decided-alone calls wait for you. The server must be running.
›
serverStarts the dashboard server on port 8780, which serves the page and writes your answers to GitHub and the rule-proposal files.
›
checksRuns the dashboard's 199 checks against the real data and a real server.
›
conceptsStarts the concepts dashboard on port 8781, to compare with the main one by its output.
›
concepts checksRuns the concepts dashboard's 17 checks.
›
shotsOpens the screenshots of the dashboard's screens.
›
guideOpens the dashboard guide: what it reads, what it writes and how it reloads.
›
‹ Home

machine

The Linux machine's own utilities: power, display, internet, the lid, Deskflow, audio, clipboard and repairs.

powerPrints the power screen: the two CPU power profiles.
›
fix_old_monitor_hdmi.shRuns xrandr to set the external HDMI or DP output's mode and refresh rate, default 1920x1080 at 59.88.
›
internetPrints the internet screen: the two repairs for a lost connection.
›
lidPrints the lid screen: what closing the laptop lid does, and the closed-lid record.
›
deskflowPrints the deskflow screen: the shared keyboard and trackpad with the Windows machine.
›
audioPrints the audio screen: sending Linux audio to the Windows machine.
›
clipboardPrints the clipboard screen: the clipboard history picker, server and watcher.
›
repairPrints the repair screen: the fix helpers for keyboard, mouse, disk and WhatsApp.
›
supabase-keepaliveRuns the Supabase keepalive; its timer is supabase-keepalive.timer.
›
‹ machine

power

The two CPU power profiles, for the Intel machine only.

cpu-min-power.shRuns the power-saver profile: turbo off and the CPU capped at 8% of max. Asks for sudo.
›
cpu-normal-power.shRuns the balanced profile: turbo on and the cap back to 100%. Asks for sudo.
›
‹ machine

internet

The two repairs for a machine that lost its internet connection.

linux-internet-recovery.shRuns the DNS and network repair: systemd-resolved, resolv.conf, a NetworkManager restart and a DNS flush. Re-runs itself with sudo.
›
recover-tailscale-remote-terminal.shRuns the Tailscale repair, starts the remote-terminal service and checks port 3500.
›
‹ machine

lid

The settings for what closing the laptop lid does, and the record of the closed-lid test.

keep-running-with-lid-closed.shRuns the logind change so closing the lid does nothing. It applies after a reboot.
›
restore-default-lid-behavior.shRuns the removal of that change. It applies after a reboot.
›
closed-lid incidentOpens the record of the closed-lid test that kept CodeBot serving.
›
‹ machine

deskflow

Deskflow, which shares the laptop's keyboard and trackpad with the Windows machine.

resume-kvmStarts Deskflow again and asks for input access when that was cancelled.
›
deskflow.serviceStarts the Deskflow server with the graphical session.
›
guideOpens the Deskflow guide: everyday use, recovery and the setup.
›
usb-mouse notesOpens the notes on keyboard following the mouse and on USB sharing, which has been off since 2026-10-20.
›
lan-mouse (retired)Opens the retired Lan Mouse guide, kept only for rollback.
›
‹ machine

audio

Sending the Linux machine's audio to the Windows machine over Tailscale.

audio-startStarts sending all Linux audio to the Windows machine, which becomes the default output.
›
audio-pausePauses the share and restores the speakers.
›
audio-share statusPrints whether audio is being sent to the Windows machine.
›
audio-share tonePlays a test tone to the Windows machine.
›
‹ machine

clipboard

The clipboard history: its picker, its server, its watcher and its Windows script.

pickerRuns the clipboard history picker.
›
serverStarts the clipboard server, run by clipstack-server.service.
›
watcherStarts the clipboard watcher, run by clipstack-watcher.service.
›
clipstack.ahkOpens the Windows clipboard script.
›
installInstalls the clipboard services on this machine.
›
‹ machine

repair

The repair helpers in zsh.d/utils.zsh, for a keyboard, mouse, disk or WhatsApp that stopped working.

fix-keyboardRuns the keyboard repair.
›
fix-mouseRuns the mouse repair.
›
fix-diskRuns the disk repair.
›
fix-whatsappRuns the WhatsApp repair.
›
‹ Home

shell

The shell on this machine: git, the OpenCode profiles, and the helpers in zsh.d.

gitPrints the git screen: the checkout guard, the git settings and the hooks.
›
opencodePrints the OpenCode screen: the profiles and their commands.
›
utilsOpens the terminal helpers: set-title, killport, IP aliases, lazy nvm and node, Android, Java and Bun.
›
infraOpens the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts.
›
api-keys-editEdits the general-use API keys in ~/.config/api-keys/env. They are never kept in Git.
›
review-openOpens a file for review. It also works from bash and from agents.
›
‹ shell

git

The git setup: the guard on checkout, the git settings and the hooks that run in every repo.

git-safetyRuns git checkout through the wrapper that lists the files and asks [y/N] before discarding unstaged changes.
›
gitconfigEdits the author identity, Git LFS, the credential helper and the hooks path.
›
git-hooksOpens the Lefthook shims that run in every repo, including the push and commit gates.
›
‹ shell

opencode

The OpenCode profiles, and the commands that run and switch them.

opencodeRuns OpenCode with the current profile. The oc command does the same.
›
opencode helpPrints every profile's files, one column each, and the commands. With more than 3 profiles it writes them to ~/.opencode-profiles/help.md and opens it.
›
opencode-profileSets the name of the current profile.
›
opencode-profilesLists each profile and what it loads.
›
opencode-switchSwitches every shell's new runs to the named profile.
›
opencode-loginSigns the current profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editEdits one of the current profile's files.
›
profile filesOpens the profile files: profiles.py and its tests.
›
‹ Home

assistants

The AI assistant setup: the rules, the Claude and Codex settings, skills, agents, the usage guard, the mods and Hermes.

rulesPrints the rules, or the rules of one folder.
›
claudePrints the Claude screen: its global instructions, settings, hooks and session types.
›
codexPrints the Codex screen: its config and the Chrome bridge.
›
skillsPrints the skills screen: the shortlist, the backups and the source repo.
›
agentsPrints the agents screen: the Agent Sandbox, the agent records, the roles and the teams.
›
usage-guardPrints the usage guard screen: the claude wrapper and its install.
›
modsPrints the mods screen: the Claude Code plugins kept here.
›
hermesPrints the Hermes screen: running it, its configs and its restore runbook.
›
‹ assistants

claude

Claude's global instructions, settings, hooks and session types.

CLAUDE.mdEdits the global rules: browser automation, communication style, research and how to present work.
›
AGENTS.mdEdits the shorter global agent notes.
›
settings.jsonEdits the Claude Code settings that init-windows deploys.
›
hooksPrints the hooks screen: the five hooks wired into Claude's settings.
›
session typesOpens the session types guide: how claude --main -c and -r pick a session.
›
‹ claude

hooks

The five hooks in claude/hooks, wired into the Claude settings.

core-rules.shPrints the rules at session start and before Bash calls.
›
local-server-guard.pyRuns before each Bash call as the local server guard.
›
machine-history.shRuns as a hook that keeps the machine history.
›
proof-reminder.shReminds you to record proof after edits and Bash calls.
›
team-activity.shRuns as a hook that records team activity.
›
‹ assistants

codex

Codex's CLI config and the Chrome bridge that keeps its Chrome plugin working.

config.tomlEdits the Codex CLI config that init-windows deploys.
›
chrome-bridge guideOpens the Chrome bridge guide: installing it and the restarts it needs.
›
chrome-bridge installInstalls the bridge's systemd watcher and timer on Linux.
›
repair.mjsRuns the repair that restores the Chrome plugin's latest link and reapplies the file navigation patch.
›
playwright-mcp (retired)Opens the retired Playwright setup. It installs no browser server now.
›
‹ assistants

skills

The skills: which are installed, the backups kept here and the source repo.

shortlistOpens the skills researched on skills.sh and what is installed.
›
skill backupsOpens the skill backups kept here. Copy in the ones you want installed.
›
my-skills repoOpens the global skills repo that every installed skill is linked from.
›
skill syncPrints the Windows skill sync screen.
›
‹ assistants

agents

The agents: the Agent Sandbox that tests them, their records, the roles and the teams.

agent serveStarts the Agent Sandbox page on port 8790, where agents are tested in real sessions.
›
agent checkChecks every agent record and refuses broken ones with exit 1.
›
agent listLists the agents with their tier, model and number of tests.
›
agent framework guideOpens the agent framework guide: how the sandbox works and the words it uses.
›
agent recordsOpens the agent records, one folder per agent with its agent.yaml.
›
rolesOpens the draft role files: worker, supervisor, admin and qa-agent.
›
spawn-teamStarts a team from its team file in Claude. In Codex, $spawn-team does the same.
›
team-parkRuns team-park. Its guide is claude/team-park/README.md.
›
‹ assistants

usage-guard

The usage guard: the wrapper that stands in front of the claude command.

claude wrapperRuns claude through the usage guard, ahead of the native claude.
›
install.shInstalls the native claude and the wrapper on this machine.
›
Install-Windows.ps1Installs the usage guard on Windows.
›
guideOpens the usage guard guide.
›
testsOpens the usage guard tests: the request budget and the live refresh.
›
‹ assistants

mods

The Claude Code plugins kept here: the changelog pane, the review pane, the scratchpad playground and the team board.

changelog-paneOpens the changelog pane plugin: its hooks, types and tests.
›
review-paneOpens the review pane plugin's guide, with its design and flow notes.
›
scratchpad-playgroundOpens the scratchpad playground plugin: its hooks and types.
›
team-boardOpens the team board plugin: its hooks, types and tests.
›
‹ assistants

hermes

The Hermes agent: its launcher, its example settings and how to restore it.

hermesRuns the Hermes agent from its source checkout in ~/projects/hermes-agent.
›
RESTORE.mdOpens the restore runbook for Hermes and its profiles.
›
BACKUP-2026-10-02.mdOpens the record of the 2026-10-02 backup.
›
default config exampleOpens the example settings for the default profile, with no secrets.
›
jobs config exampleOpens the example settings for the jobs profile, with no secrets.
›
guideOpens the Hermes setup guide: installation, current configuration and history.
›
‹ Home

browser

Chrome automation: the browser command, the Chrome launcher and the behavioral browser QA.

browser statusPrints whether the background server and its Chrome are up.
›
browser closeCloses the Chrome window and stops the background server.
›
browser stepsRuns the steps in the one open Chrome window and prints the results as JSON.
›
browser guideOpens the browser command guide: actions, viewports, annotating, network capture and logins.
›
recording proofOpens how to record proof of a feature with recordStart and recordStop.
›
chrome.shStarts Chrome with the flags in chrome/flags. It is the only correct way to start Chrome here.
›
chrome installInstalls the Chrome links and menu entry that route to chrome.sh. Run once per machine.
›
chrome flagsEdits the Chrome flags, read at every start and by the browser command.
›
chrome guideOpens the Chrome guide: why the capture flag exists and its limits.
›
jev-browser-testRuns a goal in a browser and reports only the text and URL checks you give it.
›
jev installInstalls jev-browser-test and its pinned jev-ultrafast checkout.
›
jev guideOpens the browser QA guide: config, exit codes and the Jev loop.
›
codex browser notesOpens the notes on Codex's direct Chrome path. For recording, the browser command now replaces it.
›
‹ Home

windows

The Windows machine: the bootstrap, the skill sync, the repo clone and the desktop mirror.

init-windows guideOpens the Windows bootstrap guide: prerequisites, install, check and rollback.
›
Start-Install.cmdInstalls the pinned programs, Node versions, VS Code settings, Git config and user scripts. Needs the administrator prompt approved.
›
Smoke-Test-Windows.ps1Runs the smoke test that checks the install.
›
Remove-WindowsPack.ps1Removes the install, rolling it back from its journal.
›
secrets checklistOpens the sign-ins to redo by hand after the install.
›
inventoryOpens what the capture contains.
›
skills-syncPrints the skills sync screen: the runner that syncs skills after each push.
›
Clone-BetecRepos.ps1Clones the missing Betec repositories into the standard layout. Safe to re-run.
›
desktop mirrorOpens the mirror of the Windows desktop's global Claude folder.
›
desktop backupOpens the portable snapshot of the desktop's instructions and two skills, for manual restore.
›
‹ windows

skills-sync

The Windows skill sync: the runner, its scripts, the catch-up task and its last success.

runner serviceRuns the self-hosted runner that starts a sync after each trusted push to master.
›
Sync-Skills.ps1Runs the sync: fast-forwards the checkout and links the skills into the three skill folders.
›
Test-Sync.ps1Runs the sync test.
›
Test-Account.ps1Runs the account check for the sync's Windows account.
›
catch-up taskRuns the sync once after startup, retried three times if an attempt fails.
›
last successOpens the record of the last successful sync.
›
sync guideOpens the sync guide: installed parts, permissions and the trust boundary.
›
verificationOpens how the sync was verified.
›
‹ Home

documents

The documents: the CVs, the case studies, the incident records and the project's own docs.

cvPrints the cv screen: the three CVs and how to rebuild them.
›
codebot return caseOpens the case study of one design request run with and without the conceptual-modeling skill.
›
signal garden caseOpens the case study of a doc exhibit that separates durable explanation from the live interface.
›
kernel resultsOpens the results of testing Kernel cloud browsers against local Chrome, including session recording.
›
incidentsOpens the list of dated incident records and their outcomes.
›
docsPrints the docs screen: changelog, plans, designs, flows, items, research, specs and playbooks.
›
‹ documents

cv

The three CVs and the tools that rebuild them.

cv-full-stack.pdfOpens the Full Stack Developer CV.
›
cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV.
›
cv-ai-integrations.pdfOpens the AI Integrations CV.
›
pdflatex rebuildRuns pdflatex to rebuild one CV from its LaTeX source. Run it in cv/.
›
text buildRuns the build of the plain-text CV versions.
›
versionsOpens the dated CV versions, 2026-10-04 and 2026-10-04-v2.
›
cv guideOpens the CV guide: sources, shared content and the update steps.
›
cv workflowOpens the CV workflow.
›
‹ documents

docs

The project's own docs: changelog, plans, designs, flows, items, research, the intent and feature specs, and the playbooks.

changelogOpens the dated changelog entries.
›
plansOpens the dated plans, one folder each.
›
designOpens the dated design pitches and recommendations.
›
flowsOpens the flow cards, one per screen change.
›
itemsOpens the planned, urgent and work items.
›
researchOpens the dated research notes.
›
playbooksOpens the playbooks, such as how to talk while a team builds.
›
project intentOpens the project intent that the per-module specs follow.
›
feature specsOpens the behavior specs, one feature file per area.
›
Raw answer
The workstation map is below, with the scenario and judgment calls first. I read only the file dump, so nothing here is checked against the machine.

**Scenario** (reasoning from the README, not observed): Liel is at the Linux laptop and something has stopped working (internet, audio, the mouse crossing the edge, the dashboard) or Liel needs to find where a thing lives. They want one place that says what each command does and where it is.

**Judgment calls**
- Groups follow jobs and reuse the README's own headings: dashboard, machine, shell, assistants, browser, windows, documents.
- Many similar files (design pitches, screenshots, research runs, skill references) get one folder row, not one row per file.
- Secret-bearing helpers get no rows. Their names are listed under questions.
- Rows for items I could not read are worded from the name and the README only. The questions list them so they can be confirmed.
- Paths are relative to `~/projects/workstation` unless absolute.

```json
{"screens": [
{"path": [], "sentence": "The groups of this workstation, each one a place to reach one part of it.", "rows": [
 {"name": "dashboard", "form": "workstation dashboard", "what": "Prints the dashboard screen: its page, server and checks."},
 {"name": "machine", "form": "workstation machine", "what": "Prints the machine screen: the Linux machine's power, display, internet, lid, Deskflow, audio, clipboard and repairs."},
 {"name": "shell", "form": "workstation shell", "what": "Prints the shell screen: git, OpenCode profiles and the helpers in zsh.d."},
 {"name": "assistants", "form": "workstation assistants", "what": "Prints the assistants screen: rules, Claude, Codex, skills, agents, usage guard, mods and Hermes."},
 {"name": "browser", "form": "workstation browser", "what": "Prints the browser screen: the browser command, Chrome and browser QA."},
 {"name": "windows", "form": "workstation windows", "what": "Prints the windows screen: the Windows bootstrap, skill sync, repo clone and desktop mirror."},
 {"name": "documents", "form": "workstation documents", "what": "Prints the documents screen: the CVs, case studies, incident records and project docs."}
]},

{"path": ["dashboard"], "sentence": "The dashboard on this machine: its page, its server, its checks and the concepts version beside it.", "rows": [
 {"name": "page", "form": "http://127.0.0.1:8780", "what": "Opens the dashboard page, where asked cases, rule changes and decided-alone calls wait for you. The server must be running."},
 {"name": "server", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard server on port 8780, which serves the page and writes your answers to GitHub and the rule-proposal files."},
 {"name": "checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard", "what": "Runs the dashboard's 199 checks against the real data and a real server."},
 {"name": "concepts", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts dashboard on port 8781, to compare with the main one by its output."},
 {"name": "concepts checks", "form": "python3 -I -m unittest discover -s ~/projects/workstation/dashboard-concepts", "what": "Runs the concepts dashboard's 17 checks."},
 {"name": "shots", "form": "dashboard/shots/", "what": "Opens the screenshots of the dashboard's screens."},
 {"name": "guide", "form": "dashboard/README.md", "what": "Opens the dashboard guide: what it reads, what it writes and how it reloads."}
]},

{"path": ["machine"], "sentence": "The Linux machine's own utilities: power, display, internet, the lid, Deskflow, audio, clipboard and repairs.", "rows": [
 {"name": "power", "form": "workstation machine power", "what": "Prints the power screen: the two CPU power profiles."},
 {"name": "fix_old_monitor_hdmi.sh", "form": "fix_old_monitor_hdmi.sh", "what": "Runs xrandr to set the external HDMI or DP output's mode and refresh rate, default 1920x1080 at 59.88."},
 {"name": "internet", "form": "workstation machine internet", "what": "Prints the internet screen: the two repairs for a lost connection."},
 {"name": "lid", "form": "workstation machine lid", "what": "Prints the lid screen: what closing the laptop lid does, and the closed-lid record."},
 {"name": "deskflow", "form": "workstation machine deskflow", "what": "Prints the deskflow screen: the shared keyboard and trackpad with the Windows machine."},
 {"name": "audio", "form": "workstation machine audio", "what": "Prints the audio screen: sending Linux audio to the Windows machine."},
 {"name": "clipboard", "form": "workstation machine clipboard", "what": "Prints the clipboard screen: the clipboard history picker, server and watcher."},
 {"name": "repair", "form": "workstation machine repair", "what": "Prints the repair screen: the fix helpers for keyboard, mouse, disk and WhatsApp."},
 {"name": "supabase-keepalive", "form": "supabase-keepalive/supabase-keepalive.sh", "what": "Runs the Supabase keepalive; its timer is supabase-keepalive.timer."}
]},

{"path": ["machine", "power"], "sentence": "The two CPU power profiles, for the Intel machine only.", "rows": [
 {"name": "cpu-min-power.sh", "form": "cpu-min-power.sh", "what": "Runs the power-saver profile: turbo off and the CPU capped at 8% of max. Asks for sudo."},
 {"name": "cpu-normal-power.sh", "form": "cpu-normal-power.sh", "what": "Runs the balanced profile: turbo on and the cap back to 100%. Asks for sudo."}
]},

{"path": ["machine", "internet"], "sentence": "The two repairs for a machine that lost its internet connection.", "rows": [
 {"name": "linux-internet-recovery.sh", "form": "linux-internet-recovery.sh", "what": "Runs the DNS and network repair: systemd-resolved, resolv.conf, a NetworkManager restart and a DNS flush. Re-runs itself with sudo."},
 {"name": "recover-tailscale-remote-terminal.sh", "form": "recover-tailscale-remote-terminal.sh", "what": "Runs the Tailscale repair, starts the remote-terminal service and checks port 3500."}
]},

{"path": ["machine", "lid"], "sentence": "The settings for what closing the laptop lid does, and the record of the closed-lid test.", "rows": [
 {"name": "keep-running-with-lid-closed.sh", "form": "laptop-utilities/keep-running-with-lid-closed.sh", "what": "Runs the logind change so closing the lid does nothing. It applies after a reboot."},
 {"name": "restore-default-lid-behavior.sh", "form": "laptop-utilities/restore-default-lid-behavior.sh", "what": "Runs the removal of that change. It applies after a reboot."},
 {"name": "closed-lid incident", "form": "reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "Opens the record of the closed-lid test that kept CodeBot serving."}
]},

{"path": ["machine", "deskflow"], "sentence": "Deskflow, which shares the laptop's keyboard and trackpad with the Windows machine.", "rows": [
 {"name": "resume-kvm", "form": "resume-kvm", "what": "Starts Deskflow again and asks for input access when that was cancelled."},
 {"name": "deskflow.service", "form": "~/.config/systemd/user/deskflow.service", "what": "Starts the Deskflow server with the graphical session."},
 {"name": "guide", "form": "deskflow/README.md", "what": "Opens the Deskflow guide: everyday use, recovery and the setup."},
 {"name": "usb-mouse notes", "form": "deskflow/usb-mouse/README.md", "what": "Opens the notes on keyboard following the mouse and on USB sharing, which has been off since 2026-10-20."},
 {"name": "lan-mouse (retired)", "form": "lan-mouse/README.md", "what": "Opens the retired Lan Mouse guide, kept only for rollback."}
]},

{"path": ["machine", "audio"], "sentence": "Sending the Linux machine's audio to the Windows machine over Tailscale.", "rows": [
 {"name": "audio-start", "form": "audio-start", "what": "Starts sending all Linux audio to the Windows machine, which becomes the default output."},
 {"name": "audio-pause", "form": "audio-pause", "what": "Pauses the share and restores the speakers."},
 {"name": "audio-share status", "form": "audio-share status", "what": "Prints whether audio is being sent to the Windows machine."},
 {"name": "audio-share tone", "form": "audio-share tone", "what": "Plays a test tone to the Windows machine."}
]},

{"path": ["machine", "clipboard"], "sentence": "The clipboard history: its picker, its server, its watcher and its Windows script.", "rows": [
 {"name": "picker", "form": "clipstack/picker.py", "what": "Runs the clipboard history picker."},
 {"name": "server", "form": "clipstack/server.py", "what": "Starts the clipboard server, run by clipstack-server.service."},
 {"name": "watcher", "form": "clipstack/watcher.py", "what": "Starts the clipboard watcher, run by clipstack-watcher.service."},
 {"name": "clipstack.ahk", "form": "clipstack/windows/clipstack.ahk", "what": "Opens the Windows clipboard script."},
 {"name": "install", "form": "clipstack/install.sh", "what": "Installs the clipboard services on this machine."}
]},

{"path": ["machine", "repair"], "sentence": "The repair helpers in zsh.d/utils.zsh, for a keyboard, mouse, disk or WhatsApp that stopped working.", "rows": [
 {"name": "fix-keyboard", "form": "fix-keyboard", "what": "Runs the keyboard repair."},
 {"name": "fix-mouse", "form": "fix-mouse", "what": "Runs the mouse repair."},
 {"name": "fix-disk", "form": "fix-disk", "what": "Runs the disk repair."},
 {"name": "fix-whatsapp", "form": "fix-whatsapp", "what": "Runs the WhatsApp repair."}
]},

{"path": ["shell"], "sentence": "The shell on this machine: git, the OpenCode profiles, and the helpers in zsh.d.", "rows": [
 {"name": "git", "form": "workstation shell git", "what": "Prints the git screen: the checkout guard, the git settings and the hooks."},
 {"name": "opencode", "form": "workstation shell opencode", "what": "Prints the OpenCode screen: the profiles and their commands."},
 {"name": "utils", "form": "zsh.d/utils.zsh", "what": "Opens the terminal helpers: set-title, killport, IP aliases, lazy nvm and node, Android, Java and Bun."},
 {"name": "infra", "form": "zsh.d/infra.zsh", "what": "Opens the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts."},
 {"name": "api-keys-edit", "form": "api-keys-edit", "what": "Edits the general-use API keys in ~/.config/api-keys/env. They are never kept in Git."},
 {"name": "review-open", "form": "review-open", "what": "Opens a file for review. It also works from bash and from agents."}
]},

{"path": ["shell", "git"], "sentence": "The git setup: the guard on checkout, the git settings and the hooks that run in every repo.", "rows": [
 {"name": "git-safety", "form": "zsh.d/git-safety.zsh", "what": "Runs git checkout through the wrapper that lists the files and asks [y/N] before discarding unstaged changes."},
 {"name": "gitconfig", "form": "~/.gitconfig", "what": "Edits the author identity, Git LFS, the credential helper and the hooks path."},
 {"name": "git-hooks", "form": "~/.git-hooks/", "what": "Opens the Lefthook shims that run in every repo, including the push and commit gates."}
]},

{"path": ["shell", "opencode"], "sentence": "The OpenCode profiles, and the commands that run and switch them.", "rows": [
 {"name": "opencode", "form": "opencode", "what": "Runs OpenCode with the current profile. The oc command does the same."},
 {"name": "opencode help", "form": "opencode help", "what": "Prints every profile's files, one column each, and the commands. With more than 3 profiles it writes them to ~/.opencode-profiles/help.md and opens it."},
 {"name": "opencode-profile", "form": "opencode-profile", "what": "Sets the name of the current profile."},
 {"name": "opencode-profiles", "form": "opencode-profiles", "what": "Lists each profile and what it loads."},
 {"name": "opencode-switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
 {"name": "opencode-login", "form": "opencode-login", "what": "Signs the current profile's Claude Code in."},
 {"name": "opencode-files", "form": "opencode-files", "what": "Lists the current profile's files."},
 {"name": "opencode-edit", "form": "opencode-edit <file>", "what": "Edits one of the current profile's files."},
 {"name": "profile files", "form": "opencode-profiles/", "what": "Opens the profile files: profiles.py and its tests."}
]},

{"path": ["assistants"], "sentence": "The AI assistant setup: the rules, the Claude and Codex settings, skills, agents, the usage guard, the mods and Hermes.", "rows": [
 {"name": "rules", "form": "rules [folder]", "what": "Prints the rules, or the rules of one folder."},
 {"name": "claude", "form": "workstation assistants claude", "what": "Prints the Claude screen: its global instructions, settings, hooks and session types."},
 {"name": "codex", "form": "workstation assistants codex", "what": "Prints the Codex screen: its config and the Chrome bridge."},
 {"name": "skills", "form": "workstation assistants skills", "what": "Prints the skills screen: the shortlist, the backups and the source repo."},
 {"name": "agents", "form": "workstation assistants agents", "what": "Prints the agents screen: the Agent Sandbox, the agent records, the roles and the teams."},
 {"name": "usage-guard", "form": "workstation assistants usage-guard", "what": "Prints the usage guard screen: the claude wrapper and its install."},
 {"name": "mods", "form": "workstation assistants mods", "what": "Prints the mods screen: the Claude Code plugins kept here."},
 {"name": "hermes", "form": "workstation assistants hermes", "what": "Prints the Hermes screen: running it, its configs and its restore runbook."}
]},

{"path": ["assistants", "claude"], "sentence": "Claude's global instructions, settings, hooks and session types.", "rows": [
 {"name": "CLAUDE.md", "form": "claude/CLAUDE.md", "what": "Edits the global rules: browser automation, communication style, research and how to present work."},
 {"name": "AGENTS.md", "form": "claude/AGENTS.md", "what": "Edits the shorter global agent notes."},
 {"name": "settings.json", "form": "claude/settings.json", "what": "Edits the Claude Code settings that init-windows deploys."},
 {"name": "hooks", "form": "workstation assistants claude hooks", "what": "Prints the hooks screen: the five hooks wired into Claude's settings."},
 {"name": "session types", "form": "claude/session-types/README.md", "what": "Opens the session types guide: how claude --main -c and -r pick a session."}
]},

{"path": ["assistants", "claude", "hooks"], "sentence": "The five hooks in claude/hooks, wired into the Claude settings.", "rows": [
 {"name": "core-rules.sh", "form": "claude/hooks/core-rules.sh", "what": "Prints the rules at session start and before Bash calls."},
 {"name": "local-server-guard.py", "form": "claude/hooks/local-server-guard.py", "what": "Runs before each Bash call as the local server guard."},
 {"name": "machine-history.sh", "form": "claude/hooks/machine-history.sh", "what": "Runs as a hook that keeps the machine history."},
 {"name": "proof-reminder.sh", "form": "claude/hooks/proof-reminder.sh", "what": "Reminds you to record proof after edits and Bash calls."},
 {"name": "team-activity.sh", "form": "claude/hooks/team-activity.sh", "what": "Runs as a hook that records team activity."}
]},

{"path": ["assistants", "codex"], "sentence": "Codex's CLI config and the Chrome bridge that keeps its Chrome plugin working.", "rows": [
 {"name": "config.toml", "form": "codex/config.toml", "what": "Edits the Codex CLI config that init-windows deploys."},
 {"name": "chrome-bridge guide", "form": "codex/chrome-bridge/README.md", "what": "Opens the Chrome bridge guide: installing it and the restarts it needs."},
 {"name": "chrome-bridge install", "form": "codex/chrome-bridge/install.sh", "what": "Installs the bridge's systemd watcher and timer on Linux."},
 {"name": "repair.mjs", "form": "codex/chrome-bridge/repair.mjs", "what": "Runs the repair that restores the Chrome plugin's latest link and reapplies the file navigation patch."},
 {"name": "playwright-mcp (retired)", "form": "codex/playwright-mcp/README.md", "what": "Opens the retired Playwright setup. It installs no browser server now."}
]},

{"path": ["assistants", "skills"], "sentence": "The skills: which are installed, the backups kept here and the source repo.", "rows": [
 {"name": "shortlist", "form": "claude/skills-shortlist.md", "what": "Opens the skills researched on skills.sh and what is installed."},
 {"name": "skill backups", "form": "claude/skills/", "what": "Opens the skill backups kept here. Copy in the ones you want installed."},
 {"name": "my-skills repo", "form": "~/projects/my-skills", "what": "Opens the global skills repo that every installed skill is linked from."},
 {"name": "skill sync", "form": "workstation windows skills-sync", "what": "Prints the Windows skill sync screen."}
]},

{"path": ["assistants", "agents"], "sentence": "The agents: the Agent Sandbox that tests them, their records, the roles and the teams.", "rows": [
 {"name": "agent serve", "form": "agent-framework/agent serve", "what": "Starts the Agent Sandbox page on port 8790, where agents are tested in real sessions."},
 {"name": "agent check", "form": "agent-framework/agent check", "what": "Checks every agent record and refuses broken ones with exit 1."},
 {"name": "agent list", "form": "agent-framework/agent list", "what": "Lists the agents with their tier, model and number of tests."},
 {"name": "agent framework guide", "form": "agent-framework/README.md", "what": "Opens the agent framework guide: how the sandbox works and the words it uses."},
 {"name": "agent records", "form": "~/projects/my-skills/agents/", "what": "Opens the agent records, one folder per agent with its agent.yaml."},
 {"name": "roles", "form": "docs/roles/", "what": "Opens the draft role files: worker, supervisor, admin and qa-agent."},
 {"name": "spawn-team", "form": "/spawn-team <team>", "what": "Starts a team from its team file in Claude. In Codex, $spawn-team does the same."},
 {"name": "team-park", "form": "~/.local/bin/team-park", "what": "Runs team-park. Its guide is claude/team-park/README.md."}
]},

{"path": ["assistants", "usage-guard"], "sentence": "The usage guard: the wrapper that stands in front of the claude command.", "rows": [
 {"name": "claude wrapper", "form": "~/bin/claude", "what": "Runs claude through the usage guard, ahead of the native claude."},
 {"name": "install.sh", "form": "claude/usage-guard/install.sh", "what": "Installs the native claude and the wrapper on this machine."},
 {"name": "Install-Windows.ps1", "form": "claude/usage-guard/Install-Windows.ps1", "what": "Installs the usage guard on Windows."},
 {"name": "guide", "form": "claude/usage-guard/README.md", "what": "Opens the usage guard guide."},
 {"name": "tests", "form": "claude/usage-guard/tests/", "what": "Opens the usage guard tests: the request budget and the live refresh."}
]},

{"path": ["assistants", "mods"], "sentence": "The Claude Code plugins kept here: the changelog pane, the review pane, the scratchpad playground and the team board.", "rows": [
 {"name": "changelog-pane", "form": "claude/mods/changelog-pane/", "what": "Opens the changelog pane plugin: its hooks, types and tests."},
 {"name": "review-pane", "form": "claude/mods/review-pane/README.md", "what": "Opens the review pane plugin's guide, with its design and flow notes."},
 {"name": "scratchpad-playground", "form": "claude/mods/scratchpad-playground/", "what": "Opens the scratchpad playground plugin: its hooks and types."},
 {"name": "team-board", "form": "claude/mods/team-board/", "what": "Opens the team board plugin: its hooks, types and tests."}
]},

{"path": ["assistants", "hermes"], "sentence": "The Hermes agent: its launcher, its example settings and how to restore it.", "rows": [
 {"name": "hermes", "form": "hermes", "what": "Runs the Hermes agent from its source checkout in ~/projects/hermes-agent."},
 {"name": "RESTORE.md", "form": "hermes/RESTORE.md", "what": "Opens the restore runbook for Hermes and its profiles."},
 {"name": "BACKUP-2026-10-02.md", "form": "hermes/BACKUP-2026-10-02.md", "what": "Opens the record of the 2026-10-02 backup."},
 {"name": "default config example", "form": "hermes/default.config.example.yaml", "what": "Opens the example settings for the default profile, with no secrets."},
 {"name": "jobs config example", "form": "hermes/jobs.config.example.yaml", "what": "Opens the example settings for the jobs profile, with no secrets."},
 {"name": "guide", "form": "hermes/README.md", "what": "Opens the Hermes setup guide: installation, current configuration and history."}
]},

{"path": ["browser"], "sentence": "Chrome automation: the browser command, the Chrome launcher and the behavioral browser QA.", "rows": [
 {"name": "browser status", "form": "browser status", "what": "Prints whether the background server and its Chrome are up."},
 {"name": "browser close", "form": "browser close", "what": "Closes the Chrome window and stops the background server."},
 {"name": "browser steps", "form": "browser '<json-array-of-steps>'", "what": "Runs the steps in the one open Chrome window and prints the results as JSON."},
 {"name": "browser guide", "form": "browser/README.md", "what": "Opens the browser command guide: actions, viewports, annotating, network capture and logins."},
 {"name": "recording proof", "form": "browser/README.md#recording-proof", "what": "Opens how to record proof of a feature with recordStart and recordStop."},
 {"name": "chrome.sh", "form": "chrome/chrome.sh", "what": "Starts Chrome with the flags in chrome/flags. It is the only correct way to start Chrome here."},
 {"name": "chrome install", "form": "chrome/install.sh", "what": "Installs the Chrome links and menu entry that route to chrome.sh. Run once per machine."},
 {"name": "chrome flags", "form": "chrome/flags", "what": "Edits the Chrome flags, read at every start and by the browser command."},
 {"name": "chrome guide", "form": "chrome/README.md", "what": "Opens the Chrome guide: why the capture flag exists and its limits."},
 {"name": "jev-browser-test", "form": "jev-browser-test", "what": "Runs a goal in a browser and reports only the text and URL checks you give it."},
 {"name": "jev install", "form": "sh jev-browser-test/install.sh", "what": "Installs jev-browser-test and its pinned jev-ultrafast checkout."},
 {"name": "jev guide", "form": "jev-browser-test/README.md", "what": "Opens the browser QA guide: config, exit codes and the Jev loop."},
 {"name": "codex browser notes", "form": "codex/browser/README.md", "what": "Opens the notes on Codex's direct Chrome path. For recording, the browser command now replaces it."}
]},

{"path": ["windows"], "sentence": "The Windows machine: the bootstrap, the skill sync, the repo clone and the desktop mirror.", "rows": [
 {"name": "init-windows guide", "form": "init-windows/README.md", "what": "Opens the Windows bootstrap guide: prerequisites, install, check and rollback."},
 {"name": "Start-Install.cmd", "form": "init-windows/Start-Install.cmd", "what": "Installs the pinned programs, Node versions, VS Code settings, Git config and user scripts. Needs the administrator prompt approved."},
 {"name": "Smoke-Test-Windows.ps1", "form": "init-windows/Smoke-Test-Windows.ps1", "what": "Runs the smoke test that checks the install."},
 {"name": "Remove-WindowsPack.ps1", "form": "init-windows/Remove-WindowsPack.ps1", "what": "Removes the install, rolling it back from its journal."},
 {"name": "secrets checklist", "form": "init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand after the install."},
 {"name": "inventory", "form": "init-windows/inventory.md", "what": "Opens what the capture contains."},
 {"name": "skills-sync", "form": "workstation windows skills-sync", "what": "Prints the skills sync screen: the runner that syncs skills after each push."},
 {"name": "Clone-BetecRepos.ps1", "form": "repos/Clone-BetecRepos.ps1", "what": "Clones the missing Betec repositories into the standard layout. Safe to re-run."},
 {"name": "desktop mirror", "form": "claude/windows-global/", "what": "Opens the mirror of the Windows desktop's global Claude folder."},
 {"name": "desktop backup", "form": "claude/backups/desktop-v2-2026/", "what": "Opens the portable snapshot of the desktop's instructions and two skills, for manual restore."}
]},

{"path": ["windows", "skills-sync"], "sentence": "The Windows skill sync: the runner, its scripts, the catch-up task and its last success.", "rows": [
 {"name": "runner service", "form": "actions.runner.Lebnor-my-skills.my-skills-liel-windows", "what": "Runs the self-hosted runner that starts a sync after each trusted push to master."},
 {"name": "Sync-Skills.ps1", "form": "skills-sync-windows/Sync-Skills.ps1", "what": "Runs the sync: fast-forwards the checkout and links the skills into the three skill folders."},
 {"name": "Test-Sync.ps1", "form": "skills-sync-windows/Test-Sync.ps1", "what": "Runs the sync test."},
 {"name": "Test-Account.ps1", "form": "skills-sync-windows/Test-Account.ps1", "what": "Runs the account check for the sync's Windows account."},
 {"name": "catch-up task", "form": "MySkillsSync-CatchUp", "what": "Runs the sync once after startup, retried three times if an attempt fails."},
 {"name": "last success", "form": "C:/ProgramData/MySkillsSync/state/last-success.json", "what": "Opens the record of the last successful sync."},
 {"name": "sync guide", "form": "skills-sync-windows/README.md", "what": "Opens the sync guide: installed parts, permissions and the trust boundary."},
 {"name": "verification", "form": "skills-sync-windows/verification.md", "what": "Opens how the sync was verified."}
]},

{"path": ["documents"], "sentence": "The documents: the CVs, the case studies, the incident records and the project's own docs.", "rows": [
 {"name": "cv", "form": "workstation documents cv", "what": "Prints the cv screen: the three CVs and how to rebuild them."},
 {"name": "codebot return case", "form": "case-studies/conceptual-modeling/2026-09-15-codebot-return/README.md", "what": "Opens the case study of one design request run with and without the conceptual-modeling skill."},
 {"name": "signal garden case", "form": "case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "Opens the case study of a doc exhibit that separates durable explanation from the live interface."},
 {"name": "kernel results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the results of testing Kernel cloud browsers against local Chrome, including session recording."},
 {"name": "incidents", "form": "reference/README.md", "what": "Opens the list of dated incident records and their outcomes."},
 {"name": "docs", "form": "workstation documents docs", "what": "Prints the docs screen: changelog, plans, designs, flows, items, research, specs and playbooks."}
]},

{"path": ["documents", "cv"], "sentence": "The three CVs and the tools that rebuild them.", "rows": [
 {"name": "cv-full-stack.pdf", "form": "cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV."},
 {"name": "cv-ai-full-stack.pdf", "form": "cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV."},
 {"name": "cv-ai-integrations.pdf", "form": "cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV."},
 {"name": "pdflatex rebuild", "form": "pdflatex -interaction=nonstopmode -halt-on-error <cv>.tex", "what": "Runs pdflatex to rebuild one CV from its LaTeX source. Run it in cv/."},
 {"name": "text build", "form": "cv/text/build-full.sh", "what": "Runs the build of the plain-text CV versions."},
 {"name": "versions", "form": "cv/versions/", "what": "Opens the dated CV versions, 2026-10-04 and 2026-10-04-v2."},
 {"name": "cv guide", "form": "cv/README.md", "what": "Opens the CV guide: sources, shared content and the update steps."},
 {"name": "cv workflow", "form": "cv/WORKFLOW.md", "what": "Opens the CV workflow."}
]},

{"path": ["documents", "docs"], "sentence": "The project's own docs: changelog, plans, designs, flows, items, research, the intent and feature specs, and the playbooks.", "rows": [
 {"name": "changelog", "form": "docs/changelog/", "what": "Opens the dated changelog entries."},
 {"name": "plans", "form": "docs/plans/", "what": "Opens the dated plans, one folder each."},
 {"name": "design", "form": "docs/design/", "what": "Opens the dated design pitches and recommendations."},
 {"name": "flows", "form": "docs/flows/", "what": "Opens the flow cards, one per screen change."},
 {"name": "items", "form": "docs/items/", "what": "Opens the planned, urgent and work items."},
 {"name": "research", "form": "docs/research/", "what": "Opens the dated research notes."},
 {"name": "playbooks", "form": "docs/playbooks/", "what": "Opens the playbooks, such as how to talk while a team builds."},
 {"name": "project intent", "form": ".idd/project.intent.md", "what": "Opens the project intent that the per-module specs follow."},
 {"name": "feature specs", "form": ".bdd/features/", "what": "Opens the behavior specs, one feature file per area."}
]}
],
"questions": [
"Top screen has seven groups (dashboard, machine, shell, assistants, browser, windows, documents). Recommendation: keep them. If you want fewer, fold browser into assistants, since most of its use is by agents.",
"Which facade name do you type? The README names workstation, setup and ws. Recommendation: ws as the short alias, workstation help as the map, and setup kept as it is.",
"These are named in the README but are not in git ls-files: workstation-cli/workstation.py, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, init-windows/Start-Install.cmd, init-windows/inventory.md, resume-kvm, and the ~/.local/bin rules and review-open wrappers. Recommendation: confirm which exist on the machine, track them, and keep their rows. Otherwise drop the rows, because a thing with no row is what the map's test catches.",
"These row descriptions come from names and README wiring, not from reading the files: killport, the fix-keyboard/mouse/disk/whatsapp helpers, team-park, the five Claude hooks, clipstack, supabase-keepalive, and Test-Account.ps1. Recommendation: confirm each in its file before the what-lines are final.",
"zsh.d/dash-path-warn.zsh has no row because I cannot tell its purpose from the file name. Recommendation: tell me what it does, and I will add its row.",
"rules: under assistants (it prints agent rules) or under shell (it is a command)? Recommendation: assistants, with the command in its row.",
"The repair helpers live in zsh.d/utils.zsh but do machine repair. Recommendation: put them under machine.repair, not shell.utils.",
"The retired Lan Mouse and Playwright setups have rows, marked retired, so their rollback paths stay findable. Recommendation: keep them until rollback is no longer needed, then delete the rows.",
"The helpers update-gitlab-token and git_pull_with_creds carry a credential in their URLs, which the README says to rotate. They have no rows. Recommendation: rotate the credential, then add rows that name the command only.",
"dashboard-concepts is a comparison version. Recommendation: keep its rows until the comparison is decided, then remove the one you do not choose. Which one stays?"
]}
```

screen-decomposition, final · run 5 exit=0 seconds=217 · prompt

P1 Recall: 0.843P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.978P5 Short top: 6P6 Own words: 1.0P8 Worded per screen: 0P9 Grouping (ARI): 0.308
As terminal help
Everything on this workstation, grouped by what you are trying to do.
machineworkstation machineOpens the machine screen: repairs, power, sharing with Windows, and background services for this Linux laptop.
shellworkstation shellOpens the shell screen: git guards, opencode profiles, API keys and terminal helpers.
agentsworkstation agentsOpens the agents screen: rules, assistants, skills, the sandbox, the dashboard and the data repo.
browserworkstation browserOpens the browser screen: the persistent Chrome command, Chrome itself and the smoke-test tool.
windowsworkstation windowsOpens the windows screen: the Windows PC's setup, scripts and skills sync (these run on Windows).
documentsworkstation documentsOpens the documents screen: the README, CVs, plans, research, case studies and reference records.
machine
Repairs, power and sharing for this Linux laptop, and the services that run in the background.
repairworkstation machine repairOpens the repair screen: fixes for network, screen, keyboard, mouse and disk.
powerworkstation machine powerOpens the power screen: CPU power profiles and what closing the lid does.
shareworkstation machine shareOpens the share screen: Deskflow, audio, the shared clipboard and the Windows USB mouse notes.
servicesworkstation machine servicesOpens the services screen: the background services that run on this laptop.
machine › repair
Repair helpers for the laptop's network, screen, keyboard, mouse and disk.
fix-keyboardfix-keyboard (zsh.d/utils.zsh)Runs the keyboard repair helper.
fix-mousefix-mouse (zsh.d/utils.zsh)Runs the mouse repair helper.
fix-diskfix-disk (zsh.d/utils.zsh)Runs the disk repair helper.
fix-whatsappfix-whatsapp (zsh.d/utils.zsh)Runs the WhatsApp repair helper.
linux-internet-recovery.sh~/projects/workstation/linux-internet-recovery.shRuns the network recovery: systemd-resolved DNS, NetworkManager restart and DNS flush; re-runs itself with sudo.
recover-tailscale-remote-terminal.sh~/projects/workstation/recover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, then starts the remote-terminal service and checks port 3500.
fix_old_monitor_hdmi.sh~/projects/workstation/fix_old_monitor_hdmi.shSets the external screen's mode and refresh rate with xrandr (default 1920x1080 at 59.88).
machine › power
Scripts that set the CPU power profile and what closing the lid does.
cpu-min-power.sh~/projects/workstation/cpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8%; asks for sudo; Intel only.
cpu-normal-power.sh~/projects/workstation/cpu-normal-power.shSets the balanced profile, turns turbo on and lifts the cap to 100%.
keep-running-with-lid-closed.sh~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.shWrites a logind setting so closing the lid does nothing; applies after a reboot.
restore-default-lid-behavior.sh~/projects/workstation/laptop-utilities/restore-default-lid-behavior.shRemoves that logind setting; applies after a reboot.
machine › share
Tools that share this laptop's trackpad, keyboard, audio and clipboard with the Windows PC.
deskflow service~/.config/systemd/user/deskflow.serviceRuns the Deskflow server that shares this trackpad and keyboard with Windows.
deskflow guide~/projects/workstation/deskflow/README.mdOpens the Deskflow guide: everyday use, recovery and the input-access prompt.
resume-kvmresume-kvmStarts Deskflow again and asks GNOME for input access.
audio-startaudio-start (zsh.d/audio-share.zsh)Sends all Linux audio to the Windows PC over Tailscale.
audio-pauseaudio-pauseRestores the laptop speakers as the audio output.
audio-shareaudio-share on|off|status|toneTurns audio sharing on or off, prints its status, or plays a test tone.
clipstack~/projects/workstation/clipstack/Opens the shared clipboard folder: its server, watcher, picker and install script.
usb-mouse notes~/projects/workstation/deskflow/usb-mouse/README.mdOpens the notes on the Windows USB mouse, off since 2026-10-20, and how to turn it back on.
machine › services
Background services that run on this laptop.
supabase-keepalive~/projects/workstation/supabase-keepalive/Runs on a timer to keep the Supabase connection from going idle.
remote-terminalremote-terminal user service (port 3500)Runs the remote terminal on port 3500, the service the Tailscale recovery script starts.
data-pull~/.config/systemd/user/data-pull.*Pulls answers from the data repo every 5 minutes.
shell
Commands you type in the terminal: git guards, opencode profiles, API keys and helpers.
gitworkstation shell gitOpens the git screen: the checkout guard, the hooks and the git identity.
opencodeworkstation shell opencodeOpens the opencode screen: the commands that run opencode with the current profile.
keysworkstation shell keysOpens the keys screen: the general-use API keys the shell exports.
infra.zsh~/projects/workstation/zsh.d/infra.zshRuns the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts; it holds a git credential to rotate.
utils.zsh~/projects/workstation/zsh.d/utils.zshRuns terminal helpers (set-title, killport), IP aliases, lazy nvm, node, npm and npx, Android, Java and Bun setup.
update-gitlab-tokenupdate-gitlab-token (zsh.d/utils.zsh)Updates the GitLab token in git URLs; it holds a credential, see the known issue.
review-openreview-open (zsh.d/review-open.zsh, ~/.local/bin/review-open)Opens a file for review, from the shell or from an agent.
dash-path-warn.zsh~/projects/workstation/zsh.d/dash-path-warn.zshWarns about the dash path; its purpose is in the file header.
shell › git
Git guards, the hooks that run in every repo, and the git identity.
git-safety~/projects/workstation/zsh.d/git-safety.zshWraps git checkout: lists the files and asks [y/N] before discarding unstaged changes.
git hooks~/.git-hooks/ (from git-hooks/)Runs the approval, branch and commit gates in every repo; needs lefthook on PATH.
gitconfig~/.gitconfig (from ~/projects/workstation/.gitconfig)Sets the author identity, Git LFS, the credential store and the hooks path.
shell › opencode
The opencode commands and their profiles.
opencode / ocopencode (zsh.d/opencode-profiles.zsh)Runs opencode and oc with the current profile.
opencode-profileopencode-profileNames the current profile.
opencode-profilesopencode-profilesShows what each profile loads.
opencode-switchopencode-switch <name>Switches every shell's new runs to the named profile.
opencode-loginopencode-loginSigns a profile's Claude Code in.
opencode-filesopencode-filesLists the current profile's files.
opencode-editopencode-edit <file>Opens one of the current profile's files.
opencode helpopencode help (also oc help, opencode-help, oc-help)Prints every profile's files, one column each, and the commands; with more than 3 profiles it writes help.md and opens it.
profile files~/projects/workstation/opencode-profiles/Opens the folder of profile files, including private-leb-experimental.
shell › keys
The general-use API keys the shell exports, and how to edit them.
api-keys~/projects/workstation/zsh.d/api-keys.zshExports the general-use API keys from ~/.config/api-keys/env into new shells.
api-keys-editapi-keys-editOpens ~/.config/api-keys/env in the editor; the keys stay out of Git.
agents
The agent system: rules, assistants, skills, the sandbox, the dashboard and the data repo.
rulesworkstation agents rulesOpens the rules screen: the rules every agent follows and the hooks that enforce them.
assistantsworkstation agents assistantsOpens the assistants screen: Claude and Codex setup, the usage guard, session tools and Claude plugins.
skillsworkstation agents skillsOpens the skills screen: skills kept here and the global skills linked from my-skills.
sandboxworkstation agents sandboxOpens the sandbox screen: the Agent Sandbox page and the agent record commands.
dashboardworkstation agents dashboardOpens the dashboard screen: the two dashboard versions and their guides.
data~/projects/data/Opens the data repo, a separate private repo: cases, rule proposals, verdicts and team reviews.
hermes~/.local/bin/hermesRuns Hermes, the agent behind the two Telegram bots and the job schedules.
hermes restore~/projects/workstation/hermes/RESTORE.mdOpens the Hermes restore runbook.
team-park~/.local/bin/team-parkRuns the team park tool; its README says what it parks.
agents › rules
The rules every agent follows and the hooks that run them inside Claude Code.
rules~/.local/bin/rulesPrints the rules; rules [folder] prints the ones for that folder.
rules source~/projects/workstation/workboard/rules.yamlOpens the source of the rules; changed only by the user or an accepted proposal.
rules metadata~/projects/workstation/workboard/rules-meta.yamlOpens the metadata for each rule.
generated rules~/.claude/references/rules.mdOpens the generated copy sessions read; it is made from rules.yaml.
rules reminder~/projects/workstation/docs/plans/2026-10-24-rules-per-role/reminder/Opens the rules-per-role reminder timer and its service.
core-rules.sh~/projects/workstation/claude/hooks/core-rules.shRuns at session start and before Bash commands with the core rules.
local-server-guard.py~/projects/workstation/claude/hooks/local-server-guard.pyRuns before Bash commands to guard local servers.
proof-reminder.sh~/projects/workstation/claude/hooks/proof-reminder.shRuns after edits and Bash commands to remind the agent to record proof.
machine-history.sh~/projects/workstation/claude/hooks/machine-history.shRuns as a Claude Code hook; its purpose is in the file header.
team-activity.sh~/projects/workstation/claude/hooks/team-activity.shRuns as a Claude Code hook; its purpose is in the file header.
agents › assistants
The Claude and Codex setup: their global notes, the usage guard, session tools and Claude plugins.
claude~/bin/claudeRuns Claude Code through the usage guard wrapper, ahead of the native claude.
usage guard install~/projects/workstation/claude/usage-guard/install.shInstalls the usage guard wrapper and the native Claude Code.
usage guard guide~/projects/workstation/claude/usage-guard/README.mdOpens the usage guard guide: its request budget and stale-usage notes.
main session continueclaude --main -cContinues the main Claude session.
main session resumeclaude --main -rResumes the main Claude session.
session types guide~/projects/workstation/claude/session-types/README.mdOpens the session types guide: the SessionStart hook and main sessions.
review pane~/projects/workstation/claude/mods/review-pane/README.mdOpens the review pane guide: a Claude Code pane for reviewing changes.
changelog pane~/projects/workstation/claude/mods/changelog-pane/README.mdOpens the changelog pane guide.
team board~/projects/workstation/claude/mods/team-board/Opens the team board plugin's folder.
scratchpad playground~/projects/workstation/claude/mods/scratchpad-playground/Opens the scratchpad playground plugin's folder.
Linux Claude rules~/projects/workstation/claude/linux-global/CLAUDE.mdOpens the global Claude rules copy for this laptop; the installed file is machine-local.
Linux agent notes~/projects/workstation/claude/linux-global/AGENTS.mdOpens the shorter global agent notes copy for this laptop.
Linux Claude settings~/.claude/settings.jsonOpens the Claude Code settings on this laptop; machine-local, not in Git.
communication draft~/projects/workstation/claude/communication-framework.mdOpens a draft of communication design; it is not enforced anywhere yet.
agents › skills
The skills kept on this workstation and the global skills they link from.
keptworkstation agents skills keptOpens the kept skills: backups you can copy in.
globalworkstation agents skills globalOpens the global skills that live only in my-skills.
my-skills~/projects/my-skills/Opens the global skills source; install links it into the assistants' skill folders.
install skills~/projects/my-skills/install.shLinks the global skills and agents into the assistant folders.
agents › skills › kept
Skills kept here as backups; copy the ones you want installed.
contextual-value-product-thinking~/projects/workstation/claude/skills/contextual-value-product-thinking/Analyzes products and startup ideas through contextual human values.
elad12390--web-research-assistant~/projects/workstation/claude/skills/elad12390--web-research-assistant/Runs web research: search, crawling, stealth scraping, and package and GitHub lookups; setup is in SETUP-NOTES.md.
epic-fanout-planning~/projects/workstation/claude/skills/epic-fanout-planning/Plans QA-gap epics with parallel-agent fan-out and merge and release gates.
impeccable~/projects/workstation/claude/skills/impeccable/Runs frontend design work: shape, critique, audit and polish; its engine downloads on first run.
api-key-creation~/projects/workstation/claude/skills/api-key-creation/Gets a missing API key with browser tools instead of escalating.
iterative-action-review~/projects/workstation/claude/skills/iterative-action-review/Reviews a finished real-world action as one step in a series.
post-feature-cleanup~/projects/workstation/claude/skills/post-feature-cleanup/Runs the cleanup pass after code: UI defects, leftovers, verification and repo hygiene.
powershell-launching~/projects/workstation/claude/skills/powershell-launching/Launches PowerShell or a new terminal window on Windows.
reboot-resume~/projects/workstation/claude/skills/reboot-resume/Preserves and resumes work across a reboot or a Claude Code restart.
resume-project~/projects/workstation/claude/skills/resume-project/Resumes a project and writes its mentor report with resume_project.py.
mentor-mode~/projects/workstation/claude/skills/mentor-mode/Runs a teaching mode that prepares and serves a mentor page.
lab-experiment~/projects/workstation/claude/skills/lab-experiment/Runs an experiment in the ai-lab project.
clone-website~/projects/workstation/claude/skills/clone-website/Reverse-engineers and clones a website with parallel builder agents.
supabase~/projects/workstation/claude/skills/supabase/Supabase's own skill: Auth, RLS, client libraries, migrations, CLI and debugging.
supabase-postgres-best-practices~/projects/workstation/claude/skills/supabase-postgres-best-practices/Supabase's Postgres performance rules.
tech-cv-writer~/projects/workstation/claude/skills/tech-cv-writer/Writes CVs with ATS-friendly architecture, bullet formulas and role templates.
tech-ledger~/projects/workstation/claude/skills/tech-ledger/Reads and writes the betec Tech Ledger of evaluated tech.
tank--communication-engineering~/projects/workstation/claude/skills/tank--communication-engineering/Applies engineering discipline to what an agent says and how much.
tank--skill-creator~/projects/workstation/claude/skills/tank--skill-creator/Creates new skills.
tank--bulletproof~/projects/workstation/claude/linux-global/skills/tank--bulletproof/Opens the bulletproof skill copy installed on this laptop.
volatility-based-skill-design~/projects/workstation/claude/linux-global/skills/volatility-based-skill-design/Opens the skill-design skill copy installed on this laptop; it requires a usage tier.
solaraai skills~/projects/workstation/claude/skills/solaraai-*/Opens the four SolaraAI skills: content calendar, deployment, design system and forms.
agents › skills › global
Global skills that live only in my-skills, not kept here.
coding-guidelines~/projects/my-skills/coding-guidelines/Opens the house coding rules: lean code, reuse before writing, no normalization sprawl.
volatility-based-decomposition~/projects/my-skills/volatility-based-decomposition/Opens the skill for decomposing systems around independently changing decisions.
working-with-windows~/projects/my-skills/working-with-windows/Opens the Windows gotchas for Node MCP servers that call PowerShell.
spawn-team/spawn-team <team> (Claude); $spawn-team <team> (Codex)Starts a team from its team file.
coordinated-agentic-session~/projects/my-skills/coordinated-agentic-session/Opens the rules for how team members hand off and message each other.
agents › sandbox
The Agent Sandbox page and the commands that check and list agent records.
agent serve~/projects/workstation/agent-framework/agent serveStarts the Agent Sandbox page at http://127.0.0.1:8790.
agent check~/projects/workstation/agent-framework/agent checkRefuses broken agent records and exits 1.
agent list~/projects/workstation/agent-framework/agent listLists agents with their tier, model and number of tests.
sandbox guide~/projects/workstation/agent-framework/README.mdOpens the sandbox guide: how the page works and what its words mean.
sandbox PRD~/projects/workstation/docs/plans/2026-10-22-agent-sandbox/prd.htmlOpens the sandbox's product requirements and mockups.
agents › dashboard
The two dashboard versions on this machine, and their guides.
dashboardpython3 ~/projects/workstation/dashboard/server.pyStarts the dashboard on http://127.0.0.1:8780 with its Waiting and Overview tabs.
dashboard-conceptspython3 ~/projects/workstation/dashboard-concepts/server.pyStarts the concepts version on http://127.0.0.1:8781, to compare against the dashboard.
dashboard guide~/projects/workstation/dashboard/README.mdOpens the dashboard guide: what each tab shows and what it writes.
concepts guide~/projects/workstation/dashboard-concepts/README.mdOpens the concepts version guide.
browser
The browser commands: the persistent Chrome window, Chrome itself, and the smoke-test tool.
browserbrowser '<json-array-of-steps>'Runs browser steps in one Chrome window that stays open between calls.
browser statusbrowser statusPrints whether the background browser server is up.
browser closebrowser closeCloses Chrome and stops the browser server.
recordStart / recordStopsteps inside browser '<json>'Starts or stops a tab recording, the proof that a feature works.
browser guide~/projects/workstation/browser/README.mdOpens the browser guide: actions, presets, network capture and login notes.
chromegoogle-chrome (~/.local/bin, runs chrome/chrome.sh)Starts Chrome with the recording flag; the only way to start Chrome here.
chrome flags~/projects/workstation/chrome/flagsOpens the flags Chrome starts with; edit only this list.
chrome install~/projects/workstation/chrome/install.shLinks the Chrome launcher and menu entry to chrome.sh; run once per machine.
chrome guide~/projects/workstation/chrome/README.mdOpens the Chrome guide: why it starts this way, and its limits.
codex chrome bridge~/projects/workstation/codex/chrome-bridge/install.shInstalls the watcher and timer that keep Codex's Chrome plugin working.
codex browser notes~/projects/workstation/codex/browser/README.mdOpens the notes on Codex's direct Chrome commands and their live checks.
jev-browser-testjev-browser-testRuns a goal in a browser and reports only the text and URL you assert.
jev install~/projects/workstation/jev-browser-test/install.shInstalls jev-browser-test and its pinned upstream checkout.
jev guide~/projects/workstation/jev-browser-test/README.mdOpens the smoke-test guide: exit codes, the privacy boundary and the Jev loop.
windows
The Windows PC's setup, scripts and sync, run on Windows.
init-windows~/projects/workstation/init-windows/Start-Install.cmdRebuilds the Windows dev environment from the manifests; double-click on Windows.
smoke test~/projects/workstation/init-windows/Smoke-Test-Windows.ps1Checks the Windows environment after an install.
rollback~/projects/workstation/init-windows/Remove-WindowsPack.ps1Rolls back the Windows install.
export~/projects/workstation/init-windows/Export-Windows.ps1Captures the current Windows setup into the manifests.
init-windows guide~/projects/workstation/init-windows/README.mdOpens the Windows bootstrap guide.
sign-ins checklist~/projects/workstation/init-windows/secrets-checklist.mdOpens the sign-ins to redo by hand.
inventory~/projects/workstation/init-windows/inventory.mdOpens the list of what the install captured.
user scripts~/projects/workstation/init-windows/user-scripts/Opens the Windows user scripts that are deployed to the Scripts folder.
Sync-Skills.ps1~/projects/workstation/skills-sync-windows/Sync-Skills.ps1Syncs my-skills into the Windows skill folders; the runner runs it, not you.
skills sync guide~/projects/workstation/skills-sync-windows/README.mdOpens the sync guide: the runner, its account and what it may touch.
clone work repos~/projects/workstation/repos/Clone-BetecRepos.ps1Clones the missing work repos into the workspace layout; safe to re-run.
Windows Claude rules~/projects/workstation/claude/CLAUDE.mdOpens the global Claude rules deployed to Windows.
Windows agent notes~/projects/workstation/claude/AGENTS.mdOpens the shorter global agent notes deployed to Windows.
Windows Claude settings~/projects/workstation/claude/settings.jsonOpens the Claude Code settings deployed to Windows.
Codex config~/projects/workstation/codex/config.tomlOpens the Codex CLI config deployed to Windows.
desktop snapshot~/projects/workstation/claude/backups/desktop-v2-2026/Opens the Windows desktop instruction snapshot; it is not loaded automatically.
Windows Deskflow settings~/projects/workstation/deskflow/windows.conf, windows-service.confOpens the Windows Deskflow client and service settings.
documents
Written work: the README, CVs, plans, research, case studies and reference records.
workstation README~/projects/workstation/README.mdOpens the workstation README: what lives where and the conventions.
cvworkstation documents cvOpens the CV screen: the three CV versions, their sources and dated copies.
case-studiesworkstation documents case-studiesOpens the case studies screen: archived experiments, each with its own README.
reference~/projects/workstation/reference/README.mdOpens the reference index: dated records of machine failures and their verified fixes.
lid incident~/projects/workstation/reference/incidents/2026-10-01-codebot-lid-closed.mdOpens the lid-closed incident record and its passing closed-lid test.
plans~/projects/workstation/docs/plans/Opens the plans folder: one dated folder per piece of work.
design~/projects/workstation/docs/design/Opens the design pitches and recommendations by date; references are in docs/design-references/.
flows~/projects/workstation/docs/flows/Opens the flow cards and data models by date.
research~/projects/workstation/docs/research/Opens the research notes by date.
functional research~/projects/workstation/docs/functional-research/2026-10-21/Opens the research on other agent frameworks, 2026-10-21.
changelog~/projects/workstation/docs/changelog/Opens the dated changelog entries.
items~/projects/workstation/docs/items/Opens the planned, urgent and work item lists.
playbook~/projects/workstation/docs/playbooks/talk-while-team-builds.mdOpens the playbook for talking while a team builds.
role files~/projects/workstation/docs/roles/Opens the role files for the QA agent and the 2026-10-23 drafts.
module intents~/projects/workstation/.idd/modules/Opens each module's intent: what it must do and its rules.
behavior specs~/projects/workstation/.bdd/features/Opens each module's behavior specs written in Gherkin.
documents › cv
The three CV versions, their sources and dated copies.
Full Stack Developer CV~/projects/workstation/cv/cv-full-stack.pdfOpens the Full Stack Developer CV as a PDF.
AI Full Stack Engineer CV~/projects/workstation/cv/cv-ai-full-stack.pdfOpens the AI Full Stack Engineer CV as a PDF.
AI Integrations CV~/projects/workstation/cv/cv-ai-integrations.pdfOpens the AI Integrations CV as a PDF.
cv guide~/projects/workstation/cv/README.mdOpens the CV guide: the LaTeX sources and how to rebuild the PDFs.
cv workflow~/projects/workstation/cv/WORKFLOW.mdOpens the CV workflow notes.
dated versions~/projects/workstation/cv/versions/Opens the dated CV versions from 2026-10-04 and 2026-10-04-v2.
documents › case-studies
Archived, human-reviewed experiments, each with its own README.
codebot return~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/README.mdOpens the codebot return case: the same design request with and without the skill.
signal garden~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/README.mdOpens the signal garden case: an exhibit that separates explanation from the live interface.
kernel results/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.mdOpens the Kernel cloud-browser results, which live outside this repo.
Questions
  • Keep 'windows' as its own top group, or fold it into 'machine'? Recommendation: keep it; these items are on another machine with their own scripts, and each row says it runs on Windows.
  • Facade names: 'workstation' with 'ws' is clear. The README also lists 'setup', which is generic and may clash. Recommendation: drop 'setup' unless 'whence -a setup' shows it is free.
  • Confirm retired items stay off the map: lan-mouse (retired 2026-10-05, Deskflow replaces it) and codex/playwright-mcp (retired, no browser server). Recommendation: keep them off.
  • Several paths the README names are not in the git file list: workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, and browser server.mjs, steps.mjs and recorder.mjs. Recommendation: confirm they exist before the CLI links to them, because a missing path breaks the 'every path opens' check.
  • The credential in zsh.d/infra.zsh and update-gitlab-token (utils.zsh) is a known issue. Recommendation: rotate it and move it to a credential manager before the help is wired; the map names it without the value.
  • These purposes were written from file names only: machine-history.sh, team-activity.sh, dash-path-warn.zsh, team-park, supabase-keepalive, remote-terminal, data-pull and the team-board and scratchpad-playground plugins. Recommendation: confirm them, or point me to their file headers, before the wording is final.
As phone screens

Home

Everything on this workstation, grouped by what you are trying to do.

machineOpens the machine screen: repairs, power, sharing with Windows, and background services for this Linux laptop.
›
shellOpens the shell screen: git guards, opencode profiles, API keys and terminal helpers.
›
agentsOpens the agents screen: rules, assistants, skills, the sandbox, the dashboard and the data repo.
›
browserOpens the browser screen: the persistent Chrome command, Chrome itself and the smoke-test tool.
›
windowsOpens the windows screen: the Windows PC's setup, scripts and skills sync (these run on Windows).
›
documentsOpens the documents screen: the README, CVs, plans, research, case studies and reference records.
›
‹ Home

machine

Repairs, power and sharing for this Linux laptop, and the services that run in the background.

repairOpens the repair screen: fixes for network, screen, keyboard, mouse and disk.
›
powerOpens the power screen: CPU power profiles and what closing the lid does.
›
shareOpens the share screen: Deskflow, audio, the shared clipboard and the Windows USB mouse notes.
›
servicesOpens the services screen: the background services that run on this laptop.
›
‹ machine

repair

Repair helpers for the laptop's network, screen, keyboard, mouse and disk.

fix-keyboardRuns the keyboard repair helper.
›
fix-mouseRuns the mouse repair helper.
›
fix-diskRuns the disk repair helper.
›
fix-whatsappRuns the WhatsApp repair helper.
›
linux-internet-recovery.shRuns the network recovery: systemd-resolved DNS, NetworkManager restart and DNS flush; re-runs itself with sudo.
›
recover-tailscale-remote-terminal.shRepairs DNS, restarts tailscaled, then starts the remote-terminal service and checks port 3500.
›
fix_old_monitor_hdmi.shSets the external screen's mode and refresh rate with xrandr (default 1920x1080 at 59.88).
›
‹ machine

power

Scripts that set the CPU power profile and what closing the lid does.

cpu-min-power.shSets the power-saver profile, turns turbo off and caps the CPU at 8%; asks for sudo; Intel only.
›
cpu-normal-power.shSets the balanced profile, turns turbo on and lifts the cap to 100%.
›
keep-running-with-lid-closed.shWrites a logind setting so closing the lid does nothing; applies after a reboot.
›
restore-default-lid-behavior.shRemoves that logind setting; applies after a reboot.
›
‹ machine

share

Tools that share this laptop's trackpad, keyboard, audio and clipboard with the Windows PC.

deskflow serviceRuns the Deskflow server that shares this trackpad and keyboard with Windows.
›
deskflow guideOpens the Deskflow guide: everyday use, recovery and the input-access prompt.
›
resume-kvmStarts Deskflow again and asks GNOME for input access.
›
audio-startSends all Linux audio to the Windows PC over Tailscale.
›
audio-pauseRestores the laptop speakers as the audio output.
›
audio-shareTurns audio sharing on or off, prints its status, or plays a test tone.
›
clipstackOpens the shared clipboard folder: its server, watcher, picker and install script.
›
usb-mouse notesOpens the notes on the Windows USB mouse, off since 2026-10-20, and how to turn it back on.
›
‹ machine

services

Background services that run on this laptop.

supabase-keepaliveRuns on a timer to keep the Supabase connection from going idle.
›
remote-terminalRuns the remote terminal on port 3500, the service the Tailscale recovery script starts.
›
data-pullPulls answers from the data repo every 5 minutes.
›
‹ Home

shell

Commands you type in the terminal: git guards, opencode profiles, API keys and helpers.

gitOpens the git screen: the checkout guard, the hooks and the git identity.
›
opencodeOpens the opencode screen: the commands that run opencode with the current profile.
›
keysOpens the keys screen: the general-use API keys the shell exports.
›
infra.zshRuns the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts; it holds a git credential to rotate.
›
utils.zshRuns terminal helpers (set-title, killport), IP aliases, lazy nvm, node, npm and npx, Android, Java and Bun setup.
›
update-gitlab-tokenUpdates the GitLab token in git URLs; it holds a credential, see the known issue.
›
review-openOpens a file for review, from the shell or from an agent.
›
dash-path-warn.zshWarns about the dash path; its purpose is in the file header.
›
‹ shell

git

Git guards, the hooks that run in every repo, and the git identity.

git-safetyWraps git checkout: lists the files and asks [y/N] before discarding unstaged changes.
›
git hooksRuns the approval, branch and commit gates in every repo; needs lefthook on PATH.
›
gitconfigSets the author identity, Git LFS, the credential store and the hooks path.
›
‹ shell

opencode

The opencode commands and their profiles.

opencode / ocRuns opencode and oc with the current profile.
›
opencode-profileNames the current profile.
›
opencode-profilesShows what each profile loads.
›
opencode-switchSwitches every shell's new runs to the named profile.
›
opencode-loginSigns a profile's Claude Code in.
›
opencode-filesLists the current profile's files.
›
opencode-editOpens one of the current profile's files.
›
opencode helpPrints every profile's files, one column each, and the commands; with more than 3 profiles it writes help.md and opens it.
›
profile filesOpens the folder of profile files, including private-leb-experimental.
›
‹ shell

keys

The general-use API keys the shell exports, and how to edit them.

api-keysExports the general-use API keys from ~/.config/api-keys/env into new shells.
›
api-keys-editOpens ~/.config/api-keys/env in the editor; the keys stay out of Git.
›
‹ Home

agents

The agent system: rules, assistants, skills, the sandbox, the dashboard and the data repo.

rulesOpens the rules screen: the rules every agent follows and the hooks that enforce them.
›
assistantsOpens the assistants screen: Claude and Codex setup, the usage guard, session tools and Claude plugins.
›
skillsOpens the skills screen: skills kept here and the global skills linked from my-skills.
›
sandboxOpens the sandbox screen: the Agent Sandbox page and the agent record commands.
›
dashboardOpens the dashboard screen: the two dashboard versions and their guides.
›
dataOpens the data repo, a separate private repo: cases, rule proposals, verdicts and team reviews.
›
hermesRuns Hermes, the agent behind the two Telegram bots and the job schedules.
›
hermes restoreOpens the Hermes restore runbook.
›
team-parkRuns the team park tool; its README says what it parks.
›
‹ agents

rules

The rules every agent follows and the hooks that run them inside Claude Code.

rulesPrints the rules; rules [folder] prints the ones for that folder.
›
rules sourceOpens the source of the rules; changed only by the user or an accepted proposal.
›
rules metadataOpens the metadata for each rule.
›
generated rulesOpens the generated copy sessions read; it is made from rules.yaml.
›
rules reminderOpens the rules-per-role reminder timer and its service.
›
core-rules.shRuns at session start and before Bash commands with the core rules.
›
local-server-guard.pyRuns before Bash commands to guard local servers.
›
proof-reminder.shRuns after edits and Bash commands to remind the agent to record proof.
›
machine-history.shRuns as a Claude Code hook; its purpose is in the file header.
›
team-activity.shRuns as a Claude Code hook; its purpose is in the file header.
›
‹ agents

assistants

The Claude and Codex setup: their global notes, the usage guard, session tools and Claude plugins.

claudeRuns Claude Code through the usage guard wrapper, ahead of the native claude.
›
usage guard installInstalls the usage guard wrapper and the native Claude Code.
›
usage guard guideOpens the usage guard guide: its request budget and stale-usage notes.
›
main session continueContinues the main Claude session.
›
main session resumeResumes the main Claude session.
›
session types guideOpens the session types guide: the SessionStart hook and main sessions.
›
review paneOpens the review pane guide: a Claude Code pane for reviewing changes.
›
changelog paneOpens the changelog pane guide.
›
team boardOpens the team board plugin's folder.
›
scratchpad playgroundOpens the scratchpad playground plugin's folder.
›
Linux Claude rulesOpens the global Claude rules copy for this laptop; the installed file is machine-local.
›
Linux agent notesOpens the shorter global agent notes copy for this laptop.
›
Linux Claude settingsOpens the Claude Code settings on this laptop; machine-local, not in Git.
›
communication draftOpens a draft of communication design; it is not enforced anywhere yet.
›
‹ agents

skills

The skills kept on this workstation and the global skills they link from.

keptOpens the kept skills: backups you can copy in.
›
globalOpens the global skills that live only in my-skills.
›
my-skillsOpens the global skills source; install links it into the assistants' skill folders.
›
install skillsLinks the global skills and agents into the assistant folders.
›
‹ skills

kept

Skills kept here as backups; copy the ones you want installed.

contextual-value-product-thinkingAnalyzes products and startup ideas through contextual human values.
›
elad12390--web-research-assistantRuns web research: search, crawling, stealth scraping, and package and GitHub lookups; setup is in SETUP-NOTES.md.
›
epic-fanout-planningPlans QA-gap epics with parallel-agent fan-out and merge and release gates.
›
impeccableRuns frontend design work: shape, critique, audit and polish; its engine downloads on first run.
›
api-key-creationGets a missing API key with browser tools instead of escalating.
›
iterative-action-reviewReviews a finished real-world action as one step in a series.
›
post-feature-cleanupRuns the cleanup pass after code: UI defects, leftovers, verification and repo hygiene.
›
powershell-launchingLaunches PowerShell or a new terminal window on Windows.
›
reboot-resumePreserves and resumes work across a reboot or a Claude Code restart.
›
resume-projectResumes a project and writes its mentor report with resume_project.py.
›
mentor-modeRuns a teaching mode that prepares and serves a mentor page.
›
lab-experimentRuns an experiment in the ai-lab project.
›
clone-websiteReverse-engineers and clones a website with parallel builder agents.
›
supabaseSupabase's own skill: Auth, RLS, client libraries, migrations, CLI and debugging.
›
supabase-postgres-best-practicesSupabase's Postgres performance rules.
›
tech-cv-writerWrites CVs with ATS-friendly architecture, bullet formulas and role templates.
›
tech-ledgerReads and writes the betec Tech Ledger of evaluated tech.
›
tank--communication-engineeringApplies engineering discipline to what an agent says and how much.
›
tank--skill-creatorCreates new skills.
›
tank--bulletproofOpens the bulletproof skill copy installed on this laptop.
›
volatility-based-skill-designOpens the skill-design skill copy installed on this laptop; it requires a usage tier.
›
solaraai skillsOpens the four SolaraAI skills: content calendar, deployment, design system and forms.
›
‹ skills

global

Global skills that live only in my-skills, not kept here.

coding-guidelinesOpens the house coding rules: lean code, reuse before writing, no normalization sprawl.
›
volatility-based-decompositionOpens the skill for decomposing systems around independently changing decisions.
›
working-with-windowsOpens the Windows gotchas for Node MCP servers that call PowerShell.
›
spawn-teamStarts a team from its team file.
›
coordinated-agentic-sessionOpens the rules for how team members hand off and message each other.
›
‹ agents

sandbox

The Agent Sandbox page and the commands that check and list agent records.

agent serveStarts the Agent Sandbox page at http://127.0.0.1:8790.
›
agent checkRefuses broken agent records and exits 1.
›
agent listLists agents with their tier, model and number of tests.
›
sandbox guideOpens the sandbox guide: how the page works and what its words mean.
›
sandbox PRDOpens the sandbox's product requirements and mockups.
›
‹ agents

dashboard

The two dashboard versions on this machine, and their guides.

dashboardStarts the dashboard on http://127.0.0.1:8780 with its Waiting and Overview tabs.
›
dashboard-conceptsStarts the concepts version on http://127.0.0.1:8781, to compare against the dashboard.
›
dashboard guideOpens the dashboard guide: what each tab shows and what it writes.
›
concepts guideOpens the concepts version guide.
›
‹ Home

browser

The browser commands: the persistent Chrome window, Chrome itself, and the smoke-test tool.

browserRuns browser steps in one Chrome window that stays open between calls.
›
browser statusPrints whether the background browser server is up.
›
browser closeCloses Chrome and stops the browser server.
›
recordStart / recordStopStarts or stops a tab recording, the proof that a feature works.
›
browser guideOpens the browser guide: actions, presets, network capture and login notes.
›
chromeStarts Chrome with the recording flag; the only way to start Chrome here.
›
chrome flagsOpens the flags Chrome starts with; edit only this list.
›
chrome installLinks the Chrome launcher and menu entry to chrome.sh; run once per machine.
›
chrome guideOpens the Chrome guide: why it starts this way, and its limits.
›
codex chrome bridgeInstalls the watcher and timer that keep Codex's Chrome plugin working.
›
codex browser notesOpens the notes on Codex's direct Chrome commands and their live checks.
›
jev-browser-testRuns a goal in a browser and reports only the text and URL you assert.
›
jev installInstalls jev-browser-test and its pinned upstream checkout.
›
jev guideOpens the smoke-test guide: exit codes, the privacy boundary and the Jev loop.
›
‹ Home

windows

The Windows PC's setup, scripts and sync, run on Windows.

init-windowsRebuilds the Windows dev environment from the manifests; double-click on Windows.
›
smoke testChecks the Windows environment after an install.
›
rollbackRolls back the Windows install.
›
exportCaptures the current Windows setup into the manifests.
›
init-windows guideOpens the Windows bootstrap guide.
›
sign-ins checklistOpens the sign-ins to redo by hand.
›
inventoryOpens the list of what the install captured.
›
user scriptsOpens the Windows user scripts that are deployed to the Scripts folder.
›
Sync-Skills.ps1Syncs my-skills into the Windows skill folders; the runner runs it, not you.
›
skills sync guideOpens the sync guide: the runner, its account and what it may touch.
›
clone work reposClones the missing work repos into the workspace layout; safe to re-run.
›
Windows Claude rulesOpens the global Claude rules deployed to Windows.
›
Windows agent notesOpens the shorter global agent notes deployed to Windows.
›
Windows Claude settingsOpens the Claude Code settings deployed to Windows.
›
Codex configOpens the Codex CLI config deployed to Windows.
›
desktop snapshotOpens the Windows desktop instruction snapshot; it is not loaded automatically.
›
Windows Deskflow settingsOpens the Windows Deskflow client and service settings.
›
‹ Home

documents

Written work: the README, CVs, plans, research, case studies and reference records.

workstation READMEOpens the workstation README: what lives where and the conventions.
›
cvOpens the CV screen: the three CV versions, their sources and dated copies.
›
case-studiesOpens the case studies screen: archived experiments, each with its own README.
›
referenceOpens the reference index: dated records of machine failures and their verified fixes.
›
lid incidentOpens the lid-closed incident record and its passing closed-lid test.
›
plansOpens the plans folder: one dated folder per piece of work.
›
designOpens the design pitches and recommendations by date; references are in docs/design-references/.
›
flowsOpens the flow cards and data models by date.
›
researchOpens the research notes by date.
›
functional researchOpens the research on other agent frameworks, 2026-10-21.
›
changelogOpens the dated changelog entries.
›
itemsOpens the planned, urgent and work item lists.
›
playbookOpens the playbook for talking while a team builds.
›
role filesOpens the role files for the QA agent and the 2026-10-23 drafts.
›
module intentsOpens each module's intent: what it must do and its rules.
›
behavior specsOpens each module's behavior specs written in Gherkin.
›
‹ documents

cv

The three CV versions, their sources and dated copies.

Full Stack Developer CVOpens the Full Stack Developer CV as a PDF.
›
AI Full Stack Engineer CVOpens the AI Full Stack Engineer CV as a PDF.
›
AI Integrations CVOpens the AI Integrations CV as a PDF.
›
cv guideOpens the CV guide: the LaTeX sources and how to rebuild the PDFs.
›
cv workflowOpens the CV workflow notes.
›
dated versionsOpens the dated CV versions from 2026-10-04 and 2026-10-04-v2.
›
‹ documents

case-studies

Archived, human-reviewed experiments, each with its own README.

codebot returnOpens the codebot return case: the same design request with and without the skill.
›
signal gardenOpens the signal garden case: an exhibit that separates explanation from the live interface.
›
kernel resultsOpens the Kernel cloud-browser results, which live outside this repo.
›
Raw answer
**Scenario (reasoning from the project's own docs, not observed use):** Liel, at the Linux laptop mid-task, reaches for a repair when the network, screen, or keyboard misbehaves; a power or sharing setting; a shell command for git or opencode; a browser check; an agent's rules, skills, or dashboard; or a document such as a CV, plan, or case study. The Windows items run on the Windows PC, so the Linux help shows them as text.

**Judgment calls**

- **Top screen:** six groups, named from the README's own words (`machine`, `shell`, `agents`, `browser`, `windows`, `documents`). Each deeper group is its own screen.
- **Left off the map:** retired items, which the README says are no longer used (`lan-mouse`, `codex/playwright-mcp`); tests; research run outputs; screenshots, fonts and images; skill reference files; `init-windows` configs, libraries and manifests; and `docs/superpowers` and the `.old` role drafts.
- **Secrets:** the credential in `infra.zsh` and `update-gitlab-token` is named but its value is never printed.
- **Hooks** sit under `rules`, since they enforce the rules inside Claude Code.
- **Skill copies:** a skill appears once. Backups in `claude/skills` are listed there, and the `my-skills`-only ones are listed under `global`.
- **Purposes:** where the dump gave no description, I wrote the purpose from the file name and flagged it in the questions.

```json
{"screens": [
{"path": [], "sentence": "Everything on this workstation, grouped by what you are trying to do.", "rows": [
{"name": "machine", "form": "workstation machine", "what": "Opens the machine screen: repairs, power, sharing with Windows, and background services for this Linux laptop."},
{"name": "shell", "form": "workstation shell", "what": "Opens the shell screen: git guards, opencode profiles, API keys and terminal helpers."},
{"name": "agents", "form": "workstation agents", "what": "Opens the agents screen: rules, assistants, skills, the sandbox, the dashboard and the data repo."},
{"name": "browser", "form": "workstation browser", "what": "Opens the browser screen: the persistent Chrome command, Chrome itself and the smoke-test tool."},
{"name": "windows", "form": "workstation windows", "what": "Opens the windows screen: the Windows PC's setup, scripts and skills sync (these run on Windows)."},
{"name": "documents", "form": "workstation documents", "what": "Opens the documents screen: the README, CVs, plans, research, case studies and reference records."}
]},
{"path": ["machine"], "sentence": "Repairs, power and sharing for this Linux laptop, and the services that run in the background.", "rows": [
{"name": "repair", "form": "workstation machine repair", "what": "Opens the repair screen: fixes for network, screen, keyboard, mouse and disk."},
{"name": "power", "form": "workstation machine power", "what": "Opens the power screen: CPU power profiles and what closing the lid does."},
{"name": "share", "form": "workstation machine share", "what": "Opens the share screen: Deskflow, audio, the shared clipboard and the Windows USB mouse notes."},
{"name": "services", "form": "workstation machine services", "what": "Opens the services screen: the background services that run on this laptop."}
]},
{"path": ["machine", "repair"], "sentence": "Repair helpers for the laptop's network, screen, keyboard, mouse and disk.", "rows": [
{"name": "fix-keyboard", "form": "fix-keyboard (zsh.d/utils.zsh)", "what": "Runs the keyboard repair helper."},
{"name": "fix-mouse", "form": "fix-mouse (zsh.d/utils.zsh)", "what": "Runs the mouse repair helper."},
{"name": "fix-disk", "form": "fix-disk (zsh.d/utils.zsh)", "what": "Runs the disk repair helper."},
{"name": "fix-whatsapp", "form": "fix-whatsapp (zsh.d/utils.zsh)", "what": "Runs the WhatsApp repair helper."},
{"name": "linux-internet-recovery.sh", "form": "~/projects/workstation/linux-internet-recovery.sh", "what": "Runs the network recovery: systemd-resolved DNS, NetworkManager restart and DNS flush; re-runs itself with sudo."},
{"name": "recover-tailscale-remote-terminal.sh", "form": "~/projects/workstation/recover-tailscale-remote-terminal.sh", "what": "Repairs DNS, restarts tailscaled, then starts the remote-terminal service and checks port 3500."},
{"name": "fix_old_monitor_hdmi.sh", "form": "~/projects/workstation/fix_old_monitor_hdmi.sh", "what": "Sets the external screen's mode and refresh rate with xrandr (default 1920x1080 at 59.88)."}
]},
{"path": ["machine", "power"], "sentence": "Scripts that set the CPU power profile and what closing the lid does.", "rows": [
{"name": "cpu-min-power.sh", "form": "~/projects/workstation/cpu-min-power.sh", "what": "Sets the power-saver profile, turns turbo off and caps the CPU at 8%; asks for sudo; Intel only."},
{"name": "cpu-normal-power.sh", "form": "~/projects/workstation/cpu-normal-power.sh", "what": "Sets the balanced profile, turns turbo on and lifts the cap to 100%."},
{"name": "keep-running-with-lid-closed.sh", "form": "~/projects/workstation/laptop-utilities/keep-running-with-lid-closed.sh", "what": "Writes a logind setting so closing the lid does nothing; applies after a reboot."},
{"name": "restore-default-lid-behavior.sh", "form": "~/projects/workstation/laptop-utilities/restore-default-lid-behavior.sh", "what": "Removes that logind setting; applies after a reboot."}
]},
{"path": ["machine", "share"], "sentence": "Tools that share this laptop's trackpad, keyboard, audio and clipboard with the Windows PC.", "rows": [
{"name": "deskflow service", "form": "~/.config/systemd/user/deskflow.service", "what": "Runs the Deskflow server that shares this trackpad and keyboard with Windows."},
{"name": "deskflow guide", "form": "~/projects/workstation/deskflow/README.md", "what": "Opens the Deskflow guide: everyday use, recovery and the input-access prompt."},
{"name": "resume-kvm", "form": "resume-kvm", "what": "Starts Deskflow again and asks GNOME for input access."},
{"name": "audio-start", "form": "audio-start (zsh.d/audio-share.zsh)", "what": "Sends all Linux audio to the Windows PC over Tailscale."},
{"name": "audio-pause", "form": "audio-pause", "what": "Restores the laptop speakers as the audio output."},
{"name": "audio-share", "form": "audio-share on|off|status|tone", "what": "Turns audio sharing on or off, prints its status, or plays a test tone."},
{"name": "clipstack", "form": "~/projects/workstation/clipstack/", "what": "Opens the shared clipboard folder: its server, watcher, picker and install script."},
{"name": "usb-mouse notes", "form": "~/projects/workstation/deskflow/usb-mouse/README.md", "what": "Opens the notes on the Windows USB mouse, off since 2026-10-20, and how to turn it back on."}
]},
{"path": ["machine", "services"], "sentence": "Background services that run on this laptop.", "rows": [
{"name": "supabase-keepalive", "form": "~/projects/workstation/supabase-keepalive/", "what": "Runs on a timer to keep the Supabase connection from going idle."},
{"name": "remote-terminal", "form": "remote-terminal user service (port 3500)", "what": "Runs the remote terminal on port 3500, the service the Tailscale recovery script starts."},
{"name": "data-pull", "form": "~/.config/systemd/user/data-pull.*", "what": "Pulls answers from the data repo every 5 minutes."}
]},
{"path": ["shell"], "sentence": "Commands you type in the terminal: git guards, opencode profiles, API keys and helpers.", "rows": [
{"name": "git", "form": "workstation shell git", "what": "Opens the git screen: the checkout guard, the hooks and the git identity."},
{"name": "opencode", "form": "workstation shell opencode", "what": "Opens the opencode screen: the commands that run opencode with the current profile."},
{"name": "keys", "form": "workstation shell keys", "what": "Opens the keys screen: the general-use API keys the shell exports."},
{"name": "infra.zsh", "form": "~/projects/workstation/zsh.d/infra.zsh", "what": "Runs the Docker, Compose, Prisma, Postgres, nginx and VPN shortcuts; it holds a git credential to rotate."},
{"name": "utils.zsh", "form": "~/projects/workstation/zsh.d/utils.zsh", "what": "Runs terminal helpers (set-title, killport), IP aliases, lazy nvm, node, npm and npx, Android, Java and Bun setup."},
{"name": "update-gitlab-token", "form": "update-gitlab-token (zsh.d/utils.zsh)", "what": "Updates the GitLab token in git URLs; it holds a credential, see the known issue."},
{"name": "review-open", "form": "review-open (zsh.d/review-open.zsh, ~/.local/bin/review-open)", "what": "Opens a file for review, from the shell or from an agent."},
{"name": "dash-path-warn.zsh", "form": "~/projects/workstation/zsh.d/dash-path-warn.zsh", "what": "Warns about the dash path; its purpose is in the file header."}
]},
{"path": ["shell", "git"], "sentence": "Git guards, the hooks that run in every repo, and the git identity.", "rows": [
{"name": "git-safety", "form": "~/projects/workstation/zsh.d/git-safety.zsh", "what": "Wraps git checkout: lists the files and asks [y/N] before discarding unstaged changes."},
{"name": "git hooks", "form": "~/.git-hooks/ (from git-hooks/)", "what": "Runs the approval, branch and commit gates in every repo; needs lefthook on PATH."},
{"name": "gitconfig", "form": "~/.gitconfig (from ~/projects/workstation/.gitconfig)", "what": "Sets the author identity, Git LFS, the credential store and the hooks path."}
]},
{"path": ["shell", "opencode"], "sentence": "The opencode commands and their profiles.", "rows": [
{"name": "opencode / oc", "form": "opencode (zsh.d/opencode-profiles.zsh)", "what": "Runs opencode and oc with the current profile."},
{"name": "opencode-profile", "form": "opencode-profile", "what": "Names the current profile."},
{"name": "opencode-profiles", "form": "opencode-profiles", "what": "Shows what each profile loads."},
{"name": "opencode-switch", "form": "opencode-switch <name>", "what": "Switches every shell's new runs to the named profile."},
{"name": "opencode-login", "form": "opencode-login", "what": "Signs a profile's Claude Code in."},
{"name": "opencode-files", "form": "opencode-files", "what": "Lists the current profile's files."},
{"name": "opencode-edit", "form": "opencode-edit <file>", "what": "Opens one of the current profile's files."},
{"name": "opencode help", "form": "opencode help (also oc help, opencode-help, oc-help)", "what": "Prints every profile's files, one column each, and the commands; with more than 3 profiles it writes help.md and opens it."},
{"name": "profile files", "form": "~/projects/workstation/opencode-profiles/", "what": "Opens the folder of profile files, including private-leb-experimental."}
]},
{"path": ["shell", "keys"], "sentence": "The general-use API keys the shell exports, and how to edit them.", "rows": [
{"name": "api-keys", "form": "~/projects/workstation/zsh.d/api-keys.zsh", "what": "Exports the general-use API keys from ~/.config/api-keys/env into new shells."},
{"name": "api-keys-edit", "form": "api-keys-edit", "what": "Opens ~/.config/api-keys/env in the editor; the keys stay out of Git."}
]},
{"path": ["agents"], "sentence": "The agent system: rules, assistants, skills, the sandbox, the dashboard and the data repo.", "rows": [
{"name": "rules", "form": "workstation agents rules", "what": "Opens the rules screen: the rules every agent follows and the hooks that enforce them."},
{"name": "assistants", "form": "workstation agents assistants", "what": "Opens the assistants screen: Claude and Codex setup, the usage guard, session tools and Claude plugins."},
{"name": "skills", "form": "workstation agents skills", "what": "Opens the skills screen: skills kept here and the global skills linked from my-skills."},
{"name": "sandbox", "form": "workstation agents sandbox", "what": "Opens the sandbox screen: the Agent Sandbox page and the agent record commands."},
{"name": "dashboard", "form": "workstation agents dashboard", "what": "Opens the dashboard screen: the two dashboard versions and their guides."},
{"name": "data", "form": "~/projects/data/", "what": "Opens the data repo, a separate private repo: cases, rule proposals, verdicts and team reviews."},
{"name": "hermes", "form": "~/.local/bin/hermes", "what": "Runs Hermes, the agent behind the two Telegram bots and the job schedules."},
{"name": "hermes restore", "form": "~/projects/workstation/hermes/RESTORE.md", "what": "Opens the Hermes restore runbook."},
{"name": "team-park", "form": "~/.local/bin/team-park", "what": "Runs the team park tool; its README says what it parks."}
]},
{"path": ["agents", "rules"], "sentence": "The rules every agent follows and the hooks that run them inside Claude Code.", "rows": [
{"name": "rules", "form": "~/.local/bin/rules", "what": "Prints the rules; rules [folder] prints the ones for that folder."},
{"name": "rules source", "form": "~/projects/workstation/workboard/rules.yaml", "what": "Opens the source of the rules; changed only by the user or an accepted proposal."},
{"name": "rules metadata", "form": "~/projects/workstation/workboard/rules-meta.yaml", "what": "Opens the metadata for each rule."},
{"name": "generated rules", "form": "~/.claude/references/rules.md", "what": "Opens the generated copy sessions read; it is made from rules.yaml."},
{"name": "rules reminder", "form": "~/projects/workstation/docs/plans/2026-10-24-rules-per-role/reminder/", "what": "Opens the rules-per-role reminder timer and its service."},
{"name": "core-rules.sh", "form": "~/projects/workstation/claude/hooks/core-rules.sh", "what": "Runs at session start and before Bash commands with the core rules."},
{"name": "local-server-guard.py", "form": "~/projects/workstation/claude/hooks/local-server-guard.py", "what": "Runs before Bash commands to guard local servers."},
{"name": "proof-reminder.sh", "form": "~/projects/workstation/claude/hooks/proof-reminder.sh", "what": "Runs after edits and Bash commands to remind the agent to record proof."},
{"name": "machine-history.sh", "form": "~/projects/workstation/claude/hooks/machine-history.sh", "what": "Runs as a Claude Code hook; its purpose is in the file header."},
{"name": "team-activity.sh", "form": "~/projects/workstation/claude/hooks/team-activity.sh", "what": "Runs as a Claude Code hook; its purpose is in the file header."}
]},
{"path": ["agents", "assistants"], "sentence": "The Claude and Codex setup: their global notes, the usage guard, session tools and Claude plugins.", "rows": [
{"name": "claude", "form": "~/bin/claude", "what": "Runs Claude Code through the usage guard wrapper, ahead of the native claude."},
{"name": "usage guard install", "form": "~/projects/workstation/claude/usage-guard/install.sh", "what": "Installs the usage guard wrapper and the native Claude Code."},
{"name": "usage guard guide", "form": "~/projects/workstation/claude/usage-guard/README.md", "what": "Opens the usage guard guide: its request budget and stale-usage notes."},
{"name": "main session continue", "form": "claude --main -c", "what": "Continues the main Claude session."},
{"name": "main session resume", "form": "claude --main -r", "what": "Resumes the main Claude session."},
{"name": "session types guide", "form": "~/projects/workstation/claude/session-types/README.md", "what": "Opens the session types guide: the SessionStart hook and main sessions."},
{"name": "review pane", "form": "~/projects/workstation/claude/mods/review-pane/README.md", "what": "Opens the review pane guide: a Claude Code pane for reviewing changes."},
{"name": "changelog pane", "form": "~/projects/workstation/claude/mods/changelog-pane/README.md", "what": "Opens the changelog pane guide."},
{"name": "team board", "form": "~/projects/workstation/claude/mods/team-board/", "what": "Opens the team board plugin's folder."},
{"name": "scratchpad playground", "form": "~/projects/workstation/claude/mods/scratchpad-playground/", "what": "Opens the scratchpad playground plugin's folder."},
{"name": "Linux Claude rules", "form": "~/projects/workstation/claude/linux-global/CLAUDE.md", "what": "Opens the global Claude rules copy for this laptop; the installed file is machine-local."},
{"name": "Linux agent notes", "form": "~/projects/workstation/claude/linux-global/AGENTS.md", "what": "Opens the shorter global agent notes copy for this laptop."},
{"name": "Linux Claude settings", "form": "~/.claude/settings.json", "what": "Opens the Claude Code settings on this laptop; machine-local, not in Git."},
{"name": "communication draft", "form": "~/projects/workstation/claude/communication-framework.md", "what": "Opens a draft of communication design; it is not enforced anywhere yet."}
]},
{"path": ["agents", "skills"], "sentence": "The skills kept on this workstation and the global skills they link from.", "rows": [
{"name": "kept", "form": "workstation agents skills kept", "what": "Opens the kept skills: backups you can copy in."},
{"name": "global", "form": "workstation agents skills global", "what": "Opens the global skills that live only in my-skills."},
{"name": "my-skills", "form": "~/projects/my-skills/", "what": "Opens the global skills source; install links it into the assistants' skill folders."},
{"name": "install skills", "form": "~/projects/my-skills/install.sh", "what": "Links the global skills and agents into the assistant folders."}
]},
{"path": ["agents", "skills", "kept"], "sentence": "Skills kept here as backups; copy the ones you want installed.", "rows": [
{"name": "contextual-value-product-thinking", "form": "~/projects/workstation/claude/skills/contextual-value-product-thinking/", "what": "Analyzes products and startup ideas through contextual human values."},
{"name": "elad12390--web-research-assistant", "form": "~/projects/workstation/claude/skills/elad12390--web-research-assistant/", "what": "Runs web research: search, crawling, stealth scraping, and package and GitHub lookups; setup is in SETUP-NOTES.md."},
{"name": "epic-fanout-planning", "form": "~/projects/workstation/claude/skills/epic-fanout-planning/", "what": "Plans QA-gap epics with parallel-agent fan-out and merge and release gates."},
{"name": "impeccable", "form": "~/projects/workstation/claude/skills/impeccable/", "what": "Runs frontend design work: shape, critique, audit and polish; its engine downloads on first run."},
{"name": "api-key-creation", "form": "~/projects/workstation/claude/skills/api-key-creation/", "what": "Gets a missing API key with browser tools instead of escalating."},
{"name": "iterative-action-review", "form": "~/projects/workstation/claude/skills/iterative-action-review/", "what": "Reviews a finished real-world action as one step in a series."},
{"name": "post-feature-cleanup", "form": "~/projects/workstation/claude/skills/post-feature-cleanup/", "what": "Runs the cleanup pass after code: UI defects, leftovers, verification and repo hygiene."},
{"name": "powershell-launching", "form": "~/projects/workstation/claude/skills/powershell-launching/", "what": "Launches PowerShell or a new terminal window on Windows."},
{"name": "reboot-resume", "form": "~/projects/workstation/claude/skills/reboot-resume/", "what": "Preserves and resumes work across a reboot or a Claude Code restart."},
{"name": "resume-project", "form": "~/projects/workstation/claude/skills/resume-project/", "what": "Resumes a project and writes its mentor report with resume_project.py."},
{"name": "mentor-mode", "form": "~/projects/workstation/claude/skills/mentor-mode/", "what": "Runs a teaching mode that prepares and serves a mentor page."},
{"name": "lab-experiment", "form": "~/projects/workstation/claude/skills/lab-experiment/", "what": "Runs an experiment in the ai-lab project."},
{"name": "clone-website", "form": "~/projects/workstation/claude/skills/clone-website/", "what": "Reverse-engineers and clones a website with parallel builder agents."},
{"name": "supabase", "form": "~/projects/workstation/claude/skills/supabase/", "what": "Supabase's own skill: Auth, RLS, client libraries, migrations, CLI and debugging."},
{"name": "supabase-postgres-best-practices", "form": "~/projects/workstation/claude/skills/supabase-postgres-best-practices/", "what": "Supabase's Postgres performance rules."},
{"name": "tech-cv-writer", "form": "~/projects/workstation/claude/skills/tech-cv-writer/", "what": "Writes CVs with ATS-friendly architecture, bullet formulas and role templates."},
{"name": "tech-ledger", "form": "~/projects/workstation/claude/skills/tech-ledger/", "what": "Reads and writes the betec Tech Ledger of evaluated tech."},
{"name": "tank--communication-engineering", "form": "~/projects/workstation/claude/skills/tank--communication-engineering/", "what": "Applies engineering discipline to what an agent says and how much."},
{"name": "tank--skill-creator", "form": "~/projects/workstation/claude/skills/tank--skill-creator/", "what": "Creates new skills."},
{"name": "tank--bulletproof", "form": "~/projects/workstation/claude/linux-global/skills/tank--bulletproof/", "what": "Opens the bulletproof skill copy installed on this laptop."},
{"name": "volatility-based-skill-design", "form": "~/projects/workstation/claude/linux-global/skills/volatility-based-skill-design/", "what": "Opens the skill-design skill copy installed on this laptop; it requires a usage tier."},
{"name": "solaraai skills", "form": "~/projects/workstation/claude/skills/solaraai-*/", "what": "Opens the four SolaraAI skills: content calendar, deployment, design system and forms."}
]},
{"path": ["agents", "skills", "global"], "sentence": "Global skills that live only in my-skills, not kept here.", "rows": [
{"name": "coding-guidelines", "form": "~/projects/my-skills/coding-guidelines/", "what": "Opens the house coding rules: lean code, reuse before writing, no normalization sprawl."},
{"name": "volatility-based-decomposition", "form": "~/projects/my-skills/volatility-based-decomposition/", "what": "Opens the skill for decomposing systems around independently changing decisions."},
{"name": "working-with-windows", "form": "~/projects/my-skills/working-with-windows/", "what": "Opens the Windows gotchas for Node MCP servers that call PowerShell."},
{"name": "spawn-team", "form": "/spawn-team <team> (Claude); $spawn-team <team> (Codex)", "what": "Starts a team from its team file."},
{"name": "coordinated-agentic-session", "form": "~/projects/my-skills/coordinated-agentic-session/", "what": "Opens the rules for how team members hand off and message each other."}
]},
{"path": ["agents", "sandbox"], "sentence": "The Agent Sandbox page and the commands that check and list agent records.", "rows": [
{"name": "agent serve", "form": "~/projects/workstation/agent-framework/agent serve", "what": "Starts the Agent Sandbox page at http://127.0.0.1:8790."},
{"name": "agent check", "form": "~/projects/workstation/agent-framework/agent check", "what": "Refuses broken agent records and exits 1."},
{"name": "agent list", "form": "~/projects/workstation/agent-framework/agent list", "what": "Lists agents with their tier, model and number of tests."},
{"name": "sandbox guide", "form": "~/projects/workstation/agent-framework/README.md", "what": "Opens the sandbox guide: how the page works and what its words mean."},
{"name": "sandbox PRD", "form": "~/projects/workstation/docs/plans/2026-10-22-agent-sandbox/prd.html", "what": "Opens the sandbox's product requirements and mockups."}
]},
{"path": ["agents", "dashboard"], "sentence": "The two dashboard versions on this machine, and their guides.", "rows": [
{"name": "dashboard", "form": "python3 ~/projects/workstation/dashboard/server.py", "what": "Starts the dashboard on http://127.0.0.1:8780 with its Waiting and Overview tabs."},
{"name": "dashboard-concepts", "form": "python3 ~/projects/workstation/dashboard-concepts/server.py", "what": "Starts the concepts version on http://127.0.0.1:8781, to compare against the dashboard."},
{"name": "dashboard guide", "form": "~/projects/workstation/dashboard/README.md", "what": "Opens the dashboard guide: what each tab shows and what it writes."},
{"name": "concepts guide", "form": "~/projects/workstation/dashboard-concepts/README.md", "what": "Opens the concepts version guide."}
]},
{"path": ["browser"], "sentence": "The browser commands: the persistent Chrome window, Chrome itself, and the smoke-test tool.", "rows": [
{"name": "browser", "form": "browser '<json-array-of-steps>'", "what": "Runs browser steps in one Chrome window that stays open between calls."},
{"name": "browser status", "form": "browser status", "what": "Prints whether the background browser server is up."},
{"name": "browser close", "form": "browser close", "what": "Closes Chrome and stops the browser server."},
{"name": "recordStart / recordStop", "form": "steps inside browser '<json>'", "what": "Starts or stops a tab recording, the proof that a feature works."},
{"name": "browser guide", "form": "~/projects/workstation/browser/README.md", "what": "Opens the browser guide: actions, presets, network capture and login notes."},
{"name": "chrome", "form": "google-chrome (~/.local/bin, runs chrome/chrome.sh)", "what": "Starts Chrome with the recording flag; the only way to start Chrome here."},
{"name": "chrome flags", "form": "~/projects/workstation/chrome/flags", "what": "Opens the flags Chrome starts with; edit only this list."},
{"name": "chrome install", "form": "~/projects/workstation/chrome/install.sh", "what": "Links the Chrome launcher and menu entry to chrome.sh; run once per machine."},
{"name": "chrome guide", "form": "~/projects/workstation/chrome/README.md", "what": "Opens the Chrome guide: why it starts this way, and its limits."},
{"name": "codex chrome bridge", "form": "~/projects/workstation/codex/chrome-bridge/install.sh", "what": "Installs the watcher and timer that keep Codex's Chrome plugin working."},
{"name": "codex browser notes", "form": "~/projects/workstation/codex/browser/README.md", "what": "Opens the notes on Codex's direct Chrome commands and their live checks."},
{"name": "jev-browser-test", "form": "jev-browser-test", "what": "Runs a goal in a browser and reports only the text and URL you assert."},
{"name": "jev install", "form": "~/projects/workstation/jev-browser-test/install.sh", "what": "Installs jev-browser-test and its pinned upstream checkout."},
{"name": "jev guide", "form": "~/projects/workstation/jev-browser-test/README.md", "what": "Opens the smoke-test guide: exit codes, the privacy boundary and the Jev loop."}
]},
{"path": ["windows"], "sentence": "The Windows PC's setup, scripts and sync, run on Windows.", "rows": [
{"name": "init-windows", "form": "~/projects/workstation/init-windows/Start-Install.cmd", "what": "Rebuilds the Windows dev environment from the manifests; double-click on Windows."},
{"name": "smoke test", "form": "~/projects/workstation/init-windows/Smoke-Test-Windows.ps1", "what": "Checks the Windows environment after an install."},
{"name": "rollback", "form": "~/projects/workstation/init-windows/Remove-WindowsPack.ps1", "what": "Rolls back the Windows install."},
{"name": "export", "form": "~/projects/workstation/init-windows/Export-Windows.ps1", "what": "Captures the current Windows setup into the manifests."},
{"name": "init-windows guide", "form": "~/projects/workstation/init-windows/README.md", "what": "Opens the Windows bootstrap guide."},
{"name": "sign-ins checklist", "form": "~/projects/workstation/init-windows/secrets-checklist.md", "what": "Opens the sign-ins to redo by hand."},
{"name": "inventory", "form": "~/projects/workstation/init-windows/inventory.md", "what": "Opens the list of what the install captured."},
{"name": "user scripts", "form": "~/projects/workstation/init-windows/user-scripts/", "what": "Opens the Windows user scripts that are deployed to the Scripts folder."},
{"name": "Sync-Skills.ps1", "form": "~/projects/workstation/skills-sync-windows/Sync-Skills.ps1", "what": "Syncs my-skills into the Windows skill folders; the runner runs it, not you."},
{"name": "skills sync guide", "form": "~/projects/workstation/skills-sync-windows/README.md", "what": "Opens the sync guide: the runner, its account and what it may touch."},
{"name": "clone work repos", "form": "~/projects/workstation/repos/Clone-BetecRepos.ps1", "what": "Clones the missing work repos into the workspace layout; safe to re-run."},
{"name": "Windows Claude rules", "form": "~/projects/workstation/claude/CLAUDE.md", "what": "Opens the global Claude rules deployed to Windows."},
{"name": "Windows agent notes", "form": "~/projects/workstation/claude/AGENTS.md", "what": "Opens the shorter global agent notes deployed to Windows."},
{"name": "Windows Claude settings", "form": "~/projects/workstation/claude/settings.json", "what": "Opens the Claude Code settings deployed to Windows."},
{"name": "Codex config", "form": "~/projects/workstation/codex/config.toml", "what": "Opens the Codex CLI config deployed to Windows."},
{"name": "desktop snapshot", "form": "~/projects/workstation/claude/backups/desktop-v2-2026/", "what": "Opens the Windows desktop instruction snapshot; it is not loaded automatically."},
{"name": "Windows Deskflow settings", "form": "~/projects/workstation/deskflow/windows.conf, windows-service.conf", "what": "Opens the Windows Deskflow client and service settings."}
]},
{"path": ["documents"], "sentence": "Written work: the README, CVs, plans, research, case studies and reference records.", "rows": [
{"name": "workstation README", "form": "~/projects/workstation/README.md", "what": "Opens the workstation README: what lives where and the conventions."},
{"name": "cv", "form": "workstation documents cv", "what": "Opens the CV screen: the three CV versions, their sources and dated copies."},
{"name": "case-studies", "form": "workstation documents case-studies", "what": "Opens the case studies screen: archived experiments, each with its own README."},
{"name": "reference", "form": "~/projects/workstation/reference/README.md", "what": "Opens the reference index: dated records of machine failures and their verified fixes."},
{"name": "lid incident", "form": "~/projects/workstation/reference/incidents/2026-10-01-codebot-lid-closed.md", "what": "Opens the lid-closed incident record and its passing closed-lid test."},
{"name": "plans", "form": "~/projects/workstation/docs/plans/", "what": "Opens the plans folder: one dated folder per piece of work."},
{"name": "design", "form": "~/projects/workstation/docs/design/", "what": "Opens the design pitches and recommendations by date; references are in docs/design-references/."},
{"name": "flows", "form": "~/projects/workstation/docs/flows/", "what": "Opens the flow cards and data models by date."},
{"name": "research", "form": "~/projects/workstation/docs/research/", "what": "Opens the research notes by date."},
{"name": "functional research", "form": "~/projects/workstation/docs/functional-research/2026-10-21/", "what": "Opens the research on other agent frameworks, 2026-10-21."},
{"name": "changelog", "form": "~/projects/workstation/docs/changelog/", "what": "Opens the dated changelog entries."},
{"name": "items", "form": "~/projects/workstation/docs/items/", "what": "Opens the planned, urgent and work item lists."},
{"name": "playbook", "form": "~/projects/workstation/docs/playbooks/talk-while-team-builds.md", "what": "Opens the playbook for talking while a team builds."},
{"name": "role files", "form": "~/projects/workstation/docs/roles/", "what": "Opens the role files for the QA agent and the 2026-10-23 drafts."},
{"name": "module intents", "form": "~/projects/workstation/.idd/modules/", "what": "Opens each module's intent: what it must do and its rules."},
{"name": "behavior specs", "form": "~/projects/workstation/.bdd/features/", "what": "Opens each module's behavior specs written in Gherkin."}
]},
{"path": ["documents", "cv"], "sentence": "The three CV versions, their sources and dated copies.", "rows": [
{"name": "Full Stack Developer CV", "form": "~/projects/workstation/cv/cv-full-stack.pdf", "what": "Opens the Full Stack Developer CV as a PDF."},
{"name": "AI Full Stack Engineer CV", "form": "~/projects/workstation/cv/cv-ai-full-stack.pdf", "what": "Opens the AI Full Stack Engineer CV as a PDF."},
{"name": "AI Integrations CV", "form": "~/projects/workstation/cv/cv-ai-integrations.pdf", "what": "Opens the AI Integrations CV as a PDF."},
{"name": "cv guide", "form": "~/projects/workstation/cv/README.md", "what": "Opens the CV guide: the LaTeX sources and how to rebuild the PDFs."},
{"name": "cv workflow", "form": "~/projects/workstation/cv/WORKFLOW.md", "what": "Opens the CV workflow notes."},
{"name": "dated versions", "form": "~/projects/workstation/cv/versions/", "what": "Opens the dated CV versions from 2026-10-04 and 2026-10-04-v2."}
]},
{"path": ["documents", "case-studies"], "sentence": "Archived, human-reviewed experiments, each with its own README.", "rows": [
{"name": "codebot return", "form": "~/projects/workstation/case-studies/conceptual-modeling/2026-09-15-codebot-return/README.md", "what": "Opens the codebot return case: the same design request with and without the skill."},
{"name": "signal garden", "form": "~/projects/workstation/case-studies/blume-astryx/2026-09-16-signal-garden/README.md", "what": "Opens the signal garden case: an exhibit that separates explanation from the live interface."},
{"name": "kernel results", "form": "/home/liel/projects/ai-lab/experiments/2026-10-08-kernel-use-cases/insights/RESULTS.md", "what": "Opens the Kernel cloud-browser results, which live outside this repo."}
]}
],
"questions": [
"Keep 'windows' as its own top group, or fold it into 'machine'? Recommendation: keep it; these items are on another machine with their own scripts, and each row says it runs on Windows.",
"Facade names: 'workstation' with 'ws' is clear. The README also lists 'setup', which is generic and may clash. Recommendation: drop 'setup' unless 'whence -a setup' shows it is free.",
"Confirm retired items stay off the map: lan-mouse (retired 2026-10-05, Deskflow replaces it) and codex/playwright-mcp (retired, no browser server). Recommendation: keep them off.",
"Several paths the README names are not in the git file list: workstation-cli/, zsh.d/workstation.zsh, zsh.d/audio-share.zsh, audio-share/, and browser server.mjs, steps.mjs and recorder.mjs. Recommendation: confirm they exist before the CLI links to them, because a missing path breaks the 'every path opens' check.",
"The credential in zsh.d/infra.zsh and update-gitlab-token (utils.zsh) is a known issue. Recommendation: rotate it and move it to a credential manager before the help is wired; the map names it without the value.",
"These purposes were written from file names only: machine-history.sh, team-activity.sh, dash-path-warn.zsh, team-park, supabase-keepalive, remote-terminal, data-pull and the team-board and scratchpad-playground plugins. Recommendation: confirm them, or point me to their file headers, before the wording is final."
],
"judgment_calls": "Groups use the README's words: machine (Machine utilities), shell (Shell and git), agents (Agent system), documents (working documents), share (shared mouse, audio, clipboard). Tests, research run outputs, screenshots, fonts, skill reference files, init-windows configs and manifests, superpowers plans and .old drafts stay off the map. Retired items are off per the owner's notes. Hooks sit under rules because they enforce the rules. A skill appears once: kept backups on 'kept', my-skills-only skills on 'global'."}
```

burrow, planted (CLI)

The approved map (ground truth)
{
 "vocabulary": [
  "rig",
  "stash",
  "chore",
  "porch",
  "pulse"
 ],
 "forbidden_words": [
  "server",
  "host"
 ],
 "things": [
  {
   "id": "rigs-list",
   "name": "List rigs and whether they answer",
   "form": "burrow rigs",
   "kind": "command",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "stash-one",
   "name": "Take a stash of one rig",
   "form": "burrow stash attic",
   "kind": "command",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "stash-all",
   "name": "Stash every rig",
   "form": "make stash-all",
   "kind": "command",
   "hidden": false,
   "where": "Makefile"
  },
  {
   "id": "stash-list",
   "name": "List a rig's stashes",
   "form": "@stash_cmd.command(\"list\")",
   "kind": "command",
   "hidden": false,
   "where": "burrow/cli.py"
  },
  {
   "id": "restore",
   "name": "Put a stash back on a rig",
   "form": "burrow restore attic --from 2026-10-20",
   "kind": "command",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "prune",
   "name": "Delete old stashes",
   "form": "make prune-stashes",
   "kind": "command",
   "hidden": false,
   "where": "Makefile"
  },
  {
   "id": "chores-list",
   "name": "List chores",
   "form": "burrow chores list",
   "kind": "command",
   "hidden": false,
   "where": "docs/chores.md"
  },
  {
   "id": "chores-run",
   "name": "Run a chore by hand",
   "form": "burrow chores run disk-check",
   "kind": "command",
   "hidden": false,
   "where": "docs/chores.md"
  },
  {
   "id": "chores-status",
   "name": "When each chore last ran",
   "form": "burrow chores status",
   "kind": "command",
   "hidden": false,
   "where": "docs/chores.md"
  },
  {
   "id": "porch-cmd",
   "name": "Run the porch dashboard",
   "form": "burrow porch --bind 0.0.0.0:8470",
   "kind": "command",
   "hidden": false,
   "where": "deploy/burrow-porch.service"
  },
  {
   "id": "install",
   "name": "Install burrow",
   "form": "make install",
   "kind": "command",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "install-unit",
   "name": "Install the porch systemd unit",
   "form": "make install-unit",
   "kind": "command",
   "hidden": false,
   "where": "Makefile"
  },
  {
   "id": "up",
   "name": "Start the metrics containers",
   "form": "make up",
   "kind": "command",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "test",
   "name": "Run the tests",
   "form": "make test",
   "kind": "command",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "main-config",
   "name": "Main settings file",
   "form": "config/burrow.toml",
   "kind": "file",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "rigs-config",
   "name": "List of rigs",
   "form": "config/rigs.toml",
   "kind": "file",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "env",
   "name": "Secrets and environment",
   "form": "/opt/burrow/.env",
   "kind": "file",
   "hidden": false,
   "where": "deploy/burrow-porch.service"
  },
  {
   "id": "stash-store",
   "name": "Where stashes are kept",
   "form": "/srv/burrow/stashes",
   "kind": "folder",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "scripts-folder",
   "name": "Shell helpers folder",
   "form": "scripts/",
   "kind": "folder",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "porch-url",
   "name": "The porch dashboard",
   "form": "http://127.0.0.1:8470",
   "kind": "url",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "porch-chores-url",
   "name": "Chores page on the porch",
   "form": "http://127.0.0.1:8470/chores",
   "kind": "url",
   "hidden": false,
   "where": "docs/chores.md"
  },
  {
   "id": "porch-health",
   "name": "Porch health check",
   "form": "http://127.0.0.1:8470/healthz",
   "kind": "url",
   "hidden": false,
   "where": "docs/setup.md"
  },
  {
   "id": "grafana-url",
   "name": "Grafana graphs",
   "form": "http://127.0.0.1:3000",
   "kind": "url",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "porch-service",
   "name": "Porch systemd service",
   "form": "burrow-porch.service",
   "kind": "service",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "crontab",
   "name": "Chores crontab",
   "form": "deploy/burrow.crontab",
   "kind": "file",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "chores-log",
   "name": "Chores log",
   "form": "/var/log/burrow/chores.log",
   "kind": "log",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "chores-state",
   "name": "Last run of each chore",
   "form": "/srv/burrow/state/last-run.json",
   "kind": "state",
   "hidden": false,
   "where": "docs/chores.md"
  },
  {
   "id": "adding-rig-doc",
   "name": "How to add a rig",
   "form": "docs/adding-a-rig.md",
   "kind": "doc",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "setup-doc",
   "name": "Setup guide",
   "form": "docs/setup.md",
   "kind": "doc",
   "hidden": false,
   "where": "docs/setup.md"
  },
  {
   "id": "chores-doc",
   "name": "Chores doc",
   "form": "docs/chores.md",
   "kind": "doc",
   "hidden": false,
   "where": "README.md"
  },
  {
   "id": "prune-cron",
   "name": "Weekly stash prune cron job",
   "form": "40 4 * * 0 cd /opt/burrow && make prune-stashes",
   "kind": "command",
   "hidden": true,
   "where": "Makefile"
  },
  {
   "id": "pulse-port",
   "name": "pulse metrics exporter port",
   "form": ":9188",
   "kind": "port",
   "hidden": true,
   "where": "docker-compose.yml"
  },
  {
   "id": "porch-log",
   "name": "Porch log",
   "form": "/var/log/burrow/porch.log",
   "kind": "log",
   "hidden": true,
   "where": "deploy/burrow-porch.service"
  },
  {
   "id": "restore-by-hand-doc",
   "name": "Restoring a stash by hand",
   "form": "docs/internals/stash/format/restore-by-hand.md",
   "kind": "doc",
   "hidden": true,
   "where": "docs/internals/stash/format/restore-by-hand.md"
  },
  {
   "id": "rig-wake",
   "name": "Wake a rig over the LAN",
   "form":
Show:
No skill
Today's skills
screen-decomposition, first draft
screen-decomposition, final

No skill · run 1 exit=0 seconds=75 · prompt

P1 Recall: 0.85P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.391P5 Short top: 12P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 1
As terminal help
The burrow command and the other things you reach for around it: rigs, stashes, restores, chores, the porch, config, docs, make targets, metrics, scripts and wake.
rigsburrow rigslist rigs and whether each one answers
stashburrow stash [RIG] [--all]take a snapshot of one rig or of every rig
restoreburrow restore RIG --from YYYY-MM-DD [--dry-run]copy a stash back onto its rig
choresburrow choresrecurring jobs: list, run one, see last runs
porchburrow porch [--bind ADDR:PORT]run the web dashboard
--config optionburrow --config PATH (default config/burrow.toml)use a different settings file
configconfig/the files you edit: burrow.toml, rigs.toml, .env
docsdocs/setup, adding a rig, chores, restoring by hand
makemake <target>install, services, tests, stash-all, prune, clean
metricshttp://127.0.0.1:3000Grafana graphs of temperature and disk use
scriptsscripts/<name>.shsmall shell helpers, run by hand
wakebin/rig-wake RIGwake a sleeping rig with a magic packet
rigs
Each rig from config/rigs.toml, with whether it answers a ping. The list is read from the file, so it changes when you add a rig.
attic192.168.1.20rig; keeps /etc, /home and docker volumes
cellar192.168.1.21rig; keeps /etc and /tank/photos
garden192.168.1.22rig; keeps /etc and /opt/homeassistant
stash
Take a stash of one rig, or of every rig with --all. Two sub-things sit under it: list and prune.
take one rigburrow stash RIGsnapshot one rig now
take all rigsburrow stash --all (or make stash-all)snapshot every rig now
listburrow stash list RIGshow the stashes kept for one rig
pruneburrow stash prune [--keep N] (or make prune-stashes)delete old stashes, keeping the newest N
stash › list
Print the stashes kept for one rig, one per line.
RIGburrow stash list RIGwhich rig to list
stash › prune
Delete old stashes so the stash folder does not fill the disk. Keeps the newest N per rig.
--keep Nburrow stash prune --keep 8how many stashes to keep, default 8
restore
Copy one stash of a rig back onto that rig.
RIGburrow restore RIGwhich rig to restore
--from DATE--from YYYY-MM-DD (required)which dated stash to use
--dry-run--dry-runshow what would happen without copying
chores
Recurring jobs. You can list them, run one by hand, or see when each last ran and whether it worked.
listburrow chores listnames of the registered chores
runburrow chores run NAMErun one chore now and record the result
statusburrow chores statuswhen each chore last finished and its result
crontabdeploy/burrow.crontabthe schedule: nightly-stash at 02:15, disk-check every 6 hours
chores pagehttp://127.0.0.1:8470/choresthe same last-run table on the porch
chores › list
The two chores burrow ships with.
nightly-stashburrow chores run nightly-stashstash every rig; runs at 02:15 from cron
disk-checkburrow chores run disk-checkwarn when a rig's root disk is over 85 percent; runs every 6 hours
chores › run
Run one chore now. The result is recorded in the last-run file.
NAMEburrow chores run NAMEnightly-stash or disk-check
chores › status
When each chore last finished and whether it worked.
last-run record/srv/burrow/state/last-run.jsonthe file the table is read from
porch
Run the porch, the web dashboard, on the given address. Under systemd it runs as burrow-porch.service.
--bind ADDR:PORT--bind 0.0.0.0:8470 (default from burrow.toml)address and port to listen on
dashboardhttp://127.0.0.1:8470/the porch home page
service unitdeploy/burrow-porch.service (make install-unit)runs the porch at boot
porch › dashboard
The porch home page, with the rigs. From here you can reach the chores page, a rig's stashes and the health check.
chores pagehttp://127.0.0.1:8470/choreslast runs of the chores
rig stasheshttp://127.0.0.1:8470/stashes/RIGstashes of one rig
health checkhttp://127.0.0.1:8470/healthzis the porch up
porch › chores
Last run of each chore: when it finished and what the result was.
back to dashboardhttp://127.0.0.1:8470/the porch home page
porch › stashes
The stashes kept for one rig, shown in the porch.
RIGhttp://127.0.0.1:8470/stashes/RIGwhich rig, for example attic
porch › healthz
Health check. Returns the JSON object with ok set to true when the porch is running.
make
Make targets, run from the repo root. They cover install, services, tests, stashing and cleanup.
installmake installcreate the venv, install burrow, make the folders
install-unitmake install-unitinstall and start the porch service
upmake upstart the metrics containers
downmake downstop the metrics containers
testmake testrun the test suite
lintmake lintrun ruff on burrow and tests
stash-allmake stash-allstash every rig now
prune-stashesmake prune-stasheskeep the newest 8 stashes
install-prune-cronmake install-prune-cronadd a weekly prune to your crontab
cleanmake cleanremove the venv and build leftovers
metrics
Graphs and numbers for rig temperature and disk use, from the containers in docker-compose.yml. The pulse readings are placeholders for now and always read 0.0.
Grafanahttp://127.0.0.1:3000graphs; anonymous access is on
pulse metricshttp://127.0.0.1:9188/metricsrig temperature and disk use for Prometheus
Prometheusno host port publishedstores 30 days of metrics; reached only inside the compose network
config
The files you edit by hand.
burrow.tomlconfig/burrow.tomlstash folder, keep count, chores state file, porch bind address, ssh user
rigs.tomlconfig/rigs.tomlone block per rig: name, address, MAC, paths
.env.env (copy of .env.example)SSH key path, porch secret, ntfy topic
docs
The guides in the docs folder.
setupdocs/setup.mdfirst-time setup and the check that it worked
adding a rigdocs/adding-a-rig.mdadd a rig to rigs.toml
choresdocs/chores.mdwhat the chores do and how to run them
restore by handdocs/internals/stash/format/restore-by-hand.mdput a stash back with rsync when burrow is broken
scripts
Shell helpers in scripts/. Read the top of each before you run it. Only three are described in the dump; the rest are guessed from their names.
check-disksscripts/check-disks.shdisk use on every rig
verify-stashscripts/verify-stash.sh RIGcheck the newest stash is readable and not empty
reboot-rigscripts/reboot-rig.sh ADDRESSreboot one rig after a 10 second countdown
battery-reportscripts/battery-report.shbattery report (guessed from name)
cert-renewscripts/cert-renew.shrenew certificates (guessed from name)
dns-flushscripts/dns-flush.shflush DNS cache (guessed from name)
du-stashesscripts/du-stashes.shstash folder sizes (guessed from name)
export-choresscripts/export-chores.shexport chores (guessed from name)
fan-curvescripts/fan-curve.shfan speed curve (guessed from name)
gc-dockerscripts/gc-docker.shclean up Docker leftovers (guessed from name)
import-rigsscripts/import-rigs.shimport rigs (guessed from name)
list-portsscripts/list-ports.shlist open ports (guessed from name)
mount-nasscripts/mount-nas.shmount the NAS (guessed from name)
unmount-nasscripts/unmount-nas.shunmount the NAS (guessed from name)
net-speedscripts/net-speed.shnetwork speed test (guessed from name)
pihole-updatescripts/pihole-update.shupdate Pi-hole (guessed from name)
rotate-logsscripts/rotate-logs.shrotate logs (guessed from name)
seed-devscripts/seed-dev.shfill a dev setup with sample data (guessed from name)
smart-reportscripts/smart-report.shdisk health report (guessed from name)
ssh-keys-pushscripts/ssh-keys-push.shpush SSH keys to rigs (guessed from name)
sync-clockscripts/sync-clock.shsync the clock (guessed from name)
temp-checkscripts/temp-check.shtemperature check (guessed from name)
update-rigsscripts/update-rigs.shupdate rig packages (guessed from name)
ups-statusscripts/ups-status.shUPS battery status (guessed from name)
zfs-scrubscripts/zfs-scrub.shstart a ZFS scrub (guessed from name)
wake
Wake a sleeping rig with a magic packet. The MAC address comes from rigs.toml.
RIGbin/rig-wake RIGrig to wake, for example cellar
Questions
  • Stash mixes one action (take RIG, --all) with two sub-things (list, prune). A rig named list or prune would clash, and I could not confirm how click binds the first word. Recommendation: split the take action into 'stash take RIG' and keep 'stash list' and 'stash prune'.
  • The prune default of 8 is hard-coded in the CLI, while burrow.toml also has keep = 8 that the CLI does not read. Recommendation: take the default from the config file.
  • Make targets, scripts, docs, config and metrics are outside burrow's own command. Recommendation: keep them in the map, but leave them out of 'burrow --help' and point to them from the README.
  • Only 3 of 25 scripts are described in the dump, so 22 descriptions are guesses from names. Recommendation: you add a one-line description for each, and I read the script headers in a later pass.
  • Some helpers and commands are disruptive: reboot-rig, unmount-nas, stash prune, and restore, which overwrites files on a rig. Recommendation: say so in each help text, and ask for confirmation on restore unless --dry-run is used.
  • The porch binds to 0.0.0.0 with no login in the dump, and BURROW_PORCH_SECRET is defined but not used. Recommendation: decide whether the porch should bind to 127.0.0.1 or check the secret before you expose it on the LAN.
  • The pulse readings always return 0.0, and prometheus.yml is not in the snapshot, so the metrics stack may not start as written. Recommendation: confirm the config file exists and decide when real readings replace the placeholders.
  • restore --from needs an exact date. Recommendation: also accept 'latest' so you need not look up the date first.
  • Rigs are arguments, not screens, so there is no per-rig help page. Recommendation: keep it that way; a per-rig screen would add paths the CLI does not have.
As phone screens

Home

The burrow command and the other things you reach for around it: rigs, stashes, restores, chores, the porch, config, docs, make targets, metrics, scripts and wake.

rigslist rigs and whether each one answers
›
stashtake a snapshot of one rig or of every rig
›
restorecopy a stash back onto its rig
›
choresrecurring jobs: list, run one, see last runs
›
porchrun the web dashboard
›
--config optionuse a different settings file
›
configthe files you edit: burrow.toml, rigs.toml, .env
›
docssetup, adding a rig, chores, restoring by hand
›
makeinstall, services, tests, stash-all, prune, clean
›
metricsGrafana graphs of temperature and disk use
›
scriptssmall shell helpers, run by hand
›
wakewake a sleeping rig with a magic packet
›
‹ Home

rigs

Each rig from config/rigs.toml, with whether it answers a ping. The list is read from the file, so it changes when you add a rig.

atticrig; keeps /etc, /home and docker volumes
›
cellarrig; keeps /etc and /tank/photos
›
gardenrig; keeps /etc and /opt/homeassistant
›
‹ Home

stash

Take a stash of one rig, or of every rig with --all. Two sub-things sit under it: list and prune.

take one rigsnapshot one rig now
›
take all rigssnapshot every rig now
›
listshow the stashes kept for one rig
›
prunedelete old stashes, keeping the newest N
›
‹ stash

list

Print the stashes kept for one rig, one per line.

RIGwhich rig to list
›
‹ stash

prune

Delete old stashes so the stash folder does not fill the disk. Keeps the newest N per rig.

--keep Nhow many stashes to keep, default 8
›
‹ Home

restore

Copy one stash of a rig back onto that rig.

RIGwhich rig to restore
›
--from DATEwhich dated stash to use
›
--dry-runshow what would happen without copying
›
‹ Home

chores

Recurring jobs. You can list them, run one by hand, or see when each last ran and whether it worked.

listnames of the registered chores
›
runrun one chore now and record the result
›
statuswhen each chore last finished and its result
›
crontabthe schedule: nightly-stash at 02:15, disk-check every 6 hours
›
chores pagethe same last-run table on the porch
›
‹ chores

list

The two chores burrow ships with.

nightly-stashstash every rig; runs at 02:15 from cron
›
disk-checkwarn when a rig's root disk is over 85 percent; runs every 6 hours
›
‹ chores

run

Run one chore now. The result is recorded in the last-run file.

NAMEnightly-stash or disk-check
›
‹ chores

status

When each chore last finished and whether it worked.

last-run recordthe file the table is read from
›
‹ Home

porch

Run the porch, the web dashboard, on the given address. Under systemd it runs as burrow-porch.service.

--bind ADDR:PORTaddress and port to listen on
›
dashboardthe porch home page
›
service unitruns the porch at boot
›
‹ porch

dashboard

The porch home page, with the rigs. From here you can reach the chores page, a rig's stashes and the health check.

chores pagelast runs of the chores
›
rig stashesstashes of one rig
›
health checkis the porch up
›
‹ porch

chores

Last run of each chore: when it finished and what the result was.

back to dashboardthe porch home page
›
‹ porch

stashes

The stashes kept for one rig, shown in the porch.

RIGwhich rig, for example attic
›
‹ porch

healthz

Health check. Returns the JSON object with ok set to true when the porch is running.

‹ Home

make

Make targets, run from the repo root. They cover install, services, tests, stashing and cleanup.

installcreate the venv, install burrow, make the folders
›
install-unitinstall and start the porch service
›
upstart the metrics containers
›
downstop the metrics containers
›
testrun the test suite
›
lintrun ruff on burrow and tests
›
stash-allstash every rig now
›
prune-stasheskeep the newest 8 stashes
›
install-prune-cronadd a weekly prune to your crontab
›
cleanremove the venv and build leftovers
›
‹ Home

metrics

Graphs and numbers for rig temperature and disk use, from the containers in docker-compose.yml. The pulse readings are placeholders for now and always read 0.0.

Grafanagraphs; anonymous access is on
›
pulse metricsrig temperature and disk use for Prometheus
›
Prometheusstores 30 days of metrics; reached only inside the compose network
›
‹ Home

config

The files you edit by hand.

burrow.tomlstash folder, keep count, chores state file, porch bind address, ssh user
›
rigs.tomlone block per rig: name, address, MAC, paths
›
.envSSH key path, porch secret, ntfy topic
›
‹ Home

docs

The guides in the docs folder.

setupfirst-time setup and the check that it worked
›
adding a rigadd a rig to rigs.toml
›
choreswhat the chores do and how to run them
›
restore by handput a stash back with rsync when burrow is broken
›
‹ Home

scripts

Shell helpers in scripts/. Read the top of each before you run it. Only three are described in the dump; the rest are guessed from their names.

check-disksdisk use on every rig
›
verify-stashcheck the newest stash is readable and not empty
›
reboot-rigreboot one rig after a 10 second countdown
›
battery-reportbattery report (guessed from name)
›
cert-renewrenew certificates (guessed from name)
›
dns-flushflush DNS cache (guessed from name)
›
du-stashesstash folder sizes (guessed from name)
›
export-choresexport chores (guessed from name)
›
fan-curvefan speed curve (guessed from name)
›
gc-dockerclean up Docker leftovers (guessed from name)
›
import-rigsimport rigs (guessed from name)
›
list-portslist open ports (guessed from name)
›
mount-nasmount the NAS (guessed from name)
›
unmount-nasunmount the NAS (guessed from name)
›
net-speednetwork speed test (guessed from name)
›
pihole-updateupdate Pi-hole (guessed from name)
›
rotate-logsrotate logs (guessed from name)
›
seed-devfill a dev setup with sample data (guessed from name)
›
smart-reportdisk health report (guessed from name)
›
ssh-keys-pushpush SSH keys to rigs (guessed from name)
›
sync-clocksync the clock (guessed from name)
›
temp-checktemperature check (guessed from name)
›
update-rigsupdate rig packages (guessed from name)
›
ups-statusUPS battery status (guessed from name)
›
zfs-scrubstart a ZFS scrub (guessed from name)
›
‹ Home

wake

Wake a sleeping rig with a magic packet. The MAC address comes from rigs.toml.

RIGrig to wake, for example cellar
›
Raw answer
This is a planning map only. I didn't build or run anything. The map covers the `burrow` command, the porch pages, the make targets, the metrics endpoints, the config and docs files, the helper scripts, and the wake helper. The template HTML isn't in the dump, so the porch page links are inferred from the routes in `app.py`. The 25 helper scripts are listed by name; only three are in the dump, so the other 22 descriptions are guesses from their names. The questions at the end are decisions for you, each with my recommendation.

```json
{"screens": [
 {"path": [], "sentence": "The burrow command and the other things you reach for around it: rigs, stashes, restores, chores, the porch, config, docs, make targets, metrics, scripts and wake.", "rows": [
  {"name": "rigs", "form": "burrow rigs", "what": "list rigs and whether each one answers"},
  {"name": "stash", "form": "burrow stash [RIG] [--all]", "what": "take a snapshot of one rig or of every rig"},
  {"name": "restore", "form": "burrow restore RIG --from YYYY-MM-DD [--dry-run]", "what": "copy a stash back onto its rig"},
  {"name": "chores", "form": "burrow chores", "what": "recurring jobs: list, run one, see last runs"},
  {"name": "porch", "form": "burrow porch [--bind ADDR:PORT]", "what": "run the web dashboard"},
  {"name": "--config option", "form": "burrow --config PATH (default config/burrow.toml)", "what": "use a different settings file"},
  {"name": "config", "form": "config/", "what": "the files you edit: burrow.toml, rigs.toml, .env"},
  {"name": "docs", "form": "docs/", "what": "setup, adding a rig, chores, restoring by hand"},
  {"name": "make", "form": "make <target>", "what": "install, services, tests, stash-all, prune, clean"},
  {"name": "metrics", "form": "http://127.0.0.1:3000", "what": "Grafana graphs of temperature and disk use"},
  {"name": "scripts", "form": "scripts/<name>.sh", "what": "small shell helpers, run by hand"},
  {"name": "wake", "form": "bin/rig-wake RIG", "what": "wake a sleeping rig with a magic packet"}
 ]},
 {"path": ["rigs"], "sentence": "Each rig from config/rigs.toml, with whether it answers a ping. The list is read from the file, so it changes when you add a rig.", "rows": [
  {"name": "attic", "form": "192.168.1.20", "what": "rig; keeps /etc, /home and docker volumes"},
  {"name": "cellar", "form": "192.168.1.21", "what": "rig; keeps /etc and /tank/photos"},
  {"name": "garden", "form": "192.168.1.22", "what": "rig; keeps /etc and /opt/homeassistant"}
 ]},
 {"path": ["stash"], "sentence": "Take a stash of one rig, or of every rig with --all. Two sub-things sit under it: list and prune.", "rows": [
  {"name": "take one rig", "form": "burrow stash RIG", "what": "snapshot one rig now"},
  {"name": "take all rigs", "form": "burrow stash --all (or make stash-all)", "what": "snapshot every rig now"},
  {"name": "list", "form": "burrow stash list RIG", "what": "show the stashes kept for one rig"},
  {"name": "prune", "form": "burrow stash prune [--keep N] (or make prune-stashes)", "what": "delete old stashes, keeping the newest N"}
 ]},
 {"path": ["stash", "list"], "sentence": "Print the stashes kept for one rig, one per line.", "rows": [
  {"name": "RIG", "form": "burrow stash list RIG", "what": "which rig to list"}
 ]},
 {"path": ["stash", "prune"], "sentence": "Delete old stashes so the stash folder does not fill the disk. Keeps the newest N per rig.", "rows": [
  {"name": "--keep N", "form": "burrow stash prune --keep 8", "what": "how many stashes to keep, default 8"}
 ]},
 {"path": ["restore"], "sentence": "Copy one stash of a rig back onto that rig.", "rows": [
  {"name": "RIG", "form": "burrow restore RIG", "what": "which rig to restore"},
  {"name": "--from DATE", "form": "--from YYYY-MM-DD (required)", "what": "which dated stash to use"},
  {"name": "--dry-run", "form": "--dry-run", "what": "show what would happen without copying"}
 ]},
 {"path": ["chores"], "sentence": "Recurring jobs. You can list them, run one by hand, or see when each last ran and whether it worked.", "rows": [
  {"name": "list", "form": "burrow chores list", "what": "names of the registered chores"},
  {"name": "run", "form": "burrow chores run NAME", "what": "run one chore now and record the result"},
  {"name": "status", "form": "burrow chores status", "what": "when each chore last finished and its result"},
  {"name": "crontab", "form": "deploy/burrow.crontab", "what": "the schedule: nightly-stash at 02:15, disk-check every 6 hours"},
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "the same last-run table on the porch"}
 ]},
 {"path": ["chores", "list"], "sentence": "The two chores burrow ships with.", "rows": [
  {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "stash every rig; runs at 02:15 from cron"},
  {"name": "disk-check", "form": "burrow chores run disk-check", "what": "warn when a rig's root disk is over 85 percent; runs every 6 hours"}
 ]},
 {"path": ["chores", "run"], "sentence": "Run one chore now. The result is recorded in the last-run file.", "rows": [
  {"name": "NAME", "form": "burrow chores run NAME", "what": "nightly-stash or disk-check"}
 ]},
 {"path": ["chores", "status"], "sentence": "When each chore last finished and whether it worked.", "rows": [
  {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "the file the table is read from"}
 ]},
 {"path": ["porch"], "sentence": "Run the porch, the web dashboard, on the given address. Under systemd it runs as burrow-porch.service.", "rows": [
  {"name": "--bind ADDR:PORT", "form": "--bind 0.0.0.0:8470 (default from burrow.toml)", "what": "address and port to listen on"},
  {"name": "dashboard", "form": "http://127.0.0.1:8470/", "what": "the porch home page"},
  {"name": "service unit", "form": "deploy/burrow-porch.service (make install-unit)", "what": "runs the porch at boot"}
 ]},
 {"path": ["porch", "dashboard"], "sentence": "The porch home page, with the rigs. From here you can reach the chores page, a rig's stashes and the health check.", "rows": [
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "last runs of the chores"},
  {"name": "rig stashes", "form": "http://127.0.0.1:8470/stashes/RIG", "what": "stashes of one rig"},
  {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "is the porch up"}
 ]},
 {"path": ["porch", "chores"], "sentence": "Last run of each chore: when it finished and what the result was.", "rows": [
  {"name": "back to dashboard", "form": "http://127.0.0.1:8470/", "what": "the porch home page"}
 ]},
 {"path": ["porch", "stashes"], "sentence": "The stashes kept for one rig, shown in the porch.", "rows": [
  {"name": "RIG", "form": "http://127.0.0.1:8470/stashes/RIG", "what": "which rig, for example attic"}
 ]},
 {"path": ["porch", "healthz"], "sentence": "Health check. Returns the JSON object with ok set to true when the porch is running.", "rows": []},
 {"path": ["make"], "sentence": "Make targets, run from the repo root. They cover install, services, tests, stashing and cleanup.", "rows": [
  {"name": "install", "form": "make install", "what": "create the venv, install burrow, make the folders"},
  {"name": "install-unit", "form": "make install-unit", "what": "install and start the porch service"},
  {"name": "up", "form": "make up", "what": "start the metrics containers"},
  {"name": "down", "form": "make down", "what": "stop the metrics containers"},
  {"name": "test", "form": "make test", "what": "run the test suite"},
  {"name": "lint", "form": "make lint", "what": "run ruff on burrow and tests"},
  {"name": "stash-all", "form": "make stash-all", "what": "stash every rig now"},
  {"name": "prune-stashes", "form": "make prune-stashes", "what": "keep the newest 8 stashes"},
  {"name": "install-prune-cron", "form": "make install-prune-cron", "what": "add a weekly prune to your crontab"},
  {"name": "clean", "form": "make clean", "what": "remove the venv and build leftovers"}
 ]},
 {"path": ["metrics"], "sentence": "Graphs and numbers for rig temperature and disk use, from the containers in docker-compose.yml. The pulse readings are placeholders for now and always read 0.0.", "rows": [
  {"name": "Grafana", "form": "http://127.0.0.1:3000", "what": "graphs; anonymous access is on"},
  {"name": "pulse metrics", "form": "http://127.0.0.1:9188/metrics", "what": "rig temperature and disk use for Prometheus"},
  {"name": "Prometheus", "form": "no host port published", "what": "stores 30 days of metrics; reached only inside the compose network"}
 ]},
 {"path": ["config"], "sentence": "The files you edit by hand.", "rows": [
  {"name": "burrow.toml", "form": "config/burrow.toml", "what": "stash folder, keep count, chores state file, porch bind address, ssh user"},
  {"name": "rigs.toml", "form": "config/rigs.toml", "what": "one block per rig: name, address, MAC, paths"},
  {"name": ".env", "form": ".env (copy of .env.example)", "what": "SSH key path, porch secret, ntfy topic"}
 ]},
 {"path": ["docs"], "sentence": "The guides in the docs folder.", "rows": [
  {"name": "setup", "form": "docs/setup.md", "what": "first-time setup and the check that it worked"},
  {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "add a rig to rigs.toml"},
  {"name": "chores", "form": "docs/chores.md", "what": "what the chores do and how to run them"},
  {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "put a stash back with rsync when burrow is broken"}
 ]},
 {"path": ["scripts"], "sentence": "Shell helpers in scripts/. Read the top of each before you run it. Only three are described in the dump; the rest are guessed from their names.", "rows": [
  {"name": "check-disks", "form": "scripts/check-disks.sh", "what": "disk use on every rig"},
  {"name": "verify-stash", "form": "scripts/verify-stash.sh RIG", "what": "check the newest stash is readable and not empty"},
  {"name": "reboot-rig", "form": "scripts/reboot-rig.sh ADDRESS", "what": "reboot one rig after a 10 second countdown"},
  {"name": "battery-report", "form": "scripts/battery-report.sh", "what": "battery report (guessed from name)"},
  {"name": "cert-renew", "form": "scripts/cert-renew.sh", "what": "renew certificates (guessed from name)"},
  {"name": "dns-flush", "form": "scripts/dns-flush.sh", "what": "flush DNS cache (guessed from name)"},
  {"name": "du-stashes", "form": "scripts/du-stashes.sh", "what": "stash folder sizes (guessed from name)"},
  {"name": "export-chores", "form": "scripts/export-chores.sh", "what": "export chores (guessed from name)"},
  {"name": "fan-curve", "form": "scripts/fan-curve.sh", "what": "fan speed curve (guessed from name)"},
  {"name": "gc-docker", "form": "scripts/gc-docker.sh", "what": "clean up Docker leftovers (guessed from name)"},
  {"name": "import-rigs", "form": "scripts/import-rigs.sh", "what": "import rigs (guessed from name)"},
  {"name": "list-ports", "form": "scripts/list-ports.sh", "what": "list open ports (guessed from name)"},
  {"name": "mount-nas", "form": "scripts/mount-nas.sh", "what": "mount the NAS (guessed from name)"},
  {"name": "unmount-nas", "form": "scripts/unmount-nas.sh", "what": "unmount the NAS (guessed from name)"},
  {"name": "net-speed", "form": "scripts/net-speed.sh", "what": "network speed test (guessed from name)"},
  {"name": "pihole-update", "form": "scripts/pihole-update.sh", "what": "update Pi-hole (guessed from name)"},
  {"name": "rotate-logs", "form": "scripts/rotate-logs.sh", "what": "rotate logs (guessed from name)"},
  {"name": "seed-dev", "form": "scripts/seed-dev.sh", "what": "fill a dev setup with sample data (guessed from name)"},
  {"name": "smart-report", "form": "scripts/smart-report.sh", "what": "disk health report (guessed from name)"},
  {"name": "ssh-keys-push", "form": "scripts/ssh-keys-push.sh", "what": "push SSH keys to rigs (guessed from name)"},
  {"name": "sync-clock", "form": "scripts/sync-clock.sh", "what": "sync the clock (guessed from name)"},
  {"name": "temp-check", "form": "scripts/temp-check.sh", "what": "temperature check (guessed from name)"},
  {"name": "update-rigs", "form": "scripts/update-rigs.sh", "what": "update rig packages (guessed from name)"},
  {"name": "ups-status", "form": "scripts/ups-status.sh", "what": "UPS battery status (guessed from name)"},
  {"name": "zfs-scrub", "form": "scripts/zfs-scrub.sh", "what": "start a ZFS scrub (guessed from name)"}
 ]},
 {"path": ["wake"], "sentence": "Wake a sleeping rig with a magic packet. The MAC address comes from rigs.toml.", "rows": [
  {"name": "RIG", "form": "bin/rig-wake RIG", "what": "rig to wake, for example cellar"}
 ]}
],
"questions": [
 "Stash mixes one action (take RIG, --all) with two sub-things (list, prune). A rig named list or prune would clash, and I could not confirm how click binds the first word. Recommendation: split the take action into 'stash take RIG' and keep 'stash list' and 'stash prune'.",
 "The prune default of 8 is hard-coded in the CLI, while burrow.toml also has keep = 8 that the CLI does not read. Recommendation: take the default from the config file.",
 "Make targets, scripts, docs, config and metrics are outside burrow's own command. Recommendation: keep them in the map, but leave them out of 'burrow --help' and point to them from the README.",
 "Only 3 of 25 scripts are described in the dump, so 22 descriptions are guesses from names. Recommendation: you add a one-line description for each, and I read the script headers in a later pass.",
 "Some helpers and commands are disruptive: reboot-rig, unmount-nas, stash prune, and restore, which overwrites files on a rig. Recommendation: say so in each help text, and ask for confirmation on restore unless --dry-run is used.",
 "The porch binds to 0.0.0.0 with no login in the dump, and BURROW_PORCH_SECRET is defined but not used. Recommendation: decide whether the porch should bind to 127.0.0.1 or check the secret before you expose it on the LAN.",
 "The pulse readings always return 0.0, and prometheus.yml is not in the snapshot, so the metrics stack may not start as written. Recommendation: confirm the config file exists and decide when real readings replace the placeholders.",
 "restore --from needs an exact date. Recommendation: also accept 'latest' so you need not look up the date first.",
 "Rigs are arguments, not screens, so there is no per-rig help page. Recommendation: keep it that way; a per-rig screen would add paths the CLI does not have."
]}
```

Today's skills · run 1 exit=0 seconds=120 · prompt

P1 Recall: 0.9P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 3
As terminal help
What burrow looks after: the home lab's machines, their stashes and chores, the porch that shows them, the metrics, and the helper scripts.
rigsburrow rigsPrints the rigs screen: each machine burrow knows and whether it answers.
stashburrow stash (to change: today it errors without a rig)Prints the stash screen: how to take, list, restore and prune snapshots.
choresburrow choresPrints the chores screen: the recurring jobs and when each last ran.
porchburrow porch (to change: today it starts the server)Prints the porch screen: the dashboard's pages and how to start it.
metricsburrow metrics (to build)Prints the metrics screen: the containers that graph rig temperatures and disk use.
helpersburrow helpers (to build)Prints the helpers screen: the 25 small shell scripts in scripts/.
setupburrow setup (to build)Prints the setup screen: installing burrow, its settings, logs and guides.
rigs
The rigs burrow knows: the machines in the home lab, and whether each one answers now.
atticconfig/rigs.tomlOpens attic's entry in config/rigs.toml: its address, MAC and the paths its stashes cover.
cellarconfig/rigs.tomlOpens cellar's entry in config/rigs.toml: its address, MAC and the paths its stashes cover.
gardenconfig/rigs.tomlOpens garden's entry in config/rigs.toml: its address, MAC and the paths its stashes cover.
wake a sleeping rigbin/rig-wake <rig>Sends a wake packet to a sleeping rig, using the MAC from config/rigs.toml.
add a rigdocs/adding-a-rig.mdOpens the steps for adding a rig to config/rigs.toml.
stash
The stashes: snapshots of each rig's important folders, pulled over rsync and kept under /srv/burrow/stashes.
take a stash of one rigburrow stash <rig>Takes a stash of one rig now, into /srv/burrow/stashes.
take a stash of every rigburrow stash --all (or make stash-all)Takes a stash of every rig at once.
list a rig's stashesburrow stash list <rig>Prints the stashes kept for one rig, one dated folder each.
restore a stashburrow restore <rig> --from YYYY-MM-DDCopies a stash back onto its rig, with --dry-run to check first.
prune old stashesburrow stash prune --keep 8 (or make prune-stashes)Removes the oldest stashes, keeping the newest 8.
weekly prunemake install-prune-cronAdds a weekly prune to your crontab, on Sundays at 04:40.
stash folder/srv/burrow/stashesOpens the folder holding every rig's stashes, one folder per rig.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens how to copy a stash back with rsync when burrow itself is broken.
chores
The recurring jobs that cron runs, when each last ran, and whether it worked.
nightly stashburrow chores run nightly-stashRuns a stash of every rig; cron runs it at 02:15 each night.
disk checkburrow chores run disk-checkRuns a disk check on every rig and warns above 85%; cron runs it every 6 hours.
list choresburrow chores listLists the chores burrow knows, by name.
last runsburrow chores statusPrints when each chore last finished and whether it worked.
install into croncrontab deploy/burrow.crontabInstalls the chores into your crontab, replacing the whole crontab.
chores log/var/log/burrow/chores.logOpens the log where cron writes each chore's output.
last-run record/srv/burrow/state/last-run.jsonOpens the file that records each chore's last run.
chores guidedocs/chores.mdOpens what each chore does and how to run it by hand.
porch
The porch: a small web dashboard on port 8470 that shows the rigs, the chores and the stashes.
start the porchburrow porch start (today: burrow porch)Starts the porch in the foreground on port 8470.
run it as a servicemake install-unitInstalls and starts the porch as a systemd service that restarts on failure.
front pagehttp://127.0.0.1:8470Opens the front page, which lists the rigs.
chores pagehttp://127.0.0.1:8470/choresOpens the chores page with each chore's last run.
stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens the stashes page for one rig.
health checkhttp://127.0.0.1:8470/healthzReturns ok true while the porch is up.
porch log/var/log/burrow/porch.logOpens the log the porch service writes to.
service unitdeploy/burrow-porch.serviceOpens the systemd unit that runs the porch.
porch settingsconfig/burrow.tomlOpens the [porch] section: the bind address, the title and the refresh time.
metrics
The metrics: three containers that collect rig temperatures and disk use and graph them.
start the containersmake upStarts the metrics containers in the background.
stop the containersmake downStops the metrics containers.
Grafanahttp://127.0.0.1:3000Opens the graphs of rig temperatures and disk use.
pulse numbershttp://127.0.0.1:9188/metricsOpens the raw numbers pulse exposes for Prometheus.
compose filedocker-compose.ymlOpens the file that defines the containers.
pulse sourcepulse/pulse.pyOpens the code that reads the rigs' numbers; its temperature and disk readers still return 0.0.
helpers
The helpers: 25 small shell scripts in scripts/, each run by hand. Read the top of each before running it.
battery reportscripts/battery-report.shRuns the battery report.
certificate renewalscripts/cert-renew.shRuns the certificate renewal.
disk check on every rigscripts/check-disks.shShows disk use on every rig, over ssh.
DNS flushscripts/dns-flush.shRuns the DNS flush.
stash disk usescripts/du-stashes.shRuns the stash disk-use report.
chores exportscripts/export-chores.shRuns the chores export.
fan curvescripts/fan-curve.shRuns the fan curve.
Docker cleanupscripts/gc-docker.shRuns the Docker cleanup.
rigs importscripts/import-rigs.shRuns the rigs import.
port listscripts/list-ports.shRuns the port list.
NAS mountscripts/mount-nas.shRuns the NAS mount.
network speed testscripts/net-speed.shRuns the network speed test.
Pi-hole updatescripts/pihole-update.shRuns the Pi-hole update.
reboot a rigscripts/reboot-rig.sh <address>Reboots one rig after a 10-second countdown.
log rotationscripts/rotate-logs.shRuns the log rotation.
dev seedscripts/seed-dev.shRuns the dev seed.
SMART disk reportscripts/smart-report.shRuns the SMART disk report.
SSH key pushscripts/ssh-keys-push.shRuns the SSH key push.
clock syncscripts/sync-clock.shRuns the clock sync.
temperature checkscripts/temp-check.shRuns the temperature check.
NAS unmountscripts/unmount-nas.shRuns the NAS unmount.
rig updatesscripts/update-rigs.shRuns the rig updates.
UPS statusscripts/ups-status.shRuns the UPS status.
verify a stashscripts/verify-stash.sh <rig>Checks the newest stash of a rig is readable and not empty.
ZFS scrubscripts/zfs-scrub.shRuns the ZFS scrub.
setup
Setting burrow up and keeping it going: install, settings, secrets, logs, tests, and the guides.
installmake installCreates the virtualenv in .venv and installs the burrow command into it.
testmake testRuns the test suite.
lintmake lintChecks the code with ruff.
cleanmake cleanDeletes the virtualenv and build leftovers.
settingsconfig/burrow.tomlOpens burrow's settings: where stashes go, the porch address and the ssh user.
secrets.envOpens the secrets file: the ssh key path, the porch secret and the ntfy topic.
logs/var/log/burrowOpens the folder with the chores and porch logs.
guidesburrow setup docs (to build)Prints the guides screen: the files that explain setup, chores and restores.
setup › docs
The guides that ship with burrow, as files you can open.
readmeREADME.mdOpens the project overview and how to use it.
first-time setupdocs/setup.mdOpens the setup steps: the burrow user, install, crontab and metrics.
add a rigdocs/adding-a-rig.mdOpens the steps for adding a rig to config/rigs.toml.
chores guidedocs/chores.mdOpens what each chore does and how to run it by hand.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens how to copy a stash back with rsync when burrow itself is broken.
licenseLICENSEOpens the MIT license.
Questions
  • Bare nouns: `burrow stash` errors today without a rig or --all, and `burrow porch` starts the server instead of printing a screen. The map assumes every bare noun prints its screen, so the server would move to `burrow porch start`. Recommend making that change; the systemd unit's ExecStart and the README would change with it. Yes or no?
  • `crontab deploy/burrow.crontab` replaces the whole crontab, while `make install-prune-cron` appends to it. Recommend a `burrow chores install` that merges the way install-prune-cron does, and pointing the map row at it. Build the merge, or keep the replacing form?
  • The purposes of 22 of the 25 helper scripts come from their names only. Recommend reading each file's header, then deciding whether to split the helpers into screens by job (rigs, stash, network, hardware). Which grouping do you want, or keep the flat list?
  • The porch binds 0.0.0.0 with no auth in the code shown, and .env defines BURROW_PORCH_SECRET, which nothing in the dump reads. Is the secret used somewhere not shown? If not, the porch row should say it is open to the LAN.
  • Pulse's temperature and disk readers return 0.0, so the metrics graphs will show zeros. Recommend keeping the metrics screen and marking it as not yet wired, rather than hiding it. Keep it marked, or hide it until pulse reads the rigs?
  • Prometheus publishes no host port, so the map has no row for it. Recommend leaving it off the map, since nothing in it is reachable by hand. Confirm?
  • Restore is top-level in the CLI (`burrow restore`) but the map files it under stash. Recommend keeping `burrow restore` as the typed form and listing it under stash as well. Agreed?
As phone screens

Home

What burrow looks after: the home lab's machines, their stashes and chores, the porch that shows them, the metrics, and the helper scripts.

rigsPrints the rigs screen: each machine burrow knows and whether it answers.
›
stashPrints the stash screen: how to take, list, restore and prune snapshots.
›
choresPrints the chores screen: the recurring jobs and when each last ran.
›
porchPrints the porch screen: the dashboard's pages and how to start it.
›
metricsPrints the metrics screen: the containers that graph rig temperatures and disk use.
›
helpersPrints the helpers screen: the 25 small shell scripts in scripts/.
›
setupPrints the setup screen: installing burrow, its settings, logs and guides.
›
‹ Home

rigs

The rigs burrow knows: the machines in the home lab, and whether each one answers now.

atticOpens attic's entry in config/rigs.toml: its address, MAC and the paths its stashes cover.
›
cellarOpens cellar's entry in config/rigs.toml: its address, MAC and the paths its stashes cover.
›
gardenOpens garden's entry in config/rigs.toml: its address, MAC and the paths its stashes cover.
›
wake a sleeping rigSends a wake packet to a sleeping rig, using the MAC from config/rigs.toml.
›
add a rigOpens the steps for adding a rig to config/rigs.toml.
›
‹ Home

stash

The stashes: snapshots of each rig's important folders, pulled over rsync and kept under /srv/burrow/stashes.

take a stash of one rigTakes a stash of one rig now, into /srv/burrow/stashes.
›
take a stash of every rigTakes a stash of every rig at once.
›
list a rig's stashesPrints the stashes kept for one rig, one dated folder each.
›
restore a stashCopies a stash back onto its rig, with --dry-run to check first.
›
prune old stashesRemoves the oldest stashes, keeping the newest 8.
›
weekly pruneAdds a weekly prune to your crontab, on Sundays at 04:40.
›
stash folderOpens the folder holding every rig's stashes, one folder per rig.
›
restore by handOpens how to copy a stash back with rsync when burrow itself is broken.
›
‹ Home

chores

The recurring jobs that cron runs, when each last ran, and whether it worked.

nightly stashRuns a stash of every rig; cron runs it at 02:15 each night.
›
disk checkRuns a disk check on every rig and warns above 85%; cron runs it every 6 hours.
›
list choresLists the chores burrow knows, by name.
›
last runsPrints when each chore last finished and whether it worked.
›
install into cronInstalls the chores into your crontab, replacing the whole crontab.
›
chores logOpens the log where cron writes each chore's output.
›
last-run recordOpens the file that records each chore's last run.
›
chores guideOpens what each chore does and how to run it by hand.
›
‹ Home

porch

The porch: a small web dashboard on port 8470 that shows the rigs, the chores and the stashes.

start the porchStarts the porch in the foreground on port 8470.
›
run it as a serviceInstalls and starts the porch as a systemd service that restarts on failure.
›
front pageOpens the front page, which lists the rigs.
›
chores pageOpens the chores page with each chore's last run.
›
stashes pageOpens the stashes page for one rig.
›
health checkReturns ok true while the porch is up.
›
porch logOpens the log the porch service writes to.
›
service unitOpens the systemd unit that runs the porch.
›
porch settingsOpens the [porch] section: the bind address, the title and the refresh time.
›
‹ Home

metrics

The metrics: three containers that collect rig temperatures and disk use and graph them.

start the containersStarts the metrics containers in the background.
›
stop the containersStops the metrics containers.
›
GrafanaOpens the graphs of rig temperatures and disk use.
›
pulse numbersOpens the raw numbers pulse exposes for Prometheus.
›
compose fileOpens the file that defines the containers.
›
pulse sourceOpens the code that reads the rigs' numbers; its temperature and disk readers still return 0.0.
›
‹ Home

helpers

The helpers: 25 small shell scripts in scripts/, each run by hand. Read the top of each before running it.

battery reportRuns the battery report.
›
certificate renewalRuns the certificate renewal.
›
disk check on every rigShows disk use on every rig, over ssh.
›
DNS flushRuns the DNS flush.
›
stash disk useRuns the stash disk-use report.
›
chores exportRuns the chores export.
›
fan curveRuns the fan curve.
›
Docker cleanupRuns the Docker cleanup.
›
rigs importRuns the rigs import.
›
port listRuns the port list.
›
NAS mountRuns the NAS mount.
›
network speed testRuns the network speed test.
›
Pi-hole updateRuns the Pi-hole update.
›
reboot a rigReboots one rig after a 10-second countdown.
›
log rotationRuns the log rotation.
›
dev seedRuns the dev seed.
›
SMART disk reportRuns the SMART disk report.
›
SSH key pushRuns the SSH key push.
›
clock syncRuns the clock sync.
›
temperature checkRuns the temperature check.
›
NAS unmountRuns the NAS unmount.
›
rig updatesRuns the rig updates.
›
UPS statusRuns the UPS status.
›
verify a stashChecks the newest stash of a rig is readable and not empty.
›
ZFS scrubRuns the ZFS scrub.
›
‹ Home

setup

Setting burrow up and keeping it going: install, settings, secrets, logs, tests, and the guides.

installCreates the virtualenv in .venv and installs the burrow command into it.
›
testRuns the test suite.
›
lintChecks the code with ruff.
›
cleanDeletes the virtualenv and build leftovers.
›
settingsOpens burrow's settings: where stashes go, the porch address and the ssh user.
›
secretsOpens the secrets file: the ssh key path, the porch secret and the ntfy topic.
›
logsOpens the folder with the chores and porch logs.
›
guidesPrints the guides screen: the files that explain setup, chores and restores.
›
‹ setup

docs

The guides that ship with burrow, as files you can open.

readmeOpens the project overview and how to use it.
›
first-time setupOpens the setup steps: the burrow user, install, crontab and metrics.
›
add a rigOpens the steps for adding a rig to config/rigs.toml.
›
chores guideOpens what each chore does and how to run it by hand.
›
restore by handOpens how to copy a stash back with rsync when burrow itself is broken.
›
licenseOpens the MIT license.
›
Raw answer
The map has nine screens. The top screen names seven things: rigs, stash, chores, porch, metrics, helpers and setup. The guides sit under setup. Rigs stay arguments (`burrow stash <rig>`), not nouns, because the CLI already takes them that way. Forms are today's commands, except where marked "(to build)" or "(today: ...)". Twenty-two of the 25 helper descriptions come from file names only, since the dump includes just three scripts.

```json
{"screens": [
 {"path": [],
  "sentence": "What burrow looks after: the home lab's machines, their stashes and chores, the porch that shows them, the metrics, and the helper scripts.",
  "rows": [
   {"name": "rigs", "form": "burrow rigs", "what": "Prints the rigs screen: each machine burrow knows and whether it answers."},
   {"name": "stash", "form": "burrow stash (to change: today it errors without a rig)", "what": "Prints the stash screen: how to take, list, restore and prune snapshots."},
   {"name": "chores", "form": "burrow chores", "what": "Prints the chores screen: the recurring jobs and when each last ran."},
   {"name": "porch", "form": "burrow porch (to change: today it starts the server)", "what": "Prints the porch screen: the dashboard's pages and how to start it."},
   {"name": "metrics", "form": "burrow metrics (to build)", "what": "Prints the metrics screen: the containers that graph rig temperatures and disk use."},
   {"name": "helpers", "form": "burrow helpers (to build)", "what": "Prints the helpers screen: the 25 small shell scripts in scripts/."},
   {"name": "setup", "form": "burrow setup (to build)", "what": "Prints the setup screen: installing burrow, its settings, logs and guides."}
  ]},
 {"path": ["rigs"],
  "sentence": "The rigs burrow knows: the machines in the home lab, and whether each one answers now.",
  "rows": [
   {"name": "attic", "form": "config/rigs.toml", "what": "Opens attic's entry in config/rigs.toml: its address, MAC and the paths its stashes cover."},
   {"name": "cellar", "form": "config/rigs.toml", "what": "Opens cellar's entry in config/rigs.toml: its address, MAC and the paths its stashes cover."},
   {"name": "garden", "form": "config/rigs.toml", "what": "Opens garden's entry in config/rigs.toml: its address, MAC and the paths its stashes cover."},
   {"name": "wake a sleeping rig", "form": "bin/rig-wake <rig>", "what": "Sends a wake packet to a sleeping rig, using the MAC from config/rigs.toml."},
   {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps for adding a rig to config/rigs.toml."}
  ]},
 {"path": ["stash"],
  "sentence": "The stashes: snapshots of each rig's important folders, pulled over rsync and kept under /srv/burrow/stashes.",
  "rows": [
   {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now, into /srv/burrow/stashes."},
   {"name": "take a stash of every rig", "form": "burrow stash --all (or make stash-all)", "what": "Takes a stash of every rig at once."},
   {"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Prints the stashes kept for one rig, one dated folder each."},
   {"name": "restore a stash", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies a stash back onto its rig, with --dry-run to check first."},
   {"name": "prune old stashes", "form": "burrow stash prune --keep 8 (or make prune-stashes)", "what": "Removes the oldest stashes, keeping the newest 8."},
   {"name": "weekly prune", "form": "make install-prune-cron", "what": "Adds a weekly prune to your crontab, on Sundays at 04:40."},
   {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder holding every rig's stashes, one folder per rig."},
   {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens how to copy a stash back with rsync when burrow itself is broken."}
  ]},
 {"path": ["chores"],
  "sentence": "The recurring jobs that cron runs, when each last ran, and whether it worked.",
  "rows": [
   {"name": "nightly stash", "form": "burrow chores run nightly-stash", "what": "Runs a stash of every rig; cron runs it at 02:15 each night."},
   {"name": "disk check", "form": "burrow chores run disk-check", "what": "Runs a disk check on every rig and warns above 85%; cron runs it every 6 hours."},
   {"name": "list chores", "form": "burrow chores list", "what": "Lists the chores burrow knows, by name."},
   {"name": "last runs", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
   {"name": "install into cron", "form": "crontab deploy/burrow.crontab", "what": "Installs the chores into your crontab, replacing the whole crontab."},
   {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the log where cron writes each chore's output."},
   {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the file that records each chore's last run."},
   {"name": "chores guide", "form": "docs/chores.md", "what": "Opens what each chore does and how to run it by hand."}
  ]},
 {"path": ["porch"],
  "sentence": "The porch: a small web dashboard on port 8470 that shows the rigs, the chores and the stashes.",
  "rows": [
   {"name": "start the porch", "form": "burrow porch start (today: burrow porch)", "what": "Starts the porch in the foreground on port 8470."},
   {"name": "run it as a service", "form": "make install-unit", "what": "Installs and starts the porch as a systemd service that restarts on failure."},
   {"name": "front page", "form": "http://127.0.0.1:8470", "what": "Opens the front page, which lists the rigs."},
   {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page with each chore's last run."},
   {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens the stashes page for one rig."},
   {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns ok true while the porch is up."},
   {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the log the porch service writes to."},
   {"name": "service unit", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that runs the porch."},
   {"name": "porch settings", "form": "config/burrow.toml", "what": "Opens the [porch] section: the bind address, the title and the refresh time."}
  ]},
 {"path": ["metrics"],
  "sentence": "The metrics: three containers that collect rig temperatures and disk use and graph them.",
  "rows": [
   {"name": "start the containers", "form": "make up", "what": "Starts the metrics containers in the background."},
   {"name": "stop the containers", "form": "make down", "what": "Stops the metrics containers."},
   {"name": "Grafana", "form": "http://127.0.0.1:3000", "what": "Opens the graphs of rig temperatures and disk use."},
   {"name": "pulse numbers", "form": "http://127.0.0.1:9188/metrics", "what": "Opens the raw numbers pulse exposes for Prometheus."},
   {"name": "compose file", "form": "docker-compose.yml", "what": "Opens the file that defines the containers."},
   {"name": "pulse source", "form": "pulse/pulse.py", "what": "Opens the code that reads the rigs' numbers; its temperature and disk readers still return 0.0."}
  ]},
 {"path": ["helpers"],
  "sentence": "The helpers: 25 small shell scripts in scripts/, each run by hand. Read the top of each before running it.",
  "rows": [
   {"name": "battery report", "form": "scripts/battery-report.sh", "what": "Runs the battery report."},
   {"name": "certificate renewal", "form": "scripts/cert-renew.sh", "what": "Runs the certificate renewal."},
   {"name": "disk check on every rig", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig, over ssh."},
   {"name": "DNS flush", "form": "scripts/dns-flush.sh", "what": "Runs the DNS flush."},
   {"name": "stash disk use", "form": "scripts/du-stashes.sh", "what": "Runs the stash disk-use report."},
   {"name": "chores export", "form": "scripts/export-chores.sh", "what": "Runs the chores export."},
   {"name": "fan curve", "form": "scripts/fan-curve.sh", "what": "Runs the fan curve."},
   {"name": "Docker cleanup", "form": "scripts/gc-docker.sh", "what": "Runs the Docker cleanup."},
   {"name": "rigs import", "form": "scripts/import-rigs.sh", "what": "Runs the rigs import."},
   {"name": "port list", "form": "scripts/list-ports.sh", "what": "Runs the port list."},
   {"name": "NAS mount", "form": "scripts/mount-nas.sh", "what": "Runs the NAS mount."},
   {"name": "network speed test", "form": "scripts/net-speed.sh", "what": "Runs the network speed test."},
   {"name": "Pi-hole update", "form": "scripts/pihole-update.sh", "what": "Runs the Pi-hole update."},
   {"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10-second countdown."},
   {"name": "log rotation", "form": "scripts/rotate-logs.sh", "what": "Runs the log rotation."},
   {"name": "dev seed", "form": "scripts/seed-dev.sh", "what": "Runs the dev seed."},
   {"name": "SMART disk report", "form": "scripts/smart-report.sh", "what": "Runs the SMART disk report."},
   {"name": "SSH key push", "form": "scripts/ssh-keys-push.sh", "what": "Runs the SSH key push."},
   {"name": "clock sync", "form": "scripts/sync-clock.sh", "what": "Runs the clock sync."},
   {"name": "temperature check", "form": "scripts/temp-check.sh", "what": "Runs the temperature check."},
   {"name": "NAS unmount", "form": "scripts/unmount-nas.sh", "what": "Runs the NAS unmount."},
   {"name": "rig updates", "form": "scripts/update-rigs.sh", "what": "Runs the rig updates."},
   {"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Runs the UPS status."},
   {"name": "verify a stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks the newest stash of a rig is readable and not empty."},
   {"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Runs the ZFS scrub."}
  ]},
 {"path": ["setup"],
  "sentence": "Setting burrow up and keeping it going: install, settings, secrets, logs, tests, and the guides.",
  "rows": [
   {"name": "install", "form": "make install", "what": "Creates the virtualenv in .venv and installs the burrow command into it."},
   {"name": "test", "form": "make test", "what": "Runs the test suite."},
   {"name": "lint", "form": "make lint", "what": "Checks the code with ruff."},
   {"name": "clean", "form": "make clean", "what": "Deletes the virtualenv and build leftovers."},
   {"name": "settings", "form": "config/burrow.toml", "what": "Opens burrow's settings: where stashes go, the porch address and the ssh user."},
   {"name": "secrets", "form": ".env", "what": "Opens the secrets file: the ssh key path, the porch secret and the ntfy topic."},
   {"name": "logs", "form": "/var/log/burrow", "what": "Opens the folder with the chores and porch logs."},
   {"name": "guides", "form": "burrow setup docs (to build)", "what": "Prints the guides screen: the files that explain setup, chores and restores."}
  ]},
 {"path": ["setup", "docs"],
  "sentence": "The guides that ship with burrow, as files you can open.",
  "rows": [
   {"name": "readme", "form": "README.md", "what": "Opens the project overview and how to use it."},
   {"name": "first-time setup", "form": "docs/setup.md", "what": "Opens the setup steps: the burrow user, install, crontab and metrics."},
   {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps for adding a rig to config/rigs.toml."},
   {"name": "chores guide", "form": "docs/chores.md", "what": "Opens what each chore does and how to run it by hand."},
   {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens how to copy a stash back with rsync when burrow itself is broken."},
   {"name": "license", "form": "LICENSE", "what": "Opens the MIT license."}
  ]}
],
"questions": [
 "Bare nouns: `burrow stash` errors today without a rig or --all, and `burrow porch` starts the server instead of printing a screen. The map assumes every bare noun prints its screen, so the server would move to `burrow porch start`. Recommend making that change; the systemd unit's ExecStart and the README would change with it. Yes or no?",
 "`crontab deploy/burrow.crontab` replaces the whole crontab, while `make install-prune-cron` appends to it. Recommend a `burrow chores install` that merges the way install-prune-cron does, and pointing the map row at it. Build the merge, or keep the replacing form?",
 "The purposes of 22 of the 25 helper scripts come from their names only. Recommend reading each file's header, then deciding whether to split the helpers into screens by job (rigs, stash, network, hardware). Which grouping do you want, or keep the flat list?",
 "The porch binds 0.0.0.0 with no auth in the code shown, and .env defines BURROW_PORCH_SECRET, which nothing in the dump reads. Is the secret used somewhere not shown? If not, the porch row should say it is open to the LAN.",
 "Pulse's temperature and disk readers return 0.0, so the metrics graphs will show zeros. Recommend keeping the metrics screen and marking it as not yet wired, rather than hiding it. Keep it marked, or hide it until pulse reads the rigs?",
 "Prometheus publishes no host port, so the map has no row for it. Recommend leaving it off the map, since nothing in it is reachable by hand. Confirm?",
 "Restore is top-level in the CLI (`burrow restore`) but the map files it under stash. Recommend keeping `burrow restore` as the typed form and listing it under stash as well. Agreed?"
]}
```

screen-decomposition, first draft · run 1 exit=0 seconds=130 · prompt

P1 Recall: 0.9P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 5
As terminal help
burrow's main menu: the groups of everything in the home lab tool.
rigsburrow rigsOpens the rigs screen: the rigs burrow knows and whether each answers.
stashburrow stashOpens the stash screen: take, list, prune and restore snapshots of the rigs.
choresburrow choresOpens the chores screen: the recurring jobs and when each last ran.
porchhttp://127.0.0.1:8470Opens the porch dashboard in a browser.
metricsburrow metricsOpens the metrics screen: graphs of rig temperatures and disk use.
helpersburrow helpersOpens the helpers screen: the shell scripts in scripts/.
projectburrow projectOpens the project screen: make targets, config files and docs.
rigs
The rigs burrow knows, and what you can do with each.
wake atticbin/rig-wake atticSends a wake packet to attic so it starts if asleep.
wake cellarbin/rig-wake cellarSends a wake packet to cellar so it starts if asleep.
wake gardenbin/rig-wake gardenSends a wake packet to garden so it starts if asleep.
check disksscripts/check-disks.shShows the disk use of every rig over ssh.
reboot a rigscripts/reboot-rig.sh <address>Reboots one rig after a 10 second countdown.
rig settingsconfig/rigs.tomlShows each rig's name, address, MAC and stashed paths.
add a rigdocs/adding-a-rig.mdShows the [[rig]] block to add a rig.
stash
The stashes: snapshots of each rig's folders, and what you can do with them.
take a stash of one rigburrow stash <rig>Takes a stash of one rig now, into /srv/burrow/stashes.
take a stash of every rigburrow stash --allTakes a stash of every rig now.
list a rig's stashesburrow stash list <rig>Prints the dated stashes kept for one rig.
prune old stashesburrow stash prune --keep 8Removes the oldest stashes beyond --keep, default 8.
restore a stashburrow restore <rig> --from YYYY-MM-DDCopies a dated stash back onto its rig; --dry-run to try it first.
restore by handdocs/internals/stash/format/restore-by-hand.mdShows how to copy a stash back with rsync if burrow is broken.
stash folder/srv/burrow/stashesOpens the folder of stashes: one per rig, one dated folder per stash.
verify newest stashscripts/verify-stash.sh <rig>Checks the newest stash of a rig is readable and not empty.
stash disk usescripts/du-stashes.shShows how much disk the stashes use (from its name; header unread).
chores
The chores: recurring jobs run from cron, and when each last ran.
list choresburrow chores listPrints the names of the registered chores.
nightly stashburrow chores run nightly-stashRuns a stash of every rig now, the job cron runs at 02:15.
disk checkburrow chores run disk-checkWarns when a rig's root disk is over 85%, the job cron runs every 6 hours.
last runsburrow chores statusPrints when each chore last finished and whether it worked.
chores pagehttp://127.0.0.1:8470/choresShows the last runs on the porch.
chores log/var/log/burrow/chores.logOpens the output cron wrote for the chores.
last-run record/srv/burrow/state/last-run.jsonOpens the file that keeps each chore's last run.
cron scheduledeploy/burrow.crontabShows when cron runs each chore.
chores docdocs/chores.mdExplains each chore and how to run it by hand.
porch
The porch: the dashboard for the rigs, served on port 8470.
dashboardhttp://127.0.0.1:8470Opens the dashboard: the rigs and their stashes.
rig stashes pagehttp://127.0.0.1:8470/stashes/<rig>Shows the stashes kept for one rig.
chores pagehttp://127.0.0.1:8470/choresShows when each chore last ran.
health checkhttp://127.0.0.1:8470/healthzReturns {"ok": true} while the porch is up.
run the porchburrow porchRuns the porch dashboard in the foreground on the bind address in config.
systemd unitdeploy/burrow-porch.serviceShows the unit that keeps the porch running as a service.
porch log/var/log/burrow/porch.logOpens the porch's output log.
metrics
The metrics: graphs of rig temperatures and disk use, in Grafana.
Grafana graphshttp://127.0.0.1:3000Opens Grafana, the graphs of temperatures and disk use.
pulse numbershttp://127.0.0.1:9188/metricsShows the raw temperature and disk numbers pulse exposes.
pulse codepulse/pulse.pyShows the exporter that serves the numbers to Prometheus.
Prometheusdocker-compose.yml (service prometheus)Stores 30 days of the numbers; it has no port on the host.
compose filedocker-compose.ymlShows the three containers: pulse, prometheus and grafana.
start containersmake upStarts the containers in the background.
stop containersmake downStops the containers.
helpers
The helper scripts in scripts/, each a shell script; read its top before running it.
battery-reportscripts/battery-report.shReports battery state (from its name; header unread).
cert-renewscripts/cert-renew.shRenews certificates (from its name; header unread).
check-disksscripts/check-disks.shShows the disk use of every rig over ssh.
dns-flushscripts/dns-flush.shFlushes the DNS cache (from its name; header unread).
du-stashesscripts/du-stashes.shShows how much disk the stashes use (from its name; header unread).
export-choresscripts/export-chores.shExports the chore records (from its name; header unread).
fan-curvescripts/fan-curve.shSets the fan curve (from its name; header unread).
gc-dockerscripts/gc-docker.shCleans up unused Docker data (from its name; header unread).
import-rigsscripts/import-rigs.shImports rigs into config (from its name; header unread).
list-portsscripts/list-ports.shLists open ports (from its name; header unread).
mount-nasscripts/mount-nas.shMounts the NAS (from its name; header unread).
net-speedscripts/net-speed.shMeasures network speed (from its name; header unread).
pihole-updatescripts/pihole-update.shUpdates Pi-hole (from its name; header unread).
reboot-rigscripts/reboot-rig.sh <address>Reboots one rig after a 10 second countdown.
rotate-logsscripts/rotate-logs.shRotates the logs (from its name; header unread).
seed-devscripts/seed-dev.shSeeds development data (from its name; header unread).
smart-reportscripts/smart-report.shReports disk SMART health (from its name; header unread).
ssh-keys-pushscripts/ssh-keys-push.shPushes ssh keys to the rigs (from its name; header unread).
sync-clockscripts/sync-clock.shSyncs the clock (from its name; header unread).
temp-checkscripts/temp-check.shChecks rig temperatures (from its name; header unread).
unmount-nasscripts/unmount-nas.shUnmounts the NAS (from its name; header unread).
update-rigsscripts/update-rigs.shUpdates the rigs (from its name; header unread).
ups-statusscripts/ups-status.shShows UPS status (from its name; header unread).
verify-stashscripts/verify-stash.sh <rig>Checks the newest stash of a rig is readable and not empty.
zfs-scrubscripts/zfs-scrub.shStarts a ZFS scrub (from its name; header unread).
project
The project itself: its make targets, config files and docs.
makeburrow project makeOpens the make screen: the targets run in /opt/burrow.
configburrow project configOpens the config screen: the settings files.
docsburrow project docsOpens the docs screen: setup, rigs, chores and restoring by hand.
project › make
The make targets, run from /opt/burrow.
installmake installCreates the virtualenv in .venv/ and installs burrow into it.
install the porch servicemake install-unitCopies the systemd unit and starts burrow-porch.service (needs sudo).
start containersmake upStarts the metrics containers in the background.
stop containersmake downStops the metrics containers.
testmake testRuns the pytest suite in tests/.
lintmake lintChecks burrow and tests with ruff.
stash allmake stash-allTakes a stash of every rig now.
prune stashesmake prune-stashesRemoves old stashes, keeping 8.
weekly prune cronmake install-prune-cronAdds a weekly prune at 04:40 on Sunday to the crontab.
cleanmake cleanDeletes .venv, caches and build leftovers.
project › config
The config files burrow reads, and the settings in them.
burrow settingsconfig/burrow.tomlShows the stash folder, rsync flags, how many stashes to keep, the porch bind and the ssh user.
rigsconfig/rigs.tomlLists every rig with its address, MAC and paths; add a block to add a rig.
secrets example.env.exampleShows the three values to copy into .env: ssh key, porch secret and ntfy topic.
secrets.envHolds your ssh key, porch secret and ntfy topic; copied from .env.example.
project › docs
The docs: setup, adding a rig, chores, restoring by hand, the readme and the license.
setupdocs/setup.mdShows the steps to set up burrow on the rigs and the porch.
adding a rigdocs/adding-a-rig.mdShows the [[rig]] block to add to config/rigs.toml.
choresdocs/chores.mdExplains each chore and how to run it by hand.
restore by handdocs/internals/stash/format/restore-by-hand.mdShows how to restore a stash with rsync when burrow is broken.
readmeREADME.mdShows the overview, install, use, chores, metrics and helpers.
licenseLICENSEShows the MIT license.
Questions
  • burrow stash <rig> already takes a stash, and burrow porch already runs the server, but the map wants a bare noun to show its screen. Recommendation: keep both actions as they are (the README documents them). Bare `burrow stash` shows the stash screen, and the porch group links to its URL, so the porch screen has no command yet. Confirm?
  • The helpers screen lists 25 scripts, which is too many for one list. Recommendation: split them by job once their headers are read. Send the top of the 22 unread scripts, or confirm the split waits until later?
  • The stash screen has 9 rows. Recommendation: keep it as one screen for now, and move restore to its own screen only if the list grows?
As phone screens

Home

burrow's main menu: the groups of everything in the home lab tool.

rigsOpens the rigs screen: the rigs burrow knows and whether each answers.
›
stashOpens the stash screen: take, list, prune and restore snapshots of the rigs.
›
choresOpens the chores screen: the recurring jobs and when each last ran.
›
porchOpens the porch dashboard in a browser.
›
metricsOpens the metrics screen: graphs of rig temperatures and disk use.
›
helpersOpens the helpers screen: the shell scripts in scripts/.
›
projectOpens the project screen: make targets, config files and docs.
›
‹ Home

rigs

The rigs burrow knows, and what you can do with each.

wake atticSends a wake packet to attic so it starts if asleep.
›
wake cellarSends a wake packet to cellar so it starts if asleep.
›
wake gardenSends a wake packet to garden so it starts if asleep.
›
check disksShows the disk use of every rig over ssh.
›
reboot a rigReboots one rig after a 10 second countdown.
›
rig settingsShows each rig's name, address, MAC and stashed paths.
›
add a rigShows the [[rig]] block to add a rig.
›
‹ Home

stash

The stashes: snapshots of each rig's folders, and what you can do with them.

take a stash of one rigTakes a stash of one rig now, into /srv/burrow/stashes.
›
take a stash of every rigTakes a stash of every rig now.
›
list a rig's stashesPrints the dated stashes kept for one rig.
›
prune old stashesRemoves the oldest stashes beyond --keep, default 8.
›
restore a stashCopies a dated stash back onto its rig; --dry-run to try it first.
›
restore by handShows how to copy a stash back with rsync if burrow is broken.
›
stash folderOpens the folder of stashes: one per rig, one dated folder per stash.
›
verify newest stashChecks the newest stash of a rig is readable and not empty.
›
stash disk useShows how much disk the stashes use (from its name; header unread).
›
‹ Home

chores

The chores: recurring jobs run from cron, and when each last ran.

list choresPrints the names of the registered chores.
›
nightly stashRuns a stash of every rig now, the job cron runs at 02:15.
›
disk checkWarns when a rig's root disk is over 85%, the job cron runs every 6 hours.
›
last runsPrints when each chore last finished and whether it worked.
›
chores pageShows the last runs on the porch.
›
chores logOpens the output cron wrote for the chores.
›
last-run recordOpens the file that keeps each chore's last run.
›
cron scheduleShows when cron runs each chore.
›
chores docExplains each chore and how to run it by hand.
›
‹ Home

porch

The porch: the dashboard for the rigs, served on port 8470.

dashboardOpens the dashboard: the rigs and their stashes.
›
rig stashes pageShows the stashes kept for one rig.
›
chores pageShows when each chore last ran.
›
health checkReturns {"ok": true} while the porch is up.
›
run the porchRuns the porch dashboard in the foreground on the bind address in config.
›
systemd unitShows the unit that keeps the porch running as a service.
›
porch logOpens the porch's output log.
›
‹ Home

metrics

The metrics: graphs of rig temperatures and disk use, in Grafana.

Grafana graphsOpens Grafana, the graphs of temperatures and disk use.
›
pulse numbersShows the raw temperature and disk numbers pulse exposes.
›
pulse codeShows the exporter that serves the numbers to Prometheus.
›
PrometheusStores 30 days of the numbers; it has no port on the host.
›
compose fileShows the three containers: pulse, prometheus and grafana.
›
start containersStarts the containers in the background.
›
stop containersStops the containers.
›
‹ Home

helpers

The helper scripts in scripts/, each a shell script; read its top before running it.

battery-reportReports battery state (from its name; header unread).
›
cert-renewRenews certificates (from its name; header unread).
›
check-disksShows the disk use of every rig over ssh.
›
dns-flushFlushes the DNS cache (from its name; header unread).
›
du-stashesShows how much disk the stashes use (from its name; header unread).
›
export-choresExports the chore records (from its name; header unread).
›
fan-curveSets the fan curve (from its name; header unread).
›
gc-dockerCleans up unused Docker data (from its name; header unread).
›
import-rigsImports rigs into config (from its name; header unread).
›
list-portsLists open ports (from its name; header unread).
›
mount-nasMounts the NAS (from its name; header unread).
›
net-speedMeasures network speed (from its name; header unread).
›
pihole-updateUpdates Pi-hole (from its name; header unread).
›
reboot-rigReboots one rig after a 10 second countdown.
›
rotate-logsRotates the logs (from its name; header unread).
›
seed-devSeeds development data (from its name; header unread).
›
smart-reportReports disk SMART health (from its name; header unread).
›
ssh-keys-pushPushes ssh keys to the rigs (from its name; header unread).
›
sync-clockSyncs the clock (from its name; header unread).
›
temp-checkChecks rig temperatures (from its name; header unread).
›
unmount-nasUnmounts the NAS (from its name; header unread).
›
update-rigsUpdates the rigs (from its name; header unread).
›
ups-statusShows UPS status (from its name; header unread).
›
verify-stashChecks the newest stash of a rig is readable and not empty.
›
zfs-scrubStarts a ZFS scrub (from its name; header unread).
›
‹ Home

project

The project itself: its make targets, config files and docs.

makeOpens the make screen: the targets run in /opt/burrow.
›
configOpens the config screen: the settings files.
›
docsOpens the docs screen: setup, rigs, chores and restoring by hand.
›
‹ project

make

The make targets, run from /opt/burrow.

installCreates the virtualenv in .venv/ and installs burrow into it.
›
install the porch serviceCopies the systemd unit and starts burrow-porch.service (needs sudo).
›
start containersStarts the metrics containers in the background.
›
stop containersStops the metrics containers.
›
testRuns the pytest suite in tests/.
›
lintChecks burrow and tests with ruff.
›
stash allTakes a stash of every rig now.
›
prune stashesRemoves old stashes, keeping 8.
›
weekly prune cronAdds a weekly prune at 04:40 on Sunday to the crontab.
›
cleanDeletes .venv, caches and build leftovers.
›
‹ project

config

The config files burrow reads, and the settings in them.

burrow settingsShows the stash folder, rsync flags, how many stashes to keep, the porch bind and the ssh user.
›
rigsLists every rig with its address, MAC and paths; add a block to add a rig.
›
secrets exampleShows the three values to copy into .env: ssh key, porch secret and ntfy topic.
›
secretsHolds your ssh key, porch secret and ntfy topic; copied from .env.example.
›
‹ project

docs

The docs: setup, adding a rig, chores, restoring by hand, the readme and the license.

setupShows the steps to set up burrow on the rigs and the porch.
›
adding a rigShows the [[rig]] block to add to config/rigs.toml.
›
choresExplains each chore and how to run it by hand.
›
restore by handShows how to restore a stash with rsync when burrow is broken.
›
readmeShows the overview, install, use, chores, metrics and helpers.
›
licenseShows the MIT license.
›
Raw answer
## Scenario

Reasoning from the README, not from observed use: the owner is at a terminal with three rigs (`attic`, `cellar`, `garden`) and wants to see which ones answer, take a stash before a risky change, restore one, check whether the nightly chore ran, open the porch or Grafana, or find a helper script. They need to know whether a command starts something or only prints.

## Inventory

- **Rigs:** 3 entries in `config/rigs.toml`, one wake script (`bin/rig-wake`).
- **CLI** (`burrow/cli.py`): `rigs`, `stash` (with `list`, `prune`, `--all`), `restore`, `chores` (`list`, `run`, `status`), `porch`.
- **Chores** (`burrow/chores.py`): `nightly-stash`, `disk-check`, plus the cron schedule (`deploy/burrow.crontab`).
- **Porch pages** (`burrow/porch/app.py`): `/`, `/chores`, `/stashes/<rig>`, `/healthz`.
- **Make targets** (`Makefile`): 10.
- **Containers** (`docker-compose.yml`): pulse, prometheus, grafana.
- **Scripts:** 25 in `scripts/`. Only three were readable (`check-disks`, `verify-stash`, `reboot-rig`).
- **Config and docs:** `config/burrow.toml`, `config/rigs.toml`, `.env.example`, `.env`, 4 docs, README, LICENSE.
- **Places and logs:** `/srv/burrow/stashes`, `/srv/burrow/state/last-run.json`, `/var/log/burrow/{chores,porch}.log`.

## Judgment calls

- **Seven top groups.** `make`, `config` and `docs` sit under `project` to keep the top screen short.
- **Rigs get no screens of their own.** Three rigs fit on one screen. Split them out when a fourth rig makes the list long.
- **`restore` sits under `stash`.** It is a stash action, even though the CLI has it at top level.
- **`bin/rig-wake` sits under `rigs`** although it is outside the `burrow` CLI. `cli-engineer` can wrap it as a thin command.
- **Logs and the state file** appear on the chores and porch screens where they are used.
- **Unread script lines are guesses.** The 22 helper lines marked "header unread" come from file names alone.
- **Found while mapping:** `pulse/pulse.py` `read_temp` and `read_disk` return `0.0`, so Grafana will graph zeros until they are implemented. The metrics screen describes what pulse serves, not what the values currently are.

## Questions

1. **Naming conflict.** `burrow stash attic` already takes a stash, and `burrow porch` already runs the server. The map wants a bare noun to show its screen. **Recommendation:** keep both actions as they are, since the README documents them. Bare `burrow stash` shows the stash screen. The porch group links to its URL instead of a command, so the porch screen has no command yet. Confirm?
2. **Helper scripts.** The helpers screen lists 25 scripts, too many for one list. **Recommendation:** split them by job after reading the headers. Send the top of the 22 unread scripts, or confirm the split waits until later.
3. **Stash length.** The stash screen has 9 rows. **Recommendation:** keep it as one screen for now and move `restore` to its own screen only if the list grows.

```json
{"screens": [
 {"path": [], "sentence": "burrow's main menu: the groups of everything in the home lab tool.", "rows": [
  {"name": "rigs", "form": "burrow rigs", "what": "Opens the rigs screen: the rigs burrow knows and whether each answers."},
  {"name": "stash", "form": "burrow stash", "what": "Opens the stash screen: take, list, prune and restore snapshots of the rigs."},
  {"name": "chores", "form": "burrow chores", "what": "Opens the chores screen: the recurring jobs and when each last ran."},
  {"name": "porch", "form": "http://127.0.0.1:8470", "what": "Opens the porch dashboard in a browser."},
  {"name": "metrics", "form": "burrow metrics", "what": "Opens the metrics screen: graphs of rig temperatures and disk use."},
  {"name": "helpers", "form": "burrow helpers", "what": "Opens the helpers screen: the shell scripts in scripts/."},
  {"name": "project", "form": "burrow project", "what": "Opens the project screen: make targets, config files and docs."}
 ]},
 {"path": ["rigs"], "sentence": "The rigs burrow knows, and what you can do with each.", "rows": [
  {"name": "wake attic", "form": "bin/rig-wake attic", "what": "Sends a wake packet to attic so it starts if asleep."},
  {"name": "wake cellar", "form": "bin/rig-wake cellar", "what": "Sends a wake packet to cellar so it starts if asleep."},
  {"name": "wake garden", "form": "bin/rig-wake garden", "what": "Sends a wake packet to garden so it starts if asleep."},
  {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Shows the disk use of every rig over ssh."},
  {"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10 second countdown."},
  {"name": "rig settings", "form": "config/rigs.toml", "what": "Shows each rig's name, address, MAC and stashed paths."},
  {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Shows the [[rig]] block to add a rig."}
 ]},
 {"path": ["stash"], "sentence": "The stashes: snapshots of each rig's folders, and what you can do with them.", "rows": [
  {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now, into /srv/burrow/stashes."},
  {"name": "take a stash of every rig", "form": "burrow stash --all", "what": "Takes a stash of every rig now."},
  {"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Prints the dated stashes kept for one rig."},
  {"name": "prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes the oldest stashes beyond --keep, default 8."},
  {"name": "restore a stash", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies a dated stash back onto its rig; --dry-run to try it first."},
  {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Shows how to copy a stash back with rsync if burrow is broken."},
  {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder of stashes: one per rig, one dated folder per stash."},
  {"name": "verify newest stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks the newest stash of a rig is readable and not empty."},
  {"name": "stash disk use", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use (from its name; header unread)."}
 ]},
 {"path": ["chores"], "sentence": "The chores: recurring jobs run from cron, and when each last ran.", "rows": [
  {"name": "list chores", "form": "burrow chores list", "what": "Prints the names of the registered chores."},
  {"name": "nightly stash", "form": "burrow chores run nightly-stash", "what": "Runs a stash of every rig now, the job cron runs at 02:15."},
  {"name": "disk check", "form": "burrow chores run disk-check", "what": "Warns when a rig's root disk is over 85%, the job cron runs every 6 hours."},
  {"name": "last runs", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Shows the last runs on the porch."},
  {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the output cron wrote for the chores."},
  {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the file that keeps each chore's last run."},
  {"name": "cron schedule", "form": "deploy/burrow.crontab", "what": "Shows when cron runs each chore."},
  {"name": "chores doc", "form": "docs/chores.md", "what": "Explains each chore and how to run it by hand."}
 ]},
 {"path": ["porch"], "sentence": "The porch: the dashboard for the rigs, served on port 8470.", "rows": [
  {"name": "dashboard", "form": "http://127.0.0.1:8470", "what": "Opens the dashboard: the rigs and their stashes."},
  {"name": "rig stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Shows the stashes kept for one rig."},
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Shows when each chore last ran."},
  {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns {\"ok\": true} while the porch is up."},
  {"name": "run the porch", "form": "burrow porch", "what": "Runs the porch dashboard in the foreground on the bind address in config."},
  {"name": "systemd unit", "form": "deploy/burrow-porch.service", "what": "Shows the unit that keeps the porch running as a service."},
  {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the porch's output log."}
 ]},
 {"path": ["metrics"], "sentence": "The metrics: graphs of rig temperatures and disk use, in Grafana.", "rows": [
  {"name": "Grafana graphs", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, the graphs of temperatures and disk use."},
  {"name": "pulse numbers", "form": "http://127.0.0.1:9188/metrics", "what": "Shows the raw temperature and disk numbers pulse exposes."},
  {"name": "pulse code", "form": "pulse/pulse.py", "what": "Shows the exporter that serves the numbers to Prometheus."},
  {"name": "Prometheus", "form": "docker-compose.yml (service prometheus)", "what": "Stores 30 days of the numbers; it has no port on the host."},
  {"name": "compose file", "form": "docker-compose.yml", "what": "Shows the three containers: pulse, prometheus and grafana."},
  {"name": "start containers", "form": "make up", "what": "Starts the containers in the background."},
  {"name": "stop containers", "form": "make down", "what": "Stops the containers."}
 ]},
 {"path": ["helpers"], "sentence": "The helper scripts in scripts/, each a shell script; read its top before running it.", "rows": [
  {"name": "battery-report", "form": "scripts/battery-report.sh", "what": "Reports battery state (from its name; header unread)."},
  {"name": "cert-renew", "form": "scripts/cert-renew.sh", "what": "Renews certificates (from its name; header unread)."},
  {"name": "check-disks", "form": "scripts/check-disks.sh", "what": "Shows the disk use of every rig over ssh."},
  {"name": "dns-flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache (from its name; header unread)."},
  {"name": "du-stashes", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use (from its name; header unread)."},
  {"name": "export-chores", "form": "scripts/export-chores.sh", "what": "Exports the chore records (from its name; header unread)."},
  {"name": "fan-curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan curve (from its name; header unread)."},
  {"name": "gc-docker", "form": "scripts/gc-docker.sh", "what": "Cleans up unused Docker data (from its name; header unread)."},
  {"name": "import-rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into config (from its name; header unread)."},
  {"name": "list-ports", "form": "scripts/list-ports.sh", "what": "Lists open ports (from its name; header unread)."},
  {"name": "mount-nas", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS (from its name; header unread)."},
  {"name": "net-speed", "form": "scripts/net-speed.sh", "what": "Measures network speed (from its name; header unread)."},
  {"name": "pihole-update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole (from its name; header unread)."},
  {"name": "reboot-rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10 second countdown."},
  {"name": "rotate-logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs (from its name; header unread)."},
  {"name": "seed-dev", "form": "scripts/seed-dev.sh", "what": "Seeds development data (from its name; header unread)."},
  {"name": "smart-report", "form": "scripts/smart-report.sh", "what": "Reports disk SMART health (from its name; header unread)."},
  {"name": "ssh-keys-push", "form": "scripts/ssh-keys-push.sh", "what": "Pushes ssh keys to the rigs (from its name; header unread)."},
  {"name": "sync-clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock (from its name; header unread)."},
  {"name": "temp-check", "form": "scripts/temp-check.sh", "what": "Checks rig temperatures (from its name; header unread)."},
  {"name": "unmount-nas", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS (from its name; header unread)."},
  {"name": "update-rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs (from its name; header unread)."},
  {"name": "ups-status", "form": "scripts/ups-status.sh", "what": "Shows UPS status (from its name; header unread)."},
  {"name": "verify-stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks the newest stash of a rig is readable and not empty."},
  {"name": "zfs-scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub (from its name; header unread)."}
 ]},
 {"path": ["project"], "sentence": "The project itself: its make targets, config files and docs.", "rows": [
  {"name": "make", "form": "burrow project make", "what": "Opens the make screen: the targets run in /opt/burrow."},
  {"name": "config", "form": "burrow project config", "what": "Opens the config screen: the settings files."},
  {"name": "docs", "form": "burrow project docs", "what": "Opens the docs screen: setup, rigs, chores and restoring by hand."}
 ]},
 {"path": ["project", "make"], "sentence": "The make targets, run from /opt/burrow.", "rows": [
  {"name": "install", "form": "make install", "what": "Creates the virtualenv in .venv/ and installs burrow into it."},
  {"name": "install the porch service", "form": "make install-unit", "what": "Copies the systemd unit and starts burrow-porch.service (needs sudo)."},
  {"name": "start containers", "form": "make up", "what": "Starts the metrics containers in the background."},
  {"name": "stop containers", "form": "make down", "what": "Stops the metrics containers."},
  {"name": "test", "form": "make test", "what": "Runs the pytest suite in tests/."},
  {"name": "lint", "form": "make lint", "what": "Checks burrow and tests with ruff."},
  {"name": "stash all", "form": "make stash-all", "what": "Takes a stash of every rig now."},
  {"name": "prune stashes", "form": "make prune-stashes", "what": "Removes old stashes, keeping 8."},
  {"name": "weekly prune cron", "form": "make install-prune-cron", "what": "Adds a weekly prune at 04:40 on Sunday to the crontab."},
  {"name": "clean", "form": "make clean", "what": "Deletes .venv, caches and build leftovers."}
 ]},
 {"path": ["project", "config"], "sentence": "The config files burrow reads, and the settings in them.", "rows": [
  {"name": "burrow settings", "form": "config/burrow.toml", "what": "Shows the stash folder, rsync flags, how many stashes to keep, the porch bind and the ssh user."},
  {"name": "rigs", "form": "config/rigs.toml", "what": "Lists every rig with its address, MAC and paths; add a block to add a rig."},
  {"name": "secrets example", "form": ".env.example", "what": "Shows the three values to copy into .env: ssh key, porch secret and ntfy topic."},
  {"name": "secrets", "form": ".env", "what": "Holds your ssh key, porch secret and ntfy topic; copied from .env.example."}
 ]},
 {"path": ["project", "docs"], "sentence": "The docs: setup, adding a rig, chores, restoring by hand, the readme and the license.", "rows": [
  {"name": "setup", "form": "docs/setup.md", "what": "Shows the steps to set up burrow on the rigs and the porch."},
  {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "Shows the [[rig]] block to add to config/rigs.toml."},
  {"name": "chores", "form": "docs/chores.md", "what": "Explains each chore and how to run it by hand."},
  {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Shows how to restore a stash with rsync when burrow is broken."},
  {"name": "readme", "form": "README.md", "what": "Shows the overview, install, use, chores, metrics and helpers."},
  {"name": "license", "form": "LICENSE", "what": "Shows the MIT license."}
 ]}
],
"questions": [
 "burrow stash <rig> already takes a stash, and burrow porch already runs the server, but the map wants a bare noun to show its screen. Recommendation: keep both actions as they are (the README documents them). Bare `burrow stash` shows the stash screen, and the porch group links to its URL, so the porch screen has no command yet. Confirm?",
 "The helpers screen lists 25 scripts, which is too many for one list. Recommendation: split them by job once their headers are read. Send the top of the 22 unread scripts, or confirm the split waits until later?",
 "The stash screen has 9 rows. Recommendation: keep it as one screen for now, and move restore to its own screen only if the list grows?"
]}
```

screen-decomposition, final · run 1 exit=0 seconds=179 · prompt

P1 Recall: 0.9P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 9P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
The main menu of burrow: the rigs, their stashes and chores, the porch, the metrics, the setup, the helpers and the development tools.
rigsburrow rigsOpens the rigs screen: each rig and whether it answers.
stashburrow stashOpens the stash screen: taking, pruning and checking the stashes of every rig.
choresburrow choresOpens the chores screen: the recurring jobs and when each last ran.
porchburrow porch helpOpens the porch screen: how to start the dashboard and where to open it.
metricsburrow metricsOpens the metrics screen: the containers that chart rig temperatures and disk use.
setupburrow setupOpens the setup screen: installing burrow, its settings and its services.
helpersburrow helpersOpens the helpers screen: the small shell scripts in scripts/.
developmentburrow developmentOpens the development screen: tests, lint, clean-up and the source files.
READMEREADME.mdOpens the README: what burrow is and how to use it.
rigs
The rigs burrow knows, and whether each one answers.
atticburrow rigs atticOpens attic's screen: its stashes and what you can do to the machine.
cellarburrow rigs cellarOpens cellar's screen: its stashes and what you can do to the machine.
gardenburrow rigs gardenOpens garden's screen: its stashes and what you can do to the machine.
rig listconfig/rigs.tomlOpens the list of rigs; add a [[rig]] block to add one.
add a rigdocs/adding-a-rig.mdOpens the guide to adding a rig to config/rigs.toml.
check disksscripts/check-disks.shShows disk use on every rig in config/rigs.toml.
rigs › attic
The attic rig at 192.168.1.20 and what you can do to it.
take a stashburrow stash atticTakes a stash of attic now.
stashesburrow stash list atticLists attic's stashes, one dated folder each.
restoreburrow restore attic --from YYYY-MM-DDCopies a dated stash of attic back onto attic; --dry-run shows what would change without changing anything.
verify newest stashscripts/verify-stash.sh atticChecks attic's newest stash is readable and not empty.
stashes pagehttp://127.0.0.1:8470/stashes/atticOpens attic's stashes in the porch dashboard, in a browser.
wakebin/rig-wake atticSends a wake packet to attic, using its MAC from config/rigs.toml.
rebootscripts/reboot-rig.sh 192.168.1.20Reboots attic after a 10-second countdown.
rigs › cellar
The cellar rig at 192.168.1.21 and what you can do to it.
take a stashburrow stash cellarTakes a stash of cellar now.
stashesburrow stash list cellarLists cellar's stashes, one dated folder each.
restoreburrow restore cellar --from YYYY-MM-DDCopies a dated stash of cellar back onto cellar; --dry-run shows what would change without changing anything.
verify newest stashscripts/verify-stash.sh cellarChecks cellar's newest stash is readable and not empty.
stashes pagehttp://127.0.0.1:8470/stashes/cellarOpens cellar's stashes in the porch dashboard, in a browser.
wakebin/rig-wake cellarSends a wake packet to cellar, using its MAC from config/rigs.toml.
rebootscripts/reboot-rig.sh 192.168.1.21Reboots cellar after a 10-second countdown.
rigs › garden
The garden rig at 192.168.1.22 and what you can do to it.
take a stashburrow stash gardenTakes a stash of garden now.
stashesburrow stash list gardenLists garden's stashes, one dated folder each.
restoreburrow restore garden --from YYYY-MM-DDCopies a dated stash of garden back onto garden; --dry-run shows what would change without changing anything.
verify newest stashscripts/verify-stash.sh gardenChecks garden's newest stash is readable and not empty.
stashes pagehttp://127.0.0.1:8470/stashes/gardenOpens garden's stashes in the porch dashboard, in a browser.
wakebin/rig-wake gardenSends a wake packet to garden, using its MAC from config/rigs.toml.
rebootscripts/reboot-rig.sh 192.168.1.22Reboots garden after a 10-second countdown.
stash
The stashes of every rig, and the actions that cover all of them.
stash every rigburrow stash --all (also make stash-all)Takes a stash of every rig now.
pruneburrow stash prune --keep 8 (also make prune-stashes)Removes old stashes, keeping the newest 8.
stashes folder/srv/burrow/stashesOpens the folder holding each rig's stashes, one dated folder each.
disk use of stashesscripts/du-stashes.shShows how much disk the stashes use.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the guide to copying a stash back with rsync, for when burrow is broken.
chores
The recurring jobs, when cron runs them, and when each last ran.
nightly-stashburrow chores run nightly-stashRuns a stash of every rig now; cron runs it at 02:15 each night.
disk-checkburrow chores run disk-checkRuns the disk check now, warning when a rig's root disk is over 85%; cron runs it every 6 hours.
last runsburrow chores statusShows when each chore last ran and whether it worked.
last-run record/srv/burrow/state/last-run.jsonOpens the file that records each chore's last run.
chores log/var/log/burrow/chores.logOpens the log that cron writes chore output to.
chore scheduledeploy/burrow.crontabOpens the crontab that schedules the chores.
chore registryburrow/chores.pyOpens the registry where a new chore is added.
chores pagehttp://127.0.0.1:8470/choresOpens the chores page of the porch dashboard, in a browser.
chores guidedocs/chores.mdOpens the guide to the chores.
porch
The porch, the browser dashboard for the rigs, the chores and the stashes.
start the porchburrow porchStarts the porch server on port 8470 and keeps it running in the foreground.
dashboardhttp://127.0.0.1:8470Opens the porch dashboard in a browser, listing the rigs.
health checkhttp://127.0.0.1:8470/healthzReturns ok while the porch is up.
porch log/var/log/burrow/porch.logOpens the log the porch service writes to.
metrics
The metrics containers that chart rig temperatures and disk use.
start the containersmake upStarts the containers in docker-compose.yml: pulse, Prometheus and Grafana.
stop the containersmake downStops the containers in docker-compose.yml.
Grafanahttp://127.0.0.1:3000Opens Grafana, with the graphs of rig temperatures and disk use.
pulse readingshttp://127.0.0.1:9188/metricsShows the rig readings pulse exposes to Prometheus.
compose filedocker-compose.ymlOpens the definitions of the pulse, Prometheus and Grafana containers.
pulse codepulse/pulse.pyOpens the pulse exporter; its temperature and disk readers still return 0.0.
pulse imagepulse/DockerfileOpens the recipe that builds the pulse container.
setup
Installing burrow, its settings, and the services and schedules that keep it running.
install burrowmake installCreates the virtualenv in .venv/, installs the burrow command and makes the /srv/burrow and /var/log/burrow folders.
install the porch servicemake install-unitCopies the porch service to systemd and starts it.
porch service filedeploy/burrow-porch.serviceOpens the systemd unit that keeps the porch running.
install the chore schedulecrontab deploy/burrow.crontabReplaces the crontab with the chore schedule, dropping any other lines.
install the weekly prunemake install-prune-cronAdds the weekly stash prune to the crontab, keeping its other lines.
settings fileconfig/burrow.tomlOpens the settings: stash root, keep count, chore state file, porch address and ssh user.
secrets example.env.exampleOpens the values to copy into .env: the ssh key, porch secret and ntfy topic.
setup stepsdocs/setup.mdOpens the first-time setup steps and how to check they worked.
push ssh keys to rigsscripts/ssh-keys-push.shPushes the burrow ssh key to the rigs (header not in the dump).
another settings fileburrow --config PATHPoints burrow at another settings file, instead of config/burrow.toml.
helpers
The small shell helpers in scripts/, one for each job.
battery reportscripts/battery-report.shRuns battery-report.sh (header not in the dump).
cert renewscripts/cert-renew.shRuns cert-renew.sh (header not in the dump).
DNS flushscripts/dns-flush.shRuns dns-flush.sh (header not in the dump).
export choresscripts/export-chores.shRuns export-chores.sh (header not in the dump).
fan curvescripts/fan-curve.shRuns fan-curve.sh (header not in the dump).
gc dockerscripts/gc-docker.shRuns gc-docker.sh (header not in the dump).
import rigsscripts/import-rigs.shRuns import-rigs.sh (header not in the dump).
list portsscripts/list-ports.shRuns list-ports.sh (header not in the dump).
mount NASscripts/mount-nas.shRuns mount-nas.sh (header not in the dump).
net speedscripts/net-speed.shRuns net-speed.sh (header not in the dump).
pi-hole updatescripts/pihole-update.shRuns pihole-update.sh (header not in the dump).
rotate logsscripts/rotate-logs.shRuns rotate-logs.sh (header not in the dump).
SMART reportscripts/smart-report.shRuns smart-report.sh (header not in the dump).
sync clockscripts/sync-clock.shRuns sync-clock.sh (header not in the dump).
temp checkscripts/temp-check.shRuns temp-check.sh (header not in the dump).
unmount NASscripts/unmount-nas.shRuns unmount-nas.sh (header not in the dump).
update rigsscripts/update-rigs.shRuns update-rigs.sh (header not in the dump).
UPS statusscripts/ups-status.shRuns ups-status.sh (header not in the dump).
ZFS scrubscripts/zfs-scrub.shRuns zfs-scrub.sh (header not in the dump).
development
The tools for working on burrow: tests, lint, clean-up, and the source files.
testsmake testRuns the tests in tests/ with pytest.
lintmake lintChecks burrow and its tests with ruff, reporting problems without fixing them.
cleanmake cleanDeletes .venv, build caches and egg-info, so install must run again.
seed datascripts/seed-dev.shRuns seed-dev.sh (header not in the dump).
test filestests/Opens the tests, one file per module: stash, chores and rigs.
MakefileMakefileOpens every make target, the commands behind most rows here.
package settingspyproject.tomlOpens the project's name, version, dependencies and the burrow command entry.
commandsburrow/cli.pyOpens the file that defines every burrow command.
settings loaderburrow/config.pyOpens the code that loads burrow.toml.
stash codeburrow/stash.pyOpens the code that takes, lists, prunes and restores stashes.
rig codeburrow/rigs.pyOpens the code that loads rigs and checks whether they answer and how full their disks are.
porch codeburrow/porch/app.pyOpens the porch's routes, the code behind each porch page.
porch pagesburrow/porch/templates/Opens the porch's three HTML pages: index, chores and stashes.
licenseLICENSEOpens the MIT license.
Questions
  • burrow porch currently starts the server, and the systemd unit calls it, so the porch screen cannot be the bare command. Keep burrow porch as the start command and open the porch screen with burrow porch help? Recommendation: yes; renaming it to porch run would also mean editing deploy/burrow-porch.service.
  • The 19 helpers in scripts/ are one flat screen. Split them into hardware (battery-report, fan-curve, smart-report, temp-check, ups-status, zfs-scrub), network (dns-flush, list-ports, net-speed, pihole-update, sync-clock) and upkeep (cert-renew, export-chores, gc-docker, import-rigs, mount-nas, rotate-logs, unmount-nas, update-rigs)? Recommendation: yes, after reading the 22 script headers to confirm the grouping.
  • burrow install of the chore schedule (crontab deploy/burrow.crontab) replaces the whole crontab and so drops the weekly prune line that make install-prune-cron adds. Should the chore install merge into the crontab the way install-prune-cron does? Recommendation: yes.
As phone screens

Home

The main menu of burrow: the rigs, their stashes and chores, the porch, the metrics, the setup, the helpers and the development tools.

rigsOpens the rigs screen: each rig and whether it answers.
›
stashOpens the stash screen: taking, pruning and checking the stashes of every rig.
›
choresOpens the chores screen: the recurring jobs and when each last ran.
›
porchOpens the porch screen: how to start the dashboard and where to open it.
›
metricsOpens the metrics screen: the containers that chart rig temperatures and disk use.
›
setupOpens the setup screen: installing burrow, its settings and its services.
›
helpersOpens the helpers screen: the small shell scripts in scripts/.
›
developmentOpens the development screen: tests, lint, clean-up and the source files.
›
READMEOpens the README: what burrow is and how to use it.
›
‹ Home

rigs

The rigs burrow knows, and whether each one answers.

atticOpens attic's screen: its stashes and what you can do to the machine.
›
cellarOpens cellar's screen: its stashes and what you can do to the machine.
›
gardenOpens garden's screen: its stashes and what you can do to the machine.
›
rig listOpens the list of rigs; add a [[rig]] block to add one.
›
add a rigOpens the guide to adding a rig to config/rigs.toml.
›
check disksShows disk use on every rig in config/rigs.toml.
›
‹ rigs

attic

The attic rig at 192.168.1.20 and what you can do to it.

take a stashTakes a stash of attic now.
›
stashesLists attic's stashes, one dated folder each.
›
restoreCopies a dated stash of attic back onto attic; --dry-run shows what would change without changing anything.
›
verify newest stashChecks attic's newest stash is readable and not empty.
›
stashes pageOpens attic's stashes in the porch dashboard, in a browser.
›
wakeSends a wake packet to attic, using its MAC from config/rigs.toml.
›
rebootReboots attic after a 10-second countdown.
›
‹ rigs

cellar

The cellar rig at 192.168.1.21 and what you can do to it.

take a stashTakes a stash of cellar now.
›
stashesLists cellar's stashes, one dated folder each.
›
restoreCopies a dated stash of cellar back onto cellar; --dry-run shows what would change without changing anything.
›
verify newest stashChecks cellar's newest stash is readable and not empty.
›
stashes pageOpens cellar's stashes in the porch dashboard, in a browser.
›
wakeSends a wake packet to cellar, using its MAC from config/rigs.toml.
›
rebootReboots cellar after a 10-second countdown.
›
‹ rigs

garden

The garden rig at 192.168.1.22 and what you can do to it.

take a stashTakes a stash of garden now.
›
stashesLists garden's stashes, one dated folder each.
›
restoreCopies a dated stash of garden back onto garden; --dry-run shows what would change without changing anything.
›
verify newest stashChecks garden's newest stash is readable and not empty.
›
stashes pageOpens garden's stashes in the porch dashboard, in a browser.
›
wakeSends a wake packet to garden, using its MAC from config/rigs.toml.
›
rebootReboots garden after a 10-second countdown.
›
‹ Home

stash

The stashes of every rig, and the actions that cover all of them.

stash every rigTakes a stash of every rig now.
›
pruneRemoves old stashes, keeping the newest 8.
›
stashes folderOpens the folder holding each rig's stashes, one dated folder each.
›
disk use of stashesShows how much disk the stashes use.
›
restore by handOpens the guide to copying a stash back with rsync, for when burrow is broken.
›
‹ Home

chores

The recurring jobs, when cron runs them, and when each last ran.

nightly-stashRuns a stash of every rig now; cron runs it at 02:15 each night.
›
disk-checkRuns the disk check now, warning when a rig's root disk is over 85%; cron runs it every 6 hours.
›
last runsShows when each chore last ran and whether it worked.
›
last-run recordOpens the file that records each chore's last run.
›
chores logOpens the log that cron writes chore output to.
›
chore scheduleOpens the crontab that schedules the chores.
›
chore registryOpens the registry where a new chore is added.
›
chores pageOpens the chores page of the porch dashboard, in a browser.
›
chores guideOpens the guide to the chores.
›
‹ Home

porch

The porch, the browser dashboard for the rigs, the chores and the stashes.

start the porchStarts the porch server on port 8470 and keeps it running in the foreground.
›
dashboardOpens the porch dashboard in a browser, listing the rigs.
›
health checkReturns ok while the porch is up.
›
porch logOpens the log the porch service writes to.
›
‹ Home

metrics

The metrics containers that chart rig temperatures and disk use.

start the containersStarts the containers in docker-compose.yml: pulse, Prometheus and Grafana.
›
stop the containersStops the containers in docker-compose.yml.
›
GrafanaOpens Grafana, with the graphs of rig temperatures and disk use.
›
pulse readingsShows the rig readings pulse exposes to Prometheus.
›
compose fileOpens the definitions of the pulse, Prometheus and Grafana containers.
›
pulse codeOpens the pulse exporter; its temperature and disk readers still return 0.0.
›
pulse imageOpens the recipe that builds the pulse container.
›
‹ Home

setup

Installing burrow, its settings, and the services and schedules that keep it running.

install burrowCreates the virtualenv in .venv/, installs the burrow command and makes the /srv/burrow and /var/log/burrow folders.
›
install the porch serviceCopies the porch service to systemd and starts it.
›
porch service fileOpens the systemd unit that keeps the porch running.
›
install the chore scheduleReplaces the crontab with the chore schedule, dropping any other lines.
›
install the weekly pruneAdds the weekly stash prune to the crontab, keeping its other lines.
›
settings fileOpens the settings: stash root, keep count, chore state file, porch address and ssh user.
›
secrets exampleOpens the values to copy into .env: the ssh key, porch secret and ntfy topic.
›
setup stepsOpens the first-time setup steps and how to check they worked.
›
push ssh keys to rigsPushes the burrow ssh key to the rigs (header not in the dump).
›
another settings filePoints burrow at another settings file, instead of config/burrow.toml.
›
‹ Home

helpers

The small shell helpers in scripts/, one for each job.

battery reportRuns battery-report.sh (header not in the dump).
›
cert renewRuns cert-renew.sh (header not in the dump).
›
DNS flushRuns dns-flush.sh (header not in the dump).
›
export choresRuns export-chores.sh (header not in the dump).
›
fan curveRuns fan-curve.sh (header not in the dump).
›
gc dockerRuns gc-docker.sh (header not in the dump).
›
import rigsRuns import-rigs.sh (header not in the dump).
›
list portsRuns list-ports.sh (header not in the dump).
›
mount NASRuns mount-nas.sh (header not in the dump).
›
net speedRuns net-speed.sh (header not in the dump).
›
pi-hole updateRuns pihole-update.sh (header not in the dump).
›
rotate logsRuns rotate-logs.sh (header not in the dump).
›
SMART reportRuns smart-report.sh (header not in the dump).
›
sync clockRuns sync-clock.sh (header not in the dump).
›
temp checkRuns temp-check.sh (header not in the dump).
›
unmount NASRuns unmount-nas.sh (header not in the dump).
›
update rigsRuns update-rigs.sh (header not in the dump).
›
UPS statusRuns ups-status.sh (header not in the dump).
›
ZFS scrubRuns zfs-scrub.sh (header not in the dump).
›
‹ Home

development

The tools for working on burrow: tests, lint, clean-up, and the source files.

testsRuns the tests in tests/ with pytest.
›
lintChecks burrow and its tests with ruff, reporting problems without fixing them.
›
cleanDeletes .venv, build caches and egg-info, so install must run again.
›
seed dataRuns seed-dev.sh (header not in the dump).
›
test filesOpens the tests, one file per module: stash, chores and rigs.
›
MakefileOpens every make target, the commands behind most rows here.
›
package settingsOpens the project's name, version, dependencies and the burrow command entry.
›
commandsOpens the file that defines every burrow command.
›
settings loaderOpens the code that loads burrow.toml.
›
stash codeOpens the code that takes, lists, prunes and restores stashes.
›
rig codeOpens the code that loads rigs and checks whether they answer and how full their disks are.
›
porch codeOpens the porch's routes, the code behind each porch page.
›
porch pagesOpens the porch's three HTML pages: index, chores and stashes.
›
licenseOpens the MIT license.
›
Raw answer
## Plan: burrow's map

**Scenario (reasoning from experience, not observed):** Someone runs a few home-lab machines and opens burrow when a rig stops answering, when a file needs restoring from a stash, when they want to confirm the nightly stash ran, when they want temperature graphs, or when they set up a new machine.

**Inventory (from the dump):** 3 rigs, 2 chores, 10 make targets, the `burrow` commands (`rigs`, `stash` with `list`/`prune`/`--all`, `restore`, `chores` with `list`/`run`/`status`, `porch`, and `--config`), 25 scripts, `bin/rig-wake`, 3 docker services, 2 cron/systemd files, 3 config files, 4 docs, 3 test files, and the package source. The dump has the full text of only 3 of the 25 scripts, so the other 22 get placeholder lines.

**Judgment calls:**
- **Rig screens are generated** from `config/rigs.toml`, so a new rig gets its own screen. I wrote out the three current rigs.
- **The group is named `stash`**, matching the command. The README says "stashes."
- **Per-rig actions sit on each rig's screen; all-rig actions sit on `stash`.** For example, "take a stash" appears per rig, and "stash every rig" appears on `stash`. Each line says a different thing.
- **`check-disks.sh` and the `disk-check` chore are both listed**, with different reasons: an on-demand check over ssh, versus the scheduled in-code check that warns at 85%.
- **No `docs` group.** Each guide sits with the job it serves: setup steps on `setup`, adding a rig on `rigs`, chores on `chores`, the restore-by-hand guide on `stash`.
- **The top screen has 9 rows.** That is short, but I flagged it in case you want to fold `development` in somewhere.
- **Pulse's temperature and disk readers return 0.0** (stubs). The metrics row says so, so the screen doesn't promise live data.
- **`crontab deploy/burrow.crontab` replaces the whole crontab**, which drops the weekly prune line that `make install-prune-cron` adds. The row says so; see question 3.
- **Not in the dump:** `.env` (only `.env.example` is mapped), `prometheus.yml` (the compose file mounts it from `/etc/prometheus`, so it isn't in the repo), `burrow/config.py`'s contents, and the script headers. Their lines are marked as unverified.
- **Helper and script verbs** come from the filenames where marked. Verify them against each script's header before building.

**Questions for you:**

1. **Should `burrow porch` keep starting the server?** It does today, and the systemd unit calls it, so the porch screen can't be the bare command. **Recommendation:** keep `burrow porch` as the start command and open the porch screen with `burrow porch help`. Renaming it to `porch run` would also mean editing `deploy/burrow-porch.service`.
2. **Split the 19 helpers into three screens?** **Recommendation:** yes. *hardware*: battery-report, fan-curve, smart-report, temp-check, ups-status, zfs-scrub. *network*: dns-flush, list-ports, net-speed, pihole-update, sync-clock. *upkeep*: cert-renew, export-chores, gc-docker, import-rigs, mount-nas, rotate-logs, unmount-nas, update-rigs. The grouping is from names only, so confirm it after reading the headers. The map below keeps them flat until you decide.
3. **Should installing the chore schedule merge into the crontab, like `install-prune-cron` does?** **Recommendation:** yes. Otherwise installing the schedule silently removes the weekly prune.

```json
{"screens": [
{"path": [], "sentence": "The main menu of burrow: the rigs, their stashes and chores, the porch, the metrics, the setup, the helpers and the development tools.", "rows": [
 {"name": "rigs", "form": "burrow rigs", "what": "Opens the rigs screen: each rig and whether it answers."},
 {"name": "stash", "form": "burrow stash", "what": "Opens the stash screen: taking, pruning and checking the stashes of every rig."},
 {"name": "chores", "form": "burrow chores", "what": "Opens the chores screen: the recurring jobs and when each last ran."},
 {"name": "porch", "form": "burrow porch help", "what": "Opens the porch screen: how to start the dashboard and where to open it."},
 {"name": "metrics", "form": "burrow metrics", "what": "Opens the metrics screen: the containers that chart rig temperatures and disk use."},
 {"name": "setup", "form": "burrow setup", "what": "Opens the setup screen: installing burrow, its settings and its services."},
 {"name": "helpers", "form": "burrow helpers", "what": "Opens the helpers screen: the small shell scripts in scripts/."},
 {"name": "development", "form": "burrow development", "what": "Opens the development screen: tests, lint, clean-up and the source files."},
 {"name": "README", "form": "README.md", "what": "Opens the README: what burrow is and how to use it."}
]},
{"path": ["rigs"], "sentence": "The rigs burrow knows, and whether each one answers.", "rows": [
 {"name": "attic", "form": "burrow rigs attic", "what": "Opens attic's screen: its stashes and what you can do to the machine."},
 {"name": "cellar", "form": "burrow rigs cellar", "what": "Opens cellar's screen: its stashes and what you can do to the machine."},
 {"name": "garden", "form": "burrow rigs garden", "what": "Opens garden's screen: its stashes and what you can do to the machine."},
 {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the list of rigs; add a [[rig]] block to add one."},
 {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the guide to adding a rig to config/rigs.toml."},
 {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig in config/rigs.toml."}
]},
{"path": ["rigs", "attic"], "sentence": "The attic rig at 192.168.1.20 and what you can do to it.", "rows": [
 {"name": "take a stash", "form": "burrow stash attic", "what": "Takes a stash of attic now."},
 {"name": "stashes", "form": "burrow stash list attic", "what": "Lists attic's stashes, one dated folder each."},
 {"name": "restore", "form": "burrow restore attic --from YYYY-MM-DD", "what": "Copies a dated stash of attic back onto attic; --dry-run shows what would change without changing anything."},
 {"name": "verify newest stash", "form": "scripts/verify-stash.sh attic", "what": "Checks attic's newest stash is readable and not empty."},
 {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/attic", "what": "Opens attic's stashes in the porch dashboard, in a browser."},
 {"name": "wake", "form": "bin/rig-wake attic", "what": "Sends a wake packet to attic, using its MAC from config/rigs.toml."},
 {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.20", "what": "Reboots attic after a 10-second countdown."}
]},
{"path": ["rigs", "cellar"], "sentence": "The cellar rig at 192.168.1.21 and what you can do to it.", "rows": [
 {"name": "take a stash", "form": "burrow stash cellar", "what": "Takes a stash of cellar now."},
 {"name": "stashes", "form": "burrow stash list cellar", "what": "Lists cellar's stashes, one dated folder each."},
 {"name": "restore", "form": "burrow restore cellar --from YYYY-MM-DD", "what": "Copies a dated stash of cellar back onto cellar; --dry-run shows what would change without changing anything."},
 {"name": "verify newest stash", "form": "scripts/verify-stash.sh cellar", "what": "Checks cellar's newest stash is readable and not empty."},
 {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/cellar", "what": "Opens cellar's stashes in the porch dashboard, in a browser."},
 {"name": "wake", "form": "bin/rig-wake cellar", "what": "Sends a wake packet to cellar, using its MAC from config/rigs.toml."},
 {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.21", "what": "Reboots cellar after a 10-second countdown."}
]},
{"path": ["rigs", "garden"], "sentence": "The garden rig at 192.168.1.22 and what you can do to it.", "rows": [
 {"name": "take a stash", "form": "burrow stash garden", "what": "Takes a stash of garden now."},
 {"name": "stashes", "form": "burrow stash list garden", "what": "Lists garden's stashes, one dated folder each."},
 {"name": "restore", "form": "burrow restore garden --from YYYY-MM-DD", "what": "Copies a dated stash of garden back onto garden; --dry-run shows what would change without changing anything."},
 {"name": "verify newest stash", "form": "scripts/verify-stash.sh garden", "what": "Checks garden's newest stash is readable and not empty."},
 {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/garden", "what": "Opens garden's stashes in the porch dashboard, in a browser."},
 {"name": "wake", "form": "bin/rig-wake garden", "what": "Sends a wake packet to garden, using its MAC from config/rigs.toml."},
 {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.22", "what": "Reboots garden after a 10-second countdown."}
]},
{"path": ["stash"], "sentence": "The stashes of every rig, and the actions that cover all of them.", "rows": [
 {"name": "stash every rig", "form": "burrow stash --all (also make stash-all)", "what": "Takes a stash of every rig now."},
 {"name": "prune", "form": "burrow stash prune --keep 8 (also make prune-stashes)", "what": "Removes old stashes, keeping the newest 8."},
 {"name": "stashes folder", "form": "/srv/burrow/stashes", "what": "Opens the folder holding each rig's stashes, one dated folder each."},
 {"name": "disk use of stashes", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use."},
 {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the guide to copying a stash back with rsync, for when burrow is broken."}
]},
{"path": ["chores"], "sentence": "The recurring jobs, when cron runs them, and when each last ran.", "rows": [
 {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Runs a stash of every rig now; cron runs it at 02:15 each night."},
 {"name": "disk-check", "form": "burrow chores run disk-check", "what": "Runs the disk check now, warning when a rig's root disk is over 85%; cron runs it every 6 hours."},
 {"name": "last runs", "form": "burrow chores status", "what": "Shows when each chore last ran and whether it worked."},
 {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the file that records each chore's last run."},
 {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the log that cron writes chore output to."},
 {"name": "chore schedule", "form": "deploy/burrow.crontab", "what": "Opens the crontab that schedules the chores."},
 {"name": "chore registry", "form": "burrow/chores.py", "what": "Opens the registry where a new chore is added."},
 {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page of the porch dashboard, in a browser."},
 {"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide to the chores."}
]},
{"path": ["porch"], "sentence": "The porch, the browser dashboard for the rigs, the chores and the stashes.", "rows": [
 {"name": "start the porch", "form": "burrow porch", "what": "Starts the porch server on port 8470 and keeps it running in the foreground."},
 {"name": "dashboard", "form": "http://127.0.0.1:8470", "what": "Opens the porch dashboard in a browser, listing the rigs."},
 {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns ok while the porch is up."},
 {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the log the porch service writes to."}
]},
{"path": ["metrics"], "sentence": "The metrics containers that chart rig temperatures and disk use.", "rows": [
 {"name": "start the containers", "form": "make up", "what": "Starts the containers in docker-compose.yml: pulse, Prometheus and Grafana."},
 {"name": "stop the containers", "form": "make down", "what": "Stops the containers in docker-compose.yml."},
 {"name": "Grafana", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, with the graphs of rig temperatures and disk use."},
 {"name": "pulse readings", "form": "http://127.0.0.1:9188/metrics", "what": "Shows the rig readings pulse exposes to Prometheus."},
 {"name": "compose file", "form": "docker-compose.yml", "what": "Opens the definitions of the pulse, Prometheus and Grafana containers."},
 {"name": "pulse code", "form": "pulse/pulse.py", "what": "Opens the pulse exporter; its temperature and disk readers still return 0.0."},
 {"name": "pulse image", "form": "pulse/Dockerfile", "what": "Opens the recipe that builds the pulse container."}
]},
{"path": ["setup"], "sentence": "Installing burrow, its settings, and the services and schedules that keep it running.", "rows": [
 {"name": "install burrow", "form": "make install", "what": "Creates the virtualenv in .venv/, installs the burrow command and makes the /srv/burrow and /var/log/burrow folders."},
 {"name": "install the porch service", "form": "make install-unit", "what": "Copies the porch service to systemd and starts it."},
 {"name": "porch service file", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that keeps the porch running."},
 {"name": "install the chore schedule", "form": "crontab deploy/burrow.crontab", "what": "Replaces the crontab with the chore schedule, dropping any other lines."},
 {"name": "install the weekly prune", "form": "make install-prune-cron", "what": "Adds the weekly stash prune to the crontab, keeping its other lines."},
 {"name": "settings file", "form": "config/burrow.toml", "what": "Opens the settings: stash root, keep count, chore state file, porch address and ssh user."},
 {"name": "secrets example", "form": ".env.example", "what": "Opens the values to copy into .env: the ssh key, porch secret and ntfy topic."},
 {"name": "setup steps", "form": "docs/setup.md", "what": "Opens the first-time setup steps and how to check they worked."},
 {"name": "push ssh keys to rigs", "form": "scripts/ssh-keys-push.sh", "what": "Pushes the burrow ssh key to the rigs (header not in the dump)."},
 {"name": "another settings file", "form": "burrow --config PATH", "what": "Points burrow at another settings file, instead of config/burrow.toml."}
]},
{"path": ["helpers"], "sentence": "The small shell helpers in scripts/, one for each job.", "rows": [
 {"name": "battery report", "form": "scripts/battery-report.sh", "what": "Runs battery-report.sh (header not in the dump)."},
 {"name": "cert renew", "form": "scripts/cert-renew.sh", "what": "Runs cert-renew.sh (header not in the dump)."},
 {"name": "DNS flush", "form": "scripts/dns-flush.sh", "what": "Runs dns-flush.sh (header not in the dump)."},
 {"name": "export chores", "form": "scripts/export-chores.sh", "what": "Runs export-chores.sh (header not in the dump)."},
 {"name": "fan curve", "form": "scripts/fan-curve.sh", "what": "Runs fan-curve.sh (header not in the dump)."},
 {"name": "gc docker", "form": "scripts/gc-docker.sh", "what": "Runs gc-docker.sh (header not in the dump)."},
 {"name": "import rigs", "form": "scripts/import-rigs.sh", "what": "Runs import-rigs.sh (header not in the dump)."},
 {"name": "list ports", "form": "scripts/list-ports.sh", "what": "Runs list-ports.sh (header not in the dump)."},
 {"name": "mount NAS", "form": "scripts/mount-nas.sh", "what": "Runs mount-nas.sh (header not in the dump)."},
 {"name": "net speed", "form": "scripts/net-speed.sh", "what": "Runs net-speed.sh (header not in the dump)."},
 {"name": "pi-hole update", "form": "scripts/pihole-update.sh", "what": "Runs pihole-update.sh (header not in the dump)."},
 {"name": "rotate logs", "form": "scripts/rotate-logs.sh", "what": "Runs rotate-logs.sh (header not in the dump)."},
 {"name": "SMART report", "form": "scripts/smart-report.sh", "what": "Runs smart-report.sh (header not in the dump)."},
 {"name": "sync clock", "form": "scripts/sync-clock.sh", "what": "Runs sync-clock.sh (header not in the dump)."},
 {"name": "temp check", "form": "scripts/temp-check.sh", "what": "Runs temp-check.sh (header not in the dump)."},
 {"name": "unmount NAS", "form": "scripts/unmount-nas.sh", "what": "Runs unmount-nas.sh (header not in the dump)."},
 {"name": "update rigs", "form": "scripts/update-rigs.sh", "what": "Runs update-rigs.sh (header not in the dump)."},
 {"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Runs ups-status.sh (header not in the dump)."},
 {"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Runs zfs-scrub.sh (header not in the dump)."}
]},
{"path": ["development"], "sentence": "The tools for working on burrow: tests, lint, clean-up, and the source files.", "rows": [
 {"name": "tests", "form": "make test", "what": "Runs the tests in tests/ with pytest."},
 {"name": "lint", "form": "make lint", "what": "Checks burrow and its tests with ruff, reporting problems without fixing them."},
 {"name": "clean", "form": "make clean", "what": "Deletes .venv, build caches and egg-info, so install must run again."},
 {"name": "seed data", "form": "scripts/seed-dev.sh", "what": "Runs seed-dev.sh (header not in the dump)."},
 {"name": "test files", "form": "tests/", "what": "Opens the tests, one file per module: stash, chores and rigs."},
 {"name": "Makefile", "form": "Makefile", "what": "Opens every make target, the commands behind most rows here."},
 {"name": "package settings", "form": "pyproject.toml", "what": "Opens the project's name, version, dependencies and the burrow command entry."},
 {"name": "commands", "form": "burrow/cli.py", "what": "Opens the file that defines every burrow command."},
 {"name": "settings loader", "form": "burrow/config.py", "what": "Opens the code that loads burrow.toml."},
 {"name": "stash code", "form": "burrow/stash.py", "what": "Opens the code that takes, lists, prunes and restores stashes."},
 {"name": "rig code", "form": "burrow/rigs.py", "what": "Opens the code that loads rigs and checks whether they answer and how full their disks are."},
 {"name": "porch code", "form": "burrow/porch/app.py", "what": "Opens the porch's routes, the code behind each porch page."},
 {"name": "porch pages", "form": "burrow/porch/templates/", "what": "Opens the porch's three HTML pages: index, chores and stashes."},
 {"name": "license", "form": "LICENSE", "what": "Opens the MIT license."}
]}
],
"questions": [
 "burrow porch currently starts the server, and the systemd unit calls it, so the porch screen cannot be the bare command. Keep burrow porch as the start command and open the porch screen with burrow porch help? Recommendation: yes; renaming it to porch run would also mean editing deploy/burrow-porch.service.",
 "The 19 helpers in scripts/ are one flat screen. Split them into hardware (battery-report, fan-curve, smart-report, temp-check, ups-status, zfs-scrub), network (dns-flush, list-ports, net-speed, pihole-update, sync-clock) and upkeep (cert-renew, export-chores, gc-docker, import-rigs, mount-nas, rotate-logs, unmount-nas, update-rigs)? Recommendation: yes, after reading the 22 script headers to confirm the grouping.",
 "burrow install of the chore schedule (crontab deploy/burrow.crontab) replaces the whole crontab and so drops the weekly prune line that make install-prune-cron adds. Should the chore install merge into the crontab the way install-prune-cron does? Recommendation: yes."
]}
```

No skill · run 2 exit=0 seconds=64 · prompt

P1 Recall: 0.317P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.65P5 Short top: 9P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
The top screen of the burrow command: the commands for looking after the home lab rigs, plus the other places you reach from there. Global option --config picks a settings file other than config/burrow.toml.
rigsburrow rigsList each rig and whether it answers.
stashburrow stashTake a stash of a rig, list the stashes kept for it, or prune old ones. Opens the stash screen.
restoreburrow restore <rig> --from YYYY-MM-DD [--dry-run]Copy a dated stash back onto its rig. --from is required; --dry-run shows what would happen without copying.
choresburrow choresRecurring jobs: list them, run one by hand, or see when each last ran. Opens the chores screen.
porchburrow porch [--bind ADDR:PORT]Run the web dashboard. Default bind is 0.0.0.0:8470. Opens the porch screen.
makemake <target>Install, start, test and maintain burrow from the repo. Opens the make screen.
scriptsscripts/ and bin/rig-wakeSmall shell helpers used now and then. Opens the scripts screen.
metricsmake up, then http://127.0.0.1:3000Graphs of rig temperatures and disk use. Opens the metrics screen.
configconfig/Where settings, rigs and secrets live. Opens the config screen.
stash
Take stashes of rigs and look after the ones already kept. A bare rig name takes a stash of that rig; --all takes one of every rig.
take one rigburrow stash <rig>Take a stash of one rig now and print where it was written.
take every rigburrow stash --allTake a stash of every rig. make stash-all does the same.
listburrow stash list <rig>Show the stashes already kept for one rig, one per line.
pruneburrow stash prune [--keep N]Delete old stashes, keeping the newest N (default 8). make prune-stashes does this with 8.
chores
Recurring jobs. Two ship with burrow: nightly-stash at 02:15 (a stash of every rig) and disk-check every six hours (warns above 85 percent).
listburrow chores listName every chore that can be run.
runburrow chores run <name>Run one chore by hand and record the result.
statusburrow chores statusShow when each chore last finished and whether it worked. The same record is on the porch chores page.
porch
The web dashboard, served on the LAN. These pages open in a browser; the CLI only starts the server.
dashboardhttp://<host>:8470/The rigs and whether they answer.
chores pagehttp://<host>:8470/choresThe last run of each chore and its result.
stashes for a righttp://<host>:8470/stashes/<rig>The stashes kept for one rig.
health checkhttp://<host>:8470/healthzReturns ok true when the porch is up.
make
Make targets run from the repo root. Installing the unit and the prune cron change the system, so they need sudo or an existing crontab.
installmake installCreate the virtualenv in /opt/burrow/.venv, install burrow, and create the stash, state and log folders.
install-unitmake install-unitInstall and start the porch systemd service. Uses sudo.
upmake upStart the metrics containers in docker-compose.yml.
downmake downStop the metrics containers.
testmake testRun the test suite with pytest.
lintmake lintCheck burrow and tests with ruff.
stash-allmake stash-allTake a stash of every rig.
prune-stashesmake prune-stashesKeep the newest 8 stashes of each rig.
install-prune-cronmake install-prune-cronAdd a weekly Sunday 04:40 prune to your crontab.
cleanmake cleanRemove the virtualenv, caches and build output.
scripts
Small shell helpers. Read the top comment of each before running it. The first four are listed here; the other 22 in scripts/ are not described in the dump.
wake a rigbin/rig-wake <rig>Send a wake packet to a sleeping rig, using its MAC from config/rigs.toml.
check disksscripts/check-disks.shShow disk use on every rig over ssh.
verify stashscripts/verify-stash.sh <rig>Check the newest stash of a rig is readable and not empty.
reboot a rigscripts/reboot-rig.sh <address>Reboot one rig after a 10 second countdown.
other helpersscripts/*.shThe remaining helpers, such as battery-report, cert-renew, smart-report and zfs-scrub. Names only until their headers are read.
metrics
Metrics for graphs. The pulse service exposes rig temperature and disk use for Prometheus, which keeps 30 days; Grafana draws the graphs. In the dump, pulse's temperature and disk readers return 0.0, so no real values appear yet.
grafanahttp://127.0.0.1:3000Graphs of rig temperatures and disk use. Anonymous access is on.
pulse metricshttp://127.0.0.1:9188/metricsThe raw gauges that Prometheus scrapes: burrow_rig_temp_celsius and burrow_rig_disk_used_ratio.
config
The files that hold settings, rigs and secrets. Each is read at start-up or on each run, so a change takes effect the next time burrow runs.
settingsconfig/burrow.tomlStash location and rsync flags, chores state file, porch bind and title, and the ssh user and key variable.
rigsconfig/rigs.tomlThe rigs: name, address, MAC and paths. Add one per docs/adding-a-rig.md.
secrets.env (copy of .env.example)BURROW_SSH_KEY, BURROW_PORCH_SECRET and BURROW_NTFY_TOPIC.
Questions
  • Does 'burrow stash <rig>' and its subcommands parse as written? The rig argument on the stash group is optional, so 'burrow stash list attic' and 'burrow stash prune' probably take 'list' or 'prune' as a rig name instead of a subcommand. I could not run it to confirm. Recommendation: run both to check. If they fail, make the take action an explicit subcommand (burrow stash take <rig> and burrow stash take --all) and keep the bare form as an alias. The map shows today's forms until you decide.
  • Should make targets, scripts, metrics and config appear in burrow's own help, or only in the docs? Recommendation: burrow --help lists only the burrow commands. The other screens stay in the map and the README, with a see-also line from the top screen, so nothing is lost.
  • Should the 22 unlisted scripts be named individually? Recommendation: yes, but only after reading each file's top comment, so every line in the help is true. Until then the scripts screen names them as a group.
  • Should the metrics screen promise values? In the dump, pulse's read_temp and read_disk return 0.0. Recommendation: mark the metrics screen as not yet working, or hide it, until both readers are filled in.
  • Is rig-wake a burrow command or a helper? It is a shell script outside the burrow CLI. Recommendation: keep it under scripts. If you wake rigs often, add a burrow wake <rig> command that wraps it.
  • Is the porch safe to leave open on the LAN? The default bind is 0.0.0.0:8470, and BURROW_PORCH_SECRET does not appear in the code shown, so nothing checks it. Recommendation: say on the porch screen that it is open to the LAN, and decide whether to add a check using the secret or to bind to 127.0.0.1 by default. The choice is yours.
As phone screens

Home

The top screen of the burrow command: the commands for looking after the home lab rigs, plus the other places you reach from there. Global option --config picks a settings file other than config/burrow.toml.

rigsList each rig and whether it answers.
›
stashTake a stash of a rig, list the stashes kept for it, or prune old ones. Opens the stash screen.
›
restoreCopy a dated stash back onto its rig. --from is required; --dry-run shows what would happen without copying.
›
choresRecurring jobs: list them, run one by hand, or see when each last ran. Opens the chores screen.
›
porchRun the web dashboard. Default bind is 0.0.0.0:8470. Opens the porch screen.
›
makeInstall, start, test and maintain burrow from the repo. Opens the make screen.
›
scriptsSmall shell helpers used now and then. Opens the scripts screen.
›
metricsGraphs of rig temperatures and disk use. Opens the metrics screen.
›
configWhere settings, rigs and secrets live. Opens the config screen.
›
‹ Home

stash

Take stashes of rigs and look after the ones already kept. A bare rig name takes a stash of that rig; --all takes one of every rig.

take one rigTake a stash of one rig now and print where it was written.
›
take every rigTake a stash of every rig. make stash-all does the same.
›
listShow the stashes already kept for one rig, one per line.
›
pruneDelete old stashes, keeping the newest N (default 8). make prune-stashes does this with 8.
›
‹ Home

chores

Recurring jobs. Two ship with burrow: nightly-stash at 02:15 (a stash of every rig) and disk-check every six hours (warns above 85 percent).

listName every chore that can be run.
›
runRun one chore by hand and record the result.
›
statusShow when each chore last finished and whether it worked. The same record is on the porch chores page.
›
‹ Home

porch

The web dashboard, served on the LAN. These pages open in a browser; the CLI only starts the server.

dashboardThe rigs and whether they answer.
›
chores pageThe last run of each chore and its result.
›
stashes for a rigThe stashes kept for one rig.
›
health checkReturns ok true when the porch is up.
›
‹ Home

make

Make targets run from the repo root. Installing the unit and the prune cron change the system, so they need sudo or an existing crontab.

installCreate the virtualenv in /opt/burrow/.venv, install burrow, and create the stash, state and log folders.
›
install-unitInstall and start the porch systemd service. Uses sudo.
›
upStart the metrics containers in docker-compose.yml.
›
downStop the metrics containers.
›
testRun the test suite with pytest.
›
lintCheck burrow and tests with ruff.
›
stash-allTake a stash of every rig.
›
prune-stashesKeep the newest 8 stashes of each rig.
›
install-prune-cronAdd a weekly Sunday 04:40 prune to your crontab.
›
cleanRemove the virtualenv, caches and build output.
›
‹ Home

scripts

Small shell helpers. Read the top comment of each before running it. The first four are listed here; the other 22 in scripts/ are not described in the dump.

wake a rigSend a wake packet to a sleeping rig, using its MAC from config/rigs.toml.
›
check disksShow disk use on every rig over ssh.
›
verify stashCheck the newest stash of a rig is readable and not empty.
›
reboot a rigReboot one rig after a 10 second countdown.
›
other helpersThe remaining helpers, such as battery-report, cert-renew, smart-report and zfs-scrub. Names only until their headers are read.
›
‹ Home

metrics

Metrics for graphs. The pulse service exposes rig temperature and disk use for Prometheus, which keeps 30 days; Grafana draws the graphs. In the dump, pulse's temperature and disk readers return 0.0, so no real values appear yet.

grafanaGraphs of rig temperatures and disk use. Anonymous access is on.
›
pulse metricsThe raw gauges that Prometheus scrapes: burrow_rig_temp_celsius and burrow_rig_disk_used_ratio.
›
‹ Home

config

The files that hold settings, rigs and secrets. Each is read at start-up or on each run, so a change takes effect the next time burrow runs.

settingsStash location and rsync flags, chores state file, porch bind and title, and the ssh user and key variable.
›
rigsThe rigs: name, address, MAC and paths. Add one per docs/adding-a-rig.md.
›
secretsBURROW_SSH_KEY, BURROW_PORCH_SECRET and BURROW_NTFY_TOPIC.
›
Raw answer
I planned the map from the dump only and didn't run anything. The burrow screens follow the click command tree, and the porch, make, scripts, metrics and config screens cover the other places you'd reach. Two things to check before building: the `stash` group may not parse its subcommands (question 1), and the metrics readers are stubs (question 4).

```json
{"screens": [
{"path": [], "sentence": "The top screen of the burrow command: the commands for looking after the home lab rigs, plus the other places you reach from there. Global option --config picks a settings file other than config/burrow.toml.", "rows": [
{"name": "rigs", "form": "burrow rigs", "what": "List each rig and whether it answers."},
{"name": "stash", "form": "burrow stash", "what": "Take a stash of a rig, list the stashes kept for it, or prune old ones. Opens the stash screen."},
{"name": "restore", "form": "burrow restore <rig> --from YYYY-MM-DD [--dry-run]", "what": "Copy a dated stash back onto its rig. --from is required; --dry-run shows what would happen without copying."},
{"name": "chores", "form": "burrow chores", "what": "Recurring jobs: list them, run one by hand, or see when each last ran. Opens the chores screen."},
{"name": "porch", "form": "burrow porch [--bind ADDR:PORT]", "what": "Run the web dashboard. Default bind is 0.0.0.0:8470. Opens the porch screen."},
{"name": "make", "form": "make <target>", "what": "Install, start, test and maintain burrow from the repo. Opens the make screen."},
{"name": "scripts", "form": "scripts/ and bin/rig-wake", "what": "Small shell helpers used now and then. Opens the scripts screen."},
{"name": "metrics", "form": "make up, then http://127.0.0.1:3000", "what": "Graphs of rig temperatures and disk use. Opens the metrics screen."},
{"name": "config", "form": "config/", "what": "Where settings, rigs and secrets live. Opens the config screen."}
]},
{"path": ["stash"], "sentence": "Take stashes of rigs and look after the ones already kept. A bare rig name takes a stash of that rig; --all takes one of every rig.", "rows": [
{"name": "take one rig", "form": "burrow stash <rig>", "what": "Take a stash of one rig now and print where it was written."},
{"name": "take every rig", "form": "burrow stash --all", "what": "Take a stash of every rig. make stash-all does the same."},
{"name": "list", "form": "burrow stash list <rig>", "what": "Show the stashes already kept for one rig, one per line."},
{"name": "prune", "form": "burrow stash prune [--keep N]", "what": "Delete old stashes, keeping the newest N (default 8). make prune-stashes does this with 8."}
]},
{"path": ["chores"], "sentence": "Recurring jobs. Two ship with burrow: nightly-stash at 02:15 (a stash of every rig) and disk-check every six hours (warns above 85 percent).", "rows": [
{"name": "list", "form": "burrow chores list", "what": "Name every chore that can be run."},
{"name": "run", "form": "burrow chores run <name>", "what": "Run one chore by hand and record the result."},
{"name": "status", "form": "burrow chores status", "what": "Show when each chore last finished and whether it worked. The same record is on the porch chores page."}
]},
{"path": ["porch"], "sentence": "The web dashboard, served on the LAN. These pages open in a browser; the CLI only starts the server.", "rows": [
{"name": "dashboard", "form": "http://<host>:8470/", "what": "The rigs and whether they answer."},
{"name": "chores page", "form": "http://<host>:8470/chores", "what": "The last run of each chore and its result."},
{"name": "stashes for a rig", "form": "http://<host>:8470/stashes/<rig>", "what": "The stashes kept for one rig."},
{"name": "health check", "form": "http://<host>:8470/healthz", "what": "Returns ok true when the porch is up."}
]},
{"path": ["make"], "sentence": "Make targets run from the repo root. Installing the unit and the prune cron change the system, so they need sudo or an existing crontab.", "rows": [
{"name": "install", "form": "make install", "what": "Create the virtualenv in /opt/burrow/.venv, install burrow, and create the stash, state and log folders."},
{"name": "install-unit", "form": "make install-unit", "what": "Install and start the porch systemd service. Uses sudo."},
{"name": "up", "form": "make up", "what": "Start the metrics containers in docker-compose.yml."},
{"name": "down", "form": "make down", "what": "Stop the metrics containers."},
{"name": "test", "form": "make test", "what": "Run the test suite with pytest."},
{"name": "lint", "form": "make lint", "what": "Check burrow and tests with ruff."},
{"name": "stash-all", "form": "make stash-all", "what": "Take a stash of every rig."},
{"name": "prune-stashes", "form": "make prune-stashes", "what": "Keep the newest 8 stashes of each rig."},
{"name": "install-prune-cron", "form": "make install-prune-cron", "what": "Add a weekly Sunday 04:40 prune to your crontab."},
{"name": "clean", "form": "make clean", "what": "Remove the virtualenv, caches and build output."}
]},
{"path": ["scripts"], "sentence": "Small shell helpers. Read the top comment of each before running it. The first four are listed here; the other 22 in scripts/ are not described in the dump.", "rows": [
{"name": "wake a rig", "form": "bin/rig-wake <rig>", "what": "Send a wake packet to a sleeping rig, using its MAC from config/rigs.toml."},
{"name": "check disks", "form": "scripts/check-disks.sh", "what": "Show disk use on every rig over ssh."},
{"name": "verify stash", "form": "scripts/verify-stash.sh <rig>", "what": "Check the newest stash of a rig is readable and not empty."},
{"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboot one rig after a 10 second countdown."},
{"name": "other helpers", "form": "scripts/*.sh", "what": "The remaining helpers, such as battery-report, cert-renew, smart-report and zfs-scrub. Names only until their headers are read."}
]},
{"path": ["metrics"], "sentence": "Metrics for graphs. The pulse service exposes rig temperature and disk use for Prometheus, which keeps 30 days; Grafana draws the graphs. In the dump, pulse's temperature and disk readers return 0.0, so no real values appear yet.", "rows": [
{"name": "grafana", "form": "http://127.0.0.1:3000", "what": "Graphs of rig temperatures and disk use. Anonymous access is on."},
{"name": "pulse metrics", "form": "http://127.0.0.1:9188/metrics", "what": "The raw gauges that Prometheus scrapes: burrow_rig_temp_celsius and burrow_rig_disk_used_ratio."}
]},
{"path": ["config"], "sentence": "The files that hold settings, rigs and secrets. Each is read at start-up or on each run, so a change takes effect the next time burrow runs.", "rows": [
{"name": "settings", "form": "config/burrow.toml", "what": "Stash location and rsync flags, chores state file, porch bind and title, and the ssh user and key variable."},
{"name": "rigs", "form": "config/rigs.toml", "what": "The rigs: name, address, MAC and paths. Add one per docs/adding-a-rig.md."},
{"name": "secrets", "form": ".env (copy of .env.example)", "what": "BURROW_SSH_KEY, BURROW_PORCH_SECRET and BURROW_NTFY_TOPIC."}
]}
],
"questions": [
"Does 'burrow stash <rig>' and its subcommands parse as written? The rig argument on the stash group is optional, so 'burrow stash list attic' and 'burrow stash prune' probably take 'list' or 'prune' as a rig name instead of a subcommand. I could not run it to confirm. Recommendation: run both to check. If they fail, make the take action an explicit subcommand (burrow stash take <rig> and burrow stash take --all) and keep the bare form as an alias. The map shows today's forms until you decide.",
"Should make targets, scripts, metrics and config appear in burrow's own help, or only in the docs? Recommendation: burrow --help lists only the burrow commands. The other screens stay in the map and the README, with a see-also line from the top screen, so nothing is lost.",
"Should the 22 unlisted scripts be named individually? Recommendation: yes, but only after reading each file's top comment, so every line in the help is true. Until then the scripts screen names them as a group.",
"Should the metrics screen promise values? In the dump, pulse's read_temp and read_disk return 0.0. Recommendation: mark the metrics screen as not yet working, or hide it, until both readers are filled in.",
"Is rig-wake a burrow command or a helper? It is a shell script outside the burrow CLI. Recommendation: keep it under scripts. If you wake rigs often, add a burrow wake <rig> command that wraps it.",
"Is the porch safe to leave open on the LAN? The default bind is 0.0.0.0:8470, and BURROW_PORCH_SECRET does not appear in the code shown, so nothing checks it. Recommendation: say on the porch screen that it is open to the LAN, and decide whether to add a check using the secret or to bind to 127.0.0.1 by default. The choice is yours."
],
"sentences_note": "Each screen sentence is in plain words; technical forms are in the rows."}
```

Today's skills · run 2 exit=0 seconds=142 · prompt

P1 Recall: 0.867P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 6P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 2
As terminal help
burrow looks after the machines in your home lab: the rigs, their stashes, the chores, the porch and the metrics, plus the project itself.
Rigsburrow rigsPrints the rigs screen: every rig, its address, and whether it answers.
Stashesburrow stashPrints the stash screen: the stashes kept for each rig, and the cleanup of old ones.
Choresburrow choresPrints the chores screen: the recurring jobs and when each last ran.
Porchburrow porchPrints the porch screen: the dashboard's address and whether it is running.
Metricsburrow metricsPrints the metrics screen: the graphs and the numbers behind them.
Projectburrow projectPrints the project screen: install, settings, helper scripts, docs and development.
rigs
Every rig burrow knows, and whether each one answers.
atticburrow rigs atticPrints the attic screen: its address, the folders stashed from it, and its wake and reboot commands.
cellarburrow rigs cellarPrints the cellar screen: its address, the folders stashed from it, and its wake and reboot commands.
gardenburrow rigs gardenPrints the garden screen: its address, the folders stashed from it, and its wake and reboot commands.
Rig listconfig/rigs.tomlOpens the rig list, where each rig's address, MAC and folders are set.
Disk use on every rigscripts/check-disks.shOpens the script that shows disk use on every rig.
rigs › attic
The attic rig: where it is on the LAN, and what burrow keeps from it.
Address192.168.1.20Shows the address burrow uses to reach attic over ssh.
Folders stashed/etc, /home, /var/lib/docker/volumes (on attic)Lists the folders on attic that each stash copies.
Stashesburrow stash atticPrints the attic stash screen: every stash taken from attic, newest last.
Wakebin/rig-wake atticRuns the wake script, which sends a magic packet to wake attic from sleep.
Rebootscripts/reboot-rig.sh 192.168.1.20Runs the reboot script, which reboots attic after a 10 second countdown.
rigs › cellar
The cellar rig: where it is on the LAN, and what burrow keeps from it.
Address192.168.1.21Shows the address burrow uses to reach cellar over ssh.
Folders stashed/etc, /tank/photos (on cellar)Lists the folders on cellar that each stash copies.
Stashesburrow stash cellarPrints the cellar stash screen: every stash taken from cellar, newest last.
Wakebin/rig-wake cellarRuns the wake script, which sends a magic packet to wake cellar from sleep.
Rebootscripts/reboot-rig.sh 192.168.1.21Runs the reboot script, which reboots cellar after a 10 second countdown.
rigs › garden
The garden rig: where it is on the LAN, and what burrow keeps from it.
Address192.168.1.22Shows the address burrow uses to reach garden over ssh.
Folders stashed/etc, /opt/homeassistant (on garden)Lists the folders on garden that each stash copies.
Stashesburrow stash gardenPrints the garden stash screen: every stash taken from garden, newest last.
Wakebin/rig-wake gardenRuns the wake script, which sends a magic packet to wake garden from sleep.
Rebootscripts/reboot-rig.sh 192.168.1.22Runs the reboot script, which reboots garden after a 10 second countdown.
stash
The stashes: snapshots of each rig's important folders, pulled over rsync, and the cleanup of old ones.
atticburrow stash atticPrints the attic stash screen: its stashes, and the commands to take, restore or check one.
cellarburrow stash cellarPrints the cellar stash screen: its stashes, and the commands to take, restore or check one.
gardenburrow stash gardenPrints the garden stash screen: its stashes, and the commands to take, restore or check one.
Every rigburrow stash all takeTakes a stash of every rig at once, the same as make stash-all.
Pruneburrow stash pruneRemoves the oldest stashes, keeping the newest N (set with --keep, default 8).
Stash folder/srv/burrow/stashesOpens the folder that holds every stash, one folder per rig.
stash › attic
The attic stashes: one dated folder per stash taken from attic.
Each stash/srv/burrow/stashes/attic/<YYYY-MM-DD>Opens that stash, a copy of attic's folders on that date; one row for each stash that exists.
Take a stash nowburrow stash attic takeTakes a new stash of attic right now.
Restore a stashburrow stash attic restore --from YYYY-MM-DDCopies a dated stash back onto attic; add --dry-run to see what would change first.
Check the newest stashscripts/verify-stash.sh atticRuns the check that attic's newest stash is readable and not empty.
stash › cellar
The cellar stashes: one dated folder per stash taken from cellar.
Each stash/srv/burrow/stashes/cellar/<YYYY-MM-DD>Opens that stash, a copy of cellar's folders on that date; one row for each stash that exists.
Take a stash nowburrow stash cellar takeTakes a new stash of cellar right now.
Restore a stashburrow stash cellar restore --from YYYY-MM-DDCopies a dated stash back onto cellar; add --dry-run to see what would change first.
Check the newest stashscripts/verify-stash.sh cellarRuns the check that cellar's newest stash is readable and not empty.
stash › garden
The garden stashes: one dated folder per stash taken from garden.
Each stash/srv/burrow/stashes/garden/<YYYY-MM-DD>Opens that stash, a copy of garden's folders on that date; one row for each stash that exists.
Take a stash nowburrow stash garden takeTakes a new stash of garden right now.
Restore a stashburrow stash garden restore --from YYYY-MM-DDCopies a dated stash back onto garden; add --dry-run to see what would change first.
Check the newest stashscripts/verify-stash.sh gardenRuns the check that garden's newest stash is readable and not empty.
chores
The recurring jobs burrow runs for itself, and when each last ran.
nightly-stashburrow chores nightly-stashPrints the nightly-stash screen: a stash of every rig, every night at 02:15.
disk-checkburrow chores disk-checkPrints the disk-check screen: warns when a rig's root disk is over 85%, every 6 hours.
Scheduledeploy/burrow.crontabOpens the crontab that starts both chores on time.
Chore log/var/log/burrow/chores.logOpens the log of every chore run, with its output and any errors.
Last runs/srv/burrow/state/last-run.jsonOpens the record of when each chore last ran and whether it worked.
Chore codeburrow/chores.pyOpens the file that defines the chores.
Chores pagehttp://127.0.0.1:8470/choresOpens the chores page on the porch, the same last-run list in a browser.
chores › nightly-stash
The nightly-stash chore: a stash of every rig, run every night at 02:15 by cron.
Run nowburrow chores nightly-stash runRuns the nightly stash now, outside its schedule.
Last runsburrow chores statusPrints when each chore last ran and whether it worked.
Codeburrow/chores.py (nightly_stash)Opens the file where the nightly-stash chore is defined.
Scheduledeploy/burrow.crontabOpens the crontab line that starts it at 02:15.
chores › disk-check
The disk-check chore: warns when a rig's root disk is over 85%, checked every 6 hours by cron.
Run nowburrow chores disk-check runRuns the disk check now, outside its schedule.
Last runsburrow chores statusPrints when each chore last ran and whether it worked.
Codeburrow/chores.py (disk_check)Opens the file where the disk-check chore is defined.
Scheduledeploy/burrow.crontabOpens the crontab line that starts it every 6 hours.
porch
The porch: the dashboard for the rigs, served by burrow and opened in a browser.
Open the porchhttp://127.0.0.1:8470Opens the porch dashboard in this machine's browser; from the LAN, use the rig's IP instead.
Start the porchburrow porch startStarts the porch server on 0.0.0.0:8470, the dashboard other machines reach.
Health checkhttp://127.0.0.1:8470/healthzOpens the health check, which returns ok: true when the porch is up.
Stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens the porch's stash page for one rig, such as attic.
Porch log/var/log/burrow/porch.logOpens the log the porch service writes.
Service unitdeploy/burrow-porch.serviceOpens the systemd unit that starts the porch at boot.
Settingsconfig/burrow.tomlOpens the settings file; its [porch] section sets the address, title and refresh.
metrics
The metrics: rig temperatures and disk use, kept by Prometheus and drawn in Grafana.
Grafana graphshttp://127.0.0.1:3000Opens the Grafana graphs of rig temperatures and disk use.
Raw numbershttp://127.0.0.1:9188/metricsOpens the numbers pulse exposes for Prometheus, one line per rig.
Start the metricsburrow metrics startStarts the metrics containers: pulse, Prometheus and Grafana.
Stop the metricsburrow metrics stopStops the metrics containers and keeps the numbers they have stored.
Containers filedocker-compose.ymlOpens the compose file that defines the three metrics containers and how long Prometheus keeps numbers.
Pulse codepulse/pulse.pyOpens the pulse program that reads each rig's temperature and disk use.
project
Everything around the code: how to install burrow, its settings, its helper scripts, its docs and the development commands.
Helpersburrow project helpersPrints the helpers screen: the small shell scripts kept in scripts/.
Docsburrow project docsPrints the docs screen: the setup, rig and chores guides.
Settingsburrow project configPrints the settings screen: the files that hold burrow's settings and rig list.
Developmentburrow project devPrints the development screen: tests, lint and clean-up commands.
Installmake installRuns make install, which builds the virtualenv and installs the burrow command into it.
Install the porch servicemake install-unitRuns make install-unit, which installs the porch service under systemd and starts it.
Weekly prunemake install-prune-cronRuns make install-prune-cron, which schedules a weekly stash prune.
Chores schedulecrontab deploy/burrow.crontabRuns crontab deploy/burrow.crontab, which replaces this user's crontab with the chores schedule.
MakefileMakefileOpens the Makefile, the list of every make target.
READMEREADME.mdOpens the README, the overview and how to use burrow.
project › helpers
The small shell helpers in scripts/, each doing one job on the rigs or on this machine.
Battery reportscripts/battery-report.shOpens the script that reports battery state.
Certificate renewalscripts/cert-renew.shOpens the script that renews certificates.
Disk check on every rigscripts/check-disks.shOpens the script that shows disk use on every rig.
DNS flushscripts/dns-flush.shOpens the script that flushes the DNS cache.
Stash sizesscripts/du-stashes.shOpens the script that measures how much space the stashes take.
Chores exportscripts/export-chores.shOpens the script that exports the chores.
Fan curvescripts/fan-curve.shOpens the script that sets the fan speed curve.
Docker clean-upscripts/gc-docker.shOpens the script that removes unused Docker images and containers.
Rig importscripts/import-rigs.shOpens the script that imports rigs from another list.
Open portsscripts/list-ports.shOpens the script that lists open ports.
Mount the NASscripts/mount-nas.shOpens the script that mounts the NAS.
Network speedscripts/net-speed.shOpens the script that measures network speed.
Pi-hole updatescripts/pihole-update.shOpens the script that updates Pi-hole.
Reboot a rigscripts/reboot-rig.shOpens the script that reboots one rig after a 10 second countdown.
Log rotationscripts/rotate-logs.shOpens the script that rotates the logs.
Seed dev datascripts/seed-dev.shOpens the script that seeds development data.
Disk health reportscripts/smart-report.shOpens the script that reports disk SMART health.
Push SSH keys to rigsscripts/ssh-keys-push.shOpens the script that pushes SSH keys to the rigs.
Clock syncscripts/sync-clock.shOpens the script that syncs the clock.
Temperature checkscripts/temp-check.shOpens the script that checks temperatures.
Unmount the NASscripts/unmount-nas.shOpens the script that unmounts the NAS.
Update the rigsscripts/update-rigs.shOpens the script that updates the rigs.
UPS statusscripts/ups-status.shOpens the script that shows the UPS status.
Verify a stashscripts/verify-stash.shOpens the script that checks a rig's newest stash is readable and not empty.
ZFS scrubscripts/zfs-scrub.shOpens the script that starts a ZFS scrub.
project › docs
The guides that ship with burrow.
Setupdocs/setup.mdOpens the steps to set burrow up on a new machine: rig user, install and crontab.
Adding a rigdocs/adding-a-rig.mdOpens the steps to add a rig to the list and take its first stash.
Choresdocs/chores.mdOpens the guide to the chores and how to run or check them.
Restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the steps to put a stash back with rsync when burrow itself is broken.
project › config
The files that hold burrow's settings and rig list.
Settingsconfig/burrow.tomlOpens the settings: stash location, chores, the porch and the ssh user.
Rig listconfig/rigs.tomlOpens the rig list: each rig's name, address, MAC and folders.
Secrets.envOpens the environment file with the ssh key path, porch secret and ntfy topic.
Example secrets.env.exampleOpens the template to copy into .env.
project › dev
Commands for working on burrow itself.
Testmake testRuns make test, the test suite under tests/.
Lintmake lintRuns make lint, which checks burrow and its tests with ruff.
Cleanmake cleanRuns make clean, which removes the virtualenv and build leftovers.
Tests foldertests/Opens the folder of tests for stash, chores and rigs.
Project filepyproject.tomlOpens the project file: version, dependencies and the burrow command.
Questions
  • Stash actions: should `burrow stash attic` print the screen and `burrow stash attic take` do the taking, with `burrow stash --all` and `make stash-all` kept as aliases for `burrow stash all take`, and `burrow restore` moved to `burrow stash attic restore`? Recommendation: yes.
  • Porch start: should `burrow porch` print the porch screen and `burrow porch start` run the server? Recommendation: yes, which also means changing `ExecStart` in deploy/burrow-porch.service to `burrow porch start --bind` and reinstalling the unit.
  • Helper split: the 25 helper scripts are too many for one screen. Should they be split into two screens, and in what words? Recommendation: 'for the rigs' (check-disks, reboot-rig, update-rigs, ssh-keys-push, smart-report, temp-check, verify-stash, du-stashes, export-chores, import-rigs) and 'for this machine' (the other 15).
  • Helper runners: should `burrow project helpers <name>` run each script, passing arguments through? Recommendation: yes. To describe the 22 scripts I could not see, I need their first lines, or confirmation of the names and descriptions in the map.
  • Metrics commands: should `burrow metrics start` and `burrow metrics stop` be added as thin wrappers over `make up` and `make down`? Recommendation: yes. Note that pulse returns 0.0 for temperature and disk until read_temp and read_disk are filled in, so the graphs will show zeros until then.
As phone screens

Home

burrow looks after the machines in your home lab: the rigs, their stashes, the chores, the porch and the metrics, plus the project itself.

RigsPrints the rigs screen: every rig, its address, and whether it answers.
›
StashesPrints the stash screen: the stashes kept for each rig, and the cleanup of old ones.
›
ChoresPrints the chores screen: the recurring jobs and when each last ran.
›
PorchPrints the porch screen: the dashboard's address and whether it is running.
›
MetricsPrints the metrics screen: the graphs and the numbers behind them.
›
ProjectPrints the project screen: install, settings, helper scripts, docs and development.
›
‹ Home

rigs

Every rig burrow knows, and whether each one answers.

atticPrints the attic screen: its address, the folders stashed from it, and its wake and reboot commands.
›
cellarPrints the cellar screen: its address, the folders stashed from it, and its wake and reboot commands.
›
gardenPrints the garden screen: its address, the folders stashed from it, and its wake and reboot commands.
›
Rig listOpens the rig list, where each rig's address, MAC and folders are set.
›
Disk use on every rigOpens the script that shows disk use on every rig.
›
‹ rigs

attic

The attic rig: where it is on the LAN, and what burrow keeps from it.

AddressShows the address burrow uses to reach attic over ssh.
›
Folders stashedLists the folders on attic that each stash copies.
›
StashesPrints the attic stash screen: every stash taken from attic, newest last.
›
WakeRuns the wake script, which sends a magic packet to wake attic from sleep.
›
RebootRuns the reboot script, which reboots attic after a 10 second countdown.
›
‹ rigs

cellar

The cellar rig: where it is on the LAN, and what burrow keeps from it.

AddressShows the address burrow uses to reach cellar over ssh.
›
Folders stashedLists the folders on cellar that each stash copies.
›
StashesPrints the cellar stash screen: every stash taken from cellar, newest last.
›
WakeRuns the wake script, which sends a magic packet to wake cellar from sleep.
›
RebootRuns the reboot script, which reboots cellar after a 10 second countdown.
›
‹ rigs

garden

The garden rig: where it is on the LAN, and what burrow keeps from it.

AddressShows the address burrow uses to reach garden over ssh.
›
Folders stashedLists the folders on garden that each stash copies.
›
StashesPrints the garden stash screen: every stash taken from garden, newest last.
›
WakeRuns the wake script, which sends a magic packet to wake garden from sleep.
›
RebootRuns the reboot script, which reboots garden after a 10 second countdown.
›
‹ Home

stash

The stashes: snapshots of each rig's important folders, pulled over rsync, and the cleanup of old ones.

atticPrints the attic stash screen: its stashes, and the commands to take, restore or check one.
›
cellarPrints the cellar stash screen: its stashes, and the commands to take, restore or check one.
›
gardenPrints the garden stash screen: its stashes, and the commands to take, restore or check one.
›
Every rigTakes a stash of every rig at once, the same as make stash-all.
›
PruneRemoves the oldest stashes, keeping the newest N (set with --keep, default 8).
›
Stash folderOpens the folder that holds every stash, one folder per rig.
›
‹ stash

attic

The attic stashes: one dated folder per stash taken from attic.

Each stashOpens that stash, a copy of attic's folders on that date; one row for each stash that exists.
›
Take a stash nowTakes a new stash of attic right now.
›
Restore a stashCopies a dated stash back onto attic; add --dry-run to see what would change first.
›
Check the newest stashRuns the check that attic's newest stash is readable and not empty.
›
‹ stash

cellar

The cellar stashes: one dated folder per stash taken from cellar.

Each stashOpens that stash, a copy of cellar's folders on that date; one row for each stash that exists.
›
Take a stash nowTakes a new stash of cellar right now.
›
Restore a stashCopies a dated stash back onto cellar; add --dry-run to see what would change first.
›
Check the newest stashRuns the check that cellar's newest stash is readable and not empty.
›
‹ stash

garden

The garden stashes: one dated folder per stash taken from garden.

Each stashOpens that stash, a copy of garden's folders on that date; one row for each stash that exists.
›
Take a stash nowTakes a new stash of garden right now.
›
Restore a stashCopies a dated stash back onto garden; add --dry-run to see what would change first.
›
Check the newest stashRuns the check that garden's newest stash is readable and not empty.
›
‹ Home

chores

The recurring jobs burrow runs for itself, and when each last ran.

nightly-stashPrints the nightly-stash screen: a stash of every rig, every night at 02:15.
›
disk-checkPrints the disk-check screen: warns when a rig's root disk is over 85%, every 6 hours.
›
ScheduleOpens the crontab that starts both chores on time.
›
Chore logOpens the log of every chore run, with its output and any errors.
›
Last runsOpens the record of when each chore last ran and whether it worked.
›
Chore codeOpens the file that defines the chores.
›
Chores pageOpens the chores page on the porch, the same last-run list in a browser.
›
‹ chores

nightly-stash

The nightly-stash chore: a stash of every rig, run every night at 02:15 by cron.

Run nowRuns the nightly stash now, outside its schedule.
›
Last runsPrints when each chore last ran and whether it worked.
›
CodeOpens the file where the nightly-stash chore is defined.
›
ScheduleOpens the crontab line that starts it at 02:15.
›
‹ chores

disk-check

The disk-check chore: warns when a rig's root disk is over 85%, checked every 6 hours by cron.

Run nowRuns the disk check now, outside its schedule.
›
Last runsPrints when each chore last ran and whether it worked.
›
CodeOpens the file where the disk-check chore is defined.
›
ScheduleOpens the crontab line that starts it every 6 hours.
›
‹ Home

porch

The porch: the dashboard for the rigs, served by burrow and opened in a browser.

Open the porchOpens the porch dashboard in this machine's browser; from the LAN, use the rig's IP instead.
›
Start the porchStarts the porch server on 0.0.0.0:8470, the dashboard other machines reach.
›
Health checkOpens the health check, which returns ok: true when the porch is up.
›
Stashes pageOpens the porch's stash page for one rig, such as attic.
›
Porch logOpens the log the porch service writes.
›
Service unitOpens the systemd unit that starts the porch at boot.
›
SettingsOpens the settings file; its [porch] section sets the address, title and refresh.
›
‹ Home

metrics

The metrics: rig temperatures and disk use, kept by Prometheus and drawn in Grafana.

Grafana graphsOpens the Grafana graphs of rig temperatures and disk use.
›
Raw numbersOpens the numbers pulse exposes for Prometheus, one line per rig.
›
Start the metricsStarts the metrics containers: pulse, Prometheus and Grafana.
›
Stop the metricsStops the metrics containers and keeps the numbers they have stored.
›
Containers fileOpens the compose file that defines the three metrics containers and how long Prometheus keeps numbers.
›
Pulse codeOpens the pulse program that reads each rig's temperature and disk use.
›
‹ Home

project

Everything around the code: how to install burrow, its settings, its helper scripts, its docs and the development commands.

HelpersPrints the helpers screen: the small shell scripts kept in scripts/.
›
DocsPrints the docs screen: the setup, rig and chores guides.
›
SettingsPrints the settings screen: the files that hold burrow's settings and rig list.
›
DevelopmentPrints the development screen: tests, lint and clean-up commands.
›
InstallRuns make install, which builds the virtualenv and installs the burrow command into it.
›
Install the porch serviceRuns make install-unit, which installs the porch service under systemd and starts it.
›
Weekly pruneRuns make install-prune-cron, which schedules a weekly stash prune.
›
Chores scheduleRuns crontab deploy/burrow.crontab, which replaces this user's crontab with the chores schedule.
›
MakefileOpens the Makefile, the list of every make target.
›
READMEOpens the README, the overview and how to use burrow.
›
‹ project

helpers

The small shell helpers in scripts/, each doing one job on the rigs or on this machine.

Battery reportOpens the script that reports battery state.
›
Certificate renewalOpens the script that renews certificates.
›
Disk check on every rigOpens the script that shows disk use on every rig.
›
DNS flushOpens the script that flushes the DNS cache.
›
Stash sizesOpens the script that measures how much space the stashes take.
›
Chores exportOpens the script that exports the chores.
›
Fan curveOpens the script that sets the fan speed curve.
›
Docker clean-upOpens the script that removes unused Docker images and containers.
›
Rig importOpens the script that imports rigs from another list.
›
Open portsOpens the script that lists open ports.
›
Mount the NASOpens the script that mounts the NAS.
›
Network speedOpens the script that measures network speed.
›
Pi-hole updateOpens the script that updates Pi-hole.
›
Reboot a rigOpens the script that reboots one rig after a 10 second countdown.
›
Log rotationOpens the script that rotates the logs.
›
Seed dev dataOpens the script that seeds development data.
›
Disk health reportOpens the script that reports disk SMART health.
›
Push SSH keys to rigsOpens the script that pushes SSH keys to the rigs.
›
Clock syncOpens the script that syncs the clock.
›
Temperature checkOpens the script that checks temperatures.
›
Unmount the NASOpens the script that unmounts the NAS.
›
Update the rigsOpens the script that updates the rigs.
›
UPS statusOpens the script that shows the UPS status.
›
Verify a stashOpens the script that checks a rig's newest stash is readable and not empty.
›
ZFS scrubOpens the script that starts a ZFS scrub.
›
‹ project

docs

The guides that ship with burrow.

SetupOpens the steps to set burrow up on a new machine: rig user, install and crontab.
›
Adding a rigOpens the steps to add a rig to the list and take its first stash.
›
ChoresOpens the guide to the chores and how to run or check them.
›
Restore by handOpens the steps to put a stash back with rsync when burrow itself is broken.
›
‹ project

config

The files that hold burrow's settings and rig list.

SettingsOpens the settings: stash location, chores, the porch and the ssh user.
›
Rig listOpens the rig list: each rig's name, address, MAC and folders.
›
SecretsOpens the environment file with the ssh key path, porch secret and ntfy topic.
›
Example secretsOpens the template to copy into .env.
›
‹ project

dev

Commands for working on burrow itself.

TestRuns make test, the test suite under tests/.
›
LintRuns make lint, which checks burrow and its tests with ruff.
›
CleanRuns make clean, which removes the virtualenv and build leftovers.
›
Tests folderOpens the folder of tests for stash, chores and rigs.
›
Project fileOpens the project file: version, dependencies and the burrow command.
›
Raw answer
# burrow CLI plan (planning only, nothing built)

I worked from the project dump alone. I could not run `whence -a` or `type -a` to check name clashes, so every name below still needs that check at build time. Descriptions of the 22 helper scripts I did not see come from their file names only.

## The screens as they will print

**`burrow help`** (top, no breadcrumb)

burrow looks after the machines in your home lab: the rigs, their stashes, the chores, the porch and the metrics, plus the project itself.

| Name | Its technical form | What it's for |
| --- | --- | --- |
| Rigs | `burrow rigs` | Prints the rigs screen: every rig, its address, and whether it answers. |
| Stashes | `burrow stash` | Prints the stash screen: the stashes kept for each rig, and the cleanup of old ones. |
| Chores | `burrow chores` | Prints the chores screen: the recurring jobs and when each last ran. |
| Porch | `burrow porch` | Prints the porch screen: the dashboard's address and whether it is running. |
| Metrics | `burrow metrics` | Prints the metrics screen: the graphs and the numbers behind them. |
| Project | `burrow project` | Prints the project screen: install, settings, helper scripts, docs and development. |

**`burrow rigs attic`**

burrow › rigs › attic
The attic rig: where it is on the LAN, and what burrow keeps from it.

| Name | Its technical form | What it's for |
| --- | --- | --- |
| Address | 192.168.1.20 | Shows the address burrow uses to reach attic over ssh. |
| Folders stashed | /etc, /home, /var/lib/docker/volumes (on attic) | Lists the folders on attic that each stash copies. |
| Stashes | `burrow stash attic` | Prints the attic stash screen: every stash taken from attic, newest last. |
| Wake | `bin/rig-wake attic` | Runs the wake script, which sends a magic packet to wake attic from sleep. |
| Reboot | `scripts/reboot-rig.sh 192.168.1.20` | Runs the reboot script, which reboots attic after a 10 second countdown. |

The full tree (19 screens, 25 helper scripts) is in the JSON at the end.

## Where the current CLI and this map disagree

- **`burrow stash attic` takes a stash today.** Under the convention, a bare noun prints its screen. The map moves taking into `burrow stash attic take`.
- **`burrow porch` runs the server today.** The map moves running to `burrow porch start`.
- **`burrow restore` sits at the top today.** It moves under the rig, as `burrow stash attic restore --from DATE`.
- **`burrow chores list` and `chores status` fold into the chores screens.** `status` stays as a row, because it is an action.
- **Per-rig nouns need a restructure.** The Python `click` tree has no per-rig group under `stash`, so the rig nouns need one. Each rig's screen and actions are the largest change to `burrow/cli.py`.

## Judgment calls I made

- **The top nouns are `rigs`, `stash`, `chores`, `porch`, `metrics` and `project`.** `project` is my neutral name for setup, settings, helpers, docs and development. Rename it if you prefer another word.
- **Rows whose local path is missing are dropped when the screen prints.** The affected rows are `.env`, `/var/log/burrow/*.log` and `/srv/burrow/state/last-run.json`. This follows "every path on screen opens".
- **Rig paths such as `/etc` are plain text, not links,** because they live on the rig, not on this machine.
- **Stash folders are dynamic.** The `stash/<rig>` screens print one row per stash folder that exists. The JSON shows the pattern.
- **Rig screens link to the stash screens rather than repeating stash commands.** That keeps each command in one place.
- **The `burrow` facade keeps the name `burrow`, with no separate alias,** because the name is already short.

## Things I noticed in the project

- `deploy/burrow.crontab` is installed with `crontab deploy/burrow.crontab`, which replaces the user's whole crontab. That would erase the weekly prune line that `make install-prune-cron` appends. I recommend the install step append instead of replace.
- `pulse/pulse.py` returns `0.0` from `read_temp` and `read_disk`, so the Grafana graphs will show zeros until those are filled in.
- The porch binds `0.0.0.0:8470`. `BURROW_PORCH_SECRET` appears in `.env.example`, but nothing in the code shown reads it. I could not confirm any auth on the porch from the dump.

## Questions for you, with my recommendation

1. **Stash actions.** Should `burrow stash attic` print the screen and `burrow stash attic take` do the taking? I recommend yes, with `burrow stash --all` and `make stash-all` kept as aliases for `burrow stash all take`. The same goes for `burrow restore`, which becomes `burrow stash attic restore`.
2. **Porch start.** Should `burrow porch` print the porch screen and `burrow porch start` run the server? I recommend yes. That also means changing `ExecStart` in `deploy/burrow-porch.service` to `burrow porch start --bind`, and reinstalling the unit.
3. **The helper list.** The 25 helper scripts are too many for one screen. I recommend splitting them into two screens. Which words would you use? My starting guess is "for the rigs" (`check-disks`, `reboot-rig`, `update-rigs`, `ssh-keys-push`, `smart-report`, `temp-check`, `verify-stash`, `du-stashes`, `export-chores`, `import-rigs`) and "for this machine" (the remaining 15).
4. **Running helpers.** Should `burrow project helpers <name>` run each script? I recommend yes, passing arguments through. To do that properly, I need the first lines of the 22 scripts I could not see. Please paste them, or confirm the names and descriptions above.
5. **Metrics commands.** Should `burrow metrics start` and `burrow metrics stop` be added as thin wrappers over `make up` and `make down`? I recommend yes.

```json
{"screens": [
{"path": [], "sentence": "burrow looks after the machines in your home lab: the rigs, their stashes, the chores, the porch and the metrics, plus the project itself.", "rows": [
{"name": "Rigs", "form": "burrow rigs", "what": "Prints the rigs screen: every rig, its address, and whether it answers."},
{"name": "Stashes", "form": "burrow stash", "what": "Prints the stash screen: the stashes kept for each rig, and the cleanup of old ones."},
{"name": "Chores", "form": "burrow chores", "what": "Prints the chores screen: the recurring jobs and when each last ran."},
{"name": "Porch", "form": "burrow porch", "what": "Prints the porch screen: the dashboard's address and whether it is running."},
{"name": "Metrics", "form": "burrow metrics", "what": "Prints the metrics screen: the graphs and the numbers behind them."},
{"name": "Project", "form": "burrow project", "what": "Prints the project screen: install, settings, helper scripts, docs and development."}
]},
{"path": ["rigs"], "sentence": "Every rig burrow knows, and whether each one answers.", "rows": [
{"name": "attic", "form": "burrow rigs attic", "what": "Prints the attic screen: its address, the folders stashed from it, and its wake and reboot commands."},
{"name": "cellar", "form": "burrow rigs cellar", "what": "Prints the cellar screen: its address, the folders stashed from it, and its wake and reboot commands."},
{"name": "garden", "form": "burrow rigs garden", "what": "Prints the garden screen: its address, the folders stashed from it, and its wake and reboot commands."},
{"name": "Rig list", "form": "config/rigs.toml", "what": "Opens the rig list, where each rig's address, MAC and folders are set."},
{"name": "Disk use on every rig", "form": "scripts/check-disks.sh", "what": "Opens the script that shows disk use on every rig."}
]},
{"path": ["rigs", "attic"], "sentence": "The attic rig: where it is on the LAN, and what burrow keeps from it.", "rows": [
{"name": "Address", "form": "192.168.1.20", "what": "Shows the address burrow uses to reach attic over ssh."},
{"name": "Folders stashed", "form": "/etc, /home, /var/lib/docker/volumes (on attic)", "what": "Lists the folders on attic that each stash copies."},
{"name": "Stashes", "form": "burrow stash attic", "what": "Prints the attic stash screen: every stash taken from attic, newest last."},
{"name": "Wake", "form": "bin/rig-wake attic", "what": "Runs the wake script, which sends a magic packet to wake attic from sleep."},
{"name": "Reboot", "form": "scripts/reboot-rig.sh 192.168.1.20", "what": "Runs the reboot script, which reboots attic after a 10 second countdown."}
]},
{"path": ["rigs", "cellar"], "sentence": "The cellar rig: where it is on the LAN, and what burrow keeps from it.", "rows": [
{"name": "Address", "form": "192.168.1.21", "what": "Shows the address burrow uses to reach cellar over ssh."},
{"name": "Folders stashed", "form": "/etc, /tank/photos (on cellar)", "what": "Lists the folders on cellar that each stash copies."},
{"name": "Stashes", "form": "burrow stash cellar", "what": "Prints the cellar stash screen: every stash taken from cellar, newest last."},
{"name": "Wake", "form": "bin/rig-wake cellar", "what": "Runs the wake script, which sends a magic packet to wake cellar from sleep."},
{"name": "Reboot", "form": "scripts/reboot-rig.sh 192.168.1.21", "what": "Runs the reboot script, which reboots cellar after a 10 second countdown."}
]},
{"path": ["rigs", "garden"], "sentence": "The garden rig: where it is on the LAN, and what burrow keeps from it.", "rows": [
{"name": "Address", "form": "192.168.1.22", "what": "Shows the address burrow uses to reach garden over ssh."},
{"name": "Folders stashed", "form": "/etc, /opt/homeassistant (on garden)", "what": "Lists the folders on garden that each stash copies."},
{"name": "Stashes", "form": "burrow stash garden", "what": "Prints the garden stash screen: every stash taken from garden, newest last."},
{"name": "Wake", "form": "bin/rig-wake garden", "what": "Runs the wake script, which sends a magic packet to wake garden from sleep."},
{"name": "Reboot", "form": "scripts/reboot-rig.sh 192.168.1.22", "what": "Runs the reboot script, which reboots garden after a 10 second countdown."}
]},
{"path": ["stash"], "sentence": "The stashes: snapshots of each rig's important folders, pulled over rsync, and the cleanup of old ones.", "rows": [
{"name": "attic", "form": "burrow stash attic", "what": "Prints the attic stash screen: its stashes, and the commands to take, restore or check one."},
{"name": "cellar", "form": "burrow stash cellar", "what": "Prints the cellar stash screen: its stashes, and the commands to take, restore or check one."},
{"name": "garden", "form": "burrow stash garden", "what": "Prints the garden stash screen: its stashes, and the commands to take, restore or check one."},
{"name": "Every rig", "form": "burrow stash all take", "what": "Takes a stash of every rig at once, the same as make stash-all."},
{"name": "Prune", "form": "burrow stash prune", "what": "Removes the oldest stashes, keeping the newest N (set with --keep, default 8)."},
{"name": "Stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder that holds every stash, one folder per rig."}
]},
{"path": ["stash", "attic"], "sentence": "The attic stashes: one dated folder per stash taken from attic.", "rows": [
{"name": "Each stash", "form": "/srv/burrow/stashes/attic/<YYYY-MM-DD>", "what": "Opens that stash, a copy of attic's folders on that date; one row for each stash that exists."},
{"name": "Take a stash now", "form": "burrow stash attic take", "what": "Takes a new stash of attic right now."},
{"name": "Restore a stash", "form": "burrow stash attic restore --from YYYY-MM-DD", "what": "Copies a dated stash back onto attic; add --dry-run to see what would change first."},
{"name": "Check the newest stash", "form": "scripts/verify-stash.sh attic", "what": "Runs the check that attic's newest stash is readable and not empty."}
]},
{"path": ["stash", "cellar"], "sentence": "The cellar stashes: one dated folder per stash taken from cellar.", "rows": [
{"name": "Each stash", "form": "/srv/burrow/stashes/cellar/<YYYY-MM-DD>", "what": "Opens that stash, a copy of cellar's folders on that date; one row for each stash that exists."},
{"name": "Take a stash now", "form": "burrow stash cellar take", "what": "Takes a new stash of cellar right now."},
{"name": "Restore a stash", "form": "burrow stash cellar restore --from YYYY-MM-DD", "what": "Copies a dated stash back onto cellar; add --dry-run to see what would change first."},
{"name": "Check the newest stash", "form": "scripts/verify-stash.sh cellar", "what": "Runs the check that cellar's newest stash is readable and not empty."}
]},
{"path": ["stash", "garden"], "sentence": "The garden stashes: one dated folder per stash taken from garden.", "rows": [
{"name": "Each stash", "form": "/srv/burrow/stashes/garden/<YYYY-MM-DD>", "what": "Opens that stash, a copy of garden's folders on that date; one row for each stash that exists."},
{"name": "Take a stash now", "form": "burrow stash garden take", "what": "Takes a new stash of garden right now."},
{"name": "Restore a stash", "form": "burrow stash garden restore --from YYYY-MM-DD", "what": "Copies a dated stash back onto garden; add --dry-run to see what would change first."},
{"name": "Check the newest stash", "form": "scripts/verify-stash.sh garden", "what": "Runs the check that garden's newest stash is readable and not empty."}
]},
{"path": ["chores"], "sentence": "The recurring jobs burrow runs for itself, and when each last ran.", "rows": [
{"name": "nightly-stash", "form": "burrow chores nightly-stash", "what": "Prints the nightly-stash screen: a stash of every rig, every night at 02:15."},
{"name": "disk-check", "form": "burrow chores disk-check", "what": "Prints the disk-check screen: warns when a rig's root disk is over 85%, every 6 hours."},
{"name": "Schedule", "form": "deploy/burrow.crontab", "what": "Opens the crontab that starts both chores on time."},
{"name": "Chore log", "form": "/var/log/burrow/chores.log", "what": "Opens the log of every chore run, with its output and any errors."},
{"name": "Last runs", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of when each chore last ran and whether it worked."},
{"name": "Chore code", "form": "burrow/chores.py", "what": "Opens the file that defines the chores."},
{"name": "Chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page on the porch, the same last-run list in a browser."}
]},
{"path": ["chores", "nightly-stash"], "sentence": "The nightly-stash chore: a stash of every rig, run every night at 02:15 by cron.", "rows": [
{"name": "Run now", "form": "burrow chores nightly-stash run", "what": "Runs the nightly stash now, outside its schedule."},
{"name": "Last runs", "form": "burrow chores status", "what": "Prints when each chore last ran and whether it worked."},
{"name": "Code", "form": "burrow/chores.py (nightly_stash)", "what": "Opens the file where the nightly-stash chore is defined."},
{"name": "Schedule", "form": "deploy/burrow.crontab", "what": "Opens the crontab line that starts it at 02:15."}
]},
{"path": ["chores", "disk-check"], "sentence": "The disk-check chore: warns when a rig's root disk is over 85%, checked every 6 hours by cron.", "rows": [
{"name": "Run now", "form": "burrow chores disk-check run", "what": "Runs the disk check now, outside its schedule."},
{"name": "Last runs", "form": "burrow chores status", "what": "Prints when each chore last ran and whether it worked."},
{"name": "Code", "form": "burrow/chores.py (disk_check)", "what": "Opens the file where the disk-check chore is defined."},
{"name": "Schedule", "form": "deploy/burrow.crontab", "what": "Opens the crontab line that starts it every 6 hours."}
]},
{"path": ["porch"], "sentence": "The porch: the dashboard for the rigs, served by burrow and opened in a browser.", "rows": [
{"name": "Open the porch", "form": "http://127.0.0.1:8470", "what": "Opens the porch dashboard in this machine's browser; from the LAN, use the rig's IP instead."},
{"name": "Start the porch", "form": "burrow porch start", "what": "Starts the porch server on 0.0.0.0:8470, the dashboard other machines reach."},
{"name": "Health check", "form": "http://127.0.0.1:8470/healthz", "what": "Opens the health check, which returns ok: true when the porch is up."},
{"name": "Stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens the porch's stash page for one rig, such as attic."},
{"name": "Porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the log the porch service writes."},
{"name": "Service unit", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that starts the porch at boot."},
{"name": "Settings", "form": "config/burrow.toml", "what": "Opens the settings file; its [porch] section sets the address, title and refresh."}
]},
{"path": ["metrics"], "sentence": "The metrics: rig temperatures and disk use, kept by Prometheus and drawn in Grafana.", "rows": [
{"name": "Grafana graphs", "form": "http://127.0.0.1:3000", "what": "Opens the Grafana graphs of rig temperatures and disk use."},
{"name": "Raw numbers", "form": "http://127.0.0.1:9188/metrics", "what": "Opens the numbers pulse exposes for Prometheus, one line per rig."},
{"name": "Start the metrics", "form": "burrow metrics start", "what": "Starts the metrics containers: pulse, Prometheus and Grafana."},
{"name": "Stop the metrics", "form": "burrow metrics stop", "what": "Stops the metrics containers and keeps the numbers they have stored."},
{"name": "Containers file", "form": "docker-compose.yml", "what": "Opens the compose file that defines the three metrics containers and how long Prometheus keeps numbers."},
{"name": "Pulse code", "form": "pulse/pulse.py", "what": "Opens the pulse program that reads each rig's temperature and disk use."}
]},
{"path": ["project"], "sentence": "Everything around the code: how to install burrow, its settings, its helper scripts, its docs and the development commands.", "rows": [
{"name": "Helpers", "form": "burrow project helpers", "what": "Prints the helpers screen: the small shell scripts kept in scripts/."},
{"name": "Docs", "form": "burrow project docs", "what": "Prints the docs screen: the setup, rig and chores guides."},
{"name": "Settings", "form": "burrow project config", "what": "Prints the settings screen: the files that hold burrow's settings and rig list."},
{"name": "Development", "form": "burrow project dev", "what": "Prints the development screen: tests, lint and clean-up commands."},
{"name": "Install", "form": "make install", "what": "Runs make install, which builds the virtualenv and installs the burrow command into it."},
{"name": "Install the porch service", "form": "make install-unit", "what": "Runs make install-unit, which installs the porch service under systemd and starts it."},
{"name": "Weekly prune", "form": "make install-prune-cron", "what": "Runs make install-prune-cron, which schedules a weekly stash prune."},
{"name": "Chores schedule", "form": "crontab deploy/burrow.crontab", "what": "Runs crontab deploy/burrow.crontab, which replaces this user's crontab with the chores schedule."},
{"name": "Makefile", "form": "Makefile", "what": "Opens the Makefile, the list of every make target."},
{"name": "README", "form": "README.md", "what": "Opens the README, the overview and how to use burrow."}
]},
{"path": ["project", "helpers"], "sentence": "The small shell helpers in scripts/, each doing one job on the rigs or on this machine.", "rows": [
{"name": "Battery report", "form": "scripts/battery-report.sh", "what": "Opens the script that reports battery state."},
{"name": "Certificate renewal", "form": "scripts/cert-renew.sh", "what": "Opens the script that renews certificates."},
{"name": "Disk check on every rig", "form": "scripts/check-disks.sh", "what": "Opens the script that shows disk use on every rig."},
{"name": "DNS flush", "form": "scripts/dns-flush.sh", "what": "Opens the script that flushes the DNS cache."},
{"name": "Stash sizes", "form": "scripts/du-stashes.sh", "what": "Opens the script that measures how much space the stashes take."},
{"name": "Chores export", "form": "scripts/export-chores.sh", "what": "Opens the script that exports the chores."},
{"name": "Fan curve", "form": "scripts/fan-curve.sh", "what": "Opens the script that sets the fan speed curve."},
{"name": "Docker clean-up", "form": "scripts/gc-docker.sh", "what": "Opens the script that removes unused Docker images and containers."},
{"name": "Rig import", "form": "scripts/import-rigs.sh", "what": "Opens the script that imports rigs from another list."},
{"name": "Open ports", "form": "scripts/list-ports.sh", "what": "Opens the script that lists open ports."},
{"name": "Mount the NAS", "form": "scripts/mount-nas.sh", "what": "Opens the script that mounts the NAS."},
{"name": "Network speed", "form": "scripts/net-speed.sh", "what": "Opens the script that measures network speed."},
{"name": "Pi-hole update", "form": "scripts/pihole-update.sh", "what": "Opens the script that updates Pi-hole."},
{"name": "Reboot a rig", "form": "scripts/reboot-rig.sh", "what": "Opens the script that reboots one rig after a 10 second countdown."},
{"name": "Log rotation", "form": "scripts/rotate-logs.sh", "what": "Opens the script that rotates the logs."},
{"name": "Seed dev data", "form": "scripts/seed-dev.sh", "what": "Opens the script that seeds development data."},
{"name": "Disk health report", "form": "scripts/smart-report.sh", "what": "Opens the script that reports disk SMART health."},
{"name": "Push SSH keys to rigs", "form": "scripts/ssh-keys-push.sh", "what": "Opens the script that pushes SSH keys to the rigs."},
{"name": "Clock sync", "form": "scripts/sync-clock.sh", "what": "Opens the script that syncs the clock."},
{"name": "Temperature check", "form": "scripts/temp-check.sh", "what": "Opens the script that checks temperatures."},
{"name": "Unmount the NAS", "form": "scripts/unmount-nas.sh", "what": "Opens the script that unmounts the NAS."},
{"name": "Update the rigs", "form": "scripts/update-rigs.sh", "what": "Opens the script that updates the rigs."},
{"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Opens the script that shows the UPS status."},
{"name": "Verify a stash", "form": "scripts/verify-stash.sh", "what": "Opens the script that checks a rig's newest stash is readable and not empty."},
{"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Opens the script that starts a ZFS scrub."}
]},
{"path": ["project", "docs"], "sentence": "The guides that ship with burrow.", "rows": [
{"name": "Setup", "form": "docs/setup.md", "what": "Opens the steps to set burrow up on a new machine: rig user, install and crontab."},
{"name": "Adding a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps to add a rig to the list and take its first stash."},
{"name": "Chores", "form": "docs/chores.md", "what": "Opens the guide to the chores and how to run or check them."},
{"name": "Restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the steps to put a stash back with rsync when burrow itself is broken."}
]},
{"path": ["project", "config"], "sentence": "The files that hold burrow's settings and rig list.", "rows": [
{"name": "Settings", "form": "config/burrow.toml", "what": "Opens the settings: stash location, chores, the porch and the ssh user."},
{"name": "Rig list", "form": "config/rigs.toml", "what": "Opens the rig list: each rig's name, address, MAC and folders."},
{"name": "Secrets", "form": ".env", "what": "Opens the environment file with the ssh key path, porch secret and ntfy topic."},
{"name": "Example secrets", "form": ".env.example", "what": "Opens the template to copy into .env."}
]},
{"path": ["project", "dev"], "sentence": "Commands for working on burrow itself.", "rows": [
{"name": "Test", "form": "make test", "what": "Runs make test, the test suite under tests/."},
{"name": "Lint", "form": "make lint", "what": "Runs make lint, which checks burrow and its tests with ruff."},
{"name": "Clean", "form": "make clean", "what": "Runs make clean, which removes the virtualenv and build leftovers."},
{"name": "Tests folder", "form": "tests/", "what": "Opens the folder of tests for stash, chores and rigs."},
{"name": "Project file", "form": "pyproject.toml", "what": "Opens the project file: version, dependencies and the burrow command."}
]}
],
"questions": [
"Stash actions: should `burrow stash attic` print the screen and `burrow stash attic take` do the taking, with `burrow stash --all` and `make stash-all` kept as aliases for `burrow stash all take`, and `burrow restore` moved to `burrow stash attic restore`? Recommendation: yes.",
"Porch start: should `burrow porch` print the porch screen and `burrow porch start` run the server? Recommendation: yes, which also means changing `ExecStart` in deploy/burrow-porch.service to `burrow porch start --bind` and reinstalling the unit.",
"Helper split: the 25 helper scripts are too many for one screen. Should they be split into two screens, and in what words? Recommendation: 'for the rigs' (check-disks, reboot-rig, update-rigs, ssh-keys-push, smart-report, temp-check, verify-stash, du-stashes, export-chores, import-rigs) and 'for this machine' (the other 15).",
"Helper runners: should `burrow project helpers <name>` run each script, passing arguments through? Recommendation: yes. To describe the 22 scripts I could not see, I need their first lines, or confirmation of the names and descriptions in the map.",
"Metrics commands: should `burrow metrics start` and `burrow metrics stop` be added as thin wrappers over `make up` and `make down`? Recommendation: yes. Note that pulse returns 0.0 for temperature and disk until read_temp and read_disk are filled in, so the graphs will show zeros until then."
]}
```

screen-decomposition, first draft · run 2 exit=0 seconds=128 · prompt

P1 Recall: 0.917P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
What burrow looks after: its rigs, stashes, chores, porch, metrics, scripts and setup.
rigsburrow rigsLists the rigs and whether each one answers; a rig's name opens its screen.
stashburrow stashPrints the stash screen: taking, listing, pruning and restoring stashes.
choresburrow choresPrints the chores screen: the recurring jobs, how to run one, and when each last ran.
porchburrow porchPrints the porch screen: the dashboard's pages, its service, and how to run it.
metricsburrow metrics (new command)Prints the metrics screen: starting the containers and where the graphs are.
scriptsburrow scriptsPrints the scripts screen: the helper scripts, grouped by the job they do.
setupburrow setupPrints the setup screen: installing, configuring, developing, and the setup guide.
rigs
The rigs burrow knows, and whether each one answers.
atticburrow rigs atticPrints the attic screen: its address, its folders, and what you can do to it.
cellarburrow rigs cellarPrints the cellar screen: its address, its folders, and what you can do to it.
gardenburrow rigs gardenPrints the garden screen: its address, its folders, and what you can do to it.
add a rigdocs/adding-a-rig.mdOpens the guide to adding a rig block to the rig list.
rig listconfig/rigs.tomlOpens the list of rigs, with each one's name, address, MAC and paths.
rigs › attic
The attic rig: its address, the folders stashed from it, and what you can do to it.
addressssh burrow@192.168.1.20Opens an ssh session to attic as the burrow user.
foldersconfig/rigs.tomlOpens the rig list, where attic's folders are /etc, /home and /var/lib/docker/volumes.
wakebin/rig-wake atticSends a wake packet to attic's MAC address, for when it is asleep.
take a stashburrow stash atticTakes a stash of attic now.
its stashesburrow stash list atticPrints the stashes kept for attic.
stashes pagehttp://127.0.0.1:8470/stashes/atticOpens the porch page listing attic's stashes.
restoreburrow restore attic --from YYYY-MM-DDCopies a dated stash of attic back onto attic.
rebootscripts/reboot-rig.sh 192.168.1.20Reboots attic after a 10-second countdown.
stash
The stashes: snapshots of a rig's folders, taken, listed, pruned and put back from here.
take one rig's stashburrow stash <rig>Takes a stash of the named rig, now.
take every rig's stashburrow stash --all (make stash-all)Takes a stash of every rig in the rig list.
list a rig's stashesburrow stash list <rig>Prints the stashes kept for one rig.
pruneburrow stash prune --keep 8 (make prune-stashes)Removes old stashes, keeping the newest 8 (--keep sets the number).
restoreburrow restore <rig> --from YYYY-MM-DDCopies a dated stash back onto its rig; --dry-run is the flag to check first.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the steps to copy a stash back with rsync, for when burrow itself is broken.
stash folder/srv/burrow/stashesOpens the folder stashes are written to: one folder per rig, one dated folder per stash.
stash manifest/srv/burrow/stashes/<rig>/<YYYY-MM-DD>/.burrow-manifestOpens a stash's manifest: its paths and the rsync exit code, where non-zero means partial.
verifyscripts/verify-stash.sh <rig>Checks that a rig's newest stash is readable and not empty.
stash disk usescripts/du-stashes.shRuns the stash disk-use script (purpose read from its name; confirm before building).
chores
The chores: recurring jobs that cron runs, and when each one last ran.
listburrow chores listPrints the name of every registered chore.
run oneburrow chores run <name>Runs one chore now and records its result.
statusburrow chores statusPrints when each chore last finished and whether it worked.
nightly-stashburrow chores run nightly-stashTakes a stash of every rig; cron runs it at 02:15 each night.
disk-checkburrow chores run disk-checkWarns when a rig's root disk is over 85 percent; cron runs it every 6 hours.
chore output log/var/log/burrow/chores.logOpens the log where cron writes the chores' output.
last-run record/srv/burrow/state/last-run.jsonOpens the file that records each chore's last run.
chores pagehttp://127.0.0.1:8470/choresOpens the porch page showing each chore's last run.
scheduledeploy/burrow.crontabOpens the file that sets when the chores run.
chore codeburrow/chores.pyOpens chores.py, where each chore is registered.
chores guidedocs/chores.mdOpens the guide to chores.
export choresscripts/export-chores.shRuns the chore export script (purpose read from its name; confirm before building).
porch
The porch: the dashboard for the rigs, served on port 8470.
openhttp://127.0.0.1:8470Opens the dashboard on this machine; from the LAN, use the rig's IP instead of 127.0.0.1.
runburrow porch run [--bind ADDR:PORT]Runs the dashboard until you stop it, on 0.0.0.0:8470 by default.
healthhttp://127.0.0.1:8470/healthzReturns ok true when the porch is up.
chores pagehttp://127.0.0.1:8470/choresOpens the chores page with each chore's last run.
stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens one rig's stashes page.
servicemake install-unitInstalls the porch as a systemd service and starts it now.
service filedeploy/burrow-porch.serviceOpens the systemd unit that runs the porch.
service log/var/log/burrow/porch.logOpens the log the porch service writes.
porch settingsconfig/burrow.tomlOpens the porch section: bind address, title and refresh interval.
metrics
The metrics: rig temperatures and disk use, stored by Prometheus and graphed in Grafana.
startmake up (docker compose up -d)Starts the pulse, prometheus and grafana containers in the background.
stopmake downStops those containers.
graphshttp://127.0.0.1:3000Opens Grafana, with graphs of rig temperatures and disk use.
raw valueshttp://127.0.0.1:9188/metricsShows the raw values pulse exposes for Prometheus.
pulse codepulse/pulse.pyOpens the code that reads temperatures and disk use from the rigs.
containersdocker-compose.ymlOpens the file defining the three containers and Prometheus's 30-day retention.
scripts
The helper scripts, grouped by the job they do.
healthburrow scripts healthPrints the health screen: disks, temperatures, SMART, power and fans.
rigsburrow scripts rigsPrints the rigs screen: updates, reboots, keys, clock and rig-list import.
networkburrow scripts networkPrints the network screen: speed, DNS, ports, Pi-hole and certificates.
storageburrow scripts storagePrints the storage screen: NAS mounts, scrubs, Docker cleanup and log rotation.
scripts › health
The health scripts: checks on disks, temperatures, SMART, power and fans.
check disksscripts/check-disks.shShows disk use on every rig.
temp checkscripts/temp-check.shChecks rig temperatures (purpose read from its name; confirm before building).
SMART reportscripts/smart-report.shPrints SMART disk health for the rigs' drives (purpose read from its name; confirm before building).
UPS statusscripts/ups-status.shShows the UPS battery and load (purpose read from its name; confirm before building).
battery reportscripts/battery-report.shPrints a battery report (purpose read from its name; confirm before building).
fan curvescripts/fan-curve.shSets the fan speed curve (purpose read from its name; confirm before building).
scripts › rigs
The rig scripts: updates, reboots, keys, clock and rig-list import.
update rigsscripts/update-rigs.shUpdates the rigs (purpose read from its name; confirm before building).
reboot rigscripts/reboot-rig.sh <address>Reboots one rig after a 10-second countdown.
push ssh keysscripts/ssh-keys-push.shCopies the burrow ssh key to the rigs (purpose read from its name; confirm before building).
sync clockscripts/sync-clock.shSyncs the clocks on the rigs (purpose read from its name; confirm before building).
import rigsscripts/import-rigs.shImports rigs into the rig list (purpose read from its name; confirm before building).
scripts › network
The network scripts: speed, DNS, ports, Pi-hole and certificates.
net speedscripts/net-speed.shMeasures network speed (purpose read from its name; confirm before building).
DNS flushscripts/dns-flush.shFlushes the DNS cache (purpose read from its name; confirm before building).
list portsscripts/list-ports.shLists the open ports (purpose read from its name; confirm before building).
Pi-hole updatescripts/pihole-update.shUpdates Pi-hole (purpose read from its name; confirm before building).
cert renewscripts/cert-renew.shRenews certificates (purpose read from its name; confirm before building).
scripts › storage
The storage scripts: NAS mounts, scrubs, Docker cleanup and log rotation.
mount NASscripts/mount-nas.shMounts the NAS (purpose read from its name; confirm before building).
unmount NASscripts/unmount-nas.shUnmounts the NAS (purpose read from its name; confirm before building).
ZFS scrubscripts/zfs-scrub.shRuns a ZFS scrub (purpose read from its name; confirm before building).
Docker cleanupscripts/gc-docker.shCleans up unused Docker data (purpose read from its name; confirm before building).
rotate logsscripts/rotate-logs.shRotates the logs (purpose read from its name; confirm before building).
setup
Setup: installing, starting, configuring and developing burrow, and its setup guide.
installmake installCreates the virtualenv and installs the burrow command into it.
install servicemake install-unitInstalls and starts the porch service under systemd; step two of setup.
chore schedulecrontab deploy/burrow.crontabInstalls the chore schedule into your crontab; step three of setup.
prune schedulemake install-prune-cronAdds a weekly crontab line that prunes old stashes.
metricsmake upStarts the metrics containers; the optional last setup step.
main settingsconfig/burrow.tomlOpens the main settings for stash, chores, porch and ssh.
environment template.env.exampleOpens the template to copy to .env, with the ssh key path, porch secret and ntfy topic.
config flagburrow --config PATHRuns burrow against another config file.
seed dev datascripts/seed-dev.shSeeds development data (purpose read from its name; confirm before building).
testsmake testRuns the test suite with pytest.
lintmake lintChecks burrow and the tests with ruff.
cleanmake cleanDeletes the virtualenv and build leftovers.
setup guidedocs/setup.mdOpens the setup steps in order.
Questions
  • burrow stash <rig> takes a stash today, and a bare noun is meant to print its screen. Recommendation: keep burrow stash <rig> as taking, and make bare burrow stash print the stash screen. Keep it that way?
  • burrow porch runs the dashboard today, and the systemd unit calls it. Recommendation: bare burrow porch prints the porch screen, burrow porch run runs it, and the unit's ExecStart changes to porch run. Agree?
  • Metrics needs a new burrow metrics command, a thin wrapper over make up and make down. Recommendation: keep it top-level. The alternative is folding it into setup, which gives six top groups instead of seven.
  • Split the 25 scripts into four groups (health, rigs, network, storage) behind a scripts screen. Recommendation: keep the split. The alternative is one 25-row list.
As phone screens

Home

What burrow looks after: its rigs, stashes, chores, porch, metrics, scripts and setup.

rigsLists the rigs and whether each one answers; a rig's name opens its screen.
›
stashPrints the stash screen: taking, listing, pruning and restoring stashes.
›
choresPrints the chores screen: the recurring jobs, how to run one, and when each last ran.
›
porchPrints the porch screen: the dashboard's pages, its service, and how to run it.
›
metricsPrints the metrics screen: starting the containers and where the graphs are.
›
scriptsPrints the scripts screen: the helper scripts, grouped by the job they do.
›
setupPrints the setup screen: installing, configuring, developing, and the setup guide.
›
‹ Home

rigs

The rigs burrow knows, and whether each one answers.

atticPrints the attic screen: its address, its folders, and what you can do to it.
›
cellarPrints the cellar screen: its address, its folders, and what you can do to it.
›
gardenPrints the garden screen: its address, its folders, and what you can do to it.
›
add a rigOpens the guide to adding a rig block to the rig list.
›
rig listOpens the list of rigs, with each one's name, address, MAC and paths.
›
‹ rigs

attic

The attic rig: its address, the folders stashed from it, and what you can do to it.

addressOpens an ssh session to attic as the burrow user.
›
foldersOpens the rig list, where attic's folders are /etc, /home and /var/lib/docker/volumes.
›
wakeSends a wake packet to attic's MAC address, for when it is asleep.
›
take a stashTakes a stash of attic now.
›
its stashesPrints the stashes kept for attic.
›
stashes pageOpens the porch page listing attic's stashes.
›
restoreCopies a dated stash of attic back onto attic.
›
rebootReboots attic after a 10-second countdown.
›
‹ Home

stash

The stashes: snapshots of a rig's folders, taken, listed, pruned and put back from here.

take one rig's stashTakes a stash of the named rig, now.
›
take every rig's stashTakes a stash of every rig in the rig list.
›
list a rig's stashesPrints the stashes kept for one rig.
›
pruneRemoves old stashes, keeping the newest 8 (--keep sets the number).
›
restoreCopies a dated stash back onto its rig; --dry-run is the flag to check first.
›
restore by handOpens the steps to copy a stash back with rsync, for when burrow itself is broken.
›
stash folderOpens the folder stashes are written to: one folder per rig, one dated folder per stash.
›
stash manifestOpens a stash's manifest: its paths and the rsync exit code, where non-zero means partial.
›
verifyChecks that a rig's newest stash is readable and not empty.
›
stash disk useRuns the stash disk-use script (purpose read from its name; confirm before building).
›
‹ Home

chores

The chores: recurring jobs that cron runs, and when each one last ran.

listPrints the name of every registered chore.
›
run oneRuns one chore now and records its result.
›
statusPrints when each chore last finished and whether it worked.
›
nightly-stashTakes a stash of every rig; cron runs it at 02:15 each night.
›
disk-checkWarns when a rig's root disk is over 85 percent; cron runs it every 6 hours.
›
chore output logOpens the log where cron writes the chores' output.
›
last-run recordOpens the file that records each chore's last run.
›
chores pageOpens the porch page showing each chore's last run.
›
scheduleOpens the file that sets when the chores run.
›
chore codeOpens chores.py, where each chore is registered.
›
chores guideOpens the guide to chores.
›
export choresRuns the chore export script (purpose read from its name; confirm before building).
›
‹ Home

porch

The porch: the dashboard for the rigs, served on port 8470.

openOpens the dashboard on this machine; from the LAN, use the rig's IP instead of 127.0.0.1.
›
runRuns the dashboard until you stop it, on 0.0.0.0:8470 by default.
›
healthReturns ok true when the porch is up.
›
chores pageOpens the chores page with each chore's last run.
›
stashes pageOpens one rig's stashes page.
›
serviceInstalls the porch as a systemd service and starts it now.
›
service fileOpens the systemd unit that runs the porch.
›
service logOpens the log the porch service writes.
›
porch settingsOpens the porch section: bind address, title and refresh interval.
›
‹ Home

metrics

The metrics: rig temperatures and disk use, stored by Prometheus and graphed in Grafana.

startStarts the pulse, prometheus and grafana containers in the background.
›
stopStops those containers.
›
graphsOpens Grafana, with graphs of rig temperatures and disk use.
›
raw valuesShows the raw values pulse exposes for Prometheus.
›
pulse codeOpens the code that reads temperatures and disk use from the rigs.
›
containersOpens the file defining the three containers and Prometheus's 30-day retention.
›
‹ Home

scripts

The helper scripts, grouped by the job they do.

healthPrints the health screen: disks, temperatures, SMART, power and fans.
›
rigsPrints the rigs screen: updates, reboots, keys, clock and rig-list import.
›
networkPrints the network screen: speed, DNS, ports, Pi-hole and certificates.
›
storagePrints the storage screen: NAS mounts, scrubs, Docker cleanup and log rotation.
›
‹ scripts

health

The health scripts: checks on disks, temperatures, SMART, power and fans.

check disksShows disk use on every rig.
›
temp checkChecks rig temperatures (purpose read from its name; confirm before building).
›
SMART reportPrints SMART disk health for the rigs' drives (purpose read from its name; confirm before building).
›
UPS statusShows the UPS battery and load (purpose read from its name; confirm before building).
›
battery reportPrints a battery report (purpose read from its name; confirm before building).
›
fan curveSets the fan speed curve (purpose read from its name; confirm before building).
›
‹ scripts

rigs

The rig scripts: updates, reboots, keys, clock and rig-list import.

update rigsUpdates the rigs (purpose read from its name; confirm before building).
›
reboot rigReboots one rig after a 10-second countdown.
›
push ssh keysCopies the burrow ssh key to the rigs (purpose read from its name; confirm before building).
›
sync clockSyncs the clocks on the rigs (purpose read from its name; confirm before building).
›
import rigsImports rigs into the rig list (purpose read from its name; confirm before building).
›
‹ scripts

network

The network scripts: speed, DNS, ports, Pi-hole and certificates.

net speedMeasures network speed (purpose read from its name; confirm before building).
›
DNS flushFlushes the DNS cache (purpose read from its name; confirm before building).
›
list portsLists the open ports (purpose read from its name; confirm before building).
›
Pi-hole updateUpdates Pi-hole (purpose read from its name; confirm before building).
›
cert renewRenews certificates (purpose read from its name; confirm before building).
›
‹ scripts

storage

The storage scripts: NAS mounts, scrubs, Docker cleanup and log rotation.

mount NASMounts the NAS (purpose read from its name; confirm before building).
›
unmount NASUnmounts the NAS (purpose read from its name; confirm before building).
›
ZFS scrubRuns a ZFS scrub (purpose read from its name; confirm before building).
›
Docker cleanupCleans up unused Docker data (purpose read from its name; confirm before building).
›
rotate logsRotates the logs (purpose read from its name; confirm before building).
›
‹ Home

setup

Setup: installing, starting, configuring and developing burrow, and its setup guide.

installCreates the virtualenv and installs the burrow command into it.
›
install serviceInstalls and starts the porch service under systemd; step two of setup.
›
chore scheduleInstalls the chore schedule into your crontab; step three of setup.
›
prune scheduleAdds a weekly crontab line that prunes old stashes.
›
metricsStarts the metrics containers; the optional last setup step.
›
main settingsOpens the main settings for stash, chores, porch and ssh.
›
environment templateOpens the template to copy to .env, with the ssh key path, porch secret and ntfy topic.
›
config flagRuns burrow against another config file.
›
seed dev dataSeeds development data (purpose read from its name; confirm before building).
›
testsRuns the test suite with pytest.
›
lintChecks burrow and the tests with ruff.
›
cleanDeletes the virtualenv and build leftovers.
›
setup guideOpens the setup steps in order.
›
Raw answer
## Scenario

This is reasoned from the README and docs, not from observed use. Someone who runs three or more home-lab machines reaches for burrow:

- after a power cut, to see which rigs are back (`burrow rigs`)
- before a risky change, to take a stash
- after a mistake, to put a file back from a stash
- to check whether last night's chores ran, or whether a disk is filling
- to wake a sleeping rig, or reboot one
- to see temperature and disk graphs
- to add a new rig

## Screen tree

- **top**: rigs, stash, chores, porch, metrics, scripts, setup
- **rigs**: one screen per rig, from `config/rigs.toml` (attic, cellar, garden)
- **stash**
- **chores**
- **porch**
- **metrics**
- **scripts**: health, rigs, network, storage
- **setup**

## Judgment calls

1. **Rig screens are generated** from `config/rigs.toml`. I wrote out attic. Cellar and garden get the same rows with their own names and addresses.
2. **Script descriptions are partly inferred.** I could read only three scripts (`check-disks.sh`, `verify-stash.sh`, `reboot-rig.sh`) and `rig-wake`. The other lines come from file names. Read each script's first comment line before the map is built.
3. **`bin/rig-wake` sits under attic**, not under scripts, because it lives in `bin/`.
4. **Prometheus is not listed as reachable.** It publishes no port, so it is in the inventory only.
5. **Graphs will be flat zeros as the code stands.** `read_temp` and `read_disk` in `pulse/pulse.py` return `0.0`. This is a finding, not something the map hides.
6. **Not done:** I could not run `rules`, read `~/.zsh.d`, or check command-name clashes with `whence`. Those are needed before any build.

## Questions for you

1. `burrow stash <rig>` takes a stash today, and a bare noun is meant to print its screen. **Recommendation:** keep `burrow stash <rig>` as taking, since the README uses it, and make bare `burrow stash` print the stash screen. Keep it that way?
2. `burrow porch` runs the dashboard today, and the systemd unit calls it. **Recommendation:** make bare `burrow porch` print the porch screen, add `burrow porch run` to run it, and change the unit's `ExecStart` to `porch run`. Agree?
3. Metrics needs a new `burrow metrics` command, a thin wrapper over `make up` and `make down`. **Recommendation:** keep it top-level. The alternative is folding it into setup, which gives six top groups instead of seven.
4. The 25 scripts are split into four groups behind a `scripts` screen. **Recommendation:** keep the split. The alternative is one 25-row list.

```json
{"screens": [
{"path": [], "sentence": "What burrow looks after: its rigs, stashes, chores, porch, metrics, scripts and setup.", "rows": [
{"name": "rigs", "form": "burrow rigs", "what": "Lists the rigs and whether each one answers; a rig's name opens its screen."},
{"name": "stash", "form": "burrow stash", "what": "Prints the stash screen: taking, listing, pruning and restoring stashes."},
{"name": "chores", "form": "burrow chores", "what": "Prints the chores screen: the recurring jobs, how to run one, and when each last ran."},
{"name": "porch", "form": "burrow porch", "what": "Prints the porch screen: the dashboard's pages, its service, and how to run it."},
{"name": "metrics", "form": "burrow metrics (new command)", "what": "Prints the metrics screen: starting the containers and where the graphs are."},
{"name": "scripts", "form": "burrow scripts", "what": "Prints the scripts screen: the helper scripts, grouped by the job they do."},
{"name": "setup", "form": "burrow setup", "what": "Prints the setup screen: installing, configuring, developing, and the setup guide."}
]},
{"path": ["rigs"], "sentence": "The rigs burrow knows, and whether each one answers.", "rows": [
{"name": "attic", "form": "burrow rigs attic", "what": "Prints the attic screen: its address, its folders, and what you can do to it."},
{"name": "cellar", "form": "burrow rigs cellar", "what": "Prints the cellar screen: its address, its folders, and what you can do to it."},
{"name": "garden", "form": "burrow rigs garden", "what": "Prints the garden screen: its address, its folders, and what you can do to it."},
{"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the guide to adding a rig block to the rig list."},
{"name": "rig list", "form": "config/rigs.toml", "what": "Opens the list of rigs, with each one's name, address, MAC and paths."}
]},
{"path": ["rigs", "attic"], "sentence": "The attic rig: its address, the folders stashed from it, and what you can do to it.", "rows": [
{"name": "address", "form": "ssh burrow@192.168.1.20", "what": "Opens an ssh session to attic as the burrow user."},
{"name": "folders", "form": "config/rigs.toml", "what": "Opens the rig list, where attic's folders are /etc, /home and /var/lib/docker/volumes."},
{"name": "wake", "form": "bin/rig-wake attic", "what": "Sends a wake packet to attic's MAC address, for when it is asleep."},
{"name": "take a stash", "form": "burrow stash attic", "what": "Takes a stash of attic now."},
{"name": "its stashes", "form": "burrow stash list attic", "what": "Prints the stashes kept for attic."},
{"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/attic", "what": "Opens the porch page listing attic's stashes."},
{"name": "restore", "form": "burrow restore attic --from YYYY-MM-DD", "what": "Copies a dated stash of attic back onto attic."},
{"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.20", "what": "Reboots attic after a 10-second countdown."}
]},
{"path": ["stash"], "sentence": "The stashes: snapshots of a rig's folders, taken, listed, pruned and put back from here.", "rows": [
{"name": "take one rig's stash", "form": "burrow stash <rig>", "what": "Takes a stash of the named rig, now."},
{"name": "take every rig's stash", "form": "burrow stash --all (make stash-all)", "what": "Takes a stash of every rig in the rig list."},
{"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Prints the stashes kept for one rig."},
{"name": "prune", "form": "burrow stash prune --keep 8 (make prune-stashes)", "what": "Removes old stashes, keeping the newest 8 (--keep sets the number)."},
{"name": "restore", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies a dated stash back onto its rig; --dry-run is the flag to check first."},
{"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the steps to copy a stash back with rsync, for when burrow itself is broken."},
{"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder stashes are written to: one folder per rig, one dated folder per stash."},
{"name": "stash manifest", "form": "/srv/burrow/stashes/<rig>/<YYYY-MM-DD>/.burrow-manifest", "what": "Opens a stash's manifest: its paths and the rsync exit code, where non-zero means partial."},
{"name": "verify", "form": "scripts/verify-stash.sh <rig>", "what": "Checks that a rig's newest stash is readable and not empty."},
{"name": "stash disk use", "form": "scripts/du-stashes.sh", "what": "Runs the stash disk-use script (purpose read from its name; confirm before building)."}
]},
{"path": ["chores"], "sentence": "The chores: recurring jobs that cron runs, and when each one last ran.", "rows": [
{"name": "list", "form": "burrow chores list", "what": "Prints the name of every registered chore."},
{"name": "run one", "form": "burrow chores run <name>", "what": "Runs one chore now and records its result."},
{"name": "status", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
{"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Takes a stash of every rig; cron runs it at 02:15 each night."},
{"name": "disk-check", "form": "burrow chores run disk-check", "what": "Warns when a rig's root disk is over 85 percent; cron runs it every 6 hours."},
{"name": "chore output log", "form": "/var/log/burrow/chores.log", "what": "Opens the log where cron writes the chores' output."},
{"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the file that records each chore's last run."},
{"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the porch page showing each chore's last run."},
{"name": "schedule", "form": "deploy/burrow.crontab", "what": "Opens the file that sets when the chores run."},
{"name": "chore code", "form": "burrow/chores.py", "what": "Opens chores.py, where each chore is registered."},
{"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide to chores."},
{"name": "export chores", "form": "scripts/export-chores.sh", "what": "Runs the chore export script (purpose read from its name; confirm before building)."}
]},
{"path": ["porch"], "sentence": "The porch: the dashboard for the rigs, served on port 8470.", "rows": [
{"name": "open", "form": "http://127.0.0.1:8470", "what": "Opens the dashboard on this machine; from the LAN, use the rig's IP instead of 127.0.0.1."},
{"name": "run", "form": "burrow porch run [--bind ADDR:PORT]", "what": "Runs the dashboard until you stop it, on 0.0.0.0:8470 by default."},
{"name": "health", "form": "http://127.0.0.1:8470/healthz", "what": "Returns ok true when the porch is up."},
{"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page with each chore's last run."},
{"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens one rig's stashes page."},
{"name": "service", "form": "make install-unit", "what": "Installs the porch as a systemd service and starts it now."},
{"name": "service file", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that runs the porch."},
{"name": "service log", "form": "/var/log/burrow/porch.log", "what": "Opens the log the porch service writes."},
{"name": "porch settings", "form": "config/burrow.toml", "what": "Opens the porch section: bind address, title and refresh interval."}
]},
{"path": ["metrics"], "sentence": "The metrics: rig temperatures and disk use, stored by Prometheus and graphed in Grafana.", "rows": [
{"name": "start", "form": "make up (docker compose up -d)", "what": "Starts the pulse, prometheus and grafana containers in the background."},
{"name": "stop", "form": "make down", "what": "Stops those containers."},
{"name": "graphs", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, with graphs of rig temperatures and disk use."},
{"name": "raw values", "form": "http://127.0.0.1:9188/metrics", "what": "Shows the raw values pulse exposes for Prometheus."},
{"name": "pulse code", "form": "pulse/pulse.py", "what": "Opens the code that reads temperatures and disk use from the rigs."},
{"name": "containers", "form": "docker-compose.yml", "what": "Opens the file defining the three containers and Prometheus's 30-day retention."}
]},
{"path": ["scripts"], "sentence": "The helper scripts, grouped by the job they do.", "rows": [
{"name": "health", "form": "burrow scripts health", "what": "Prints the health screen: disks, temperatures, SMART, power and fans."},
{"name": "rigs", "form": "burrow scripts rigs", "what": "Prints the rigs screen: updates, reboots, keys, clock and rig-list import."},
{"name": "network", "form": "burrow scripts network", "what": "Prints the network screen: speed, DNS, ports, Pi-hole and certificates."},
{"name": "storage", "form": "burrow scripts storage", "what": "Prints the storage screen: NAS mounts, scrubs, Docker cleanup and log rotation."}
]},
{"path": ["scripts", "health"], "sentence": "The health scripts: checks on disks, temperatures, SMART, power and fans.", "rows": [
{"name": "check disks", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig."},
{"name": "temp check", "form": "scripts/temp-check.sh", "what": "Checks rig temperatures (purpose read from its name; confirm before building)."},
{"name": "SMART report", "form": "scripts/smart-report.sh", "what": "Prints SMART disk health for the rigs' drives (purpose read from its name; confirm before building)."},
{"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Shows the UPS battery and load (purpose read from its name; confirm before building)."},
{"name": "battery report", "form": "scripts/battery-report.sh", "what": "Prints a battery report (purpose read from its name; confirm before building)."},
{"name": "fan curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan speed curve (purpose read from its name; confirm before building)."}
]},
{"path": ["scripts", "rigs"], "sentence": "The rig scripts: updates, reboots, keys, clock and rig-list import.", "rows": [
{"name": "update rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs (purpose read from its name; confirm before building)."},
{"name": "reboot rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10-second countdown."},
{"name": "push ssh keys", "form": "scripts/ssh-keys-push.sh", "what": "Copies the burrow ssh key to the rigs (purpose read from its name; confirm before building)."},
{"name": "sync clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clocks on the rigs (purpose read from its name; confirm before building)."},
{"name": "import rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into the rig list (purpose read from its name; confirm before building)."}
]},
{"path": ["scripts", "network"], "sentence": "The network scripts: speed, DNS, ports, Pi-hole and certificates.", "rows": [
{"name": "net speed", "form": "scripts/net-speed.sh", "what": "Measures network speed (purpose read from its name; confirm before building)."},
{"name": "DNS flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache (purpose read from its name; confirm before building)."},
{"name": "list ports", "form": "scripts/list-ports.sh", "what": "Lists the open ports (purpose read from its name; confirm before building)."},
{"name": "Pi-hole update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole (purpose read from its name; confirm before building)."},
{"name": "cert renew", "form": "scripts/cert-renew.sh", "what": "Renews certificates (purpose read from its name; confirm before building)."}
]},
{"path": ["scripts", "storage"], "sentence": "The storage scripts: NAS mounts, scrubs, Docker cleanup and log rotation.", "rows": [
{"name": "mount NAS", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS (purpose read from its name; confirm before building)."},
{"name": "unmount NAS", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS (purpose read from its name; confirm before building)."},
{"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Runs a ZFS scrub (purpose read from its name; confirm before building)."},
{"name": "Docker cleanup", "form": "scripts/gc-docker.sh", "what": "Cleans up unused Docker data (purpose read from its name; confirm before building)."},
{"name": "rotate logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs (purpose read from its name; confirm before building)."}
]},
{"path": ["setup"], "sentence": "Setup: installing, starting, configuring and developing burrow, and its setup guide.", "rows": [
{"name": "install", "form": "make install", "what": "Creates the virtualenv and installs the burrow command into it."},
{"name": "install service", "form": "make install-unit", "what": "Installs and starts the porch service under systemd; step two of setup."},
{"name": "chore schedule", "form": "crontab deploy/burrow.crontab", "what": "Installs the chore schedule into your crontab; step three of setup."},
{"name": "prune schedule", "form": "make install-prune-cron", "what": "Adds a weekly crontab line that prunes old stashes."},
{"name": "metrics", "form": "make up", "what": "Starts the metrics containers; the optional last setup step."},
{"name": "main settings", "form": "config/burrow.toml", "what": "Opens the main settings for stash, chores, porch and ssh."},
{"name": "environment template", "form": ".env.example", "what": "Opens the template to copy to .env, with the ssh key path, porch secret and ntfy topic."},
{"name": "config flag", "form": "burrow --config PATH", "what": "Runs burrow against another config file."},
{"name": "seed dev data", "form": "scripts/seed-dev.sh", "what": "Seeds development data (purpose read from its name; confirm before building)."},
{"name": "tests", "form": "make test", "what": "Runs the test suite with pytest."},
{"name": "lint", "form": "make lint", "what": "Checks burrow and the tests with ruff."},
{"name": "clean", "form": "make clean", "what": "Deletes the virtualenv and build leftovers."},
{"name": "setup guide", "form": "docs/setup.md", "what": "Opens the setup steps in order."}
]}
],
"questions": [
"burrow stash <rig> takes a stash today, and a bare noun is meant to print its screen. Recommendation: keep burrow stash <rig> as taking, and make bare burrow stash print the stash screen. Keep it that way?",
"burrow porch runs the dashboard today, and the systemd unit calls it. Recommendation: bare burrow porch prints the porch screen, burrow porch run runs it, and the unit's ExecStart changes to porch run. Agree?",
"Metrics needs a new burrow metrics command, a thin wrapper over make up and make down. Recommendation: keep it top-level. The alternative is folding it into setup, which gives six top groups instead of seven.",
"Split the 25 scripts into four groups (health, rigs, network, storage) behind a scripts screen. Recommendation: keep the split. The alternative is one 25-row list."
]}
```

screen-decomposition, final · run 2 exit=0 seconds=117 · prompt

P1 Recall: 0.867P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 9P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
burrow's map: its rigs, stashes, chores, porch, metrics, helper scripts, setup, development and docs.
rigsburrow rigsOpens the rigs burrow knows, and whether each one answers.
stashburrow stashOpens the stashes: taking, listing, restoring and pruning them.
choresburrow choresOpens the recurring jobs and when each one last ran.
porchburrow porch helpOpens the porch screen: the dashboard's pages and how to run it.
metricsburrow metricsOpens the metrics: the Grafana graphs and the containers behind them.
scriptsburrow scriptsOpens the helper scripts in scripts/ that you run by hand.
setupburrow setupOpens setup: installing burrow, its services and cron jobs, and its settings.
developmentburrow developmentOpens the commands for developing burrow: the tests and the linter.
docsburrow docsOpens the guides in docs/ and the README.
rigs
The rigs burrow knows, and whether each one answers now.
atticburrow rigs atticOpens attic's screen: its stash, restore, wake, check and reboot commands.
cellarburrow rigs cellarOpens cellar's screen: its stash, restore, wake, check and reboot commands.
gardenburrow rigs gardenOpens garden's screen: its stash, restore, wake, check and reboot commands.
rigs › attic
The attic rig, at 192.168.1.20, and what you can do to it.
take a stashburrow stash atticTakes a stash of attic now, into /srv/burrow/stashes/attic.
list stashesburrow stash list atticLists the stashes kept for attic.
restoreburrow restore attic --from YYYY-MM-DDCopies a stash back onto attic; add --dry-run to see what would change first.
wakebin/rig-wake atticSends a wake packet to attic, so a sleeping rig starts.
verify newest stashscripts/verify-stash.sh atticChecks that the newest stash of attic is readable and not empty.
rebootscripts/reboot-rig.sh 192.168.1.20Reboots attic after a 10 second countdown.
rigs › cellar
The cellar rig, at 192.168.1.21, and what you can do to it.
take a stashburrow stash cellarTakes a stash of cellar now, into /srv/burrow/stashes/cellar.
list stashesburrow stash list cellarLists the stashes kept for cellar.
restoreburrow restore cellar --from YYYY-MM-DDCopies a stash back onto cellar; add --dry-run to see what would change first.
wakebin/rig-wake cellarSends a wake packet to cellar, so a sleeping rig starts.
verify newest stashscripts/verify-stash.sh cellarChecks that the newest stash of cellar is readable and not empty.
rebootscripts/reboot-rig.sh 192.168.1.21Reboots cellar after a 10 second countdown.
rigs › garden
The garden rig, at 192.168.1.22, and what you can do to it.
take a stashburrow stash gardenTakes a stash of garden now, into /srv/burrow/stashes/garden.
list stashesburrow stash list gardenLists the stashes kept for garden.
restoreburrow restore garden --from YYYY-MM-DDCopies a stash back onto garden; add --dry-run to see what would change first.
wakebin/rig-wake gardenSends a wake packet to garden, so a sleeping rig starts.
verify newest stashscripts/verify-stash.sh gardenChecks that the newest stash of garden is readable and not empty.
rebootscripts/reboot-rig.sh 192.168.1.22Reboots garden after a 10 second countdown.
stash
The stashes: copies of each rig's folders, written under /srv/burrow/stashes, one folder per rig.
all rigsburrow stash --allTakes a stash of every rig at once.
pruneburrow stash prune --keep 8Removes old stashes, keeping the newest 8 (--keep sets how many).
stash folder/srv/burrow/stashesOpens the folder where every stash is written.
chores
The recurring jobs (chores), when each last ran, and whether it worked.
listburrow chores listPrints the names of the chores burrow knows.
runburrow chores run NAMERuns one chore now, such as disk-check, and records the result.
statusburrow chores statusPrints when each chore last finished and whether it worked.
chores pagehttp://127.0.0.1:8470/choresOpens the last runs of the chores in the browser, on the porch.
last-run record/srv/burrow/state/last-run.jsonOpens the record of each chore's last run.
chores log/var/log/burrow/chores.logOpens the log that the cron jobs write each chore's output to.
porch
The porch: the web dashboard on port 8470, its pages, and how to run it.
runburrow porchStarts the porch dashboard on 0.0.0.0:8470 and keeps it running until stopped.
dashboardhttp://127.0.0.1:8470Opens the dashboard with every rig on it.
stashes of a righttp://127.0.0.1:8470/stashes/atticOpens a rig's stashes in the browser; replace attic with the rig's name.
health checkhttp://127.0.0.1:8470/healthzReturns ok, as JSON, if the porch is up.
porch log/var/log/burrow/porch.logOpens the log the porch service writes to.
metrics
The metrics: graphs of rig temperatures and disk use, and the containers behind them.
startmake upStarts the containers in docker-compose.yml, Grafana among them.
stopmake downStops the containers in docker-compose.yml.
grafanahttp://127.0.0.1:3000Opens Grafana, with graphs of rig temperatures and disk use.
pulse metricshttp://127.0.0.1:9188/metricsPrints the temperature and disk gauges Prometheus reads; they read zero until the real reads are written.
containersdocker-compose.ymlOpens the containers that make up starts: pulse, Prometheus and Grafana, with their ports.
scripts
The helper scripts in scripts/, which you run by hand.
battery reportscripts/battery-report.shPrints the battery report.
cert renewscripts/cert-renew.shRenews the certificates.
check disksscripts/check-disks.shPrints disk use on every rig in config/rigs.toml.
dns flushscripts/dns-flush.shFlushes the DNS cache.
du stashesscripts/du-stashes.shPrints how much space the stashes take up.
export choresscripts/export-chores.shExports the chores to a file.
fan curvescripts/fan-curve.shSets the fan curve.
gc dockerscripts/gc-docker.shFrees space by removing unused Docker data.
import rigsscripts/import-rigs.shImports rigs into the rigs list.
list portsscripts/list-ports.shLists the open ports.
mount nasscripts/mount-nas.shMounts the NAS.
net speedscripts/net-speed.shMeasures the network speed.
pihole updatescripts/pihole-update.shUpdates Pi-hole.
rotate logsscripts/rotate-logs.shRotates the log files.
seed devscripts/seed-dev.shFills a development setup with sample data.
smart reportscripts/smart-report.shPrints the SMART disk health report.
ssh keys pushscripts/ssh-keys-push.shPushes SSH keys to the rigs.
sync clockscripts/sync-clock.shSyncs the clock.
temp checkscripts/temp-check.shPrints the temperatures.
unmount nasscripts/unmount-nas.shUnmounts the NAS.
update rigsscripts/update-rigs.shUpdates the rigs.
ups statusscripts/ups-status.shPrints the UPS status.
zfs scrubscripts/zfs-scrub.shStarts a ZFS scrub.
setup
Setting burrow up: installing it, running its services and cron jobs, and its settings files.
installmake installCreates the virtualenv in .venv/, installs burrow into it, and makes the stash, state and log folders.
install porch servicemake install-unitInstalls the porch as a systemd service and starts it.
install chores crontabcrontab deploy/burrow.crontabInstalls the cron lines for the nightly stash and the disk check.
install weekly prunemake install-prune-cronAdds a weekly stash prune to the crontab, Sundays at 04:40.
cleanmake cleanRemoves the virtualenv and build leftovers; the next install recreates them.
porch service filedeploy/burrow-porch.serviceOpens the systemd unit that runs the porch.
chores crontab filedeploy/burrow.crontabOpens the cron lines for the nightly stash and the disk check.
settingsburrow setup settingsOpens the settings files: burrow.toml, rigs.toml and .env.
setup › settings
The settings files: where burrow's options, your rigs and your secrets live.
burrow.tomlconfig/burrow.tomlOpens the options: stash folder and keep count, chores state file, porch address, and the SSH user and key variable.
rigs.tomlconfig/rigs.tomlOpens the list of rigs: each one's name, address, MAC and paths.
env.env.exampleOpens the example settings to copy to .env: SSH key path, porch secret and ntfy topic.
another settings fileburrow --config PATHUses another settings file for one command.
development
The commands for developing burrow: the tests and the linter.
testmake testRuns the test suite in tests/.
lintmake lintChecks burrow/ and tests/ with ruff.
tests foldertests/Opens the test files: test_stash, test_chores and test_rigs.
docs
The guides: the README, setup, adding a rig, chores, and restoring a stash by hand.
READMEREADME.mdOpens the README: what burrow is and how to use it.
setup guidedocs/setup.mdOpens the steps to set up the rigs and the rig that runs burrow.
adding a rigdocs/adding-a-rig.mdOpens the steps to add a rig to config/rigs.toml.
chores guidedocs/chores.mdOpens the guide to the chores and where their last runs are kept.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the steps to restore a stash with rsync when burrow itself is broken.
Questions
  • `burrow porch` already starts the server that the systemd unit runs, so it cannot also be the porch screen. Recommendation: keep `burrow porch` as the server and open the porch screen at `burrow porch help`. The alternative is to rename the server to `burrow porch serve` and change the unit's ExecStart to match. Which do you want?
  • The scripts screen lists 23 scripts. Split them into groups behind a new screen? Recommendation: five groups: checks (check disks, smart report, temp check, ups status, list ports); network (net speed, dns flush, pihole update); care (zfs scrub, gc docker, rotate logs, cert renew, du stashes); machines (mount nas, unmount nas, sync clock, ssh keys push, update rigs, fan curve, import rigs, export chores, battery report); development (seed dev, which moves under development).
  • seed-dev.sh looks like a development tool. Keep it on the scripts screen, or move it to development, or leave it off the map as unused?
  • The pulse metrics row points at a service whose temperature and disk reads still return zero. Keep the row on the map until real reads are written, or leave it off?
  • The top screen has 9 groups, at the upper edge of a short list. Keep them, or fold metrics and scripts under another screen?
As phone screens

Home

burrow's map: its rigs, stashes, chores, porch, metrics, helper scripts, setup, development and docs.

rigsOpens the rigs burrow knows, and whether each one answers.
›
stashOpens the stashes: taking, listing, restoring and pruning them.
›
choresOpens the recurring jobs and when each one last ran.
›
porchOpens the porch screen: the dashboard's pages and how to run it.
›
metricsOpens the metrics: the Grafana graphs and the containers behind them.
›
scriptsOpens the helper scripts in scripts/ that you run by hand.
›
setupOpens setup: installing burrow, its services and cron jobs, and its settings.
›
developmentOpens the commands for developing burrow: the tests and the linter.
›
docsOpens the guides in docs/ and the README.
›
‹ Home

rigs

The rigs burrow knows, and whether each one answers now.

atticOpens attic's screen: its stash, restore, wake, check and reboot commands.
›
cellarOpens cellar's screen: its stash, restore, wake, check and reboot commands.
›
gardenOpens garden's screen: its stash, restore, wake, check and reboot commands.
›
‹ rigs

attic

The attic rig, at 192.168.1.20, and what you can do to it.

take a stashTakes a stash of attic now, into /srv/burrow/stashes/attic.
›
list stashesLists the stashes kept for attic.
›
restoreCopies a stash back onto attic; add --dry-run to see what would change first.
›
wakeSends a wake packet to attic, so a sleeping rig starts.
›
verify newest stashChecks that the newest stash of attic is readable and not empty.
›
rebootReboots attic after a 10 second countdown.
›
‹ rigs

cellar

The cellar rig, at 192.168.1.21, and what you can do to it.

take a stashTakes a stash of cellar now, into /srv/burrow/stashes/cellar.
›
list stashesLists the stashes kept for cellar.
›
restoreCopies a stash back onto cellar; add --dry-run to see what would change first.
›
wakeSends a wake packet to cellar, so a sleeping rig starts.
›
verify newest stashChecks that the newest stash of cellar is readable and not empty.
›
rebootReboots cellar after a 10 second countdown.
›
‹ rigs

garden

The garden rig, at 192.168.1.22, and what you can do to it.

take a stashTakes a stash of garden now, into /srv/burrow/stashes/garden.
›
list stashesLists the stashes kept for garden.
›
restoreCopies a stash back onto garden; add --dry-run to see what would change first.
›
wakeSends a wake packet to garden, so a sleeping rig starts.
›
verify newest stashChecks that the newest stash of garden is readable and not empty.
›
rebootReboots garden after a 10 second countdown.
›
‹ Home

stash

The stashes: copies of each rig's folders, written under /srv/burrow/stashes, one folder per rig.

all rigsTakes a stash of every rig at once.
›
pruneRemoves old stashes, keeping the newest 8 (--keep sets how many).
›
stash folderOpens the folder where every stash is written.
›
‹ Home

chores

The recurring jobs (chores), when each last ran, and whether it worked.

listPrints the names of the chores burrow knows.
›
runRuns one chore now, such as disk-check, and records the result.
›
statusPrints when each chore last finished and whether it worked.
›
chores pageOpens the last runs of the chores in the browser, on the porch.
›
last-run recordOpens the record of each chore's last run.
›
chores logOpens the log that the cron jobs write each chore's output to.
›
‹ Home

porch

The porch: the web dashboard on port 8470, its pages, and how to run it.

runStarts the porch dashboard on 0.0.0.0:8470 and keeps it running until stopped.
›
dashboardOpens the dashboard with every rig on it.
›
stashes of a rigOpens a rig's stashes in the browser; replace attic with the rig's name.
›
health checkReturns ok, as JSON, if the porch is up.
›
porch logOpens the log the porch service writes to.
›
‹ Home

metrics

The metrics: graphs of rig temperatures and disk use, and the containers behind them.

startStarts the containers in docker-compose.yml, Grafana among them.
›
stopStops the containers in docker-compose.yml.
›
grafanaOpens Grafana, with graphs of rig temperatures and disk use.
›
pulse metricsPrints the temperature and disk gauges Prometheus reads; they read zero until the real reads are written.
›
containersOpens the containers that make up starts: pulse, Prometheus and Grafana, with their ports.
›
‹ Home

scripts

The helper scripts in scripts/, which you run by hand.

battery reportPrints the battery report.
›
cert renewRenews the certificates.
›
check disksPrints disk use on every rig in config/rigs.toml.
›
dns flushFlushes the DNS cache.
›
du stashesPrints how much space the stashes take up.
›
export choresExports the chores to a file.
›
fan curveSets the fan curve.
›
gc dockerFrees space by removing unused Docker data.
›
import rigsImports rigs into the rigs list.
›
list portsLists the open ports.
›
mount nasMounts the NAS.
›
net speedMeasures the network speed.
›
pihole updateUpdates Pi-hole.
›
rotate logsRotates the log files.
›
seed devFills a development setup with sample data.
›
smart reportPrints the SMART disk health report.
›
ssh keys pushPushes SSH keys to the rigs.
›
sync clockSyncs the clock.
›
temp checkPrints the temperatures.
›
unmount nasUnmounts the NAS.
›
update rigsUpdates the rigs.
›
ups statusPrints the UPS status.
›
zfs scrubStarts a ZFS scrub.
›
‹ Home

setup

Setting burrow up: installing it, running its services and cron jobs, and its settings files.

installCreates the virtualenv in .venv/, installs burrow into it, and makes the stash, state and log folders.
›
install porch serviceInstalls the porch as a systemd service and starts it.
›
install chores crontabInstalls the cron lines for the nightly stash and the disk check.
›
install weekly pruneAdds a weekly stash prune to the crontab, Sundays at 04:40.
›
cleanRemoves the virtualenv and build leftovers; the next install recreates them.
›
porch service fileOpens the systemd unit that runs the porch.
›
chores crontab fileOpens the cron lines for the nightly stash and the disk check.
›
settingsOpens the settings files: burrow.toml, rigs.toml and .env.
›
‹ setup

settings

The settings files: where burrow's options, your rigs and your secrets live.

burrow.tomlOpens the options: stash folder and keep count, chores state file, porch address, and the SSH user and key variable.
›
rigs.tomlOpens the list of rigs: each one's name, address, MAC and paths.
›
envOpens the example settings to copy to .env: SSH key path, porch secret and ntfy topic.
›
another settings fileUses another settings file for one command.
›
‹ Home

development

The commands for developing burrow: the tests and the linter.

testRuns the test suite in tests/.
›
lintChecks burrow/ and tests/ with ruff.
›
tests folderOpens the test files: test_stash, test_chores and test_rigs.
›
‹ Home

docs

The guides: the README, setup, adding a rig, chores, and restoring a stash by hand.

READMEOpens the README: what burrow is and how to use it.
›
setup guideOpens the steps to set up the rigs and the rig that runs burrow.
›
adding a rigOpens the steps to add a rig to config/rigs.toml.
›
chores guideOpens the guide to the chores and where their last runs are kept.
›
restore by handOpens the steps to restore a stash with rsync when burrow itself is broken.
›
Raw answer
## Scenario

A home-lab owner at a terminal on a Sunday. One rig is acting up, so they want a stash of it now, want to see whether last night's nightly stash ran, and may need to restore a file. Reasoning from experience, not from observed use.

## Judgment calls

- **Rig screens come from `config/rigs.toml`.** `attic`, `cellar` and `garden` each get a screen with the same six actions. All three are written out so the map is complete. A fourth rig adds a screen with no hand edit.
- **Make wrappers are not separate rows.** `make stash-all` and `make prune-stashes` run `burrow stash --all` and `burrow stash prune`. Each action is listed once, under the burrow command.
- **Porch pages sit on the porch screen, and the chores page on the chores screen.** The `/stashes/<rig>` page is listed once, on the porch screen.
- **Excluded:** the Prometheus container (no port or page for the user), `pyproject.toml` and `pulse/Dockerfile` (install internals), `LICENSE`, the `burrow/` source, `.venv/`, and `.env` (copied from `.env.example`).
- **Script purposes are inferred from their names,** except `check-disks.sh` and `reboot-rig.sh`, which I read. The 23 lines need checking against each script's header before they are built.
- **Group forms are new help screens.** `burrow rigs` exists and prints its list. `burrow stash` exists but errors when run bare, and `burrow chores` prints nothing bare. The map gives both a screen.
- **Top screen has 9 groups,** at the upper edge of "a few". I kept them rather than fold any, and the question list asks whether to.

The questions are in the JSON below.

```json
{"screens": [
  {"path": [], "sentence": "burrow's map: its rigs, stashes, chores, porch, metrics, helper scripts, setup, development and docs.", "rows": [
    {"name": "rigs", "form": "burrow rigs", "what": "Opens the rigs burrow knows, and whether each one answers."},
    {"name": "stash", "form": "burrow stash", "what": "Opens the stashes: taking, listing, restoring and pruning them."},
    {"name": "chores", "form": "burrow chores", "what": "Opens the recurring jobs and when each one last ran."},
    {"name": "porch", "form": "burrow porch help", "what": "Opens the porch screen: the dashboard's pages and how to run it."},
    {"name": "metrics", "form": "burrow metrics", "what": "Opens the metrics: the Grafana graphs and the containers behind them."},
    {"name": "scripts", "form": "burrow scripts", "what": "Opens the helper scripts in scripts/ that you run by hand."},
    {"name": "setup", "form": "burrow setup", "what": "Opens setup: installing burrow, its services and cron jobs, and its settings."},
    {"name": "development", "form": "burrow development", "what": "Opens the commands for developing burrow: the tests and the linter."},
    {"name": "docs", "form": "burrow docs", "what": "Opens the guides in docs/ and the README."}
  ]},
  {"path": ["rigs"], "sentence": "The rigs burrow knows, and whether each one answers now.", "rows": [
    {"name": "attic", "form": "burrow rigs attic", "what": "Opens attic's screen: its stash, restore, wake, check and reboot commands."},
    {"name": "cellar", "form": "burrow rigs cellar", "what": "Opens cellar's screen: its stash, restore, wake, check and reboot commands."},
    {"name": "garden", "form": "burrow rigs garden", "what": "Opens garden's screen: its stash, restore, wake, check and reboot commands."}
  ]},
  {"path": ["rigs", "attic"], "sentence": "The attic rig, at 192.168.1.20, and what you can do to it.", "rows": [
    {"name": "take a stash", "form": "burrow stash attic", "what": "Takes a stash of attic now, into /srv/burrow/stashes/attic."},
    {"name": "list stashes", "form": "burrow stash list attic", "what": "Lists the stashes kept for attic."},
    {"name": "restore", "form": "burrow restore attic --from YYYY-MM-DD", "what": "Copies a stash back onto attic; add --dry-run to see what would change first."},
    {"name": "wake", "form": "bin/rig-wake attic", "what": "Sends a wake packet to attic, so a sleeping rig starts."},
    {"name": "verify newest stash", "form": "scripts/verify-stash.sh attic", "what": "Checks that the newest stash of attic is readable and not empty."},
    {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.20", "what": "Reboots attic after a 10 second countdown."}
  ]},
  {"path": ["rigs", "cellar"], "sentence": "The cellar rig, at 192.168.1.21, and what you can do to it.", "rows": [
    {"name": "take a stash", "form": "burrow stash cellar", "what": "Takes a stash of cellar now, into /srv/burrow/stashes/cellar."},
    {"name": "list stashes", "form": "burrow stash list cellar", "what": "Lists the stashes kept for cellar."},
    {"name": "restore", "form": "burrow restore cellar --from YYYY-MM-DD", "what": "Copies a stash back onto cellar; add --dry-run to see what would change first."},
    {"name": "wake", "form": "bin/rig-wake cellar", "what": "Sends a wake packet to cellar, so a sleeping rig starts."},
    {"name": "verify newest stash", "form": "scripts/verify-stash.sh cellar", "what": "Checks that the newest stash of cellar is readable and not empty."},
    {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.21", "what": "Reboots cellar after a 10 second countdown."}
  ]},
  {"path": ["rigs", "garden"], "sentence": "The garden rig, at 192.168.1.22, and what you can do to it.", "rows": [
    {"name": "take a stash", "form": "burrow stash garden", "what": "Takes a stash of garden now, into /srv/burrow/stashes/garden."},
    {"name": "list stashes", "form": "burrow stash list garden", "what": "Lists the stashes kept for garden."},
    {"name": "restore", "form": "burrow restore garden --from YYYY-MM-DD", "what": "Copies a stash back onto garden; add --dry-run to see what would change first."},
    {"name": "wake", "form": "bin/rig-wake garden", "what": "Sends a wake packet to garden, so a sleeping rig starts."},
    {"name": "verify newest stash", "form": "scripts/verify-stash.sh garden", "what": "Checks that the newest stash of garden is readable and not empty."},
    {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.22", "what": "Reboots garden after a 10 second countdown."}
  ]},
  {"path": ["stash"], "sentence": "The stashes: copies of each rig's folders, written under /srv/burrow/stashes, one folder per rig.", "rows": [
    {"name": "all rigs", "form": "burrow stash --all", "what": "Takes a stash of every rig at once."},
    {"name": "prune", "form": "burrow stash prune --keep 8", "what": "Removes old stashes, keeping the newest 8 (--keep sets how many)."},
    {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder where every stash is written."}
  ]},
  {"path": ["chores"], "sentence": "The recurring jobs (chores), when each last ran, and whether it worked.", "rows": [
    {"name": "list", "form": "burrow chores list", "what": "Prints the names of the chores burrow knows."},
    {"name": "run", "form": "burrow chores run NAME", "what": "Runs one chore now, such as disk-check, and records the result."},
    {"name": "status", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
    {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the last runs of the chores in the browser, on the porch."},
    {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of each chore's last run."},
    {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the log that the cron jobs write each chore's output to."}
  ]},
  {"path": ["porch"], "sentence": "The porch: the web dashboard on port 8470, its pages, and how to run it.", "rows": [
    {"name": "run", "form": "burrow porch", "what": "Starts the porch dashboard on 0.0.0.0:8470 and keeps it running until stopped."},
    {"name": "dashboard", "form": "http://127.0.0.1:8470", "what": "Opens the dashboard with every rig on it."},
    {"name": "stashes of a rig", "form": "http://127.0.0.1:8470/stashes/attic", "what": "Opens a rig's stashes in the browser; replace attic with the rig's name."},
    {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns ok, as JSON, if the porch is up."},
    {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the log the porch service writes to."}
  ]},
  {"path": ["metrics"], "sentence": "The metrics: graphs of rig temperatures and disk use, and the containers behind them.", "rows": [
    {"name": "start", "form": "make up", "what": "Starts the containers in docker-compose.yml, Grafana among them."},
    {"name": "stop", "form": "make down", "what": "Stops the containers in docker-compose.yml."},
    {"name": "grafana", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, with graphs of rig temperatures and disk use."},
    {"name": "pulse metrics", "form": "http://127.0.0.1:9188/metrics", "what": "Prints the temperature and disk gauges Prometheus reads; they read zero until the real reads are written."},
    {"name": "containers", "form": "docker-compose.yml", "what": "Opens the containers that make up starts: pulse, Prometheus and Grafana, with their ports."}
  ]},
  {"path": ["scripts"], "sentence": "The helper scripts in scripts/, which you run by hand.", "rows": [
    {"name": "battery report", "form": "scripts/battery-report.sh", "what": "Prints the battery report."},
    {"name": "cert renew", "form": "scripts/cert-renew.sh", "what": "Renews the certificates."},
    {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Prints disk use on every rig in config/rigs.toml."},
    {"name": "dns flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache."},
    {"name": "du stashes", "form": "scripts/du-stashes.sh", "what": "Prints how much space the stashes take up."},
    {"name": "export chores", "form": "scripts/export-chores.sh", "what": "Exports the chores to a file."},
    {"name": "fan curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan curve."},
    {"name": "gc docker", "form": "scripts/gc-docker.sh", "what": "Frees space by removing unused Docker data."},
    {"name": "import rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into the rigs list."},
    {"name": "list ports", "form": "scripts/list-ports.sh", "what": "Lists the open ports."},
    {"name": "mount nas", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS."},
    {"name": "net speed", "form": "scripts/net-speed.sh", "what": "Measures the network speed."},
    {"name": "pihole update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole."},
    {"name": "rotate logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the log files."},
    {"name": "seed dev", "form": "scripts/seed-dev.sh", "what": "Fills a development setup with sample data."},
    {"name": "smart report", "form": "scripts/smart-report.sh", "what": "Prints the SMART disk health report."},
    {"name": "ssh keys push", "form": "scripts/ssh-keys-push.sh", "what": "Pushes SSH keys to the rigs."},
    {"name": "sync clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock."},
    {"name": "temp check", "form": "scripts/temp-check.sh", "what": "Prints the temperatures."},
    {"name": "unmount nas", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS."},
    {"name": "update rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs."},
    {"name": "ups status", "form": "scripts/ups-status.sh", "what": "Prints the UPS status."},
    {"name": "zfs scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub."}
  ]},
  {"path": ["setup"], "sentence": "Setting burrow up: installing it, running its services and cron jobs, and its settings files.", "rows": [
    {"name": "install", "form": "make install", "what": "Creates the virtualenv in .venv/, installs burrow into it, and makes the stash, state and log folders."},
    {"name": "install porch service", "form": "make install-unit", "what": "Installs the porch as a systemd service and starts it."},
    {"name": "install chores crontab", "form": "crontab deploy/burrow.crontab", "what": "Installs the cron lines for the nightly stash and the disk check."},
    {"name": "install weekly prune", "form": "make install-prune-cron", "what": "Adds a weekly stash prune to the crontab, Sundays at 04:40."},
    {"name": "clean", "form": "make clean", "what": "Removes the virtualenv and build leftovers; the next install recreates them."},
    {"name": "porch service file", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that runs the porch."},
    {"name": "chores crontab file", "form": "deploy/burrow.crontab", "what": "Opens the cron lines for the nightly stash and the disk check."},
    {"name": "settings", "form": "burrow setup settings", "what": "Opens the settings files: burrow.toml, rigs.toml and .env."}
  ]},
  {"path": ["setup", "settings"], "sentence": "The settings files: where burrow's options, your rigs and your secrets live.", "rows": [
    {"name": "burrow.toml", "form": "config/burrow.toml", "what": "Opens the options: stash folder and keep count, chores state file, porch address, and the SSH user and key variable."},
    {"name": "rigs.toml", "form": "config/rigs.toml", "what": "Opens the list of rigs: each one's name, address, MAC and paths."},
    {"name": "env", "form": ".env.example", "what": "Opens the example settings to copy to .env: SSH key path, porch secret and ntfy topic."},
    {"name": "another settings file", "form": "burrow --config PATH", "what": "Uses another settings file for one command."}
  ]},
  {"path": ["development"], "sentence": "The commands for developing burrow: the tests and the linter.", "rows": [
    {"name": "test", "form": "make test", "what": "Runs the test suite in tests/."},
    {"name": "lint", "form": "make lint", "what": "Checks burrow/ and tests/ with ruff."},
    {"name": "tests folder", "form": "tests/", "what": "Opens the test files: test_stash, test_chores and test_rigs."}
  ]},
  {"path": ["docs"], "sentence": "The guides: the README, setup, adding a rig, chores, and restoring a stash by hand.", "rows": [
    {"name": "README", "form": "README.md", "what": "Opens the README: what burrow is and how to use it."},
    {"name": "setup guide", "form": "docs/setup.md", "what": "Opens the steps to set up the rigs and the rig that runs burrow."},
    {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps to add a rig to config/rigs.toml."},
    {"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide to the chores and where their last runs are kept."},
    {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the steps to restore a stash with rsync when burrow itself is broken."}
  ]}
 ],
 "questions": [
  "`burrow porch` already starts the server that the systemd unit runs, so it cannot also be the porch screen. Recommendation: keep `burrow porch` as the server and open the porch screen at `burrow porch help`. The alternative is to rename the server to `burrow porch serve` and change the unit's ExecStart to match. Which do you want?",
  "The scripts screen lists 23 scripts. Split them into groups behind a new screen? Recommendation: five groups: checks (check disks, smart report, temp check, ups status, list ports); network (net speed, dns flush, pihole update); care (zfs scrub, gc docker, rotate logs, cert renew, du stashes); machines (mount nas, unmount nas, sync clock, ssh keys push, update rigs, fan curve, import rigs, export chores, battery report); development (seed dev, which moves under development).",
  "seed-dev.sh looks like a development tool. Keep it on the scripts screen, or move it to development, or leave it off the map as unused?",
  "The pulse metrics row points at a service whose temperature and disk reads still return zero. Keep the row on the map until real reads are written, or leave it off?",
  "The top screen has 9 groups, at the upper edge of a short list. Keep them, or fold metrics and scripts under another screen?"
 ]}
```

No skill · run 3 exit=0 seconds=76 · prompt

P1 Recall: 0.85P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.531P5 Short top: 11P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
The burrow command: look after the home-lab rigs. It lists them, takes and restores snapshots (stashes), runs recurring chores, and serves the porch dashboard.
rigsburrow rigslist rigs and whether each one answers
stashburrow stash (opens the stash screen)take snapshots of rigs, list them, prune old ones
restoreburrow restore RIG --from YYYY-MM-DD [--dry-run]copy a stash back onto its rig
choresburrow chores (opens the chores screen)recurring jobs: list, run, status
porchburrow porch [--bind ADDR:PORT] (opens the porch screen)run the web dashboard
config file--config PATH (default config/burrow.toml)use a different settings file for any command
make targetsmake (opens the make screen)install, test, stash-all and other project tasks
helpersbin/rig-wake and scripts/ (opens the helpers screen)small shell helpers outside the burrow command
settingsconfig/ and .env (opens the settings screen)what to configure and where
metricsmake up (opens the metrics screen)graphs of rig temperatures and disk use
docsREADME.md and docs/ (opens the docs screen)setup and how-to pages
rigs
Lists the rigs burrow knows and whether each one answers. Takes no options.
stash
Take a snapshot of one rig or of all rigs, or manage the stashes that already exist.
take one rigburrow stash RIGsnapshot that rig now, written under /srv/burrow/stashes/RIG/DATE
take all rigsburrow stash --all (also make stash-all)snapshot every rig now
listburrow stash list (opens the stash list screen)show the stashes kept for one rig
pruneburrow stash prune (opens the stash prune screen)delete old stashes, keeping the newest ones
stash › list
Print the stashes kept for one rig.
rigRIG argument, for example atticwhich rig's stashes to list
stash › prune
Delete old stashes so the stash folder does not fill the disk.
keep--keep N (default 8)how many of the newest stashes to keep
restore
Copy one stash back onto its rig.
rigRIG argument, for example atticthe rig to restore onto
from--from YYYY-MM-DD (required)the date of the stash to restore
dry run--dry-runshow what would be copied without copying
chores
Recurring jobs. Lists the registered ones, runs one by hand, and shows when each last ran and whether it worked.
listburrow chores listnames of the registered chores
runburrow chores run NAME (opens the chores run screen)run one chore now
statusburrow chores statuslast finish time and result of each chore
chores pagehttp://127.0.0.1:8470/choresthe same status on the porch
chores › run
Run one named chore now and record the result.
nightly-stashburrow chores run nightly-stashstash every rig; cron runs it at 02:15
disk-checkburrow chores run disk-checkwarn when a rig's root disk is over 85 percent; cron runs it every 6 hours
porch
The web dashboard. The front page lists the rigs and links to the chores and stash pages.
bind address--bind ADDR:PORT (default from porch.bind, 0.0.0.0:8470)where the dashboard listens
dashboardhttp://127.0.0.1:8470/rigs and their up or down state; refreshes every 20 seconds
chores pagehttp://127.0.0.1:8470/choreslast run of each chore
stashes pagehttp://127.0.0.1:8470/stashes/RIGstashes kept for one rig
health checkhttp://127.0.0.1:8470/healthzreturns "ok": true when the porch is up
run as a servicemake install-unit (systemd burrow-porch.service)start the porch at boot; needs sudo
make
Project tasks, run from the repository root as make TARGET.
installmake installcreate the virtualenv, install burrow, make the stash, state and log folders
install-unitmake install-unitinstall and start the porch systemd service; needs sudo
upmake upstart the metrics containers
downmake downstop the metrics containers
testmake testrun the test suite
lintmake lintrun ruff on burrow and tests
stash-allmake stash-allstash every rig, same as burrow stash --all
prune-stashesmake prune-stasheskeep the 8 newest stashes per rig
install-prune-cronmake install-prune-cronadd a weekly prune job to your crontab, Sundays at 04:40
cleanmake cleanremove the virtualenv, caches and build files
helpers
Small shell helpers outside the burrow command. Read the top of each one before running it.
rig-wakebin/rig-wake RIGsend a wake packet to a sleeping rig using its MAC from rigs.toml
check-disksscripts/check-disks.shshow disk use on every rig over ssh
verify-stashscripts/verify-stash.sh RIGcheck the newest stash of a rig is readable and not empty
reboot-rigscripts/reboot-rig.sh ADDRESSreboot one rig after a 10 second countdown
battery-reportscripts/battery-report.shbattery report (from name; body not read)
cert-renewscripts/cert-renew.shrenew certificates (from name; body not read)
dns-flushscripts/dns-flush.shflush the DNS cache (from name; body not read)
du-stashesscripts/du-stashes.shmeasure stash folder sizes (from name; body not read)
export-choresscripts/export-chores.shexport chore records (from name; body not read)
fan-curvescripts/fan-curve.shset a fan curve (from name; body not read)
gc-dockerscripts/gc-docker.shclean up unused Docker data (from name; body not read)
import-rigsscripts/import-rigs.shimport rig definitions (from name; body not read)
list-portsscripts/list-ports.shlist open ports (from name; body not read)
mount-nasscripts/mount-nas.shmount the NAS (from name; body not read)
unmount-nasscripts/unmount-nas.shunmount the NAS (from name; body not read)
net-speedscripts/net-speed.shmeasure network speed (from name; body not read)
pihole-updatescripts/pihole-update.shupdate Pi-hole (from name; body not read)
rotate-logsscripts/rotate-logs.shrotate log files (from name; body not read)
seed-devscripts/seed-dev.shfill a dev setup with sample data (from name; body not read)
smart-reportscripts/smart-report.shdisk SMART health report (from name; body not read)
ssh-keys-pushscripts/ssh-keys-push.shpush SSH keys to rigs (from name; body not read)
sync-clockscripts/sync-clock.shsync the clock (from name; body not read)
temp-checkscripts/temp-check.shcheck rig temperatures (from name; body not read)
update-rigsscripts/update-rigs.shupdate packages on rigs (from name; body not read)
ups-statusscripts/ups-status.shshow UPS status (from name; body not read)
zfs-scrubscripts/zfs-scrub.shstart a ZFS scrub (from name; body not read)
settings
Where settings live and what each one controls.
burrow.tomlconfig/burrow.tomlstash root and keep count, chores state file, porch bind address, title and refresh, ssh user and key variable
rigs.tomlconfig/rigs.tomleach rig's name, address, MAC and paths; see docs/adding-a-rig.md
environment.env (copy from .env.example)BURROW_SSH_KEY, BURROW_PORCH_SECRET, BURROW_NTFY_TOPIC
config option--config PATHpoint any burrow command at another burrow.toml
metrics
Graphs of rig temperatures and disk use, from the metrics containers.
grafanahttp://127.0.0.1:3000the graphs; anonymous viewing is on
raw metricshttp://HOST:9188/metricspulse's raw values for Prometheus; temperature and disk are placeholders (0.0) in this snapshot
startmake upstart the containers
stopmake downstop the containers
docs
Pages for setup and everyday use.
readmeREADME.mdoverview, install, use
setupdocs/setup.mdfirst-time setup steps and checks
adding a rigdocs/adding-a-rig.mdadd a rig to rigs.toml
choresdocs/chores.mdwhat the chores do and how to check them
restore by handdocs/internals/stash/format/restore-by-hand.mdcopy a stash back with rsync when burrow is broken
Questions
  • Cron config path: deploy/burrow.crontab runs burrow with no --config, and cron starts in your home directory, so the default config/burrow.toml will not be found. Recommendation: put the absolute path (--config /opt/burrow/config/burrow.toml) on both cron lines.
  • Stash command shape: stash takes an optional RIG and also has list and prune subcommands, so 'burrow stash list attic' may read 'list' as the rig name. Recommendation: run it to check; if it misparses, make the take-one-rig form an explicit subcommand, for example 'burrow stash take RIG'.
  • Stash with neither RIG nor --all: the code would look up a rig named nothing. Recommendation: make it a clear usage error that shows the help screen.
  • Porch access: it binds 0.0.0.0 with no login, and BURROW_PORCH_SECRET is not used in the code shown. Recommendation: either enforce the secret or bind to the LAN only, and document which one you chose. Enforcing it is safer.
  • Alerts: chores set notify to ntfy and .env has BURROW_NTFY_TOPIC, but no code in this snapshot sends alerts. Do you want an alerts screen? Recommendation: leave it out of the help until the sending code exists.
  • Prune count: keep is 8 in burrow.toml and also 8 as the CLI default, so changing one does not change the other. Recommendation: have the CLI read the config value and use the default only when no config is given.
  • Restore by date: --from takes only a date. If two stashes are taken on one day, the later one may overwrite the earlier one. Please confirm which behavior you want, and the help text will say it.
  • Helper scripts: 22 descriptions are inferred from file names. Recommendation: read the header of each before writing help text, and keep the helpers out of the burrow command.
  • Wake a rig: bin/rig-wake is not a burrow command. Do you want 'burrow rigs wake NAME' so all rig actions live in one place? Recommendation: yes, if you use it often.
  • Metrics placeholders: pulse returns 0.0 for temperature and disk, so the Grafana graphs will be flat until those reads are filled in. Is that in scope for this help map? Recommendation: note it in the metrics help and leave it there.
As phone screens

Home

The burrow command: look after the home-lab rigs. It lists them, takes and restores snapshots (stashes), runs recurring chores, and serves the porch dashboard.

rigslist rigs and whether each one answers
›
stashtake snapshots of rigs, list them, prune old ones
›
restorecopy a stash back onto its rig
›
choresrecurring jobs: list, run, status
›
porchrun the web dashboard
›
config fileuse a different settings file for any command
›
make targetsinstall, test, stash-all and other project tasks
›
helperssmall shell helpers outside the burrow command
›
settingswhat to configure and where
›
metricsgraphs of rig temperatures and disk use
›
docssetup and how-to pages
›
‹ Home

rigs

Lists the rigs burrow knows and whether each one answers. Takes no options.

‹ Home

stash

Take a snapshot of one rig or of all rigs, or manage the stashes that already exist.

take one rigsnapshot that rig now, written under /srv/burrow/stashes/RIG/DATE
›
take all rigssnapshot every rig now
›
listshow the stashes kept for one rig
›
prunedelete old stashes, keeping the newest ones
›
‹ stash

list

Print the stashes kept for one rig.

rigwhich rig's stashes to list
›
‹ stash

prune

Delete old stashes so the stash folder does not fill the disk.

keephow many of the newest stashes to keep
›
‹ Home

restore

Copy one stash back onto its rig.

rigthe rig to restore onto
›
fromthe date of the stash to restore
›
dry runshow what would be copied without copying
›
‹ Home

chores

Recurring jobs. Lists the registered ones, runs one by hand, and shows when each last ran and whether it worked.

listnames of the registered chores
›
runrun one chore now
›
statuslast finish time and result of each chore
›
chores pagethe same status on the porch
›
‹ chores

run

Run one named chore now and record the result.

nightly-stashstash every rig; cron runs it at 02:15
›
disk-checkwarn when a rig's root disk is over 85 percent; cron runs it every 6 hours
›
‹ Home

porch

The web dashboard. The front page lists the rigs and links to the chores and stash pages.

bind addresswhere the dashboard listens
›
dashboardrigs and their up or down state; refreshes every 20 seconds
›
chores pagelast run of each chore
›
stashes pagestashes kept for one rig
›
health checkreturns "ok": true when the porch is up
›
run as a servicestart the porch at boot; needs sudo
›
‹ Home

make

Project tasks, run from the repository root as make TARGET.

installcreate the virtualenv, install burrow, make the stash, state and log folders
›
install-unitinstall and start the porch systemd service; needs sudo
›
upstart the metrics containers
›
downstop the metrics containers
›
testrun the test suite
›
lintrun ruff on burrow and tests
›
stash-allstash every rig, same as burrow stash --all
›
prune-stasheskeep the 8 newest stashes per rig
›
install-prune-cronadd a weekly prune job to your crontab, Sundays at 04:40
›
cleanremove the virtualenv, caches and build files
›
‹ Home

helpers

Small shell helpers outside the burrow command. Read the top of each one before running it.

rig-wakesend a wake packet to a sleeping rig using its MAC from rigs.toml
›
check-disksshow disk use on every rig over ssh
›
verify-stashcheck the newest stash of a rig is readable and not empty
›
reboot-rigreboot one rig after a 10 second countdown
›
battery-reportbattery report (from name; body not read)
›
cert-renewrenew certificates (from name; body not read)
›
dns-flushflush the DNS cache (from name; body not read)
›
du-stashesmeasure stash folder sizes (from name; body not read)
›
export-choresexport chore records (from name; body not read)
›
fan-curveset a fan curve (from name; body not read)
›
gc-dockerclean up unused Docker data (from name; body not read)
›
import-rigsimport rig definitions (from name; body not read)
›
list-portslist open ports (from name; body not read)
›
mount-nasmount the NAS (from name; body not read)
›
unmount-nasunmount the NAS (from name; body not read)
›
net-speedmeasure network speed (from name; body not read)
›
pihole-updateupdate Pi-hole (from name; body not read)
›
rotate-logsrotate log files (from name; body not read)
›
seed-devfill a dev setup with sample data (from name; body not read)
›
smart-reportdisk SMART health report (from name; body not read)
›
ssh-keys-pushpush SSH keys to rigs (from name; body not read)
›
sync-clocksync the clock (from name; body not read)
›
temp-checkcheck rig temperatures (from name; body not read)
›
update-rigsupdate packages on rigs (from name; body not read)
›
ups-statusshow UPS status (from name; body not read)
›
zfs-scrubstart a ZFS scrub (from name; body not read)
›
‹ Home

settings

Where settings live and what each one controls.

burrow.tomlstash root and keep count, chores state file, porch bind address, title and refresh, ssh user and key variable
›
rigs.tomleach rig's name, address, MAC and paths; see docs/adding-a-rig.md
›
environmentBURROW_SSH_KEY, BURROW_PORCH_SECRET, BURROW_NTFY_TOPIC
›
config optionpoint any burrow command at another burrow.toml
›
‹ Home

metrics

Graphs of rig temperatures and disk use, from the metrics containers.

grafanathe graphs; anonymous viewing is on
›
raw metricspulse's raw values for Prometheus; temperature and disk are placeholders (0.0) in this snapshot
›
startstart the containers
›
stopstop the containers
›
‹ Home

docs

Pages for setup and everyday use.

readmeoverview, install, use
›
setupfirst-time setup steps and checks
›
adding a rigadd a rig to rigs.toml
›
choreswhat the chores do and how to check them
›
restore by handcopy a stash back with rsync when burrow is broken
›
Raw answer
The map covers the `burrow` command and its help screens, the porch pages, the make targets, the helper scripts, the settings files, the metrics, and the docs. The top screen is the entry point. I read the helper scripts only by name, except `check-disks.sh`, `verify-stash.sh`, and `reboot-rig.sh`, so their descriptions for the other 22 are guesses from their names. Under "questions" I flag a likely bug: the cron line runs without `--config`, and cron starts in the home directory, so the default config path will not be found.

```json
{"screens": [
{"path": [], "sentence": "The burrow command: look after the home-lab rigs. It lists them, takes and restores snapshots (stashes), runs recurring chores, and serves the porch dashboard.", "rows": [
 {"name": "rigs", "form": "burrow rigs", "what": "list rigs and whether each one answers"},
 {"name": "stash", "form": "burrow stash (opens the stash screen)", "what": "take snapshots of rigs, list them, prune old ones"},
 {"name": "restore", "form": "burrow restore RIG --from YYYY-MM-DD [--dry-run]", "what": "copy a stash back onto its rig"},
 {"name": "chores", "form": "burrow chores (opens the chores screen)", "what": "recurring jobs: list, run, status"},
 {"name": "porch", "form": "burrow porch [--bind ADDR:PORT] (opens the porch screen)", "what": "run the web dashboard"},
 {"name": "config file", "form": "--config PATH (default config/burrow.toml)", "what": "use a different settings file for any command"},
 {"name": "make targets", "form": "make (opens the make screen)", "what": "install, test, stash-all and other project tasks"},
 {"name": "helpers", "form": "bin/rig-wake and scripts/ (opens the helpers screen)", "what": "small shell helpers outside the burrow command"},
 {"name": "settings", "form": "config/ and .env (opens the settings screen)", "what": "what to configure and where"},
 {"name": "metrics", "form": "make up (opens the metrics screen)", "what": "graphs of rig temperatures and disk use"},
 {"name": "docs", "form": "README.md and docs/ (opens the docs screen)", "what": "setup and how-to pages"}
]},
{"path": ["rigs"], "sentence": "Lists the rigs burrow knows and whether each one answers. Takes no options.", "rows": []},
{"path": ["stash"], "sentence": "Take a snapshot of one rig or of all rigs, or manage the stashes that already exist.", "rows": [
 {"name": "take one rig", "form": "burrow stash RIG", "what": "snapshot that rig now, written under /srv/burrow/stashes/RIG/DATE"},
 {"name": "take all rigs", "form": "burrow stash --all (also make stash-all)", "what": "snapshot every rig now"},
 {"name": "list", "form": "burrow stash list (opens the stash list screen)", "what": "show the stashes kept for one rig"},
 {"name": "prune", "form": "burrow stash prune (opens the stash prune screen)", "what": "delete old stashes, keeping the newest ones"}
]},
{"path": ["stash", "list"], "sentence": "Print the stashes kept for one rig.", "rows": [
 {"name": "rig", "form": "RIG argument, for example attic", "what": "which rig's stashes to list"}
]},
{"path": ["stash", "prune"], "sentence": "Delete old stashes so the stash folder does not fill the disk.", "rows": [
 {"name": "keep", "form": "--keep N (default 8)", "what": "how many of the newest stashes to keep"}
]},
{"path": ["restore"], "sentence": "Copy one stash back onto its rig.", "rows": [
 {"name": "rig", "form": "RIG argument, for example attic", "what": "the rig to restore onto"},
 {"name": "from", "form": "--from YYYY-MM-DD (required)", "what": "the date of the stash to restore"},
 {"name": "dry run", "form": "--dry-run", "what": "show what would be copied without copying"}
]},
{"path": ["chores"], "sentence": "Recurring jobs. Lists the registered ones, runs one by hand, and shows when each last ran and whether it worked.", "rows": [
 {"name": "list", "form": "burrow chores list", "what": "names of the registered chores"},
 {"name": "run", "form": "burrow chores run NAME (opens the chores run screen)", "what": "run one chore now"},
 {"name": "status", "form": "burrow chores status", "what": "last finish time and result of each chore"},
 {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "the same status on the porch"}
]},
{"path": ["chores", "run"], "sentence": "Run one named chore now and record the result.", "rows": [
 {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "stash every rig; cron runs it at 02:15"},
 {"name": "disk-check", "form": "burrow chores run disk-check", "what": "warn when a rig's root disk is over 85 percent; cron runs it every 6 hours"}
]},
{"path": ["porch"], "sentence": "The web dashboard. The front page lists the rigs and links to the chores and stash pages.", "rows": [
 {"name": "bind address", "form": "--bind ADDR:PORT (default from porch.bind, 0.0.0.0:8470)", "what": "where the dashboard listens"},
 {"name": "dashboard", "form": "http://127.0.0.1:8470/", "what": "rigs and their up or down state; refreshes every 20 seconds"},
 {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "last run of each chore"},
 {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/RIG", "what": "stashes kept for one rig"},
 {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "returns \"ok\": true when the porch is up"},
 {"name": "run as a service", "form": "make install-unit (systemd burrow-porch.service)", "what": "start the porch at boot; needs sudo"}
]},
{"path": ["make"], "sentence": "Project tasks, run from the repository root as make TARGET.", "rows": [
 {"name": "install", "form": "make install", "what": "create the virtualenv, install burrow, make the stash, state and log folders"},
 {"name": "install-unit", "form": "make install-unit", "what": "install and start the porch systemd service; needs sudo"},
 {"name": "up", "form": "make up", "what": "start the metrics containers"},
 {"name": "down", "form": "make down", "what": "stop the metrics containers"},
 {"name": "test", "form": "make test", "what": "run the test suite"},
 {"name": "lint", "form": "make lint", "what": "run ruff on burrow and tests"},
 {"name": "stash-all", "form": "make stash-all", "what": "stash every rig, same as burrow stash --all"},
 {"name": "prune-stashes", "form": "make prune-stashes", "what": "keep the 8 newest stashes per rig"},
 {"name": "install-prune-cron", "form": "make install-prune-cron", "what": "add a weekly prune job to your crontab, Sundays at 04:40"},
 {"name": "clean", "form": "make clean", "what": "remove the virtualenv, caches and build files"}
]},
{"path": ["helpers"], "sentence": "Small shell helpers outside the burrow command. Read the top of each one before running it.", "rows": [
 {"name": "rig-wake", "form": "bin/rig-wake RIG", "what": "send a wake packet to a sleeping rig using its MAC from rigs.toml"},
 {"name": "check-disks", "form": "scripts/check-disks.sh", "what": "show disk use on every rig over ssh"},
 {"name": "verify-stash", "form": "scripts/verify-stash.sh RIG", "what": "check the newest stash of a rig is readable and not empty"},
 {"name": "reboot-rig", "form": "scripts/reboot-rig.sh ADDRESS", "what": "reboot one rig after a 10 second countdown"},
 {"name": "battery-report", "form": "scripts/battery-report.sh", "what": "battery report (from name; body not read)"},
 {"name": "cert-renew", "form": "scripts/cert-renew.sh", "what": "renew certificates (from name; body not read)"},
 {"name": "dns-flush", "form": "scripts/dns-flush.sh", "what": "flush the DNS cache (from name; body not read)"},
 {"name": "du-stashes", "form": "scripts/du-stashes.sh", "what": "measure stash folder sizes (from name; body not read)"},
 {"name": "export-chores", "form": "scripts/export-chores.sh", "what": "export chore records (from name; body not read)"},
 {"name": "fan-curve", "form": "scripts/fan-curve.sh", "what": "set a fan curve (from name; body not read)"},
 {"name": "gc-docker", "form": "scripts/gc-docker.sh", "what": "clean up unused Docker data (from name; body not read)"},
 {"name": "import-rigs", "form": "scripts/import-rigs.sh", "what": "import rig definitions (from name; body not read)"},
 {"name": "list-ports", "form": "scripts/list-ports.sh", "what": "list open ports (from name; body not read)"},
 {"name": "mount-nas", "form": "scripts/mount-nas.sh", "what": "mount the NAS (from name; body not read)"},
 {"name": "unmount-nas", "form": "scripts/unmount-nas.sh", "what": "unmount the NAS (from name; body not read)"},
 {"name": "net-speed", "form": "scripts/net-speed.sh", "what": "measure network speed (from name; body not read)"},
 {"name": "pihole-update", "form": "scripts/pihole-update.sh", "what": "update Pi-hole (from name; body not read)"},
 {"name": "rotate-logs", "form": "scripts/rotate-logs.sh", "what": "rotate log files (from name; body not read)"},
 {"name": "seed-dev", "form": "scripts/seed-dev.sh", "what": "fill a dev setup with sample data (from name; body not read)"},
 {"name": "smart-report", "form": "scripts/smart-report.sh", "what": "disk SMART health report (from name; body not read)"},
 {"name": "ssh-keys-push", "form": "scripts/ssh-keys-push.sh", "what": "push SSH keys to rigs (from name; body not read)"},
 {"name": "sync-clock", "form": "scripts/sync-clock.sh", "what": "sync the clock (from name; body not read)"},
 {"name": "temp-check", "form": "scripts/temp-check.sh", "what": "check rig temperatures (from name; body not read)"},
 {"name": "update-rigs", "form": "scripts/update-rigs.sh", "what": "update packages on rigs (from name; body not read)"},
 {"name": "ups-status", "form": "scripts/ups-status.sh", "what": "show UPS status (from name; body not read)"},
 {"name": "zfs-scrub", "form": "scripts/zfs-scrub.sh", "what": "start a ZFS scrub (from name; body not read)"}
]},
{"path": ["settings"], "sentence": "Where settings live and what each one controls.", "rows": [
 {"name": "burrow.toml", "form": "config/burrow.toml", "what": "stash root and keep count, chores state file, porch bind address, title and refresh, ssh user and key variable"},
 {"name": "rigs.toml", "form": "config/rigs.toml", "what": "each rig's name, address, MAC and paths; see docs/adding-a-rig.md"},
 {"name": "environment", "form": ".env (copy from .env.example)", "what": "BURROW_SSH_KEY, BURROW_PORCH_SECRET, BURROW_NTFY_TOPIC"},
 {"name": "config option", "form": "--config PATH", "what": "point any burrow command at another burrow.toml"}
]},
{"path": ["metrics"], "sentence": "Graphs of rig temperatures and disk use, from the metrics containers.", "rows": [
 {"name": "grafana", "form": "http://127.0.0.1:3000", "what": "the graphs; anonymous viewing is on"},
 {"name": "raw metrics", "form": "http://HOST:9188/metrics", "what": "pulse's raw values for Prometheus; temperature and disk are placeholders (0.0) in this snapshot"},
 {"name": "start", "form": "make up", "what": "start the containers"},
 {"name": "stop", "form": "make down", "what": "stop the containers"}
]},
{"path": ["docs"], "sentence": "Pages for setup and everyday use.", "rows": [
 {"name": "readme", "form": "README.md", "what": "overview, install, use"},
 {"name": "setup", "form": "docs/setup.md", "what": "first-time setup steps and checks"},
 {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "add a rig to rigs.toml"},
 {"name": "chores", "form": "docs/chores.md", "what": "what the chores do and how to check them"},
 {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "copy a stash back with rsync when burrow is broken"}
]}
],
"questions": [
 "Cron config path: deploy/burrow.crontab runs burrow with no --config, and cron starts in your home directory, so the default config/burrow.toml will not be found. Recommendation: put the absolute path (--config /opt/burrow/config/burrow.toml) on both cron lines.",
 "Stash command shape: stash takes an optional RIG and also has list and prune subcommands, so 'burrow stash list attic' may read 'list' as the rig name. Recommendation: run it to check; if it misparses, make the take-one-rig form an explicit subcommand, for example 'burrow stash take RIG'.",
 "Stash with neither RIG nor --all: the code would look up a rig named nothing. Recommendation: make it a clear usage error that shows the help screen.",
 "Porch access: it binds 0.0.0.0 with no login, and BURROW_PORCH_SECRET is not used in the code shown. Recommendation: either enforce the secret or bind to the LAN only, and document which one you chose. Enforcing it is safer.",
 "Alerts: chores set notify to ntfy and .env has BURROW_NTFY_TOPIC, but no code in this snapshot sends alerts. Do you want an alerts screen? Recommendation: leave it out of the help until the sending code exists.",
 "Prune count: keep is 8 in burrow.toml and also 8 as the CLI default, so changing one does not change the other. Recommendation: have the CLI read the config value and use the default only when no config is given.",
 "Restore by date: --from takes only a date. If two stashes are taken on one day, the later one may overwrite the earlier one. Please confirm which behavior you want, and the help text will say it.",
 "Helper scripts: 22 descriptions are inferred from file names. Recommendation: read the header of each before writing help text, and keep the helpers out of the burrow command.",
 "Wake a rig: bin/rig-wake is not a burrow command. Do you want 'burrow rigs wake NAME' so all rig actions live in one place? Recommendation: yes, if you use it often.",
 "Metrics placeholders: pulse returns 0.0 for temperature and disk, so the Grafana graphs will be flat until those reads are filled in. Is that in scope for this help map? Recommendation: note it in the metrics help and leave it there."
]}
```

Today's skills · run 3 exit=0 seconds=125 · prompt

P1 Recall: 0.883P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 11P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
burrow looks after the home lab's rigs: their stashes, the chores that run by themselves, and the porch dashboard. Pick a row to go deeper.
rigsburrow rigsPrints each rig and whether it answers.
stashburrow stashPrints the stash screen: take, list and prune snapshots of a rig's folders.
restoreburrow restorePrints the restore screen: how to put a stash back onto its rig.
choresburrow choresPrints the chores screen: the recurring jobs and when each last ran.
porchburrow porch helpPrints the porch screen: the dashboard's pages and log. Starting it is burrow porch.
metricsburrow metricsPrints the metrics screen: the containers, Grafana and the raw numbers.
scriptsburrow scriptsPrints the scripts screen: the shell helpers in scripts, grouped by job.
configburrow configPrints the config screen: the settings and rig list files.
docsburrow docsPrints the docs screen: the README and the setup and chore guides.
setupburrow setupPrints the setup screen: install burrow and wire in its service and crontabs.
devburrow devPrints the dev screen: run the tests and the linter, and clean up.
rigs
The rigs burrow knows, from config/rigs.toml, and whether each one answers.
atticconfig/rigs.tomlOpens the attic entry: address 192.168.1.20 and the folders it stashes.
cellarconfig/rigs.tomlOpens the cellar entry: address 192.168.1.21 and the folders it stashes.
gardenconfig/rigs.tomlOpens the garden entry: address 192.168.1.22 and the folders it stashes.
wake a sleeping rigbin/rig-wake <rig>Sends a wake packet to a sleeping rig, using its MAC address from rigs.toml.
stash
Snapshots of a rig's folders: take them, list them, prune the old ones, and check them.
take a stash of one rigburrow stash <rig>Takes a stash of the named rig now, for example burrow stash attic.
take a stash of every rigburrow stash --allTakes a stash of every rig at once.
list a rig's stashesburrow stash list <rig>Lists a rig's stashes, one per dated folder.
prune old stashesburrow stash prune --keep 8Removes the oldest stashes, keeping the newest 8.
stash folder/srv/burrow/stashesOpens the folder with one folder per rig and a dated folder per stash.
check the newest stashscripts/verify-stash.shChecks that a rig's newest stash is readable and not empty.
stash sizesscripts/du-stashes.shShows how much space the stashes take (inferred).
restore
Putting a stash back onto its rig, from the date you pick.
restore a stashburrow restore <rig> --from YYYY-MM-DDCopies the stash from that date back onto its rig.
preview a restoreburrow restore <rig> --from YYYY-MM-DD --dry-runRuns a restore as a dry run, so nothing on the rig changes.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the rsync steps for restoring a stash when burrow itself is broken.
chores
The recurring jobs that run from cron, and when each one last ran.
list the choresburrow chores listLists the chores burrow knows.
nightly stashburrow chores run nightly-stashRuns a stash of every rig now; cron runs it every night at 02:15.
disk checkburrow chores run disk-checkRuns the disk check now, warning when a root disk is over 85%; cron runs it every 6 hours.
last runsburrow chores statusPrints when each chore last ran and whether it worked.
chores pagehttp://127.0.0.1:8470/choresOpens the chores page on the porch, with the same status in a browser.
chores crontabdeploy/burrow.crontabOpens the crontab that schedules the chores.
chores log/var/log/burrow/chores.logOpens the log where cron's chores output goes.
last-run record/srv/burrow/state/last-run.jsonOpens the record of each chore's last run.
porch
The porch, a small web dashboard for the rigs, chores and stashes, on port 8470 by default.
start the porchburrow porchStarts the porch on 0.0.0.0:8470 and keeps it running in the foreground.
dashboardhttp://127.0.0.1:8470Opens the dashboard, with every rig on it.
a rig's stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens one rig's stashes in the browser.
health checkhttp://127.0.0.1:8470/healthzOpens the health check, which reports ok while the porch is up.
porch servicedeploy/burrow-porch.serviceOpens the systemd unit that runs the porch; install it with make install-unit.
porch log/var/log/burrow/porch.logOpens the porch's log.
metrics
The metrics containers: rig temperatures and disk use, stored by Prometheus and graphed in Grafana.
start the containersmake upStarts the metrics containers in the background.
stop the containersmake downStops and removes the metrics containers.
Grafana graphshttp://127.0.0.1:3000Opens Grafana, the graphs of temperatures and disk use.
raw numbershttp://127.0.0.1:9188/metricsOpens the numbers pulse exposes for Prometheus.
compose filedocker-compose.ymlOpens the file that defines the pulse, Prometheus and Grafana containers.
scripts
The small shell helpers in scripts, grouped by what they act on. Read the top of each one before you run it.
rigsburrow scripts rigsPrints the scripts that act on the rigs themselves.
healthburrow scripts healthPrints the scripts that read sensors: temperature, battery, disk health and power.
storageburrow scripts storagePrints the scripts for mounts, scrubs, Docker space and logs.
networkburrow scripts networkPrints the scripts for DNS, ports, speed, Pi-hole and certificates.
databurrow scripts dataPrints the scripts that export, import or seed chores, rigs and dev data.
scripts › rigs
Scripts that act on the rigs themselves.
check disksscripts/check-disks.shShows disk use on every rig in config/rigs.toml.
reboot a rigscripts/reboot-rig.shReboots one rig by address, after a 10 second countdown.
update rigsscripts/update-rigs.shUpdates the rigs (inferred).
push ssh keysscripts/ssh-keys-push.shPushes ssh keys to the rigs (inferred).
sync clocksscripts/sync-clock.shSets the rigs' clocks to the same time (inferred).
scripts › health
Scripts that read the sensors: temperature, battery, disk health and power.
battery reportscripts/battery-report.shPrints a battery report (inferred).
SMART reportscripts/smart-report.shPrints the disk health report (inferred).
temperature checkscripts/temp-check.shChecks the rigs' temperatures (inferred).
fan curvescripts/fan-curve.shSets fan speeds against temperature (inferred).
UPS statusscripts/ups-status.shPrints the UPS power status (inferred).
scripts › storage
Scripts for mounts, scrubs, Docker space and logs.
mount NASscripts/mount-nas.shMounts the NAS (inferred).
unmount NASscripts/unmount-nas.shUnmounts the NAS (inferred).
ZFS scrubscripts/zfs-scrub.shStarts a ZFS scrub, which checks the pool's data (inferred).
clean Dockerscripts/gc-docker.shRemoves unused Docker images and volumes (inferred).
rotate logsscripts/rotate-logs.shRotates the log files (inferred).
scripts › network
Scripts for DNS, ports, speed, Pi-hole and certificates.
flush DNSscripts/dns-flush.shFlushes the DNS cache (inferred).
list portsscripts/list-ports.shLists the open ports (inferred).
network speedscripts/net-speed.shMeasures the network speed (inferred).
update Pi-holescripts/pihole-update.shUpdates Pi-hole (inferred).
renew certificatesscripts/cert-renew.shRenews the certificates (inferred).
scripts › data
Scripts that export, import or seed chores, rigs and dev data.
export choresscripts/export-chores.shExports the chores record (inferred).
import rigsscripts/import-rigs.shImports rigs (inferred).
seed dev datascripts/seed-dev.shFills a dev setup with sample data (inferred).
config
The settings files: how burrow keeps stashes, runs chores, serves the porch and reaches the rigs.
burrow settingsconfig/burrow.tomlOpens the settings: stash folder and how many to keep, chores, porch address, ssh user.
rig listconfig/rigs.tomlOpens the list of rigs, their addresses and their folders.
secrets.envOpens your secrets and ssh key path; create it by copying .env.example.
secrets template.env.exampleOpens the template for .env, with the keys to fill in.
logs folder/var/log/burrowOpens the folder with the chores and porch logs.
docs
The guides: the README, setup, adding a rig and the chores.
READMEREADME.mdOpens the README: what burrow is and how to install it.
setupdocs/setup.mdOpens the first-time setup steps.
adding a rigdocs/adding-a-rig.mdOpens how to add a rig to rigs.toml.
chores guidedocs/chores.mdOpens the guide to the chores.
setup
Installing burrow on a rig, and wiring its service and crontabs in.
installmake installCreates the .venv, installs the burrow command, and makes the stash, state and log folders.
install the porch servicemake install-unitInstalls and starts the porch as a systemd service; needs sudo.
install the chores crontabcrontab deploy/burrow.crontabInstalls the chores schedule, replacing the whole crontab.
weekly stash prunemake install-prune-cronAdds a weekly prune on Sundays at 04:40, replacing the whole crontab.
dev
Running the tests and the linter, and cleaning up the build.
testsmake testRuns the test suite in tests.
lintmake lintChecks the code with ruff.
cleanmake cleanDeletes .venv, caches and build files; run make install again after.
Questions
  • Bare stash and restore: `burrow stash` and `burrow restore` with no arguments error today. Recommend: with no arguments they print their screen; with arguments they keep acting (`burrow stash attic`, `burrow stash --all`, `burrow restore attic --from ...`), so the README and Makefile keep working. Agree?
  • porch: bare `burrow porch` starts the server, and the systemd unit's ExecStart depends on it. Recommend keeping it, and reaching the porch screen only through `burrow porch help`. Agree?
  • Crontab clobber: `make install-prune-cron` and `crontab deploy/burrow.crontab` each replace the whole user crontab, so installing one removes the other. Recommend moving the weekly prune line into deploy/burrow.crontab and dropping install-prune-cron. This edits the Makefile and the crontab, so it is your call.
  • Scripts: 22 descriptions are inferred from file names and marked (inferred). Send the headers of those scripts, or accept the inferred wording, before the screens are built.
  • Prune scope: does `--keep 8` keep 8 per rig or 8 in total? stash.py was not in the dump. The map says 'the newest 8'. Recommend confirming in stash.py before the help text is final.
  • Make targets: show them as `make up` and `make test` (recommended, no second name for each), or wrap them as burrow commands such as `burrow metrics up`?
  • Per-rig screen: should `burrow rigs attic` show that rig's address, folders, last stash and up or down state? Recommend yes once the rig list grows. It is new logic, so it is a worker task, not part of the first build.
  • pulse's read_temp and read_disk return 0.0, so the Grafana graphs would show zeros. Recommend finishing the stub before the metrics screen advertises those graphs. Should the stub be finished first?
  • Top screen has 11 rows. Merge `dev` into `setup` to get 10? Recommend keeping 11; it still fits on one screen.
As phone screens

Home

burrow looks after the home lab's rigs: their stashes, the chores that run by themselves, and the porch dashboard. Pick a row to go deeper.

rigsPrints each rig and whether it answers.
›
stashPrints the stash screen: take, list and prune snapshots of a rig's folders.
›
restorePrints the restore screen: how to put a stash back onto its rig.
›
choresPrints the chores screen: the recurring jobs and when each last ran.
›
porchPrints the porch screen: the dashboard's pages and log. Starting it is burrow porch.
›
metricsPrints the metrics screen: the containers, Grafana and the raw numbers.
›
scriptsPrints the scripts screen: the shell helpers in scripts, grouped by job.
›
configPrints the config screen: the settings and rig list files.
›
docsPrints the docs screen: the README and the setup and chore guides.
›
setupPrints the setup screen: install burrow and wire in its service and crontabs.
›
devPrints the dev screen: run the tests and the linter, and clean up.
›
‹ Home

rigs

The rigs burrow knows, from config/rigs.toml, and whether each one answers.

atticOpens the attic entry: address 192.168.1.20 and the folders it stashes.
›
cellarOpens the cellar entry: address 192.168.1.21 and the folders it stashes.
›
gardenOpens the garden entry: address 192.168.1.22 and the folders it stashes.
›
wake a sleeping rigSends a wake packet to a sleeping rig, using its MAC address from rigs.toml.
›
‹ Home

stash

Snapshots of a rig's folders: take them, list them, prune the old ones, and check them.

take a stash of one rigTakes a stash of the named rig now, for example burrow stash attic.
›
take a stash of every rigTakes a stash of every rig at once.
›
list a rig's stashesLists a rig's stashes, one per dated folder.
›
prune old stashesRemoves the oldest stashes, keeping the newest 8.
›
stash folderOpens the folder with one folder per rig and a dated folder per stash.
›
check the newest stashChecks that a rig's newest stash is readable and not empty.
›
stash sizesShows how much space the stashes take (inferred).
›
‹ Home

restore

Putting a stash back onto its rig, from the date you pick.

restore a stashCopies the stash from that date back onto its rig.
›
preview a restoreRuns a restore as a dry run, so nothing on the rig changes.
›
restore by handOpens the rsync steps for restoring a stash when burrow itself is broken.
›
‹ Home

chores

The recurring jobs that run from cron, and when each one last ran.

list the choresLists the chores burrow knows.
›
nightly stashRuns a stash of every rig now; cron runs it every night at 02:15.
›
disk checkRuns the disk check now, warning when a root disk is over 85%; cron runs it every 6 hours.
›
last runsPrints when each chore last ran and whether it worked.
›
chores pageOpens the chores page on the porch, with the same status in a browser.
›
chores crontabOpens the crontab that schedules the chores.
›
chores logOpens the log where cron's chores output goes.
›
last-run recordOpens the record of each chore's last run.
›
‹ Home

porch

The porch, a small web dashboard for the rigs, chores and stashes, on port 8470 by default.

start the porchStarts the porch on 0.0.0.0:8470 and keeps it running in the foreground.
›
dashboardOpens the dashboard, with every rig on it.
›
a rig's stashes pageOpens one rig's stashes in the browser.
›
health checkOpens the health check, which reports ok while the porch is up.
›
porch serviceOpens the systemd unit that runs the porch; install it with make install-unit.
›
porch logOpens the porch's log.
›
‹ Home

metrics

The metrics containers: rig temperatures and disk use, stored by Prometheus and graphed in Grafana.

start the containersStarts the metrics containers in the background.
›
stop the containersStops and removes the metrics containers.
›
Grafana graphsOpens Grafana, the graphs of temperatures and disk use.
›
raw numbersOpens the numbers pulse exposes for Prometheus.
›
compose fileOpens the file that defines the pulse, Prometheus and Grafana containers.
›
‹ Home

scripts

The small shell helpers in scripts, grouped by what they act on. Read the top of each one before you run it.

rigsPrints the scripts that act on the rigs themselves.
›
healthPrints the scripts that read sensors: temperature, battery, disk health and power.
›
storagePrints the scripts for mounts, scrubs, Docker space and logs.
›
networkPrints the scripts for DNS, ports, speed, Pi-hole and certificates.
›
dataPrints the scripts that export, import or seed chores, rigs and dev data.
›
‹ scripts

rigs

Scripts that act on the rigs themselves.

check disksShows disk use on every rig in config/rigs.toml.
›
reboot a rigReboots one rig by address, after a 10 second countdown.
›
update rigsUpdates the rigs (inferred).
›
push ssh keysPushes ssh keys to the rigs (inferred).
›
sync clocksSets the rigs' clocks to the same time (inferred).
›
‹ scripts

health

Scripts that read the sensors: temperature, battery, disk health and power.

battery reportPrints a battery report (inferred).
›
SMART reportPrints the disk health report (inferred).
›
temperature checkChecks the rigs' temperatures (inferred).
›
fan curveSets fan speeds against temperature (inferred).
›
UPS statusPrints the UPS power status (inferred).
›
‹ scripts

storage

Scripts for mounts, scrubs, Docker space and logs.

mount NASMounts the NAS (inferred).
›
unmount NASUnmounts the NAS (inferred).
›
ZFS scrubStarts a ZFS scrub, which checks the pool's data (inferred).
›
clean DockerRemoves unused Docker images and volumes (inferred).
›
rotate logsRotates the log files (inferred).
›
‹ scripts

network

Scripts for DNS, ports, speed, Pi-hole and certificates.

flush DNSFlushes the DNS cache (inferred).
›
list portsLists the open ports (inferred).
›
network speedMeasures the network speed (inferred).
›
update Pi-holeUpdates Pi-hole (inferred).
›
renew certificatesRenews the certificates (inferred).
›
‹ scripts

data

Scripts that export, import or seed chores, rigs and dev data.

export choresExports the chores record (inferred).
›
import rigsImports rigs (inferred).
›
seed dev dataFills a dev setup with sample data (inferred).
›
‹ Home

config

The settings files: how burrow keeps stashes, runs chores, serves the porch and reaches the rigs.

burrow settingsOpens the settings: stash folder and how many to keep, chores, porch address, ssh user.
›
rig listOpens the list of rigs, their addresses and their folders.
›
secretsOpens your secrets and ssh key path; create it by copying .env.example.
›
secrets templateOpens the template for .env, with the keys to fill in.
›
logs folderOpens the folder with the chores and porch logs.
›
‹ Home

docs

The guides: the README, setup, adding a rig and the chores.

READMEOpens the README: what burrow is and how to install it.
›
setupOpens the first-time setup steps.
›
adding a rigOpens how to add a rig to rigs.toml.
›
chores guideOpens the guide to the chores.
›
‹ Home

setup

Installing burrow on a rig, and wiring its service and crontabs in.

installCreates the .venv, installs the burrow command, and makes the stash, state and log folders.
›
install the porch serviceInstalls and starts the porch as a systemd service; needs sudo.
›
install the chores crontabInstalls the chores schedule, replacing the whole crontab.
›
weekly stash pruneAdds a weekly prune on Sundays at 04:40, replacing the whole crontab.
›
‹ Home

dev

Running the tests and the linter, and cleaning up the build.

testsRuns the test suite in tests.
›
lintChecks the code with ruff.
›
cleanDeletes .venv, caches and build files; run make install again after.
›
Raw answer
I mapped burrow's command line as 17 screens under one facade, `burrow`. The top screen has 11 rows, so it stays short as the project grows.

**What I could not see:** `stash.py`, `rigs.py`, `config.py` and the porch templates were not in the dump, so the behaviour of take, restore and prune is inferred from `cli.py` and the docs. Only three of the 25 scripts were shown (`check-disks.sh`, `reboot-rig.sh`, `verify-stash.sh`). The other 22 descriptions come from their file names and are marked "(inferred)".

**Conflicts the plan has to resolve:**
- **Bare `burrow stash` and `burrow restore` fail today** because they need arguments. The plan has them print their screen when no arguments are given, and keep acting when arguments are given, so the README and Makefile still work.
- **Bare `burrow porch` starts the server**, and the systemd unit depends on that. Its screen is reached through `burrow porch help`.
- **Two crontab installs overwrite each other.** `make install-prune-cron` and `crontab deploy/burrow.crontab` each replace the whole crontab.
- **pulse returns 0.0 for temperature and disk**, so Grafana would show flat zero graphs. The metrics screen should not advertise those graphs until the stub is finished.

```json
{"screens": [
{"path": [], "sentence": "burrow looks after the home lab's rigs: their stashes, the chores that run by themselves, and the porch dashboard. Pick a row to go deeper.", "rows": [
 {"name": "rigs", "form": "burrow rigs", "what": "Prints each rig and whether it answers."},
 {"name": "stash", "form": "burrow stash", "what": "Prints the stash screen: take, list and prune snapshots of a rig's folders."},
 {"name": "restore", "form": "burrow restore", "what": "Prints the restore screen: how to put a stash back onto its rig."},
 {"name": "chores", "form": "burrow chores", "what": "Prints the chores screen: the recurring jobs and when each last ran."},
 {"name": "porch", "form": "burrow porch help", "what": "Prints the porch screen: the dashboard's pages and log. Starting it is burrow porch."},
 {"name": "metrics", "form": "burrow metrics", "what": "Prints the metrics screen: the containers, Grafana and the raw numbers."},
 {"name": "scripts", "form": "burrow scripts", "what": "Prints the scripts screen: the shell helpers in scripts, grouped by job."},
 {"name": "config", "form": "burrow config", "what": "Prints the config screen: the settings and rig list files."},
 {"name": "docs", "form": "burrow docs", "what": "Prints the docs screen: the README and the setup and chore guides."},
 {"name": "setup", "form": "burrow setup", "what": "Prints the setup screen: install burrow and wire in its service and crontabs."},
 {"name": "dev", "form": "burrow dev", "what": "Prints the dev screen: run the tests and the linter, and clean up."}
]},
{"path": ["rigs"], "sentence": "The rigs burrow knows, from config/rigs.toml, and whether each one answers.", "rows": [
 {"name": "attic", "form": "config/rigs.toml", "what": "Opens the attic entry: address 192.168.1.20 and the folders it stashes."},
 {"name": "cellar", "form": "config/rigs.toml", "what": "Opens the cellar entry: address 192.168.1.21 and the folders it stashes."},
 {"name": "garden", "form": "config/rigs.toml", "what": "Opens the garden entry: address 192.168.1.22 and the folders it stashes."},
 {"name": "wake a sleeping rig", "form": "bin/rig-wake <rig>", "what": "Sends a wake packet to a sleeping rig, using its MAC address from rigs.toml."}
]},
{"path": ["stash"], "sentence": "Snapshots of a rig's folders: take them, list them, prune the old ones, and check them.", "rows": [
 {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of the named rig now, for example burrow stash attic."},
 {"name": "take a stash of every rig", "form": "burrow stash --all", "what": "Takes a stash of every rig at once."},
 {"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Lists a rig's stashes, one per dated folder."},
 {"name": "prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes the oldest stashes, keeping the newest 8."},
 {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder with one folder per rig and a dated folder per stash."},
 {"name": "check the newest stash", "form": "scripts/verify-stash.sh", "what": "Checks that a rig's newest stash is readable and not empty."},
 {"name": "stash sizes", "form": "scripts/du-stashes.sh", "what": "Shows how much space the stashes take (inferred)."}
]},
{"path": ["restore"], "sentence": "Putting a stash back onto its rig, from the date you pick.", "rows": [
 {"name": "restore a stash", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies the stash from that date back onto its rig."},
 {"name": "preview a restore", "form": "burrow restore <rig> --from YYYY-MM-DD --dry-run", "what": "Runs a restore as a dry run, so nothing on the rig changes."},
 {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the rsync steps for restoring a stash when burrow itself is broken."}
]},
{"path": ["chores"], "sentence": "The recurring jobs that run from cron, and when each one last ran.", "rows": [
 {"name": "list the chores", "form": "burrow chores list", "what": "Lists the chores burrow knows."},
 {"name": "nightly stash", "form": "burrow chores run nightly-stash", "what": "Runs a stash of every rig now; cron runs it every night at 02:15."},
 {"name": "disk check", "form": "burrow chores run disk-check", "what": "Runs the disk check now, warning when a root disk is over 85%; cron runs it every 6 hours."},
 {"name": "last runs", "form": "burrow chores status", "what": "Prints when each chore last ran and whether it worked."},
 {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page on the porch, with the same status in a browser."},
 {"name": "chores crontab", "form": "deploy/burrow.crontab", "what": "Opens the crontab that schedules the chores."},
 {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the log where cron's chores output goes."},
 {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of each chore's last run."}
]},
{"path": ["porch"], "sentence": "The porch, a small web dashboard for the rigs, chores and stashes, on port 8470 by default.", "rows": [
 {"name": "start the porch", "form": "burrow porch", "what": "Starts the porch on 0.0.0.0:8470 and keeps it running in the foreground."},
 {"name": "dashboard", "form": "http://127.0.0.1:8470", "what": "Opens the dashboard, with every rig on it."},
 {"name": "a rig's stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens one rig's stashes in the browser."},
 {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Opens the health check, which reports ok while the porch is up."},
 {"name": "porch service", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that runs the porch; install it with make install-unit."},
 {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the porch's log."}
]},
{"path": ["metrics"], "sentence": "The metrics containers: rig temperatures and disk use, stored by Prometheus and graphed in Grafana.", "rows": [
 {"name": "start the containers", "form": "make up", "what": "Starts the metrics containers in the background."},
 {"name": "stop the containers", "form": "make down", "what": "Stops and removes the metrics containers."},
 {"name": "Grafana graphs", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, the graphs of temperatures and disk use."},
 {"name": "raw numbers", "form": "http://127.0.0.1:9188/metrics", "what": "Opens the numbers pulse exposes for Prometheus."},
 {"name": "compose file", "form": "docker-compose.yml", "what": "Opens the file that defines the pulse, Prometheus and Grafana containers."}
]},
{"path": ["scripts"], "sentence": "The small shell helpers in scripts, grouped by what they act on. Read the top of each one before you run it.", "rows": [
 {"name": "rigs", "form": "burrow scripts rigs", "what": "Prints the scripts that act on the rigs themselves."},
 {"name": "health", "form": "burrow scripts health", "what": "Prints the scripts that read sensors: temperature, battery, disk health and power."},
 {"name": "storage", "form": "burrow scripts storage", "what": "Prints the scripts for mounts, scrubs, Docker space and logs."},
 {"name": "network", "form": "burrow scripts network", "what": "Prints the scripts for DNS, ports, speed, Pi-hole and certificates."},
 {"name": "data", "form": "burrow scripts data", "what": "Prints the scripts that export, import or seed chores, rigs and dev data."}
]},
{"path": ["scripts", "rigs"], "sentence": "Scripts that act on the rigs themselves.", "rows": [
 {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig in config/rigs.toml."},
 {"name": "reboot a rig", "form": "scripts/reboot-rig.sh", "what": "Reboots one rig by address, after a 10 second countdown."},
 {"name": "update rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs (inferred)."},
 {"name": "push ssh keys", "form": "scripts/ssh-keys-push.sh", "what": "Pushes ssh keys to the rigs (inferred)."},
 {"name": "sync clocks", "form": "scripts/sync-clock.sh", "what": "Sets the rigs' clocks to the same time (inferred)."}
]},
{"path": ["scripts", "health"], "sentence": "Scripts that read the sensors: temperature, battery, disk health and power.", "rows": [
 {"name": "battery report", "form": "scripts/battery-report.sh", "what": "Prints a battery report (inferred)."},
 {"name": "SMART report", "form": "scripts/smart-report.sh", "what": "Prints the disk health report (inferred)."},
 {"name": "temperature check", "form": "scripts/temp-check.sh", "what": "Checks the rigs' temperatures (inferred)."},
 {"name": "fan curve", "form": "scripts/fan-curve.sh", "what": "Sets fan speeds against temperature (inferred)."},
 {"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Prints the UPS power status (inferred)."}
]},
{"path": ["scripts", "storage"], "sentence": "Scripts for mounts, scrubs, Docker space and logs.", "rows": [
 {"name": "mount NAS", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS (inferred)."},
 {"name": "unmount NAS", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS (inferred)."},
 {"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub, which checks the pool's data (inferred)."},
 {"name": "clean Docker", "form": "scripts/gc-docker.sh", "what": "Removes unused Docker images and volumes (inferred)."},
 {"name": "rotate logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the log files (inferred)."}
]},
{"path": ["scripts", "network"], "sentence": "Scripts for DNS, ports, speed, Pi-hole and certificates.", "rows": [
 {"name": "flush DNS", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache (inferred)."},
 {"name": "list ports", "form": "scripts/list-ports.sh", "what": "Lists the open ports (inferred)."},
 {"name": "network speed", "form": "scripts/net-speed.sh", "what": "Measures the network speed (inferred)."},
 {"name": "update Pi-hole", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole (inferred)."},
 {"name": "renew certificates", "form": "scripts/cert-renew.sh", "what": "Renews the certificates (inferred)."}
]},
{"path": ["scripts", "data"], "sentence": "Scripts that export, import or seed chores, rigs and dev data.", "rows": [
 {"name": "export chores", "form": "scripts/export-chores.sh", "what": "Exports the chores record (inferred)."},
 {"name": "import rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs (inferred)."},
 {"name": "seed dev data", "form": "scripts/seed-dev.sh", "what": "Fills a dev setup with sample data (inferred)."}
]},
{"path": ["config"], "sentence": "The settings files: how burrow keeps stashes, runs chores, serves the porch and reaches the rigs.", "rows": [
 {"name": "burrow settings", "form": "config/burrow.toml", "what": "Opens the settings: stash folder and how many to keep, chores, porch address, ssh user."},
 {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the list of rigs, their addresses and their folders."},
 {"name": "secrets", "form": ".env", "what": "Opens your secrets and ssh key path; create it by copying .env.example."},
 {"name": "secrets template", "form": ".env.example", "what": "Opens the template for .env, with the keys to fill in."},
 {"name": "logs folder", "form": "/var/log/burrow", "what": "Opens the folder with the chores and porch logs."}
]},
{"path": ["docs"], "sentence": "The guides: the README, setup, adding a rig and the chores.", "rows": [
 {"name": "README", "form": "README.md", "what": "Opens the README: what burrow is and how to install it."},
 {"name": "setup", "form": "docs/setup.md", "what": "Opens the first-time setup steps."},
 {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "Opens how to add a rig to rigs.toml."},
 {"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide to the chores."}
]},
{"path": ["setup"], "sentence": "Installing burrow on a rig, and wiring its service and crontabs in.", "rows": [
 {"name": "install", "form": "make install", "what": "Creates the .venv, installs the burrow command, and makes the stash, state and log folders."},
 {"name": "install the porch service", "form": "make install-unit", "what": "Installs and starts the porch as a systemd service; needs sudo."},
 {"name": "install the chores crontab", "form": "crontab deploy/burrow.crontab", "what": "Installs the chores schedule, replacing the whole crontab."},
 {"name": "weekly stash prune", "form": "make install-prune-cron", "what": "Adds a weekly prune on Sundays at 04:40, replacing the whole crontab."}
]},
{"path": ["dev"], "sentence": "Running the tests and the linter, and cleaning up the build.", "rows": [
 {"name": "tests", "form": "make test", "what": "Runs the test suite in tests."},
 {"name": "lint", "form": "make lint", "what": "Checks the code with ruff."},
 {"name": "clean", "form": "make clean", "what": "Deletes .venv, caches and build files; run make install again after."}
]}
],
"questions": [
"Bare stash and restore: `burrow stash` and `burrow restore` with no arguments error today. Recommend: with no arguments they print their screen; with arguments they keep acting (`burrow stash attic`, `burrow stash --all`, `burrow restore attic --from ...`), so the README and Makefile keep working. Agree?",
"porch: bare `burrow porch` starts the server, and the systemd unit's ExecStart depends on it. Recommend keeping it, and reaching the porch screen only through `burrow porch help`. Agree?",
"Crontab clobber: `make install-prune-cron` and `crontab deploy/burrow.crontab` each replace the whole user crontab, so installing one removes the other. Recommend moving the weekly prune line into deploy/burrow.crontab and dropping install-prune-cron. This edits the Makefile and the crontab, so it is your call.",
"Scripts: 22 descriptions are inferred from file names and marked (inferred). Send the headers of those scripts, or accept the inferred wording, before the screens are built.",
"Prune scope: does `--keep 8` keep 8 per rig or 8 in total? stash.py was not in the dump. The map says 'the newest 8'. Recommend confirming in stash.py before the help text is final.",
"Make targets: show them as `make up` and `make test` (recommended, no second name for each), or wrap them as burrow commands such as `burrow metrics up`?",
"Per-rig screen: should `burrow rigs attic` show that rig's address, folders, last stash and up or down state? Recommend yes once the rig list grows. It is new logic, so it is a worker task, not part of the first build.",
"pulse's read_temp and read_disk return 0.0, so the Grafana graphs would show zeros. Recommend finishing the stub before the metrics screen advertises those graphs. Should the stub be finished first?",
"Top screen has 11 rows. Merge `dev` into `setup` to get 10? Recommend keeping 11; it still fits on one screen."
]}
```

screen-decomposition, first draft · run 3 exit=0 seconds=136 · prompt

P1 Recall: 0.917P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 4
As terminal help
burrow's map: the home-lab rigs, their stashes and chores, the porch that shows them, and the scripts, metrics, setup and docs around them.
rigsburrow rigsShows the rigs screen: which rigs burrow knows and whether each one answers.
stashburrow stashShows the stashes screen: snapshots of each rig's folders, and how to take, list, prune and restore them.
choresburrow choresShows the chores screen: the recurring jobs and when each last ran.
porchburrow porchRuns the porch, the web dashboard for the rigs, on port 8470 (today this command starts the server; see questions).
metricsburrow metrics (new)Shows the metrics screen: rig temperatures and disk use, graphed in Grafana.
scriptsburrow scripts (new)Shows the scripts screen: the helper scripts in scripts/ and what each one does.
setupburrow setup (new)Shows the setup screen: installing burrow, its settings, and the tests and lint.
docsburrow docs (new)Shows the docs screen: the README and the guides under docs/.
rigs
The rigs burrow knows and whether each one answers.
atticburrow rigs atticShows attic: its address, its paths, and what you can do with it.
cellarburrow rigs cellarShows cellar: its address, its paths, and what you can do with it.
gardenburrow rigs gardenShows garden: its address, its paths, and what you can do with it.
wake a rigbin/rig-wake <rig-name>Sends a wake packet to a sleeping rig, using its MAC from config/rigs.toml.
check disks on every rigscripts/check-disks.shShows disk use on every rig, over ssh.
add a rigdocs/adding-a-rig.mdShows how to add a rig to config/rigs.toml.
rig listconfig/rigs.tomlOpens the rig list: each rig's name, address, MAC and paths.
rigs › attic
attic, one of the rigs burrow looks after.
its entryconfig/rigs.tomlOpens attic's entry in config/rigs.toml: its address, MAC and paths.
take a stash nowburrow stash atticTakes a stash of attic now, into /srv/burrow/stashes.
its stashesburrow stash list atticLists attic's stashes, one dated folder each.
its stashes on the porchhttp://127.0.0.1:8470/stashes/atticShows attic's stashes on the porch (use the rig's IP from another machine).
restore a stashburrow restore attic --from <YYYY-MM-DD>Copies a stash back onto attic; add --dry-run to see what would change without writing.
verify newest stashscripts/verify-stash.sh atticChecks that attic's newest stash is readable and not empty.
rebootscripts/reboot-rig.sh 192.168.1.20Reboots attic after a 10 second countdown.
wakebin/rig-wake atticSends a wake packet to attic.
rigs › cellar
cellar, one of the rigs burrow looks after.
its entryconfig/rigs.tomlOpens cellar's entry in config/rigs.toml: its address, MAC and paths.
take a stash nowburrow stash cellarTakes a stash of cellar now, into /srv/burrow/stashes.
its stashesburrow stash list cellarLists cellar's stashes, one dated folder each.
its stashes on the porchhttp://127.0.0.1:8470/stashes/cellarShows cellar's stashes on the porch (use the rig's IP from another machine).
restore a stashburrow restore cellar --from <YYYY-MM-DD>Copies a stash back onto cellar; add --dry-run to see what would change without writing.
verify newest stashscripts/verify-stash.sh cellarChecks that cellar's newest stash is readable and not empty.
rebootscripts/reboot-rig.sh 192.168.1.21Reboots cellar after a 10 second countdown.
wakebin/rig-wake cellarSends a wake packet to cellar.
rigs › garden
garden, one of the rigs burrow looks after.
its entryconfig/rigs.tomlOpens garden's entry in config/rigs.toml: its address, MAC and paths.
take a stash nowburrow stash gardenTakes a stash of garden now, into /srv/burrow/stashes.
its stashesburrow stash list gardenLists garden's stashes, one dated folder each.
its stashes on the porchhttp://127.0.0.1:8470/stashes/gardenShows garden's stashes on the porch (use the rig's IP from another machine).
restore a stashburrow restore garden --from <YYYY-MM-DD>Copies a stash back onto garden; add --dry-run to see what would change without writing.
verify newest stashscripts/verify-stash.sh gardenChecks that garden's newest stash is readable and not empty.
rebootscripts/reboot-rig.sh 192.168.1.22Reboots garden after a 10 second countdown.
wakebin/rig-wake gardenSends a wake packet to garden.
stash
The stashes: one dated folder per stash of each rig's folders, kept under /srv/burrow/stashes.
take a stash of every rigburrow stash --allTakes a stash of every rig now (also make stash-all).
take a stash of one rigburrow stash <rig>Takes a stash of one rig now.
list a rig's stashesburrow stash list <rig>Lists one rig's stashes, one dated folder each.
prune old stashesburrow stash prune --keep 8Removes the old stashes of every rig, keeping the newest 8 (also make prune-stashes).
restore a stashburrow restore <rig> --from <YYYY-MM-DD>Copies a stash back onto its rig; --dry-run shows what would change without writing.
stash folder/srv/burrow/stashesOpens the folder that holds every rig's stashes.
a rig's stashes on the porchhttp://127.0.0.1:8470/stashes/<rig>Shows a rig's stashes on the porch.
verify a rig's newest stashscripts/verify-stash.sh <rig>Checks that a rig's newest stash is readable and not empty.
disk used by stashesscripts/du-stashes.shShows how much space the stashes use (from its name; not read).
put a stash back by handdocs/internals/stash/format/restore-by-hand.mdShows how to put a stash back with rsync when burrow itself is broken.
chores
The recurring jobs burrow runs, and when each last ran and whether it worked.
chore namesburrow chores listLists the names of the chores burrow knows.
nightly-stashburrow chores run nightly-stashRuns the nightly stash: takes a stash of every rig; cron runs it at 02:15 (defined in burrow/chores.py).
disk-checkburrow chores run disk-checkRuns the disk check: warns when a rig's root disk is over 85%; cron runs it every 6 hours (defined in burrow/chores.py).
last runsburrow chores statusPrints when each chore last finished and whether it worked.
chores on the porchhttp://127.0.0.1:8470/choresShows the chores and their last runs on the porch.
cron output/var/log/burrow/chores.logOpens the output that cron wrote for the chores.
last-run record/srv/burrow/state/last-run.jsonOpens the file that records each chore's last run.
cron linesdeploy/burrow.crontabShows the cron lines that run the chores.
porch
The porch: the dashboard that shows the rigs, their stashes and chores, on port 8470.
run the porchburrow porchRuns the porch on 0.0.0.0:8470 in the foreground; the systemd unit runs it as a service.
front pagehttp://127.0.0.1:8470Shows the rigs on the porch's front page (use the rig's IP from another machine).
chores pagehttp://127.0.0.1:8470/choresShows the chores and their last runs.
health checkhttp://127.0.0.1:8470/healthzAnswers {"ok": true} when the porch is up.
service unitdeploy/burrow-porch.serviceShows the systemd unit that runs the porch as a service.
porch log/var/log/burrow/porch.logOpens the porch's log.
metrics
The metrics: rig temperatures and disk use, collected by pulse and graphed in Grafana.
Grafanahttp://127.0.0.1:3000Opens Grafana, the graphs of rig temperatures and disk use.
pulse's valueshttp://127.0.0.1:9188/metricsShows the values pulse exposes for Prometheus; its reads are stubs (0.0) for now.
start the metrics containersmake upStarts the metrics containers (pulse, Prometheus, Grafana) in the background.
stop the metrics containersmake downStops the metrics containers.
compose filedocker-compose.ymlOpens the file that defines the metrics containers.
pulse sourcepulse/pulse.pyOpens pulse, the reader of rig temperatures and disk use.
pulse imagepulse/DockerfileOpens the file that builds the pulse image.
Prometheusdocker-compose.yml (service prometheus, no port published)Stores the metrics for 30 days, for Grafana to graph.
scripts
The helper scripts in scripts/, run by hand; each one explains itself at the top of its file.
battery reportscripts/battery-report.shWrites a battery report for a machine (from its name; not read).
certificate renewscripts/cert-renew.shRenews a certificate (from its name; not read).
check disksscripts/check-disks.shShows disk use on every rig in config/rigs.toml, over ssh.
DNS flushscripts/dns-flush.shFlushes the DNS cache (from its name; not read).
stash disk usescripts/du-stashes.shShows how much space the stashes use (from its name; not read).
export choresscripts/export-chores.shExports the chores (from its name; not read).
fan curvescripts/fan-curve.shSets the fan speed curve (from its name; not read).
clean up dockerscripts/gc-docker.shCleans up unused docker data (from its name; not read).
import rigsscripts/import-rigs.shImports rigs into config/rigs.toml (from its name; not read).
list portsscripts/list-ports.shLists open ports (from its name; not read).
mount the NASscripts/mount-nas.shMounts the NAS (from its name; not read).
network speedscripts/net-speed.shMeasures network speed (from its name; not read).
Pi-hole updatescripts/pihole-update.shUpdates Pi-hole (from its name; not read).
reboot a rigscripts/reboot-rig.sh <address>Reboots one rig after a 10 second countdown.
rotate logsscripts/rotate-logs.shRotates the log files (from its name; not read).
seed dev datascripts/seed-dev.shSeeds development data (from its name; not read).
disk health reportscripts/smart-report.shWrites a disk SMART health report (from its name; not read).
push ssh keysscripts/ssh-keys-push.shPushes ssh keys to the rigs (from its name; not read).
sync clockscripts/sync-clock.shSyncs the clock (from its name; not read).
check temperaturesscripts/temp-check.shChecks rig temperatures (from its name; not read).
unmount the NASscripts/unmount-nas.shUnmounts the NAS (from its name; not read).
update rigsscripts/update-rigs.shUpdates the rigs (from its name; not read).
UPS statusscripts/ups-status.shShows the UPS status (from its name; not read).
verify a stashscripts/verify-stash.sh <rig>Checks that a rig's newest stash is readable and not empty.
ZFS scrubscripts/zfs-scrub.shStarts a ZFS scrub (from its name; not read).
setup
Installing burrow on a rig, its settings, and the tests and lint.
installmake installCreates the virtualenv in .venv/, installs the burrow command, and makes the stash, state and log folders.
install the porch servicemake install-unitInstalls the porch as a systemd service and starts it (needs sudo).
install the chores croncrontab deploy/burrow.crontabReplaces the crontab with the chores lines; this overwrites any existing crontab.
install the weekly prunemake install-prune-cronAdds a weekly stash prune to the crontab (Sunday 04:40); not in the README.
settingsconfig/burrow.tomlOpens the settings: stash folder and keep count, chores state file, porch address, ssh user.
rig listconfig/rigs.tomlOpens the rig list: each rig's name, address, MAC and paths.
secrets.env (copy of .env.example)Opens the secrets file: the ssh key path, the porch secret and the ntfy topic.
package filepyproject.tomlOpens the package file: the version, the dependencies and the burrow command.
run the testsmake testRuns the test suite in tests/.
lintmake lintChecks burrow and its tests with ruff.
cleanmake cleanDeletes the virtualenv and build leftovers.
docs
The written guides: the README and the docs folder.
READMEREADME.mdOpens the README: what burrow is and how to use it.
setup guidedocs/setup.mdShows the steps to set up burrow on a new rig.
adding a rigdocs/adding-a-rig.mdShows how to add a rig to config/rigs.toml.
chores guidedocs/chores.mdShows what the chores are and how to run and check them.
restore by handdocs/internals/stash/format/restore-by-hand.mdShows how to put a stash back with rsync when burrow is broken.
licenseLICENSEOpens the MIT license.
Questions
  • Actions and the screen rule: under the rule a bare noun prints a screen, but `burrow porch` starts the server, `burrow stash <rig>` takes a stash, `burrow chores run <name>` and `burrow restore` are verb-first. The cron line and the systemd unit call `chores run` and `porch`. Recommendation: keep the existing forms for now and label them as actions in the help. Move them to noun-then-verb only once cron and the unit are updated too.
  • The noun for stashes: the CLI says `stash`, the README and porch say "stashes". Recommendation: keep `stash` as the command word and use "stashes" as the screen's sentence.
  • Scripts that may not be burrow's: several (Pi-hole, NAS, ZFS, UPS, fan curve, DNS) may belong to other machines. Recommendation: keep all 25 in the map, read each one before building, and move any that are not burrow's out of burrow's help.
  • Splitting the scripts screen: 25 rows is too many for one screen. Recommendation: once they are read, split by job into about five groups (disks and power, network, rigs and stashes, system and logs, the rest). I have not split it.
  • Porch access control: `.env.example` defines BURROW_PORCH_SECRET, and the porch binds 0.0.0.0:8470 with no login in the code I read. Recommendation: decide before building whether to add a login or remove the variable. The map leaves the secret out until then.
As phone screens

Home

burrow's map: the home-lab rigs, their stashes and chores, the porch that shows them, and the scripts, metrics, setup and docs around them.

rigsShows the rigs screen: which rigs burrow knows and whether each one answers.
›
stashShows the stashes screen: snapshots of each rig's folders, and how to take, list, prune and restore them.
›
choresShows the chores screen: the recurring jobs and when each last ran.
›
porchRuns the porch, the web dashboard for the rigs, on port 8470 (today this command starts the server; see questions).
›
metricsShows the metrics screen: rig temperatures and disk use, graphed in Grafana.
›
scriptsShows the scripts screen: the helper scripts in scripts/ and what each one does.
›
setupShows the setup screen: installing burrow, its settings, and the tests and lint.
›
docsShows the docs screen: the README and the guides under docs/.
›
‹ Home

rigs

The rigs burrow knows and whether each one answers.

atticShows attic: its address, its paths, and what you can do with it.
›
cellarShows cellar: its address, its paths, and what you can do with it.
›
gardenShows garden: its address, its paths, and what you can do with it.
›
wake a rigSends a wake packet to a sleeping rig, using its MAC from config/rigs.toml.
›
check disks on every rigShows disk use on every rig, over ssh.
›
add a rigShows how to add a rig to config/rigs.toml.
›
rig listOpens the rig list: each rig's name, address, MAC and paths.
›
‹ rigs

attic

attic, one of the rigs burrow looks after.

its entryOpens attic's entry in config/rigs.toml: its address, MAC and paths.
›
take a stash nowTakes a stash of attic now, into /srv/burrow/stashes.
›
its stashesLists attic's stashes, one dated folder each.
›
its stashes on the porchShows attic's stashes on the porch (use the rig's IP from another machine).
›
restore a stashCopies a stash back onto attic; add --dry-run to see what would change without writing.
›
verify newest stashChecks that attic's newest stash is readable and not empty.
›
rebootReboots attic after a 10 second countdown.
›
wakeSends a wake packet to attic.
›
‹ rigs

cellar

cellar, one of the rigs burrow looks after.

its entryOpens cellar's entry in config/rigs.toml: its address, MAC and paths.
›
take a stash nowTakes a stash of cellar now, into /srv/burrow/stashes.
›
its stashesLists cellar's stashes, one dated folder each.
›
its stashes on the porchShows cellar's stashes on the porch (use the rig's IP from another machine).
›
restore a stashCopies a stash back onto cellar; add --dry-run to see what would change without writing.
›
verify newest stashChecks that cellar's newest stash is readable and not empty.
›
rebootReboots cellar after a 10 second countdown.
›
wakeSends a wake packet to cellar.
›
‹ rigs

garden

garden, one of the rigs burrow looks after.

its entryOpens garden's entry in config/rigs.toml: its address, MAC and paths.
›
take a stash nowTakes a stash of garden now, into /srv/burrow/stashes.
›
its stashesLists garden's stashes, one dated folder each.
›
its stashes on the porchShows garden's stashes on the porch (use the rig's IP from another machine).
›
restore a stashCopies a stash back onto garden; add --dry-run to see what would change without writing.
›
verify newest stashChecks that garden's newest stash is readable and not empty.
›
rebootReboots garden after a 10 second countdown.
›
wakeSends a wake packet to garden.
›
‹ Home

stash

The stashes: one dated folder per stash of each rig's folders, kept under /srv/burrow/stashes.

take a stash of every rigTakes a stash of every rig now (also make stash-all).
›
take a stash of one rigTakes a stash of one rig now.
›
list a rig's stashesLists one rig's stashes, one dated folder each.
›
prune old stashesRemoves the old stashes of every rig, keeping the newest 8 (also make prune-stashes).
›
restore a stashCopies a stash back onto its rig; --dry-run shows what would change without writing.
›
stash folderOpens the folder that holds every rig's stashes.
›
a rig's stashes on the porchShows a rig's stashes on the porch.
›
verify a rig's newest stashChecks that a rig's newest stash is readable and not empty.
›
disk used by stashesShows how much space the stashes use (from its name; not read).
›
put a stash back by handShows how to put a stash back with rsync when burrow itself is broken.
›
‹ Home

chores

The recurring jobs burrow runs, and when each last ran and whether it worked.

chore namesLists the names of the chores burrow knows.
›
nightly-stashRuns the nightly stash: takes a stash of every rig; cron runs it at 02:15 (defined in burrow/chores.py).
›
disk-checkRuns the disk check: warns when a rig's root disk is over 85%; cron runs it every 6 hours (defined in burrow/chores.py).
›
last runsPrints when each chore last finished and whether it worked.
›
chores on the porchShows the chores and their last runs on the porch.
›
cron outputOpens the output that cron wrote for the chores.
›
last-run recordOpens the file that records each chore's last run.
›
cron linesShows the cron lines that run the chores.
›
‹ Home

porch

The porch: the dashboard that shows the rigs, their stashes and chores, on port 8470.

run the porchRuns the porch on 0.0.0.0:8470 in the foreground; the systemd unit runs it as a service.
›
front pageShows the rigs on the porch's front page (use the rig's IP from another machine).
›
chores pageShows the chores and their last runs.
›
health checkAnswers {"ok": true} when the porch is up.
›
service unitShows the systemd unit that runs the porch as a service.
›
porch logOpens the porch's log.
›
‹ Home

metrics

The metrics: rig temperatures and disk use, collected by pulse and graphed in Grafana.

GrafanaOpens Grafana, the graphs of rig temperatures and disk use.
›
pulse's valuesShows the values pulse exposes for Prometheus; its reads are stubs (0.0) for now.
›
start the metrics containersStarts the metrics containers (pulse, Prometheus, Grafana) in the background.
›
stop the metrics containersStops the metrics containers.
›
compose fileOpens the file that defines the metrics containers.
›
pulse sourceOpens pulse, the reader of rig temperatures and disk use.
›
pulse imageOpens the file that builds the pulse image.
›
PrometheusStores the metrics for 30 days, for Grafana to graph.
›
‹ Home

scripts

The helper scripts in scripts/, run by hand; each one explains itself at the top of its file.

battery reportWrites a battery report for a machine (from its name; not read).
›
certificate renewRenews a certificate (from its name; not read).
›
check disksShows disk use on every rig in config/rigs.toml, over ssh.
›
DNS flushFlushes the DNS cache (from its name; not read).
›
stash disk useShows how much space the stashes use (from its name; not read).
›
export choresExports the chores (from its name; not read).
›
fan curveSets the fan speed curve (from its name; not read).
›
clean up dockerCleans up unused docker data (from its name; not read).
›
import rigsImports rigs into config/rigs.toml (from its name; not read).
›
list portsLists open ports (from its name; not read).
›
mount the NASMounts the NAS (from its name; not read).
›
network speedMeasures network speed (from its name; not read).
›
Pi-hole updateUpdates Pi-hole (from its name; not read).
›
reboot a rigReboots one rig after a 10 second countdown.
›
rotate logsRotates the log files (from its name; not read).
›
seed dev dataSeeds development data (from its name; not read).
›
disk health reportWrites a disk SMART health report (from its name; not read).
›
push ssh keysPushes ssh keys to the rigs (from its name; not read).
›
sync clockSyncs the clock (from its name; not read).
›
check temperaturesChecks rig temperatures (from its name; not read).
›
unmount the NASUnmounts the NAS (from its name; not read).
›
update rigsUpdates the rigs (from its name; not read).
›
UPS statusShows the UPS status (from its name; not read).
›
verify a stashChecks that a rig's newest stash is readable and not empty.
›
ZFS scrubStarts a ZFS scrub (from its name; not read).
›
‹ Home

setup

Installing burrow on a rig, its settings, and the tests and lint.

installCreates the virtualenv in .venv/, installs the burrow command, and makes the stash, state and log folders.
›
install the porch serviceInstalls the porch as a systemd service and starts it (needs sudo).
›
install the chores cronReplaces the crontab with the chores lines; this overwrites any existing crontab.
›
install the weekly pruneAdds a weekly stash prune to the crontab (Sunday 04:40); not in the README.
›
settingsOpens the settings: stash folder and keep count, chores state file, porch address, ssh user.
›
rig listOpens the rig list: each rig's name, address, MAC and paths.
›
secretsOpens the secrets file: the ssh key path, the porch secret and the ntfy topic.
›
package fileOpens the package file: the version, the dependencies and the burrow command.
›
run the testsRuns the test suite in tests/.
›
lintChecks burrow and its tests with ruff.
›
cleanDeletes the virtualenv and build leftovers.
›
‹ Home

docs

The written guides: the README and the docs folder.

READMEOpens the README: what burrow is and how to use it.
›
setup guideShows the steps to set up burrow on a new rig.
›
adding a rigShows how to add a rig to config/rigs.toml.
›
chores guideShows what the chores are and how to run and check them.
›
restore by handShows how to put a stash back with rsync when burrow is broken.
›
licenseOpens the MIT license.
›
Raw answer
## Map: burrow

**Scenario** (from the README, not from direct use): the owner keeps three home-lab rigs (attic, cellar, garden) running. They check whether a rig answers, take a stash before a risky change, put a stash back after something breaks, see whether last night's chores ran, wake a sleeping rig, and graph temperatures. The map is built around those moments.

**Inventory and where each thing is defined:**
- **Rigs:** attic, cellar, garden in `config/rigs.toml`. Live state (up/down) comes from `burrow rigs`.
- **CLI:** `burrow rigs`, `stash` (`<rig>`, `--all`, `list`, `prune`), `restore`, `chores` (`list`, `run`, `status`), `porch` in `burrow/cli.py`.
- **Chores:** `nightly-stash`, `disk-check` in `burrow/chores.py`. Cron lines in `deploy/burrow.crontab`.
- **Porch pages:** `/`, `/chores`, `/stashes/<rig>`, `/healthz` in `burrow/porch/app.py`. Service unit in `deploy/burrow-porch.service`.
- **Make targets:** install, install-unit, up, down, test, lint, stash-all, prune-stashes, install-prune-cron, clean (`Makefile`).
- **Metrics:** pulse (`:9188`), Prometheus (no published port), Grafana (`:3000`) in `docker-compose.yml`. The `pulse/Dockerfile` builds pulse.
- **Scripts:** 25 files in `scripts/`. `bin/rig-wake` is a separate helper.
- **Files:** `config/burrow.toml`, `config/rigs.toml`, `.env.example`, `pyproject.toml`, `LICENSE`, the logs in `/var/log/burrow/`, `/srv/burrow/stashes`, and `/srv/burrow/state/last-run.json`.
- **Docs:** README and four guides under `docs/`.

**Limits of what I read:** I read the CLI, chores, porch app, pulse, the Makefile, config, and three of the 25 scripts. I did not read `stash.py`, `rigs.py`, `config.py`, the porch templates, or 22 scripts. Their "what" lines below come from file names and are marked as such.

## Screens

The full map is in the JSON block at the end. Summary:
- **Top:** rigs, stash, chores, porch, metrics, scripts, setup, docs.
- **Under `rigs`:** one screen per rig (`rigs › attic`, and the same for cellar and garden), plus wake, disk check, and add-a-rig.
- **Under `stash`:** take, list, prune, restore, verify, the folder, and the by-hand guide.
- **Under `chores`:** the two chores, run, status, the porch page, the logs, and the cron lines.
- **Under `porch`, `metrics`, `scripts`, `setup`, `docs`:** their rows as listed in the JSON.

## Questions for you

1. **Actions and the screen rule.** Under the map's rule a bare noun prints a screen, but four existing commands act instead: `burrow porch` starts the server, `burrow stash <rig>` takes a stash, `burrow chores run <name>` and `burrow restore` are verb-first. The cron line and the systemd unit call `chores run` and `porch`. **Recommendation:** keep the existing forms for now, since changing them breaks cron and systemd, and let the help label them as actions. The JSON uses the existing forms.
2. **The noun for stashes.** The CLI says `stash`; the README and porch say "stashes". **Recommendation:** keep `stash` as the command word and use "stashes" as the screen's sentence.
3. **Scripts that may not be burrow's.** Several names (pihole, NAS, ZFS, UPS, fan curve, DNS) may belong to other machines. **Recommendation:** keep all 25 in the map, since the map covers everything the user reaches from the project, then read each one before building and move any that are not burrow's.
4. **Splitting the scripts screen.** It has 25 rows, which is too many for one screen. **Recommendation:** after reading them, split by job (disks and power, network, rigs and stashes, system and logs, the rest). I have not split it myself.
5. **Porch access control.** `.env.example` defines `BURROW_PORCH_SECRET`, and the porch binds `0.0.0.0:8470` with no login in the code I read. **Recommendation:** decide before building whether to add a login or remove the variable. The map leaves the secret out until then.

## Judgment calls

- **Restore** appears under `stash` and under each rig, worded for each place.
- **Live state** (up/down, last runs, a rig's stash list) lives on the screen that prints it.
- **Pulse reads are stubs** (they return 0.0). The metrics rows say so rather than promising real values.
- **Prometheus** has no published port, so its row describes the compose service and has no URL.
- **`make install-prune-cron`** is not in the README. It is listed under setup.
- **`make install` replaces nothing** but `crontab deploy/burrow.crontab` replaces the whole crontab. The row warns about that.
- **`ntfy`** is named in `config/burrow.toml` and `.env.example`, but nothing I read uses it, so it is not listed as a feature.
- **`.burrow-manifest`** is described in the restore guide. I could not confirm `stash.py` writes it, so no row names it as a file.
- **`bin/rig-wake`** stays a standalone helper. It is not turned into a burrow command.
- **New screens** (`metrics`, `scripts`, `setup`, `docs`) are marked `(new)` in their forms, because those commands do not exist yet.
- **A new rig** adds a row under `rigs` and gets its own screen from `config/rigs.toml`. It does not create a new group.

```json
{"screens": [
 {"path": [], "sentence": "burrow's map: the home-lab rigs, their stashes and chores, the porch that shows them, and the scripts, metrics, setup and docs around them.", "rows": [
  {"name": "rigs", "form": "burrow rigs", "what": "Shows the rigs screen: which rigs burrow knows and whether each one answers."},
  {"name": "stash", "form": "burrow stash", "what": "Shows the stashes screen: snapshots of each rig's folders, and how to take, list, prune and restore them."},
  {"name": "chores", "form": "burrow chores", "what": "Shows the chores screen: the recurring jobs and when each last ran."},
  {"name": "porch", "form": "burrow porch", "what": "Runs the porch, the web dashboard for the rigs, on port 8470 (today this command starts the server; see questions)."},
  {"name": "metrics", "form": "burrow metrics (new)", "what": "Shows the metrics screen: rig temperatures and disk use, graphed in Grafana."},
  {"name": "scripts", "form": "burrow scripts (new)", "what": "Shows the scripts screen: the helper scripts in scripts/ and what each one does."},
  {"name": "setup", "form": "burrow setup (new)", "what": "Shows the setup screen: installing burrow, its settings, and the tests and lint."},
  {"name": "docs", "form": "burrow docs (new)", "what": "Shows the docs screen: the README and the guides under docs/."}
 ]},
 {"path": ["rigs"], "sentence": "The rigs burrow knows and whether each one answers.", "rows": [
  {"name": "attic", "form": "burrow rigs attic", "what": "Shows attic: its address, its paths, and what you can do with it."},
  {"name": "cellar", "form": "burrow rigs cellar", "what": "Shows cellar: its address, its paths, and what you can do with it."},
  {"name": "garden", "form": "burrow rigs garden", "what": "Shows garden: its address, its paths, and what you can do with it."},
  {"name": "wake a rig", "form": "bin/rig-wake <rig-name>", "what": "Sends a wake packet to a sleeping rig, using its MAC from config/rigs.toml."},
  {"name": "check disks on every rig", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig, over ssh."},
  {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Shows how to add a rig to config/rigs.toml."},
  {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the rig list: each rig's name, address, MAC and paths."}
 ]},
 {"path": ["rigs", "attic"], "sentence": "attic, one of the rigs burrow looks after.", "rows": [
  {"name": "its entry", "form": "config/rigs.toml", "what": "Opens attic's entry in config/rigs.toml: its address, MAC and paths."},
  {"name": "take a stash now", "form": "burrow stash attic", "what": "Takes a stash of attic now, into /srv/burrow/stashes."},
  {"name": "its stashes", "form": "burrow stash list attic", "what": "Lists attic's stashes, one dated folder each."},
  {"name": "its stashes on the porch", "form": "http://127.0.0.1:8470/stashes/attic", "what": "Shows attic's stashes on the porch (use the rig's IP from another machine)."},
  {"name": "restore a stash", "form": "burrow restore attic --from <YYYY-MM-DD>", "what": "Copies a stash back onto attic; add --dry-run to see what would change without writing."},
  {"name": "verify newest stash", "form": "scripts/verify-stash.sh attic", "what": "Checks that attic's newest stash is readable and not empty."},
  {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.20", "what": "Reboots attic after a 10 second countdown."},
  {"name": "wake", "form": "bin/rig-wake attic", "what": "Sends a wake packet to attic."}
 ]},
 {"path": ["rigs", "cellar"], "sentence": "cellar, one of the rigs burrow looks after.", "rows": [
  {"name": "its entry", "form": "config/rigs.toml", "what": "Opens cellar's entry in config/rigs.toml: its address, MAC and paths."},
  {"name": "take a stash now", "form": "burrow stash cellar", "what": "Takes a stash of cellar now, into /srv/burrow/stashes."},
  {"name": "its stashes", "form": "burrow stash list cellar", "what": "Lists cellar's stashes, one dated folder each."},
  {"name": "its stashes on the porch", "form": "http://127.0.0.1:8470/stashes/cellar", "what": "Shows cellar's stashes on the porch (use the rig's IP from another machine)."},
  {"name": "restore a stash", "form": "burrow restore cellar --from <YYYY-MM-DD>", "what": "Copies a stash back onto cellar; add --dry-run to see what would change without writing."},
  {"name": "verify newest stash", "form": "scripts/verify-stash.sh cellar", "what": "Checks that cellar's newest stash is readable and not empty."},
  {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.21", "what": "Reboots cellar after a 10 second countdown."},
  {"name": "wake", "form": "bin/rig-wake cellar", "what": "Sends a wake packet to cellar."}
 ]},
 {"path": ["rigs", "garden"], "sentence": "garden, one of the rigs burrow looks after.", "rows": [
  {"name": "its entry", "form": "config/rigs.toml", "what": "Opens garden's entry in config/rigs.toml: its address, MAC and paths."},
  {"name": "take a stash now", "form": "burrow stash garden", "what": "Takes a stash of garden now, into /srv/burrow/stashes."},
  {"name": "its stashes", "form": "burrow stash list garden", "what": "Lists garden's stashes, one dated folder each."},
  {"name": "its stashes on the porch", "form": "http://127.0.0.1:8470/stashes/garden", "what": "Shows garden's stashes on the porch (use the rig's IP from another machine)."},
  {"name": "restore a stash", "form": "burrow restore garden --from <YYYY-MM-DD>", "what": "Copies a stash back onto garden; add --dry-run to see what would change without writing."},
  {"name": "verify newest stash", "form": "scripts/verify-stash.sh garden", "what": "Checks that garden's newest stash is readable and not empty."},
  {"name": "reboot", "form": "scripts/reboot-rig.sh 192.168.1.22", "what": "Reboots garden after a 10 second countdown."},
  {"name": "wake", "form": "bin/rig-wake garden", "what": "Sends a wake packet to garden."}
 ]},
 {"path": ["stash"], "sentence": "The stashes: one dated folder per stash of each rig's folders, kept under /srv/burrow/stashes.", "rows": [
  {"name": "take a stash of every rig", "form": "burrow stash --all", "what": "Takes a stash of every rig now (also make stash-all)."},
  {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now."},
  {"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Lists one rig's stashes, one dated folder each."},
  {"name": "prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes the old stashes of every rig, keeping the newest 8 (also make prune-stashes)."},
  {"name": "restore a stash", "form": "burrow restore <rig> --from <YYYY-MM-DD>", "what": "Copies a stash back onto its rig; --dry-run shows what would change without writing."},
  {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder that holds every rig's stashes."},
  {"name": "a rig's stashes on the porch", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Shows a rig's stashes on the porch."},
  {"name": "verify a rig's newest stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks that a rig's newest stash is readable and not empty."},
  {"name": "disk used by stashes", "form": "scripts/du-stashes.sh", "what": "Shows how much space the stashes use (from its name; not read)."},
  {"name": "put a stash back by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Shows how to put a stash back with rsync when burrow itself is broken."}
 ]},
 {"path": ["chores"], "sentence": "The recurring jobs burrow runs, and when each last ran and whether it worked.", "rows": [
  {"name": "chore names", "form": "burrow chores list", "what": "Lists the names of the chores burrow knows."},
  {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Runs the nightly stash: takes a stash of every rig; cron runs it at 02:15 (defined in burrow/chores.py)."},
  {"name": "disk-check", "form": "burrow chores run disk-check", "what": "Runs the disk check: warns when a rig's root disk is over 85%; cron runs it every 6 hours (defined in burrow/chores.py)."},
  {"name": "last runs", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
  {"name": "chores on the porch", "form": "http://127.0.0.1:8470/chores", "what": "Shows the chores and their last runs on the porch."},
  {"name": "cron output", "form": "/var/log/burrow/chores.log", "what": "Opens the output that cron wrote for the chores."},
  {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the file that records each chore's last run."},
  {"name": "cron lines", "form": "deploy/burrow.crontab", "what": "Shows the cron lines that run the chores."}
 ]},
 {"path": ["porch"], "sentence": "The porch: the dashboard that shows the rigs, their stashes and chores, on port 8470.", "rows": [
  {"name": "run the porch", "form": "burrow porch", "what": "Runs the porch on 0.0.0.0:8470 in the foreground; the systemd unit runs it as a service."},
  {"name": "front page", "form": "http://127.0.0.1:8470", "what": "Shows the rigs on the porch's front page (use the rig's IP from another machine)."},
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Shows the chores and their last runs."},
  {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Answers {\"ok\": true} when the porch is up."},
  {"name": "service unit", "form": "deploy/burrow-porch.service", "what": "Shows the systemd unit that runs the porch as a service."},
  {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the porch's log."}
 ]},
 {"path": ["metrics"], "sentence": "The metrics: rig temperatures and disk use, collected by pulse and graphed in Grafana.", "rows": [
  {"name": "Grafana", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, the graphs of rig temperatures and disk use."},
  {"name": "pulse's values", "form": "http://127.0.0.1:9188/metrics", "what": "Shows the values pulse exposes for Prometheus; its reads are stubs (0.0) for now."},
  {"name": "start the metrics containers", "form": "make up", "what": "Starts the metrics containers (pulse, Prometheus, Grafana) in the background."},
  {"name": "stop the metrics containers", "form": "make down", "what": "Stops the metrics containers."},
  {"name": "compose file", "form": "docker-compose.yml", "what": "Opens the file that defines the metrics containers."},
  {"name": "pulse source", "form": "pulse/pulse.py", "what": "Opens pulse, the reader of rig temperatures and disk use."},
  {"name": "pulse image", "form": "pulse/Dockerfile", "what": "Opens the file that builds the pulse image."},
  {"name": "Prometheus", "form": "docker-compose.yml (service prometheus, no port published)", "what": "Stores the metrics for 30 days, for Grafana to graph."}
 ]},
 {"path": ["scripts"], "sentence": "The helper scripts in scripts/, run by hand; each one explains itself at the top of its file.", "rows": [
  {"name": "battery report", "form": "scripts/battery-report.sh", "what": "Writes a battery report for a machine (from its name; not read)."},
  {"name": "certificate renew", "form": "scripts/cert-renew.sh", "what": "Renews a certificate (from its name; not read)."},
  {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig in config/rigs.toml, over ssh."},
  {"name": "DNS flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache (from its name; not read)."},
  {"name": "stash disk use", "form": "scripts/du-stashes.sh", "what": "Shows how much space the stashes use (from its name; not read)."},
  {"name": "export chores", "form": "scripts/export-chores.sh", "what": "Exports the chores (from its name; not read)."},
  {"name": "fan curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan speed curve (from its name; not read)."},
  {"name": "clean up docker", "form": "scripts/gc-docker.sh", "what": "Cleans up unused docker data (from its name; not read)."},
  {"name": "import rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into config/rigs.toml (from its name; not read)."},
  {"name": "list ports", "form": "scripts/list-ports.sh", "what": "Lists open ports (from its name; not read)."},
  {"name": "mount the NAS", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS (from its name; not read)."},
  {"name": "network speed", "form": "scripts/net-speed.sh", "what": "Measures network speed (from its name; not read)."},
  {"name": "Pi-hole update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole (from its name; not read)."},
  {"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10 second countdown."},
  {"name": "rotate logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the log files (from its name; not read)."},
  {"name": "seed dev data", "form": "scripts/seed-dev.sh", "what": "Seeds development data (from its name; not read)."},
  {"name": "disk health report", "form": "scripts/smart-report.sh", "what": "Writes a disk SMART health report (from its name; not read)."},
  {"name": "push ssh keys", "form": "scripts/ssh-keys-push.sh", "what": "Pushes ssh keys to the rigs (from its name; not read)."},
  {"name": "sync clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock (from its name; not read)."},
  {"name": "check temperatures", "form": "scripts/temp-check.sh", "what": "Checks rig temperatures (from its name; not read)."},
  {"name": "unmount the NAS", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS (from its name; not read)."},
  {"name": "update rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs (from its name; not read)."},
  {"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Shows the UPS status (from its name; not read)."},
  {"name": "verify a stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks that a rig's newest stash is readable and not empty."},
  {"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub (from its name; not read)."}
 ]},
 {"path": ["setup"], "sentence": "Installing burrow on a rig, its settings, and the tests and lint.", "rows": [
  {"name": "install", "form": "make install", "what": "Creates the virtualenv in .venv/, installs the burrow command, and makes the stash, state and log folders."},
  {"name": "install the porch service", "form": "make install-unit", "what": "Installs the porch as a systemd service and starts it (needs sudo)."},
  {"name": "install the chores cron", "form": "crontab deploy/burrow.crontab", "what": "Replaces the crontab with the chores lines; this overwrites any existing crontab."},
  {"name": "install the weekly prune", "form": "make install-prune-cron", "what": "Adds a weekly stash prune to the crontab (Sunday 04:40); not in the README."},
  {"name": "settings", "form": "config/burrow.toml", "what": "Opens the settings: stash folder and keep count, chores state file, porch address, ssh user."},
  {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the rig list: each rig's name, address, MAC and paths."},
  {"name": "secrets", "form": ".env (copy of .env.example)", "what": "Opens the secrets file: the ssh key path, the porch secret and the ntfy topic."},
  {"name": "package file", "form": "pyproject.toml", "what": "Opens the package file: the version, the dependencies and the burrow command."},
  {"name": "run the tests", "form": "make test", "what": "Runs the test suite in tests/."},
  {"name": "lint", "form": "make lint", "what": "Checks burrow and its tests with ruff."},
  {"name": "clean", "form": "make clean", "what": "Deletes the virtualenv and build leftovers."}
 ]},
 {"path": ["docs"], "sentence": "The written guides: the README and the docs folder.", "rows": [
  {"name": "README", "form": "README.md", "what": "Opens the README: what burrow is and how to use it."},
  {"name": "setup guide", "form": "docs/setup.md", "what": "Shows the steps to set up burrow on a new rig."},
  {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "Shows how to add a rig to config/rigs.toml."},
  {"name": "chores guide", "form": "docs/chores.md", "what": "Shows what the chores are and how to run and check them."},
  {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Shows how to put a stash back with rsync when burrow is broken."},
  {"name": "license", "form": "LICENSE", "what": "Opens the MIT license."}
 ]}
],
"questions": [
 "Actions and the screen rule: under the rule a bare noun prints a screen, but `burrow porch` starts the server, `burrow stash <rig>` takes a stash, `burrow chores run <name>` and `burrow restore` are verb-first. The cron line and the systemd unit call `chores run` and `porch`. Recommendation: keep the existing forms for now and label them as actions in the help. Move them to noun-then-verb only once cron and the unit are updated too.",
 "The noun for stashes: the CLI says `stash`, the README and porch say \"stashes\". Recommendation: keep `stash` as the command word and use \"stashes\" as the screen's sentence.",
 "Scripts that may not be burrow's: several (Pi-hole, NAS, ZFS, UPS, fan curve, DNS) may belong to other machines. Recommendation: keep all 25 in the map, read each one before building, and move any that are not burrow's out of burrow's help.",
 "Splitting the scripts screen: 25 rows is too many for one screen. Recommendation: once they are read, split by job into about five groups (disks and power, network, rigs and stashes, system and logs, the rest). I have not split it.",
 "Porch access control: `.env.example` defines BURROW_PORCH_SECRET, and the porch binds 0.0.0.0:8470 with no login in the code I read. Recommendation: decide before building whether to add a login or remove the variable. The map leaves the secret out until then."
]}
```

screen-decomposition, final · run 3 exit=0 seconds=137 · prompt

P1 Recall: 0.867P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
What burrow looks after: its rigs, stashes, restores, chores, porch, metrics, helpers and project.
rigsburrow rigsLists the rigs and whether each one answers.
stashburrow stashShows the stash screen: taking, listing and pruning stashes.
restoreburrow restoreShows how to copy a stash back onto a rig.
choresburrow choresShows the chores screen: the jobs, running one, and when each last ran.
porchburrow porchShows the porch screen: the dashboard and its pages.
metricsburrow metricsShows the metrics screen: the graphs and the containers behind them.
helpersburrow helpersShows the helper scripts and what each one does.
projectburrow projectShows the project screen: install, configure and development.
rigs
The rigs burrow looks after, and whether each one answers.
atticconfig/rigs.tomlHolds attic's address 192.168.1.20 and the paths its stashes take.
cellarconfig/rigs.tomlHolds cellar's address 192.168.1.21 and the paths its stashes take.
gardenconfig/rigs.tomlHolds garden's address 192.168.1.22 and the paths its stashes take.
wake a rigbin/rig-wake <rig>Sends a magic packet that wakes a sleeping rig.
add a rigdocs/adding-a-rig.mdExplains how to add a rig block and check that it answers.
stash
The stashes, which are dated snapshots of each rig's important folders, and what you can do with them.
take one rigburrow stash <rig>Takes a stash of one rig now, into /srv/burrow/stashes.
take every rigburrow stash --allTakes a stash of every rig now.
list a rig's stashesburrow stash list <rig>Prints the stash dates of one rig.
pruneburrow stash prune --keep 8Removes old stashes, keeping the newest 8.
check newest stashscripts/verify-stash.shLists the first files of a rig's newest stash and its size.
stash spacescripts/du-stashes.shShows how much disk the stashes use.
weekly prune cronmake install-prune-cronInstalls the cron line that prunes stashes every Sunday at 04:40.
stash folder/srv/burrow/stashesHolds one folder per rig and one dated folder per stash.
restore
How to put a stash back onto its rig.
restore a rigburrow restore <rig> --from YYYY-MM-DDCopies the stash of that date back onto the rig.
dry runburrow restore <rig> --from YYYY-MM-DD --dry-runShows what a restore would copy, without changing the rig.
restore by handdocs/internals/stash/format/restore-by-hand.mdExplains copying a stash back with rsync when burrow is broken.
stash manifest/srv/burrow/stashes/<rig>/<date>/.burrow-manifestLists the paths and rsync exit code of the run that made the stash; non-zero means partial.
chores
The recurring jobs burrow runs, when they last ran, and the schedule that runs them.
list choresburrow chores listPrints the names of the chores burrow knows.
statusburrow chores statusPrints when each chore last finished and whether it worked.
nightly-stashburrow chores run nightly-stashRuns a stash of every rig; cron runs it at 02:15.
disk-checkburrow chores run disk-checkWarns about any rig whose root disk is over 85%; cron runs it every 6 hours.
scheduledeploy/burrow.crontabSchedules the two chores; install it with crontab deploy/burrow.crontab.
export choresscripts/export-chores.shExports the chores; read its header for where they go.
chores log/var/log/burrow/chores.logHolds the output of the scheduled chores.
last-run record/srv/burrow/state/last-run.jsonHolds when each chore last ran and its result.
chores guidedocs/chores.mdExplains the chores and how to run one by hand.
porch
The porch, burrow's web dashboard for the rigs, the chores and the stashes.
run the porchburrow porchRuns the dashboard on port 8470 and keeps running until stopped.
front pagehttp://127.0.0.1:8470Opens the front page, which lists the rigs.
chores pagehttp://127.0.0.1:8470/choresOpens the last run of each chore in the browser.
stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens one rig's stashes in the browser.
health checkhttp://127.0.0.1:8470/healthzAnswers the check with ok: true when the porch is up.
service unitdeploy/burrow-porch.serviceDescribes the systemd service that keeps the porch running.
install servicemake install-unitCopies the service into systemd and starts it.
porch log/var/log/burrow/porch.logHolds the porch's output.
metrics
The metrics containers: Grafana graphs of rig temperature and disk use, fed by pulse and Prometheus.
start metricsmake upStarts the metrics containers in the background.
stop metricsmake downStops the metrics containers.
graphshttp://127.0.0.1:3000Opens Grafana, the graphs of rig temperature and disk use.
pulsehttp://127.0.0.1:9188/metricsServes rig temperature and disk use to Prometheus; reports 0.0 until its readers are written.
prometheusdocker-compose.yml (service prometheus)Stores the readings for 30 days.
compose filedocker-compose.ymlDefines the metrics containers: pulse, prometheus and grafana.
helpers
Small shell helpers that burrow does not run itself; read the top of each one before you run it.
battery-reportscripts/battery-report.shReports battery condition.
cert-renewscripts/cert-renew.shRenews certificates.
check disksscripts/check-disks.shShows disk use on every rig, over ssh.
dns-flushscripts/dns-flush.shFlushes the DNS cache.
fan-curvescripts/fan-curve.shSets the fan speed curve.
gc-dockerscripts/gc-docker.shRemoves unused Docker data.
import-rigsscripts/import-rigs.shImports rigs into config/rigs.toml.
list-portsscripts/list-ports.shLists the open ports.
mount-nasscripts/mount-nas.shMounts the NAS.
net-speedscripts/net-speed.shMeasures network speed.
pihole-updatescripts/pihole-update.shUpdates Pi-hole.
reboot a rigscripts/reboot-rig.shReboots one rig after a 10 second countdown.
rotate-logsscripts/rotate-logs.shRotates the logs.
seed-devscripts/seed-dev.shSeeds development data.
smart-reportscripts/smart-report.shReports disk SMART health.
ssh-keys-pushscripts/ssh-keys-push.shPushes ssh keys to the rigs.
sync-clockscripts/sync-clock.shSyncs the clock.
temp-checkscripts/temp-check.shChecks temperatures.
unmount-nasscripts/unmount-nas.shUnmounts the NAS.
update-rigsscripts/update-rigs.shUpdates the rigs.
ups-statusscripts/ups-status.shShows the UPS status.
zfs-scrubscripts/zfs-scrub.shStarts a ZFS scrub.
project
Installing, configuring and developing burrow itself.
installburrow project installShows the install steps and the make targets that do them.
configureburrow project configureShows the settings files and what each one holds.
developmentburrow project developmentShows the test, lint and clean targets.
project › install
Installing burrow onto a machine, step by step.
install burrowmake installCreates .venv in the project, installs burrow into it, and makes the /srv and /var/log folders.
setup guidedocs/setup.mdExplains the steps to set up burrow on a rig, from the burrow user to the crontab.
project › configure
The settings burrow reads, and the file that holds each one.
burrow settingsconfig/burrow.tomlSets the stash folder and how many to keep, the chores' record file, the porch's address, and the SSH user.
rig listconfig/rigs.tomlLists the rigs, one [[rig]] block each.
environment.env.exampleHolds the environment settings to copy to .env: the SSH key, porch secret and ntfy topic.
project › development
Testing, checking and tidying the burrow code.
testmake testRuns the pytest suite in tests/.
lintmake lintChecks burrow and its tests with ruff.
cleanmake cleanRemoves .venv, caches and build output.
Questions
  • Porch command: `burrow porch` starts a blocking server today. Recommendation: make `burrow porch` print the porch screen, add `burrow porch run` to start it, and change ExecStart in burrow-porch.service to match. Do you agree?
  • Helpers list: 22 scripts on one screen is too long. Recommendation: split into three groups by job. Disks and health: battery-report, check-disks, fan-curve, smart-report, temp-check, ups-status, zfs-scrub. Network and names: cert-renew, dns-flush, list-ports, net-speed, pihole-update, sync-clock. Rigs and storage: gc-docker, import-rigs, mount-nas, reboot-rig, rotate-logs, seed-dev, ssh-keys-push, unmount-nas, update-rigs. Do you want this split?
  • Script headers: I could only read check-disks.sh, reboot-rig.sh and verify-stash.sh. Please send the header comments of the other scripts so their lines come from the code, not their names.
  • Pulse stubs: read_temp and read_disk return 0.0, so the graphs show zeros. Recommendation: keep pulse and Grafana on the map, with a line saying it reports 0.0 until the readers exist. Agree?
  • Prometheus config: prometheus.yml is referenced but not in the dump, so I cannot name its scrape targets. Please send it.
As phone screens

Home

What burrow looks after: its rigs, stashes, restores, chores, porch, metrics, helpers and project.

rigsLists the rigs and whether each one answers.
›
stashShows the stash screen: taking, listing and pruning stashes.
›
restoreShows how to copy a stash back onto a rig.
›
choresShows the chores screen: the jobs, running one, and when each last ran.
›
porchShows the porch screen: the dashboard and its pages.
›
metricsShows the metrics screen: the graphs and the containers behind them.
›
helpersShows the helper scripts and what each one does.
›
projectShows the project screen: install, configure and development.
›
‹ Home

rigs

The rigs burrow looks after, and whether each one answers.

atticHolds attic's address 192.168.1.20 and the paths its stashes take.
›
cellarHolds cellar's address 192.168.1.21 and the paths its stashes take.
›
gardenHolds garden's address 192.168.1.22 and the paths its stashes take.
›
wake a rigSends a magic packet that wakes a sleeping rig.
›
add a rigExplains how to add a rig block and check that it answers.
›
‹ Home

stash

The stashes, which are dated snapshots of each rig's important folders, and what you can do with them.

take one rigTakes a stash of one rig now, into /srv/burrow/stashes.
›
take every rigTakes a stash of every rig now.
›
list a rig's stashesPrints the stash dates of one rig.
›
pruneRemoves old stashes, keeping the newest 8.
›
check newest stashLists the first files of a rig's newest stash and its size.
›
stash spaceShows how much disk the stashes use.
›
weekly prune cronInstalls the cron line that prunes stashes every Sunday at 04:40.
›
stash folderHolds one folder per rig and one dated folder per stash.
›
‹ Home

restore

How to put a stash back onto its rig.

restore a rigCopies the stash of that date back onto the rig.
›
dry runShows what a restore would copy, without changing the rig.
›
restore by handExplains copying a stash back with rsync when burrow is broken.
›
stash manifestLists the paths and rsync exit code of the run that made the stash; non-zero means partial.
›
‹ Home

chores

The recurring jobs burrow runs, when they last ran, and the schedule that runs them.

list choresPrints the names of the chores burrow knows.
›
statusPrints when each chore last finished and whether it worked.
›
nightly-stashRuns a stash of every rig; cron runs it at 02:15.
›
disk-checkWarns about any rig whose root disk is over 85%; cron runs it every 6 hours.
›
scheduleSchedules the two chores; install it with crontab deploy/burrow.crontab.
›
export choresExports the chores; read its header for where they go.
›
chores logHolds the output of the scheduled chores.
›
last-run recordHolds when each chore last ran and its result.
›
chores guideExplains the chores and how to run one by hand.
›
‹ Home

porch

The porch, burrow's web dashboard for the rigs, the chores and the stashes.

run the porchRuns the dashboard on port 8470 and keeps running until stopped.
›
front pageOpens the front page, which lists the rigs.
›
chores pageOpens the last run of each chore in the browser.
›
stashes pageOpens one rig's stashes in the browser.
›
health checkAnswers the check with ok: true when the porch is up.
›
service unitDescribes the systemd service that keeps the porch running.
›
install serviceCopies the service into systemd and starts it.
›
porch logHolds the porch's output.
›
‹ Home

metrics

The metrics containers: Grafana graphs of rig temperature and disk use, fed by pulse and Prometheus.

start metricsStarts the metrics containers in the background.
›
stop metricsStops the metrics containers.
›
graphsOpens Grafana, the graphs of rig temperature and disk use.
›
pulseServes rig temperature and disk use to Prometheus; reports 0.0 until its readers are written.
›
prometheusStores the readings for 30 days.
›
compose fileDefines the metrics containers: pulse, prometheus and grafana.
›
‹ Home

helpers

Small shell helpers that burrow does not run itself; read the top of each one before you run it.

battery-reportReports battery condition.
›
cert-renewRenews certificates.
›
check disksShows disk use on every rig, over ssh.
›
dns-flushFlushes the DNS cache.
›
fan-curveSets the fan speed curve.
›
gc-dockerRemoves unused Docker data.
›
import-rigsImports rigs into config/rigs.toml.
›
list-portsLists the open ports.
›
mount-nasMounts the NAS.
›
net-speedMeasures network speed.
›
pihole-updateUpdates Pi-hole.
›
reboot a rigReboots one rig after a 10 second countdown.
›
rotate-logsRotates the logs.
›
seed-devSeeds development data.
›
smart-reportReports disk SMART health.
›
ssh-keys-pushPushes ssh keys to the rigs.
›
sync-clockSyncs the clock.
›
temp-checkChecks temperatures.
›
unmount-nasUnmounts the NAS.
›
update-rigsUpdates the rigs.
›
ups-statusShows the UPS status.
›
zfs-scrubStarts a ZFS scrub.
›
‹ Home

project

Installing, configuring and developing burrow itself.

installShows the install steps and the make targets that do them.
›
configureShows the settings files and what each one holds.
›
developmentShows the test, lint and clean targets.
›
‹ project

install

Installing burrow onto a machine, step by step.

install burrowCreates .venv in the project, installs burrow into it, and makes the /srv and /var/log folders.
›
setup guideExplains the steps to set up burrow on a rig, from the burrow user to the crontab.
›
‹ project

configure

The settings burrow reads, and the file that holds each one.

burrow settingsSets the stash folder and how many to keep, the chores' record file, the porch's address, and the SSH user.
›
rig listLists the rigs, one [[rig]] block each.
›
environmentHolds the environment settings to copy to .env: the SSH key, porch secret and ntfy topic.
›
‹ project

development

Testing, checking and tidying the burrow code.

testRuns the pytest suite in tests/.
›
lintChecks burrow and its tests with ruff.
›
cleanRemoves .venv, caches and build output.
›
Raw answer
**Scenario** (reasoning from the README and code, not from the owner's use): the lab owner opens a terminal when a rig seems down, a chore failed, a file is missing, or they want to see the graphs. They need to check the rigs, take or restore a stash, confirm the nightly run worked, and open the dashboard.

**Inventory** (where each thing is defined): `cli.py` (9 commands and groups), `Makefile` (13 targets), `porch/app.py` (4 routes), `docker-compose.yml` (3 services), `config/` (3 files), `deploy/` (service unit and crontab), `bin/rig-wake`, `scripts/` (25 scripts), `docs/` (4 guides), and the log and state paths in the config.

**Questions**

1. **Porch command.** `burrow porch` starts a blocking server today, which breaks the rule that a bare noun prints its screen. *Recommendation:* make `burrow porch` print the porch screen and add `burrow porch run` to start it, then change `ExecStart` in `burrow-porch.service` to match.
2. **Helpers list.** 22 scripts on one screen is too long. *Recommendation:* split by job into three groups. Disks and health: battery-report, check-disks, fan-curve, smart-report, temp-check, ups-status, zfs-scrub. Network and names: cert-renew, dns-flush, list-ports, net-speed, pihole-update, sync-clock. Rigs and storage: gc-docker, import-rigs, mount-nas, reboot-rig, rotate-logs, seed-dev, ssh-keys-push, unmount-nas, update-rigs. These groups come from the names alone.
3. **Script headers.** I could read only `check-disks.sh`, `reboot-rig.sh` and `verify-stash.sh`. Please send the header comments of the other scripts so their lines come from the code instead of their names.
4. **Pulse stubs.** `read_temp` and `read_disk` return 0.0, so the metrics currently show zeros. *Recommendation:* keep pulse and Grafana on the map and say in the line that it reports 0.0 until the readers exist.
5. **Prometheus config.** `prometheus.yml` is referenced but not in the dump, so I cannot name its scrape targets. Please send it.

**Judgment calls**

- **Top screen has 8 groups**, which is short enough. "Project" is taken from the README's "a personal project", since the README has no word for install, configure and development together.
- **Each job sits on one screen.** The `make stash-all` and `make prune-stashes` targets do the same as `burrow stash --all` and `stash prune`, so the map uses only the burrow commands.
- **Placements:** `rig-wake` is under rigs, `verify-stash`, `du-stashes` and the stash folder are under stash, and `export-chores` is under chores. `check-disks` stays on helpers because a user who runs it wants current disk use, while the `disk-check` chore only warns on a schedule.
- **Left off the map:** `pulse/Dockerfile`, the image pins, the HTML templates and the test files. A user does not reach these directly. The owner excluded nothing.
- **Bare nouns** like `burrow restore`, `burrow stash` and `burrow chores` currently error or print usage. The build should print their screens instead.
- **`stash prune`** says "keeping the newest 8". The code does not show whether that is per rig or in total, so the line stays general until confirmed.
- **Localhost URLs** use `127.0.0.1` as the README does. The LAN form uses the rig's IP.
- **`chores status`** prints raw epoch times. The map says "when"; formatting is a build decision.

```json
{"screens": [
 {"path": [], "sentence": "What burrow looks after: its rigs, stashes, restores, chores, porch, metrics, helpers and project.", "rows": [
  {"name": "rigs", "form": "burrow rigs", "what": "Lists the rigs and whether each one answers."},
  {"name": "stash", "form": "burrow stash", "what": "Shows the stash screen: taking, listing and pruning stashes."},
  {"name": "restore", "form": "burrow restore", "what": "Shows how to copy a stash back onto a rig."},
  {"name": "chores", "form": "burrow chores", "what": "Shows the chores screen: the jobs, running one, and when each last ran."},
  {"name": "porch", "form": "burrow porch", "what": "Shows the porch screen: the dashboard and its pages."},
  {"name": "metrics", "form": "burrow metrics", "what": "Shows the metrics screen: the graphs and the containers behind them."},
  {"name": "helpers", "form": "burrow helpers", "what": "Shows the helper scripts and what each one does."},
  {"name": "project", "form": "burrow project", "what": "Shows the project screen: install, configure and development."}
 ]},
 {"path": ["rigs"], "sentence": "The rigs burrow looks after, and whether each one answers.", "rows": [
  {"name": "attic", "form": "config/rigs.toml", "what": "Holds attic's address 192.168.1.20 and the paths its stashes take."},
  {"name": "cellar", "form": "config/rigs.toml", "what": "Holds cellar's address 192.168.1.21 and the paths its stashes take."},
  {"name": "garden", "form": "config/rigs.toml", "what": "Holds garden's address 192.168.1.22 and the paths its stashes take."},
  {"name": "wake a rig", "form": "bin/rig-wake <rig>", "what": "Sends a magic packet that wakes a sleeping rig."},
  {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Explains how to add a rig block and check that it answers."}
 ]},
 {"path": ["stash"], "sentence": "The stashes, which are dated snapshots of each rig's important folders, and what you can do with them.", "rows": [
  {"name": "take one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now, into /srv/burrow/stashes."},
  {"name": "take every rig", "form": "burrow stash --all", "what": "Takes a stash of every rig now."},
  {"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Prints the stash dates of one rig."},
  {"name": "prune", "form": "burrow stash prune --keep 8", "what": "Removes old stashes, keeping the newest 8."},
  {"name": "check newest stash", "form": "scripts/verify-stash.sh", "what": "Lists the first files of a rig's newest stash and its size."},
  {"name": "stash space", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use."},
  {"name": "weekly prune cron", "form": "make install-prune-cron", "what": "Installs the cron line that prunes stashes every Sunday at 04:40."},
  {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Holds one folder per rig and one dated folder per stash."}
 ]},
 {"path": ["restore"], "sentence": "How to put a stash back onto its rig.", "rows": [
  {"name": "restore a rig", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies the stash of that date back onto the rig."},
  {"name": "dry run", "form": "burrow restore <rig> --from YYYY-MM-DD --dry-run", "what": "Shows what a restore would copy, without changing the rig."},
  {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Explains copying a stash back with rsync when burrow is broken."},
  {"name": "stash manifest", "form": "/srv/burrow/stashes/<rig>/<date>/.burrow-manifest", "what": "Lists the paths and rsync exit code of the run that made the stash; non-zero means partial."}
 ]},
 {"path": ["chores"], "sentence": "The recurring jobs burrow runs, when they last ran, and the schedule that runs them.", "rows": [
  {"name": "list chores", "form": "burrow chores list", "what": "Prints the names of the chores burrow knows."},
  {"name": "status", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
  {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Runs a stash of every rig; cron runs it at 02:15."},
  {"name": "disk-check", "form": "burrow chores run disk-check", "what": "Warns about any rig whose root disk is over 85%; cron runs it every 6 hours."},
  {"name": "schedule", "form": "deploy/burrow.crontab", "what": "Schedules the two chores; install it with crontab deploy/burrow.crontab."},
  {"name": "export chores", "form": "scripts/export-chores.sh", "what": "Exports the chores; read its header for where they go."},
  {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Holds the output of the scheduled chores."},
  {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Holds when each chore last ran and its result."},
  {"name": "chores guide", "form": "docs/chores.md", "what": "Explains the chores and how to run one by hand."}
 ]},
 {"path": ["porch"], "sentence": "The porch, burrow's web dashboard for the rigs, the chores and the stashes.", "rows": [
  {"name": "run the porch", "form": "burrow porch", "what": "Runs the dashboard on port 8470 and keeps running until stopped."},
  {"name": "front page", "form": "http://127.0.0.1:8470", "what": "Opens the front page, which lists the rigs."},
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the last run of each chore in the browser."},
  {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens one rig's stashes in the browser."},
  {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Answers the check with ok: true when the porch is up."},
  {"name": "service unit", "form": "deploy/burrow-porch.service", "what": "Describes the systemd service that keeps the porch running."},
  {"name": "install service", "form": "make install-unit", "what": "Copies the service into systemd and starts it."},
  {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Holds the porch's output."}
 ]},
 {"path": ["metrics"], "sentence": "The metrics containers: Grafana graphs of rig temperature and disk use, fed by pulse and Prometheus.", "rows": [
  {"name": "start metrics", "form": "make up", "what": "Starts the metrics containers in the background."},
  {"name": "stop metrics", "form": "make down", "what": "Stops the metrics containers."},
  {"name": "graphs", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, the graphs of rig temperature and disk use."},
  {"name": "pulse", "form": "http://127.0.0.1:9188/metrics", "what": "Serves rig temperature and disk use to Prometheus; reports 0.0 until its readers are written."},
  {"name": "prometheus", "form": "docker-compose.yml (service prometheus)", "what": "Stores the readings for 30 days."},
  {"name": "compose file", "form": "docker-compose.yml", "what": "Defines the metrics containers: pulse, prometheus and grafana."}
 ]},
 {"path": ["helpers"], "sentence": "Small shell helpers that burrow does not run itself; read the top of each one before you run it.", "rows": [
  {"name": "battery-report", "form": "scripts/battery-report.sh", "what": "Reports battery condition."},
  {"name": "cert-renew", "form": "scripts/cert-renew.sh", "what": "Renews certificates."},
  {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig, over ssh."},
  {"name": "dns-flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache."},
  {"name": "fan-curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan speed curve."},
  {"name": "gc-docker", "form": "scripts/gc-docker.sh", "what": "Removes unused Docker data."},
  {"name": "import-rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into config/rigs.toml."},
  {"name": "list-ports", "form": "scripts/list-ports.sh", "what": "Lists the open ports."},
  {"name": "mount-nas", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS."},
  {"name": "net-speed", "form": "scripts/net-speed.sh", "what": "Measures network speed."},
  {"name": "pihole-update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole."},
  {"name": "reboot a rig", "form": "scripts/reboot-rig.sh", "what": "Reboots one rig after a 10 second countdown."},
  {"name": "rotate-logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs."},
  {"name": "seed-dev", "form": "scripts/seed-dev.sh", "what": "Seeds development data."},
  {"name": "smart-report", "form": "scripts/smart-report.sh", "what": "Reports disk SMART health."},
  {"name": "ssh-keys-push", "form": "scripts/ssh-keys-push.sh", "what": "Pushes ssh keys to the rigs."},
  {"name": "sync-clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock."},
  {"name": "temp-check", "form": "scripts/temp-check.sh", "what": "Checks temperatures."},
  {"name": "unmount-nas", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS."},
  {"name": "update-rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs."},
  {"name": "ups-status", "form": "scripts/ups-status.sh", "what": "Shows the UPS status."},
  {"name": "zfs-scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub."}
 ]},
 {"path": ["project"], "sentence": "Installing, configuring and developing burrow itself.", "rows": [
  {"name": "install", "form": "burrow project install", "what": "Shows the install steps and the make targets that do them."},
  {"name": "configure", "form": "burrow project configure", "what": "Shows the settings files and what each one holds."},
  {"name": "development", "form": "burrow project development", "what": "Shows the test, lint and clean targets."}
 ]},
 {"path": ["project", "install"], "sentence": "Installing burrow onto a machine, step by step.", "rows": [
  {"name": "install burrow", "form": "make install", "what": "Creates .venv in the project, installs burrow into it, and makes the /srv and /var/log folders."},
  {"name": "setup guide", "form": "docs/setup.md", "what": "Explains the steps to set up burrow on a rig, from the burrow user to the crontab."}
 ]},
 {"path": ["project", "configure"], "sentence": "The settings burrow reads, and the file that holds each one.", "rows": [
  {"name": "burrow settings", "form": "config/burrow.toml", "what": "Sets the stash folder and how many to keep, the chores' record file, the porch's address, and the SSH user."},
  {"name": "rig list", "form": "config/rigs.toml", "what": "Lists the rigs, one [[rig]] block each."},
  {"name": "environment", "form": ".env.example", "what": "Holds the environment settings to copy to .env: the SSH key, porch secret and ntfy topic."}
 ]},
 {"path": ["project", "development"], "sentence": "Testing, checking and tidying the burrow code.", "rows": [
  {"name": "test", "form": "make test", "what": "Runs the pytest suite in tests/."},
  {"name": "lint", "form": "make lint", "what": "Checks burrow and its tests with ruff."},
  {"name": "clean", "form": "make clean", "what": "Removes .venv, caches and build output."}
 ]}
],
"questions": [
 "Porch command: `burrow porch` starts a blocking server today. Recommendation: make `burrow porch` print the porch screen, add `burrow porch run` to start it, and change ExecStart in burrow-porch.service to match. Do you agree?",
 "Helpers list: 22 scripts on one screen is too long. Recommendation: split into three groups by job. Disks and health: battery-report, check-disks, fan-curve, smart-report, temp-check, ups-status, zfs-scrub. Network and names: cert-renew, dns-flush, list-ports, net-speed, pihole-update, sync-clock. Rigs and storage: gc-docker, import-rigs, mount-nas, reboot-rig, rotate-logs, seed-dev, ssh-keys-push, unmount-nas, update-rigs. Do you want this split?",
 "Script headers: I could only read check-disks.sh, reboot-rig.sh and verify-stash.sh. Please send the header comments of the other scripts so their lines come from the code, not their names.",
 "Pulse stubs: read_temp and read_disk return 0.0, so the graphs show zeros. Recommendation: keep pulse and Grafana on the map, with a line saying it reports 0.0 until the readers exist. Agree?",
 "Prometheus config: prometheus.yml is referenced but not in the dump, so I cannot name its scrape targets. Please send it."
],
"judgment_calls": []}
```

No skill · run 4 exit=0 seconds=45 · prompt

P1 Recall: 0.133P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.56P5 Short top: 6P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
The top of burrow: commands for rigs, stashes, restores, chores and the porch dashboard, plus one global option for the settings file.
rigsburrow rigslist the rigs and whether each one answers
stashburrow stash ...take stashes, list them, or prune old ones
restoreburrow restore <rig> --from YYYY-MM-DDcopy a stash back onto its rig
choresburrow chores ...list, run and check recurring jobs
porchburrow porch [--bind ADDR:PORT]run the web dashboard
--config--config PATH (default config/burrow.toml)use a different settings file
rigs
Lists each configured rig with its address and whether it answers (up or down).
stash
Takes a stash of one rig or of every rig, and manages the stashes already taken.
<rig>burrow stash <rig>take a stash of one rig now
--allburrow stash --alltake a stash of every rig
listburrow stash list <rig>show the stashes kept for one rig
pruneburrow stash prune [--keep N]delete old stashes, keeping the newest N
stash › list
Shows the stashes kept for one rig, one per line.
<rig>burrow stash list <rig>the rig whose stashes to show
stash › prune
Deletes old stashes so the stash folder does not fill the disk.
--keepburrow stash prune --keep N (default 8)how many of the newest stashes to keep
restore
Copies a dated stash back onto one rig.
<rig>burrow restore <rig>the rig to restore onto
--from--from YYYY-MM-DD (required)the date of the stash to restore
--dry-run--dry-runshow what would be copied without copying it
chores
Recurring jobs: see which exist, run one by hand, and check when each last ran.
listburrow chores listshow the names of the chores
runburrow chores run <name>run one chore now
statusburrow chores statusshow when each chore last finished and whether it worked
chores › list
Prints the name of every chore burrow knows.
chores › run
Runs one named chore now, the same job cron runs on schedule.
nightly-stashburrow chores run nightly-stashstash every rig (cron runs it at 02:15)
disk-checkburrow chores run disk-checkwarn about any rig whose root disk is over 85% (cron runs it every 6 hours)
chores › status
Shows each chore's last finish time and result.
porch
Runs the porch dashboard web server and lists the pages it serves.
--bind--bind ADDR:PORT (default from config, 0.0.0.0:8470)the address and port to listen on
dashboardhttp://<host>:8470/the front page with every rig
chores pagehttp://<host>:8470/choresthe last-run table for chores
stashes pagehttp://<host>:8470/stashes/<rig>the stashes kept for one rig
health checkhttp://<host>:8470/healthzreturns ok when the porch is up
Questions
  • The stash group's optional rig argument probably swallows the words 'list' and 'prune', so 'burrow stash list <rig>' and 'burrow stash prune' may not run; the Makefile's prune-stashes target depends on the second one. Recommendation: make stash a plain group with 'take' (with --all or a rig), 'list' and 'prune' subcommands, and update the README example and Makefile to match. This changes the README's 'burrow stash attic' form, so it is your call.
  • Should burrow's help also cover the make targets (stash-all, prune-stashes, up, down, test, lint, install, install-unit, install-prune-cron, clean), bin/rig-wake and the 25 helpers in scripts/? Recommendation: no. Keep the burrow help to the burrow command and document the rest in the README.
  • Should restore's --from default to the newest stash when it is left out? Recommendation: yes. Make it optional, keep it as an override, and keep --dry-run, since the newest stash is the usual target.
  • Should burrow get a 'wake <rig>' command that wraps bin/rig-wake, so rig names are only read from config in one place? Recommendation: yes, add it under the top screen next to rigs.
  • Grafana (port 3000) and the pulse metrics endpoint (port 9188) are outside the burrow command. Recommendation: leave them out of the CLI map and list their URLs in the README only.
As phone screens

Home

The top of burrow: commands for rigs, stashes, restores, chores and the porch dashboard, plus one global option for the settings file.

rigslist the rigs and whether each one answers
›
stashtake stashes, list them, or prune old ones
›
restorecopy a stash back onto its rig
›
choreslist, run and check recurring jobs
›
porchrun the web dashboard
›
--configuse a different settings file
›
‹ Home

rigs

Lists each configured rig with its address and whether it answers (up or down).

‹ Home

stash

Takes a stash of one rig or of every rig, and manages the stashes already taken.

<rig>take a stash of one rig now
›
--alltake a stash of every rig
›
listshow the stashes kept for one rig
›
prunedelete old stashes, keeping the newest N
›
‹ stash

list

Shows the stashes kept for one rig, one per line.

<rig>the rig whose stashes to show
›
‹ stash

prune

Deletes old stashes so the stash folder does not fill the disk.

--keephow many of the newest stashes to keep
›
‹ Home

restore

Copies a dated stash back onto one rig.

<rig>the rig to restore onto
›
--fromthe date of the stash to restore
›
--dry-runshow what would be copied without copying it
›
‹ Home

chores

Recurring jobs: see which exist, run one by hand, and check when each last ran.

listshow the names of the chores
›
runrun one chore now
›
statusshow when each chore last finished and whether it worked
›
‹ chores

list

Prints the name of every chore burrow knows.

‹ chores

run

Runs one named chore now, the same job cron runs on schedule.

nightly-stashstash every rig (cron runs it at 02:15)
›
disk-checkwarn about any rig whose root disk is over 85% (cron runs it every 6 hours)
›
‹ chores

status

Shows each chore's last finish time and result.

‹ Home

porch

Runs the porch dashboard web server and lists the pages it serves.

--bindthe address and port to listen on
›
dashboardthe front page with every rig
›
chores pagethe last-run table for chores
›
stashes pagethe stashes kept for one rig
›
health checkreturns ok when the porch is up
›
Raw answer
I mapped one screen per burrow command or command group, so each help screen lines up with a `--help` page. The top screen lists the five commands and the global `--config` option. Rig names come from `config/rigs.toml`, so `<rig>` stands for whatever names are configured.

I read the stash group's parsing from `burrow/cli.py` and did not run it. Click appears to consume `list` or `prune` as the optional `rig` argument, which would leave those two subcommands unreachable. That is the first question below.

```json
{"screens": [
 {"path": [], "sentence": "The top of burrow: commands for rigs, stashes, restores, chores and the porch dashboard, plus one global option for the settings file.", "rows": [
   {"name": "rigs", "form": "burrow rigs", "what": "list the rigs and whether each one answers"},
   {"name": "stash", "form": "burrow stash ...", "what": "take stashes, list them, or prune old ones"},
   {"name": "restore", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "copy a stash back onto its rig"},
   {"name": "chores", "form": "burrow chores ...", "what": "list, run and check recurring jobs"},
   {"name": "porch", "form": "burrow porch [--bind ADDR:PORT]", "what": "run the web dashboard"},
   {"name": "--config", "form": "--config PATH (default config/burrow.toml)", "what": "use a different settings file"}
 ]},
 {"path": ["rigs"], "sentence": "Lists each configured rig with its address and whether it answers (up or down).", "rows": []},
 {"path": ["stash"], "sentence": "Takes a stash of one rig or of every rig, and manages the stashes already taken.", "rows": [
   {"name": "<rig>", "form": "burrow stash <rig>", "what": "take a stash of one rig now"},
   {"name": "--all", "form": "burrow stash --all", "what": "take a stash of every rig"},
   {"name": "list", "form": "burrow stash list <rig>", "what": "show the stashes kept for one rig"},
   {"name": "prune", "form": "burrow stash prune [--keep N]", "what": "delete old stashes, keeping the newest N"}
 ]},
 {"path": ["stash", "list"], "sentence": "Shows the stashes kept for one rig, one per line.", "rows": [
   {"name": "<rig>", "form": "burrow stash list <rig>", "what": "the rig whose stashes to show"}
 ]},
 {"path": ["stash", "prune"], "sentence": "Deletes old stashes so the stash folder does not fill the disk.", "rows": [
   {"name": "--keep", "form": "burrow stash prune --keep N (default 8)", "what": "how many of the newest stashes to keep"}
 ]},
 {"path": ["restore"], "sentence": "Copies a dated stash back onto one rig.", "rows": [
   {"name": "<rig>", "form": "burrow restore <rig>", "what": "the rig to restore onto"},
   {"name": "--from", "form": "--from YYYY-MM-DD (required)", "what": "the date of the stash to restore"},
   {"name": "--dry-run", "form": "--dry-run", "what": "show what would be copied without copying it"}
 ]},
 {"path": ["chores"], "sentence": "Recurring jobs: see which exist, run one by hand, and check when each last ran.", "rows": [
   {"name": "list", "form": "burrow chores list", "what": "show the names of the chores"},
   {"name": "run", "form": "burrow chores run <name>", "what": "run one chore now"},
   {"name": "status", "form": "burrow chores status", "what": "show when each chore last finished and whether it worked"}
 ]},
 {"path": ["chores", "list"], "sentence": "Prints the name of every chore burrow knows.", "rows": []},
 {"path": ["chores", "run"], "sentence": "Runs one named chore now, the same job cron runs on schedule.", "rows": [
   {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "stash every rig (cron runs it at 02:15)"},
   {"name": "disk-check", "form": "burrow chores run disk-check", "what": "warn about any rig whose root disk is over 85% (cron runs it every 6 hours)"}
 ]},
 {"path": ["chores", "status"], "sentence": "Shows each chore's last finish time and result.", "rows": []},
 {"path": ["porch"], "sentence": "Runs the porch dashboard web server and lists the pages it serves.", "rows": [
   {"name": "--bind", "form": "--bind ADDR:PORT (default from config, 0.0.0.0:8470)", "what": "the address and port to listen on"},
   {"name": "dashboard", "form": "http://<host>:8470/", "what": "the front page with every rig"},
   {"name": "chores page", "form": "http://<host>:8470/chores", "what": "the last-run table for chores"},
   {"name": "stashes page", "form": "http://<host>:8470/stashes/<rig>", "what": "the stashes kept for one rig"},
   {"name": "health check", "form": "http://<host>:8470/healthz", "what": "returns ok when the porch is up"}
 ]}
],
"questions": [
 "The stash group's optional rig argument probably swallows the words 'list' and 'prune', so 'burrow stash list <rig>' and 'burrow stash prune' may not run; the Makefile's prune-stashes target depends on the second one. Recommendation: make stash a plain group with 'take' (with --all or a rig), 'list' and 'prune' subcommands, and update the README example and Makefile to match. This changes the README's 'burrow stash attic' form, so it is your call.",
 "Should burrow's help also cover the make targets (stash-all, prune-stashes, up, down, test, lint, install, install-unit, install-prune-cron, clean), bin/rig-wake and the 25 helpers in scripts/? Recommendation: no. Keep the burrow help to the burrow command and document the rest in the README.",
 "Should restore's --from default to the newest stash when it is left out? Recommendation: yes. Make it optional, keep it as an override, and keep --dry-run, since the newest stash is the usual target.",
 "Should burrow get a 'wake <rig>' command that wraps bin/rig-wake, so rig names are only read from config in one place? Recommendation: yes, add it under the top screen next to rigs.",
 "Grafana (port 3000) and the pulse metrics endpoint (port 9188) are outside the burrow command. Recommendation: leave them out of the CLI map and list their URLs in the README only."
]}
```

Today's skills · run 4 exit=0 seconds=152 · prompt

P1 Recall: 0.85P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 9P6 Own words: 0.9P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
Everything burrow looks after in your home lab: the rigs, their stashes, the chores that run on a schedule, the porch dashboard, and the files behind them.
Rigsburrow rigsPrints the rigs burrow knows and whether each one answers.
Stashesburrow stashPrints the stashes of every rig and the actions for them.
Choresburrow choresPrints the recurring jobs and when each last ran.
Porchburrow porchPrints the porch screen: its address, its service status and how to run it.
Metricsburrow metricsPrints the metrics stack: its containers, graphs and readings.
Helpersburrow helpersPrints the shell helpers in scripts/, grouped by what they are for.
Setupburrow setupPrints the one-time steps that set burrow up on a machine.
Developburrow developPrints the tools for changing burrow: tests, lint and clean-up.
Filesburrow filesPrints where burrow keeps its settings, stashes, logs and guides.
rigs
The rigs burrow knows, and whether each one answers.
atticburrow rigs atticPrints the attic screen: its stashes, and the wake and reboot actions for it.
cellarburrow rigs cellarPrints the cellar screen: its stashes, and the wake and reboot actions for it.
gardenburrow rigs gardenPrints the garden screen: its stashes, and the wake and reboot actions for it.
Add a rigdocs/adding-a-rig.mdOpens the steps for adding a rig to config/rigs.toml.
rigs › attic
The attic rig: what you can do to the machine, and where its stashes and settings are.
Its stashesburrow stash atticPrints the screen of attic's stashes.
Wakeburrow rigs attic wakeSends a wake packet to attic, through bin/rig-wake.
Rebootburrow rigs attic rebootReboots attic after a 10 second countdown, through scripts/reboot-rig.sh.
Its settingsconfig/rigs.tomlOpens the rigs file where attic's address, MAC address and folders are set.
stash
Snapshots of each rig's important folders, taken over rsync and kept under /srv/burrow/stashes, one dated folder each.
atticburrow stash atticPrints the screen of attic's stashes, with its dated stashes and the actions for them.
cellarburrow stash cellarPrints the screen of cellar's stashes, with its dated stashes and the actions for them.
gardenburrow stash gardenPrints the screen of garden's stashes, with its dated stashes and the actions for them.
Take every rig's stashburrow stash all takeTakes a stash of every rig at once; make stash-all does the same today.
Prune old stashesburrow stash prune --keep 8Removes all but the newest 8 stashes of each rig; cron runs it weekly.
stash › attic
The stashes of attic, one dated folder each, and what you can do with them.
Take a stash nowburrow stash attic takeTakes a stash of attic now, into its folder under /srv/burrow/stashes.
Restore a stashburrow stash attic restore --from YYYY-MM-DDCopies a dated stash back onto attic; add --dry-run to see what would change first.
Check the newestburrow stash attic verifyChecks that attic's newest stash is readable and not empty, through scripts/verify-stash.sh.
Stash folder/srv/burrow/stashes/atticOpens the folder with attic's dated stashes.
Stashes page on the porchhttp://127.0.0.1:8470/stashes/atticOpens attic's stashes page on the porch dashboard.
chores
The recurring jobs burrow runs on a schedule, when each last ran, and whether it worked.
nightly-stashburrow chores nightly-stashPrints the nightly-stash screen: a stash of every rig, taken at 02:15 each night.
disk-checkburrow chores disk-checkPrints the disk-check screen: a warning when a rig's root disk is over 85 percent, checked every 6 hours.
Last runsburrow chores statusPrints when each chore last finished and whether it worked.
Export choresscripts/export-chores.shExports the chores out of burrow, through scripts/export-chores.sh.
Chores page on the porchhttp://127.0.0.1:8470/choresOpens the chores page on the porch dashboard, with each chore's last run.
chores › nightly-stash
The nightly-stash chore: a stash of every rig, taken at 02:15 each night.
Run it nowburrow chores nightly-stash runRuns the nightly stash now, the same job the schedule runs at 02:15.
Its scheduledeploy/burrow.crontabOpens the crontab that schedules it at 02:15 each night.
Its codeburrow/chores.pyOpens the code the job runs, the nightly_stash function.
chores › disk-check
The disk-check chore: a warning when a rig's root disk is over 85 percent, checked every 6 hours.
Run it nowburrow chores disk-check runRuns the disk check now, the same job the schedule runs every 6 hours.
Its scheduledeploy/burrow.crontabOpens the crontab that schedules it every 6 hours.
Its codeburrow/chores.pyOpens the code the job runs, the disk_check function.
porch
The porch: the web dashboard for the rigs, served on port 8470 and kept running by systemd.
Open the dashboardhttp://127.0.0.1:8470Opens the dashboard here; from another machine, use the rig's IP instead of 127.0.0.1.
Health checkhttp://127.0.0.1:8470/healthzOpens the health check, which answers ok while the porch is up.
Service statusburrow porch statusPrints whether the porch service is running, from systemctl.
Restart the serviceburrow porch restartRestarts the porch service under systemd.
Run by handburrow porch runRuns the porch in the foreground on port 8470, the way systemd runs it.
Service filedeploy/burrow-porch.serviceOpens the systemd unit that starts the porch.
metrics
The metrics stack: containers that collect rig temperatures and disk use, and draw graphs of them.
Startburrow metrics startStarts the metrics containers in the background, through make up.
Stopburrow metrics stopStops the metrics containers, through make down.
Graphshttp://127.0.0.1:3000Opens the Grafana graphs of rig temperatures and disk use.
Readingshttp://127.0.0.1:9188/metricsOpens the raw readings pulse gives Prometheus.
Compose filedocker-compose.ymlOpens the file that defines the containers, Prometheus included.
Pulse codepulse/pulse.pyOpens the code that reads each rig's temperature and disk use.
helpers
Small shell helpers in scripts/, grouped by what they are for. Read the top of each one before you run it.
Rigsburrow helpers rigsPrints the helpers that act on all rigs together.
Storageburrow helpers storagePrints the helpers for disks, stashes, mounts and logs.
Networkburrow helpers networkPrints the helpers for DNS, ports, speed and certificates.
Powerburrow helpers powerPrints the helpers for the UPS, the battery and the fans.
helpers › rigs
The helpers that act on all the rigs together.
Check disksscripts/check-disks.shShows the disk use of every rig.
Temperaturesscripts/temp-check.shChecks the temperature of every rig.
Update rigsscripts/update-rigs.shUpdates the software on every rig.
Push SSH keysscripts/ssh-keys-push.shPushes the burrow SSH key to every rig.
Sync clockscripts/sync-clock.shSets the clock of every rig to the same time.
Import rigsscripts/import-rigs.shImports rigs into config/rigs.toml.
helpers › storage
The helpers for disks, stashes, mounts and logs.
ZFS scrubscripts/zfs-scrub.shStarts a ZFS scrub, which checks the pool for damage.
Disk healthscripts/smart-report.shPrints the SMART health of the disks.
Mount the NASscripts/mount-nas.shMounts the NAS share.
Unmount the NASscripts/unmount-nas.shUnmounts the NAS share.
Clean Dockerscripts/gc-docker.shRemoves unused Docker data.
Rotate logsscripts/rotate-logs.shRotates the log files.
Stash disk usescripts/du-stashes.shShows how much disk the stashes use.
helpers › network
The helpers for DNS, ports, speed and certificates.
Flush DNSscripts/dns-flush.shClears the DNS cache.
Network speedscripts/net-speed.shMeasures the network speed.
Open portsscripts/list-ports.shLists the ports that are listening.
Update Pi-holescripts/pihole-update.shUpdates Pi-hole.
Renew certificatesscripts/cert-renew.shRenews the certificates.
helpers › power
The helpers for the UPS, the battery and the fans.
UPS statusscripts/ups-status.shShows the UPS status.
Battery reportscripts/battery-report.shShows the battery report.
Fan curvescripts/fan-curve.shSets the fan curve.
setup
The steps that set burrow up, in order, the first time it goes on a machine.
Setup guidedocs/setup.mdOpens the setup steps in order.
Installburrow setup installInstalls burrow into .venv/ and creates its stash and log folders, through make install.
Porch serviceburrow setup porch-serviceInstalls and starts the porch under systemd, through make install-unit.
Chores scheduleburrow setup chores-scheduleInstalls the chores schedule from deploy/burrow.crontab into crontab.
Prune scheduleburrow setup prune-scheduleAdds the weekly prune of old stashes to crontab, Sundays at 04:40, through make install-prune-cron.
develop
Tools for changing burrow itself: its tests, its linter and its clean-up.
Run the testsburrow develop testRuns the tests in tests/ with pytest.
Lintburrow develop lintChecks burrow/ and tests/ with ruff.
Seed sample datascripts/seed-dev.shSeeds sample data for development, through scripts/seed-dev.sh.
Cleanburrow develop cleanDeletes .venv and the build output; setup install puts the venv back.
Tests foldertests/Opens the tests.
files
Where burrow keeps its settings, its stashes and logs, and its guides.
Settingsburrow files settingsPrints the settings files and the environment example.
Stashes and logsburrow files logsPrints where the stashes, the last-run record and the logs live.
Guidesburrow files guidesPrints the guides in docs/ and the README.
files › settings
The settings files, and the example to copy the environment from.
Main settingsconfig/burrow.tomlOpens the main settings: stash folder, chores, porch and SSH.
Rigsconfig/rigs.tomlOpens the list of rigs: names, addresses, MAC addresses and folders.
Environment.envOpens the environment file with the SSH key path and the porch secret.
Environment example.env.exampleOpens the example to copy to .env and fill in.
files › logs
Where burrow writes its stashes, its last-run record and its logs.
Stash folder/srv/burrow/stashesOpens the folder with every stash, one folder per rig.
Last-run record/srv/burrow/state/last-run.jsonOpens the record of when each chore last ran and whether it worked.
Chores log/var/log/burrow/chores.logOpens the output of the scheduled chores.
Porch log/var/log/burrow/porch.logOpens the output of the porch.
files › guides
The guides in docs/, and the README.
READMEREADME.mdOpens the project README.
Adding a rigdocs/adding-a-rig.mdOpens the steps to add a rig to rigs.toml.
Chores guidedocs/chores.mdOpens the guide to the chores.
Restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the steps to restore a stash without burrow.
Questions
  • Taking a stash moves from `burrow stash attic` to `burrow stash attic take`, because a bare noun must print its screen. The README and make stash-all change with it. Recommendation: move it and update both.
  • `burrow porch` runs the server today, and the systemd unit calls it that way. The map moves running to `burrow porch run` and needs ExecStart in deploy/burrow-porch.service edited in the same change. Recommendation: make that change.
  • `chores-schedule` as written runs `crontab deploy/burrow.crontab`, which replaces the whole crontab and would delete the weekly prune line. Recommendation: have setup merge the two files instead of replacing one with the other.
  • pulse's read_temp and read_disk return 0.0 in this dump, so the Graphs row would show zeros. Recommendation: keep the row, and state on the metrics screen that readings are not live yet.
  • Only the names of 22 of the 25 scripts are visible to me, so their 'what' text is a guess. Recommendation: read each script before the screens are printed and correct the rows.
  • `develop clean` deletes .venv and `stash prune` deletes old stashes. Recommendation: both ask for confirmation before they run, unless you want them silent.
As phone screens

Home

Everything burrow looks after in your home lab: the rigs, their stashes, the chores that run on a schedule, the porch dashboard, and the files behind them.

RigsPrints the rigs burrow knows and whether each one answers.
›
StashesPrints the stashes of every rig and the actions for them.
›
ChoresPrints the recurring jobs and when each last ran.
›
PorchPrints the porch screen: its address, its service status and how to run it.
›
MetricsPrints the metrics stack: its containers, graphs and readings.
›
HelpersPrints the shell helpers in scripts/, grouped by what they are for.
›
SetupPrints the one-time steps that set burrow up on a machine.
›
DevelopPrints the tools for changing burrow: tests, lint and clean-up.
›
FilesPrints where burrow keeps its settings, stashes, logs and guides.
›
‹ Home

rigs

The rigs burrow knows, and whether each one answers.

atticPrints the attic screen: its stashes, and the wake and reboot actions for it.
›
cellarPrints the cellar screen: its stashes, and the wake and reboot actions for it.
›
gardenPrints the garden screen: its stashes, and the wake and reboot actions for it.
›
Add a rigOpens the steps for adding a rig to config/rigs.toml.
›
‹ rigs

attic

The attic rig: what you can do to the machine, and where its stashes and settings are.

Its stashesPrints the screen of attic's stashes.
›
WakeSends a wake packet to attic, through bin/rig-wake.
›
RebootReboots attic after a 10 second countdown, through scripts/reboot-rig.sh.
›
Its settingsOpens the rigs file where attic's address, MAC address and folders are set.
›
‹ Home

stash

Snapshots of each rig's important folders, taken over rsync and kept under /srv/burrow/stashes, one dated folder each.

atticPrints the screen of attic's stashes, with its dated stashes and the actions for them.
›
cellarPrints the screen of cellar's stashes, with its dated stashes and the actions for them.
›
gardenPrints the screen of garden's stashes, with its dated stashes and the actions for them.
›
Take every rig's stashTakes a stash of every rig at once; make stash-all does the same today.
›
Prune old stashesRemoves all but the newest 8 stashes of each rig; cron runs it weekly.
›
‹ stash

attic

The stashes of attic, one dated folder each, and what you can do with them.

Take a stash nowTakes a stash of attic now, into its folder under /srv/burrow/stashes.
›
Restore a stashCopies a dated stash back onto attic; add --dry-run to see what would change first.
›
Check the newestChecks that attic's newest stash is readable and not empty, through scripts/verify-stash.sh.
›
Stash folderOpens the folder with attic's dated stashes.
›
Stashes page on the porchOpens attic's stashes page on the porch dashboard.
›
‹ Home

chores

The recurring jobs burrow runs on a schedule, when each last ran, and whether it worked.

nightly-stashPrints the nightly-stash screen: a stash of every rig, taken at 02:15 each night.
›
disk-checkPrints the disk-check screen: a warning when a rig's root disk is over 85 percent, checked every 6 hours.
›
Last runsPrints when each chore last finished and whether it worked.
›
Export choresExports the chores out of burrow, through scripts/export-chores.sh.
›
Chores page on the porchOpens the chores page on the porch dashboard, with each chore's last run.
›
‹ chores

nightly-stash

The nightly-stash chore: a stash of every rig, taken at 02:15 each night.

Run it nowRuns the nightly stash now, the same job the schedule runs at 02:15.
›
Its scheduleOpens the crontab that schedules it at 02:15 each night.
›
Its codeOpens the code the job runs, the nightly_stash function.
›
‹ chores

disk-check

The disk-check chore: a warning when a rig's root disk is over 85 percent, checked every 6 hours.

Run it nowRuns the disk check now, the same job the schedule runs every 6 hours.
›
Its scheduleOpens the crontab that schedules it every 6 hours.
›
Its codeOpens the code the job runs, the disk_check function.
›
‹ Home

porch

The porch: the web dashboard for the rigs, served on port 8470 and kept running by systemd.

Open the dashboardOpens the dashboard here; from another machine, use the rig's IP instead of 127.0.0.1.
›
Health checkOpens the health check, which answers ok while the porch is up.
›
Service statusPrints whether the porch service is running, from systemctl.
›
Restart the serviceRestarts the porch service under systemd.
›
Run by handRuns the porch in the foreground on port 8470, the way systemd runs it.
›
Service fileOpens the systemd unit that starts the porch.
›
‹ Home

metrics

The metrics stack: containers that collect rig temperatures and disk use, and draw graphs of them.

StartStarts the metrics containers in the background, through make up.
›
StopStops the metrics containers, through make down.
›
GraphsOpens the Grafana graphs of rig temperatures and disk use.
›
ReadingsOpens the raw readings pulse gives Prometheus.
›
Compose fileOpens the file that defines the containers, Prometheus included.
›
Pulse codeOpens the code that reads each rig's temperature and disk use.
›
‹ Home

helpers

Small shell helpers in scripts/, grouped by what they are for. Read the top of each one before you run it.

RigsPrints the helpers that act on all rigs together.
›
StoragePrints the helpers for disks, stashes, mounts and logs.
›
NetworkPrints the helpers for DNS, ports, speed and certificates.
›
PowerPrints the helpers for the UPS, the battery and the fans.
›
‹ helpers

rigs

The helpers that act on all the rigs together.

Check disksShows the disk use of every rig.
›
TemperaturesChecks the temperature of every rig.
›
Update rigsUpdates the software on every rig.
›
Push SSH keysPushes the burrow SSH key to every rig.
›
Sync clockSets the clock of every rig to the same time.
›
Import rigsImports rigs into config/rigs.toml.
›
‹ helpers

storage

The helpers for disks, stashes, mounts and logs.

ZFS scrubStarts a ZFS scrub, which checks the pool for damage.
›
Disk healthPrints the SMART health of the disks.
›
Mount the NASMounts the NAS share.
›
Unmount the NASUnmounts the NAS share.
›
Clean DockerRemoves unused Docker data.
›
Rotate logsRotates the log files.
›
Stash disk useShows how much disk the stashes use.
›
‹ helpers

network

The helpers for DNS, ports, speed and certificates.

Flush DNSClears the DNS cache.
›
Network speedMeasures the network speed.
›
Open portsLists the ports that are listening.
›
Update Pi-holeUpdates Pi-hole.
›
Renew certificatesRenews the certificates.
›
‹ helpers

power

The helpers for the UPS, the battery and the fans.

UPS statusShows the UPS status.
›
Battery reportShows the battery report.
›
Fan curveSets the fan curve.
›
‹ Home

setup

The steps that set burrow up, in order, the first time it goes on a machine.

Setup guideOpens the setup steps in order.
›
InstallInstalls burrow into .venv/ and creates its stash and log folders, through make install.
›
Porch serviceInstalls and starts the porch under systemd, through make install-unit.
›
Chores scheduleInstalls the chores schedule from deploy/burrow.crontab into crontab.
›
Prune scheduleAdds the weekly prune of old stashes to crontab, Sundays at 04:40, through make install-prune-cron.
›
‹ Home

develop

Tools for changing burrow itself: its tests, its linter and its clean-up.

Run the testsRuns the tests in tests/ with pytest.
›
LintChecks burrow/ and tests/ with ruff.
›
Seed sample dataSeeds sample data for development, through scripts/seed-dev.sh.
›
CleanDeletes .venv and the build output; setup install puts the venv back.
›
Tests folderOpens the tests.
›
‹ Home

files

Where burrow keeps its settings, its stashes and logs, and its guides.

SettingsPrints the settings files and the environment example.
›
Stashes and logsPrints where the stashes, the last-run record and the logs live.
›
GuidesPrints the guides in docs/ and the README.
›
‹ files

settings

The settings files, and the example to copy the environment from.

Main settingsOpens the main settings: stash folder, chores, porch and SSH.
›
RigsOpens the list of rigs: names, addresses, MAC addresses and folders.
›
EnvironmentOpens the environment file with the SSH key path and the porch secret.
›
Environment exampleOpens the example to copy to .env and fill in.
›
‹ files

logs

Where burrow writes its stashes, its last-run record and its logs.

Stash folderOpens the folder with every stash, one folder per rig.
›
Last-run recordOpens the record of when each chore last ran and whether it worked.
›
Chores logOpens the output of the scheduled chores.
›
Porch logOpens the output of the porch.
›
‹ files

guides

The guides in docs/, and the README.

READMEOpens the project README.
›
Adding a rigOpens the steps to add a rig to rigs.toml.
›
Chores guideOpens the guide to the chores.
›
Restore by handOpens the steps to restore a stash without burrow.
›
Raw answer
I planned the map from the dump alone. I could not read `references/house-conventions.md`, `references/cli-best-practices.md`, `workstation help`, or `opencode help`, so the screens follow the skill's rules and the project's own files, not the house examples. I built nothing.

**Decisions I made myself**
- **Facade:** `burrow`, the existing command, wrapped in a zsh function so `help` is intercepted before anything else.
- **Bare nouns print screens.** Commands that start or change things get a verb after the noun.
- **Rig screens** are generated from `config/rigs.toml`. The map shows `attic` as the template, and `cellar` and `garden` follow the same shape.
- **Each thing appears once.** Logs live under Files, and the chores and porch screens link to them rather than repeating them.

**Problems I found in the existing code**
- `burrow stash attic` takes a stash today, and `burrow porch` starts the server. Both break the rule that a bare noun prints its screen.
- `chores-schedule` (`crontab deploy/burrow.crontab`) replaces the whole crontab and would delete the weekly prune line that `make install-prune-cron` adds.
- pulse's `read_temp` and `read_disk` return `0.0`, so the Graphs row would show zeros.
- Only the names of 22 of the 25 scripts are visible, so their "what" text is a guess until each is read.

```json
{"screens": [
{"path": [], "sentence": "Everything burrow looks after in your home lab: the rigs, their stashes, the chores that run on a schedule, the porch dashboard, and the files behind them.", "rows": [
 {"name": "Rigs", "form": "burrow rigs", "what": "Prints the rigs burrow knows and whether each one answers."},
 {"name": "Stashes", "form": "burrow stash", "what": "Prints the stashes of every rig and the actions for them."},
 {"name": "Chores", "form": "burrow chores", "what": "Prints the recurring jobs and when each last ran."},
 {"name": "Porch", "form": "burrow porch", "what": "Prints the porch screen: its address, its service status and how to run it."},
 {"name": "Metrics", "form": "burrow metrics", "what": "Prints the metrics stack: its containers, graphs and readings."},
 {"name": "Helpers", "form": "burrow helpers", "what": "Prints the shell helpers in scripts/, grouped by what they are for."},
 {"name": "Setup", "form": "burrow setup", "what": "Prints the one-time steps that set burrow up on a machine."},
 {"name": "Develop", "form": "burrow develop", "what": "Prints the tools for changing burrow: tests, lint and clean-up."},
 {"name": "Files", "form": "burrow files", "what": "Prints where burrow keeps its settings, stashes, logs and guides."}
]},
{"path": ["rigs"], "sentence": "The rigs burrow knows, and whether each one answers.", "rows": [
 {"name": "attic", "form": "burrow rigs attic", "what": "Prints the attic screen: its stashes, and the wake and reboot actions for it."},
 {"name": "cellar", "form": "burrow rigs cellar", "what": "Prints the cellar screen: its stashes, and the wake and reboot actions for it."},
 {"name": "garden", "form": "burrow rigs garden", "what": "Prints the garden screen: its stashes, and the wake and reboot actions for it."},
 {"name": "Add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps for adding a rig to config/rigs.toml."}
]},
{"path": ["rigs", "attic"], "sentence": "The attic rig: what you can do to the machine, and where its stashes and settings are.", "rows": [
 {"name": "Its stashes", "form": "burrow stash attic", "what": "Prints the screen of attic's stashes."},
 {"name": "Wake", "form": "burrow rigs attic wake", "what": "Sends a wake packet to attic, through bin/rig-wake."},
 {"name": "Reboot", "form": "burrow rigs attic reboot", "what": "Reboots attic after a 10 second countdown, through scripts/reboot-rig.sh."},
 {"name": "Its settings", "form": "config/rigs.toml", "what": "Opens the rigs file where attic's address, MAC address and folders are set."}
]},
{"path": ["stash"], "sentence": "Snapshots of each rig's important folders, taken over rsync and kept under /srv/burrow/stashes, one dated folder each.", "rows": [
 {"name": "attic", "form": "burrow stash attic", "what": "Prints the screen of attic's stashes, with its dated stashes and the actions for them."},
 {"name": "cellar", "form": "burrow stash cellar", "what": "Prints the screen of cellar's stashes, with its dated stashes and the actions for them."},
 {"name": "garden", "form": "burrow stash garden", "what": "Prints the screen of garden's stashes, with its dated stashes and the actions for them."},
 {"name": "Take every rig's stash", "form": "burrow stash all take", "what": "Takes a stash of every rig at once; make stash-all does the same today."},
 {"name": "Prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes all but the newest 8 stashes of each rig; cron runs it weekly."}
]},
{"path": ["stash", "attic"], "sentence": "The stashes of attic, one dated folder each, and what you can do with them.", "rows": [
 {"name": "Take a stash now", "form": "burrow stash attic take", "what": "Takes a stash of attic now, into its folder under /srv/burrow/stashes."},
 {"name": "Restore a stash", "form": "burrow stash attic restore --from YYYY-MM-DD", "what": "Copies a dated stash back onto attic; add --dry-run to see what would change first."},
 {"name": "Check the newest", "form": "burrow stash attic verify", "what": "Checks that attic's newest stash is readable and not empty, through scripts/verify-stash.sh."},
 {"name": "Stash folder", "form": "/srv/burrow/stashes/attic", "what": "Opens the folder with attic's dated stashes."},
 {"name": "Stashes page on the porch", "form": "http://127.0.0.1:8470/stashes/attic", "what": "Opens attic's stashes page on the porch dashboard."}
]},
{"path": ["chores"], "sentence": "The recurring jobs burrow runs on a schedule, when each last ran, and whether it worked.", "rows": [
 {"name": "nightly-stash", "form": "burrow chores nightly-stash", "what": "Prints the nightly-stash screen: a stash of every rig, taken at 02:15 each night."},
 {"name": "disk-check", "form": "burrow chores disk-check", "what": "Prints the disk-check screen: a warning when a rig's root disk is over 85 percent, checked every 6 hours."},
 {"name": "Last runs", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
 {"name": "Export chores", "form": "scripts/export-chores.sh", "what": "Exports the chores out of burrow, through scripts/export-chores.sh."},
 {"name": "Chores page on the porch", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page on the porch dashboard, with each chore's last run."}
]},
{"path": ["chores", "nightly-stash"], "sentence": "The nightly-stash chore: a stash of every rig, taken at 02:15 each night.", "rows": [
 {"name": "Run it now", "form": "burrow chores nightly-stash run", "what": "Runs the nightly stash now, the same job the schedule runs at 02:15."},
 {"name": "Its schedule", "form": "deploy/burrow.crontab", "what": "Opens the crontab that schedules it at 02:15 each night."},
 {"name": "Its code", "form": "burrow/chores.py", "what": "Opens the code the job runs, the nightly_stash function."}
]},
{"path": ["chores", "disk-check"], "sentence": "The disk-check chore: a warning when a rig's root disk is over 85 percent, checked every 6 hours.", "rows": [
 {"name": "Run it now", "form": "burrow chores disk-check run", "what": "Runs the disk check now, the same job the schedule runs every 6 hours."},
 {"name": "Its schedule", "form": "deploy/burrow.crontab", "what": "Opens the crontab that schedules it every 6 hours."},
 {"name": "Its code", "form": "burrow/chores.py", "what": "Opens the code the job runs, the disk_check function."}
]},
{"path": ["porch"], "sentence": "The porch: the web dashboard for the rigs, served on port 8470 and kept running by systemd.", "rows": [
 {"name": "Open the dashboard", "form": "http://127.0.0.1:8470", "what": "Opens the dashboard here; from another machine, use the rig's IP instead of 127.0.0.1."},
 {"name": "Health check", "form": "http://127.0.0.1:8470/healthz", "what": "Opens the health check, which answers ok while the porch is up."},
 {"name": "Service status", "form": "burrow porch status", "what": "Prints whether the porch service is running, from systemctl."},
 {"name": "Restart the service", "form": "burrow porch restart", "what": "Restarts the porch service under systemd."},
 {"name": "Run by hand", "form": "burrow porch run", "what": "Runs the porch in the foreground on port 8470, the way systemd runs it."},
 {"name": "Service file", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that starts the porch."}
]},
{"path": ["metrics"], "sentence": "The metrics stack: containers that collect rig temperatures and disk use, and draw graphs of them.", "rows": [
 {"name": "Start", "form": "burrow metrics start", "what": "Starts the metrics containers in the background, through make up."},
 {"name": "Stop", "form": "burrow metrics stop", "what": "Stops the metrics containers, through make down."},
 {"name": "Graphs", "form": "http://127.0.0.1:3000", "what": "Opens the Grafana graphs of rig temperatures and disk use."},
 {"name": "Readings", "form": "http://127.0.0.1:9188/metrics", "what": "Opens the raw readings pulse gives Prometheus."},
 {"name": "Compose file", "form": "docker-compose.yml", "what": "Opens the file that defines the containers, Prometheus included."},
 {"name": "Pulse code", "form": "pulse/pulse.py", "what": "Opens the code that reads each rig's temperature and disk use."}
]},
{"path": ["helpers"], "sentence": "Small shell helpers in scripts/, grouped by what they are for. Read the top of each one before you run it.", "rows": [
 {"name": "Rigs", "form": "burrow helpers rigs", "what": "Prints the helpers that act on all rigs together."},
 {"name": "Storage", "form": "burrow helpers storage", "what": "Prints the helpers for disks, stashes, mounts and logs."},
 {"name": "Network", "form": "burrow helpers network", "what": "Prints the helpers for DNS, ports, speed and certificates."},
 {"name": "Power", "form": "burrow helpers power", "what": "Prints the helpers for the UPS, the battery and the fans."}
]},
{"path": ["helpers", "rigs"], "sentence": "The helpers that act on all the rigs together.", "rows": [
 {"name": "Check disks", "form": "scripts/check-disks.sh", "what": "Shows the disk use of every rig."},
 {"name": "Temperatures", "form": "scripts/temp-check.sh", "what": "Checks the temperature of every rig."},
 {"name": "Update rigs", "form": "scripts/update-rigs.sh", "what": "Updates the software on every rig."},
 {"name": "Push SSH keys", "form": "scripts/ssh-keys-push.sh", "what": "Pushes the burrow SSH key to every rig."},
 {"name": "Sync clock", "form": "scripts/sync-clock.sh", "what": "Sets the clock of every rig to the same time."},
 {"name": "Import rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into config/rigs.toml."}
]},
{"path": ["helpers", "storage"], "sentence": "The helpers for disks, stashes, mounts and logs.", "rows": [
 {"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub, which checks the pool for damage."},
 {"name": "Disk health", "form": "scripts/smart-report.sh", "what": "Prints the SMART health of the disks."},
 {"name": "Mount the NAS", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS share."},
 {"name": "Unmount the NAS", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS share."},
 {"name": "Clean Docker", "form": "scripts/gc-docker.sh", "what": "Removes unused Docker data."},
 {"name": "Rotate logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the log files."},
 {"name": "Stash disk use", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use."}
]},
{"path": ["helpers", "network"], "sentence": "The helpers for DNS, ports, speed and certificates.", "rows": [
 {"name": "Flush DNS", "form": "scripts/dns-flush.sh", "what": "Clears the DNS cache."},
 {"name": "Network speed", "form": "scripts/net-speed.sh", "what": "Measures the network speed."},
 {"name": "Open ports", "form": "scripts/list-ports.sh", "what": "Lists the ports that are listening."},
 {"name": "Update Pi-hole", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole."},
 {"name": "Renew certificates", "form": "scripts/cert-renew.sh", "what": "Renews the certificates."}
]},
{"path": ["helpers", "power"], "sentence": "The helpers for the UPS, the battery and the fans.", "rows": [
 {"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Shows the UPS status."},
 {"name": "Battery report", "form": "scripts/battery-report.sh", "what": "Shows the battery report."},
 {"name": "Fan curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan curve."}
]},
{"path": ["setup"], "sentence": "The steps that set burrow up, in order, the first time it goes on a machine.", "rows": [
 {"name": "Setup guide", "form": "docs/setup.md", "what": "Opens the setup steps in order."},
 {"name": "Install", "form": "burrow setup install", "what": "Installs burrow into .venv/ and creates its stash and log folders, through make install."},
 {"name": "Porch service", "form": "burrow setup porch-service", "what": "Installs and starts the porch under systemd, through make install-unit."},
 {"name": "Chores schedule", "form": "burrow setup chores-schedule", "what": "Installs the chores schedule from deploy/burrow.crontab into crontab."},
 {"name": "Prune schedule", "form": "burrow setup prune-schedule", "what": "Adds the weekly prune of old stashes to crontab, Sundays at 04:40, through make install-prune-cron."}
]},
{"path": ["develop"], "sentence": "Tools for changing burrow itself: its tests, its linter and its clean-up.", "rows": [
 {"name": "Run the tests", "form": "burrow develop test", "what": "Runs the tests in tests/ with pytest."},
 {"name": "Lint", "form": "burrow develop lint", "what": "Checks burrow/ and tests/ with ruff."},
 {"name": "Seed sample data", "form": "scripts/seed-dev.sh", "what": "Seeds sample data for development, through scripts/seed-dev.sh."},
 {"name": "Clean", "form": "burrow develop clean", "what": "Deletes .venv and the build output; setup install puts the venv back."},
 {"name": "Tests folder", "form": "tests/", "what": "Opens the tests."}
]},
{"path": ["files"], "sentence": "Where burrow keeps its settings, its stashes and logs, and its guides.", "rows": [
 {"name": "Settings", "form": "burrow files settings", "what": "Prints the settings files and the environment example."},
 {"name": "Stashes and logs", "form": "burrow files logs", "what": "Prints where the stashes, the last-run record and the logs live."},
 {"name": "Guides", "form": "burrow files guides", "what": "Prints the guides in docs/ and the README."}
]},
{"path": ["files", "settings"], "sentence": "The settings files, and the example to copy the environment from.", "rows": [
 {"name": "Main settings", "form": "config/burrow.toml", "what": "Opens the main settings: stash folder, chores, porch and SSH."},
 {"name": "Rigs", "form": "config/rigs.toml", "what": "Opens the list of rigs: names, addresses, MAC addresses and folders."},
 {"name": "Environment", "form": ".env", "what": "Opens the environment file with the SSH key path and the porch secret."},
 {"name": "Environment example", "form": ".env.example", "what": "Opens the example to copy to .env and fill in."}
]},
{"path": ["files", "logs"], "sentence": "Where burrow writes its stashes, its last-run record and its logs.", "rows": [
 {"name": "Stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder with every stash, one folder per rig."},
 {"name": "Last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of when each chore last ran and whether it worked."},
 {"name": "Chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the output of the scheduled chores."},
 {"name": "Porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the output of the porch."}
]},
{"path": ["files", "guides"], "sentence": "The guides in docs/, and the README.", "rows": [
 {"name": "README", "form": "README.md", "what": "Opens the project README."},
 {"name": "Adding a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps to add a rig to rigs.toml."},
 {"name": "Chores guide", "form": "docs/chores.md", "what": "Opens the guide to the chores."},
 {"name": "Restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the steps to restore a stash without burrow."}
]}
],
"questions": [
 "Taking a stash moves from `burrow stash attic` to `burrow stash attic take`, because a bare noun must print its screen. The README and make stash-all change with it. Recommendation: move it and update both.",
 "`burrow porch` runs the server today, and the systemd unit calls it that way. The map moves running to `burrow porch run` and needs ExecStart in deploy/burrow-porch.service edited in the same change. Recommendation: make that change.",
 "`chores-schedule` as written runs `crontab deploy/burrow.crontab`, which replaces the whole crontab and would delete the weekly prune line. Recommendation: have setup merge the two files instead of replacing one with the other.",
 "pulse's read_temp and read_disk return 0.0 in this dump, so the Graphs row would show zeros. Recommendation: keep the row, and state on the metrics screen that readings are not live yet.",
 "Only the names of 22 of the 25 scripts are visible to me, so their 'what' text is a guess. Recommendation: read each script before the screens are printed and correct the rows.",
 "`develop clean` deletes .venv and `stash prune` deletes old stashes. Recommendation: both ask for confirmation before they run, unless you want them silent."
]}
```

screen-decomposition, first draft · run 4 exit=0 seconds=160 · prompt

P1 Recall: 0.883P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 1
As terminal help
What burrow looks after in the home lab, one group each.
rigsburrow rigs helpShows the rigs screen: each rig and whether it answers.
stashburrow stash helpShows the stash screen: taking, listing and pruning snapshots of rigs.
restoreburrow restore helpShows the restore screen: putting a stash back onto its rig.
choresburrow chores helpShows the chores screen: the recurring jobs and when each last ran.
porchburrow porch helpShows the porch screen: the web dashboard and how to run it.
metricsburrow metrics helpShows the metrics screen: graphs of rig temperatures and disk use.
helpersburrow helpers helpShows the helpers screen: the small scripts in scripts/.
setupburrow setup helpShows the setup screen: installing, configuring, testing and developing burrow.
rigs
The rigs burrow knows, and whether each one answers.
each rig and whether it answersburrow rigsLists each rig with its address and whether it answers.
rig listconfig/rigs.tomlOpens the rig list: each rig's name, address, MAC and paths.
take a stash of a rigburrow stash <rig>Takes a stash of the named rig now.
restore a rigburrow restore <rig> --from YYYY-MM-DDCopies a stash of the rig back onto it.
wake a sleeping rigbin/rig-wake <rig>Sends a wake packet to the rig's MAC from config/rigs.toml.
reboot a rigscripts/reboot-rig.sh <address>Reboots the rig after a 10 second countdown.
disk use of every rigscripts/check-disks.shShows the disk use of every rig.
add a rigdocs/adding-a-rig.mdOpens the guide to adding a rig to config/rigs.toml.
stash
Snapshots of the rigs' important folders: take one, list them, and prune the old ones.
take a stash of one rigburrow stash <rig>Takes a stash of the named rig now and prints its folder.
take a stash of every rigburrow stash --all; make stash-allTakes a stash of every rig in config/rigs.toml.
list the stashes of a rigburrow stash list <rig>Lists the dated stashes a rig has.
prune old stashesburrow stash prune --keep 8Removes old stashes beyond the newest --keep (default 8).
prune with the Makefilemake prune-stashesRuns the prune with --keep 8.
weekly prunemake install-prune-cronAdds a weekly prune at 04:40 on Sunday to your crontab.
stash folder/srv/burrow/stashesOpens the stash folder: one folder per rig, one dated folder per stash.
verify a stashscripts/verify-stash.sh <rig>Checks the newest stash of a rig is readable and not empty.
stash sizes †scripts/du-stashes.shShows how much space each stash takes.
restore
Putting a stash back onto its rig, with burrow or by hand.
restore a rigburrow restore <rig> --from YYYY-MM-DDCopies the stash of that date back onto the rig.
restore as a dry runburrow restore <rig> --from YYYY-MM-DD --dry-runRuns a restore without writing to the rig.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the guide to copying a stash back with rsync when burrow is broken.
stash manifest.burrow-manifest in each stash folderLists the paths a stash holds and the rsync exit code; non-zero means partial.
chores
The recurring jobs, what they do, and when each last ran.
list choresburrow chores listLists the names of the chores burrow knows.
run a choreburrow chores run <name>Runs one chore now and records its result.
last runsburrow chores statusPrints when each chore last finished and whether it worked.
nightly-stashdeploy/burrow.crontab (15 2 * * *)Runs a stash of every rig at 02:15 each night, logged to /var/log/burrow/chores.log.
disk-checkdeploy/burrow.crontab (0 */6 * * *)Runs the disk check every 6 hours and warns above 85 percent.
chores pagehttp://127.0.0.1:8470/choresOpens the porch page with each chore's last run.
last-run record/srv/burrow/state/last-run.jsonHolds when each chore last ran and its result.
chores log/var/log/burrow/chores.logShows the output of the chores that cron ran.
install the chores crontabcrontab deploy/burrow.crontabInstalls the two chore lines, replacing the whole crontab.
chores guidedocs/chores.mdOpens the guide: what each chore does and how to run it by hand.
porch
The porch, the web dashboard that shows the rigs, chores and stashes, and how it runs.
start the porchburrow porchStarts the porch on port 8470 and keeps it running in the foreground.
porch front pagehttp://127.0.0.1:8470Opens the front page with the rigs.
chores pagehttp://127.0.0.1:8470/choresOpens the page with each job's last run.
stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens one rig's stashes.
health checkhttp://127.0.0.1:8470/healthzReturns the ok JSON while the porch is up.
run as a servicedeploy/burrow-porch.serviceRuns the porch under systemd, restarted on failure, logged to /var/log/burrow/porch.log.
install the servicemake install-unitPuts the service into systemd and starts it at boot.
porch log/var/log/burrow/porch.logShows what the porch printed while it ran as a service.
porch settingsconfig/burrow.toml [porch]Sets the bind address, title and refresh seconds.
metrics
Graphs of rig temperatures and disk use, from pulse, Prometheus and Grafana.
start the metrics containersmake upStarts pulse, Prometheus and Grafana in the background.
stop the metrics containersmake downStops the three metrics containers.
graphshttp://127.0.0.1:3000Opens Grafana with the graphs of rig temperatures and disk use.
pulse numbershttp://127.0.0.1:9188/metricsShows the temperature and disk-use numbers for Prometheus to read.
pulse codepulse/pulse.pyPolls each rig every 30 seconds; read_temp and read_disk still return 0.0.
container setupdocker-compose.ymlDefines the three containers, their ports and 30 days of Prometheus retention.
Prometheus configdocker-compose.yml (no prometheus.yml mounted)Keeps readings from pulse, but the config file it expects is not in the repo.
helpers
The helper scripts in scripts/, each run by itself. Read the top of one before running it. A † marks a script whose purpose is inferred from its name because its file was not read.
battery report †scripts/battery-report.shReports the battery state of a rig.
cert renew †scripts/cert-renew.shRenews the certificates.
check disksscripts/check-disks.shRuns df on every rig in config/rigs.toml over ssh.
dns flush †scripts/dns-flush.shFlushes the DNS cache.
du stashes †scripts/du-stashes.shShows the space each stash takes.
export chores †scripts/export-chores.shExports the chores' records to a file.
fan curve †scripts/fan-curve.shSets the fan speed curve.
gc docker †scripts/gc-docker.shRemoves unused Docker images and volumes.
import rigs †scripts/import-rigs.shImports rigs into config/rigs.toml.
list ports †scripts/list-ports.shLists the open network ports.
mount nas †scripts/mount-nas.shMounts the NAS share.
net speed †scripts/net-speed.shMeasures the network speed.
pihole update †scripts/pihole-update.shUpdates Pi-hole.
reboot rigscripts/reboot-rig.sh <address>Reboots one rig after a 10 second countdown.
rotate logs †scripts/rotate-logs.shRotates the log files.
seed dev †scripts/seed-dev.shSeeds development data; check the file before running it.
smart report †scripts/smart-report.shReports the SMART health of the disks.
ssh keys push †scripts/ssh-keys-push.shPushes SSH keys to the rigs.
sync clock †scripts/sync-clock.shSyncs the rigs' clocks.
temp check †scripts/temp-check.shChecks the rigs' temperatures.
unmount nas †scripts/unmount-nas.shUnmounts the NAS share.
update rigs †scripts/update-rigs.shUpdates the rigs' packages.
ups status †scripts/ups-status.shShows the UPS status.
verify stashscripts/verify-stash.sh <rig>Checks the newest stash of a rig is readable and not empty.
zfs scrub †scripts/zfs-scrub.shStarts a ZFS scrub.
setup
Installing, configuring, testing and developing burrow.
setup guidedocs/setup.mdOpens the setup steps: the burrow user, install, porch service and crontab.
readmeREADME.mdOpens the overview: what burrow is and how to use it.
installmake installCreates the venv in /opt/burrow and installs burrow into it.
porch servicemake install-unitInstalls the porch service and starts it at boot, step 2 of the setup guide.
chores crontabcrontab deploy/burrow.crontabInstalls the two chore lines into your crontab.
weekly prunemake install-prune-cronAdds the weekly stash prune to your crontab.
metricsmake upStarts the optional metrics containers, step 4 of the setup guide.
burrow settingsconfig/burrow.tomlSets the stash folder, rsync flags, chore state file, porch bind and ssh user.
rig listconfig/rigs.tomlLists the rigs: name, address, MAC and paths.
secrets.env (copied from .env.example)Holds the SSH key path, porch secret and ntfy topic.
another config fileburrow --config <file>Reads another config file in place of config/burrow.toml.
testsmake testRuns the test suite with pytest.
lintmake lintChecks burrow and its tests with ruff.
cleanmake cleanRemoves .venv, build output and caches.
Questions
  • Give each rig its own screen (burrow rigs <rig> help, with its address, paths, stash, restore, wake and reboot)? Recommendation: yes, because those actions already belong to a rig and a new rig would then need no new help text. It adds a noun, so it is your call.
  • The helpers screen lists 25 scripts on one screen. Split it by job into rigs, disks, network, power and dev? Recommendation: yes, after reading the 22 unread headers so each script lands in the right group. I placed none of them myself.
  • Bare burrow stash and burrow restore error today, and bare burrow porch starts the server. Make stash and restore print their screens on a bare noun? Recommendation: yes for stash and restore. Porch keeps running, and its screen is burrow porch help.
  • prune's --keep defaults to 8 in code and ignores stash.keep in config/burrow.toml. Make prune read the config? Recommendation: yes, so there is one source for the number.
  • The metrics screen shows a Prometheus config the repo lacks and pulse readings that are all 0.0. Label the screen as not wired yet, or ship both first? Recommendation: label it now and fix the two next.
  • chores.notify, BURROW_NTFY_TOPIC and BURROW_PORCH_SECRET are not read by any code in the dump. Implement them or remove them? Recommendation: remove them from the config and .env.example until something reads them.
As phone screens

Home

What burrow looks after in the home lab, one group each.

rigsShows the rigs screen: each rig and whether it answers.
›
stashShows the stash screen: taking, listing and pruning snapshots of rigs.
›
restoreShows the restore screen: putting a stash back onto its rig.
›
choresShows the chores screen: the recurring jobs and when each last ran.
›
porchShows the porch screen: the web dashboard and how to run it.
›
metricsShows the metrics screen: graphs of rig temperatures and disk use.
›
helpersShows the helpers screen: the small scripts in scripts/.
›
setupShows the setup screen: installing, configuring, testing and developing burrow.
›
‹ Home

rigs

The rigs burrow knows, and whether each one answers.

each rig and whether it answersLists each rig with its address and whether it answers.
›
rig listOpens the rig list: each rig's name, address, MAC and paths.
›
take a stash of a rigTakes a stash of the named rig now.
›
restore a rigCopies a stash of the rig back onto it.
›
wake a sleeping rigSends a wake packet to the rig's MAC from config/rigs.toml.
›
reboot a rigReboots the rig after a 10 second countdown.
›
disk use of every rigShows the disk use of every rig.
›
add a rigOpens the guide to adding a rig to config/rigs.toml.
›
‹ Home

stash

Snapshots of the rigs' important folders: take one, list them, and prune the old ones.

take a stash of one rigTakes a stash of the named rig now and prints its folder.
›
take a stash of every rigTakes a stash of every rig in config/rigs.toml.
›
list the stashes of a rigLists the dated stashes a rig has.
›
prune old stashesRemoves old stashes beyond the newest --keep (default 8).
›
prune with the MakefileRuns the prune with --keep 8.
›
weekly pruneAdds a weekly prune at 04:40 on Sunday to your crontab.
›
stash folderOpens the stash folder: one folder per rig, one dated folder per stash.
›
verify a stashChecks the newest stash of a rig is readable and not empty.
›
stash sizes †Shows how much space each stash takes.
›
‹ Home

restore

Putting a stash back onto its rig, with burrow or by hand.

restore a rigCopies the stash of that date back onto the rig.
›
restore as a dry runRuns a restore without writing to the rig.
›
restore by handOpens the guide to copying a stash back with rsync when burrow is broken.
›
stash manifestLists the paths a stash holds and the rsync exit code; non-zero means partial.
›
‹ Home

chores

The recurring jobs, what they do, and when each last ran.

list choresLists the names of the chores burrow knows.
›
run a choreRuns one chore now and records its result.
›
last runsPrints when each chore last finished and whether it worked.
›
nightly-stashRuns a stash of every rig at 02:15 each night, logged to /var/log/burrow/chores.log.
›
disk-checkRuns the disk check every 6 hours and warns above 85 percent.
›
chores pageOpens the porch page with each chore's last run.
›
last-run recordHolds when each chore last ran and its result.
›
chores logShows the output of the chores that cron ran.
›
install the chores crontabInstalls the two chore lines, replacing the whole crontab.
›
chores guideOpens the guide: what each chore does and how to run it by hand.
›
‹ Home

porch

The porch, the web dashboard that shows the rigs, chores and stashes, and how it runs.

start the porchStarts the porch on port 8470 and keeps it running in the foreground.
›
porch front pageOpens the front page with the rigs.
›
chores pageOpens the page with each job's last run.
›
stashes pageOpens one rig's stashes.
›
health checkReturns the ok JSON while the porch is up.
›
run as a serviceRuns the porch under systemd, restarted on failure, logged to /var/log/burrow/porch.log.
›
install the servicePuts the service into systemd and starts it at boot.
›
porch logShows what the porch printed while it ran as a service.
›
porch settingsSets the bind address, title and refresh seconds.
›
‹ Home

metrics

Graphs of rig temperatures and disk use, from pulse, Prometheus and Grafana.

start the metrics containersStarts pulse, Prometheus and Grafana in the background.
›
stop the metrics containersStops the three metrics containers.
›
graphsOpens Grafana with the graphs of rig temperatures and disk use.
›
pulse numbersShows the temperature and disk-use numbers for Prometheus to read.
›
pulse codePolls each rig every 30 seconds; read_temp and read_disk still return 0.0.
›
container setupDefines the three containers, their ports and 30 days of Prometheus retention.
›
Prometheus configKeeps readings from pulse, but the config file it expects is not in the repo.
›
‹ Home

helpers

The helper scripts in scripts/, each run by itself. Read the top of one before running it. A † marks a script whose purpose is inferred from its name because its file was not read.

battery report †Reports the battery state of a rig.
›
cert renew †Renews the certificates.
›
check disksRuns df on every rig in config/rigs.toml over ssh.
›
dns flush †Flushes the DNS cache.
›
du stashes †Shows the space each stash takes.
›
export chores †Exports the chores' records to a file.
›
fan curve †Sets the fan speed curve.
›
gc docker †Removes unused Docker images and volumes.
›
import rigs †Imports rigs into config/rigs.toml.
›
list ports †Lists the open network ports.
›
mount nas †Mounts the NAS share.
›
net speed †Measures the network speed.
›
pihole update †Updates Pi-hole.
›
reboot rigReboots one rig after a 10 second countdown.
›
rotate logs †Rotates the log files.
›
seed dev †Seeds development data; check the file before running it.
›
smart report †Reports the SMART health of the disks.
›
ssh keys push †Pushes SSH keys to the rigs.
›
sync clock †Syncs the rigs' clocks.
›
temp check †Checks the rigs' temperatures.
›
unmount nas †Unmounts the NAS share.
›
update rigs †Updates the rigs' packages.
›
ups status †Shows the UPS status.
›
verify stashChecks the newest stash of a rig is readable and not empty.
›
zfs scrub †Starts a ZFS scrub.
›
‹ Home

setup

Installing, configuring, testing and developing burrow.

setup guideOpens the setup steps: the burrow user, install, porch service and crontab.
›
readmeOpens the overview: what burrow is and how to use it.
›
installCreates the venv in /opt/burrow and installs burrow into it.
›
porch serviceInstalls the porch service and starts it at boot, step 2 of the setup guide.
›
chores crontabInstalls the two chore lines into your crontab.
›
weekly pruneAdds the weekly stash prune to your crontab.
›
metricsStarts the optional metrics containers, step 4 of the setup guide.
›
burrow settingsSets the stash folder, rsync flags, chore state file, porch bind and ssh user.
›
rig listLists the rigs: name, address, MAC and paths.
›
secretsHolds the SSH key path, porch secret and ntfy topic.
›
another config fileReads another config file in place of config/burrow.toml.
›
testsRuns the test suite with pytest.
›
lintChecks burrow and its tests with ruff.
›
cleanRemoves .venv, build output and caches.
›
Raw answer
## Scenario

A home-lab owner reaches for burrow when a rig stops answering, before risky work on a rig, when a file must be recovered from an older stash, or to check that the nightly chore ran. They want to see which rigs are up, take a stash now, put a file back, and read the chore record. This comes from reading the README and docs, not from observed use.

## Judgment calls

- **Eight top groups.** That is at the upper end of "a few". `metrics` stays separate from `porch` because Grafana is a separate dashboard. It could fold into `porch` if you want fewer.
- **Every group row opens with `burrow <noun> help`.** This avoids the bare-noun problem: `burrow porch` starts the server, and `burrow stash` and `burrow restore` error with no arguments today.
- **`metrics`, `helpers` and `setup` have no `burrow` command yet.** Their `burrow <x> help` forms are the proposed facade, built later by the CLI layer.
- **`restore` stays top-level** to match the existing command. Its screen holds the restore guide.
- **Docs are not a group.** Each guide sits under the screen it serves.
- **Make targets are rows with `make <target>` forms,** not wrapped as `burrow` commands.
- **Destructive scripts** (`reboot-rig.sh`, `zfs-scrub.sh`, `unmount-nas.sh`, `seed-dev.sh`) are listed by form only. The help should show them, not run them.
- **22 scripts were not read.** Only their names are in the dump. Their "what" lines are inferred from the names and are marked †. Check each file's header before the CLI relies on them.
- **`list` and `prune` are reserved.** They are subcommands of `stash`, so a rig with either name cannot be reached as `burrow stash <rig>`.
- **`bin/rig-wake` sits outside `scripts/`** and is not in the README. I placed it on `rigs`.

## Findings

- **Installing the chores crontab can remove the weekly prune.** `crontab deploy/burrow.crontab` replaces the whole user crontab. That would delete the line that `make install-prune-cron` added. This is a bug to fix, not a planning choice.
- **The porch binds `0.0.0.0:8470` with no authentication.** Anyone on the LAN can read the rig and stash lists. `BURROW_PORCH_SECRET` is defined but nothing reads it.
- **Metrics are not yet real.** `pulse.py` returns `0.0` for every reading, and `prometheus.yml` is referenced by nothing in the repo, so the Prometheus container has no config mounted.
- **Config values are ignored.** `chores.notify` and `BURROW_NTFY_TOPIC` are not read by any code in the dump. `prune` defaults to 8 instead of reading `stash.keep`.

## Questions for you

These are in the JSON `questions` array with my recommendation. Nothing has been built.

```json
{"screens": [
 {"path": [], "sentence": "What burrow looks after in the home lab, one group each.", "rows": [
   {"name": "rigs", "form": "burrow rigs help", "what": "Shows the rigs screen: each rig and whether it answers."},
   {"name": "stash", "form": "burrow stash help", "what": "Shows the stash screen: taking, listing and pruning snapshots of rigs."},
   {"name": "restore", "form": "burrow restore help", "what": "Shows the restore screen: putting a stash back onto its rig."},
   {"name": "chores", "form": "burrow chores help", "what": "Shows the chores screen: the recurring jobs and when each last ran."},
   {"name": "porch", "form": "burrow porch help", "what": "Shows the porch screen: the web dashboard and how to run it."},
   {"name": "metrics", "form": "burrow metrics help", "what": "Shows the metrics screen: graphs of rig temperatures and disk use."},
   {"name": "helpers", "form": "burrow helpers help", "what": "Shows the helpers screen: the small scripts in scripts/."},
   {"name": "setup", "form": "burrow setup help", "what": "Shows the setup screen: installing, configuring, testing and developing burrow."}
 ]},
 {"path": ["rigs"], "sentence": "The rigs burrow knows, and whether each one answers.", "rows": [
   {"name": "each rig and whether it answers", "form": "burrow rigs", "what": "Lists each rig with its address and whether it answers."},
   {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the rig list: each rig's name, address, MAC and paths."},
   {"name": "take a stash of a rig", "form": "burrow stash <rig>", "what": "Takes a stash of the named rig now."},
   {"name": "restore a rig", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies a stash of the rig back onto it."},
   {"name": "wake a sleeping rig", "form": "bin/rig-wake <rig>", "what": "Sends a wake packet to the rig's MAC from config/rigs.toml."},
   {"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots the rig after a 10 second countdown."},
   {"name": "disk use of every rig", "form": "scripts/check-disks.sh", "what": "Shows the disk use of every rig."},
   {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the guide to adding a rig to config/rigs.toml."}
 ]},
 {"path": ["stash"], "sentence": "Snapshots of the rigs' important folders: take one, list them, and prune the old ones.", "rows": [
   {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of the named rig now and prints its folder."},
   {"name": "take a stash of every rig", "form": "burrow stash --all; make stash-all", "what": "Takes a stash of every rig in config/rigs.toml."},
   {"name": "list the stashes of a rig", "form": "burrow stash list <rig>", "what": "Lists the dated stashes a rig has."},
   {"name": "prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes old stashes beyond the newest --keep (default 8)."},
   {"name": "prune with the Makefile", "form": "make prune-stashes", "what": "Runs the prune with --keep 8."},
   {"name": "weekly prune", "form": "make install-prune-cron", "what": "Adds a weekly prune at 04:40 on Sunday to your crontab."},
   {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the stash folder: one folder per rig, one dated folder per stash."},
   {"name": "verify a stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks the newest stash of a rig is readable and not empty."},
   {"name": "stash sizes †", "form": "scripts/du-stashes.sh", "what": "Shows how much space each stash takes."}
 ]},
 {"path": ["restore"], "sentence": "Putting a stash back onto its rig, with burrow or by hand.", "rows": [
   {"name": "restore a rig", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies the stash of that date back onto the rig."},
   {"name": "restore as a dry run", "form": "burrow restore <rig> --from YYYY-MM-DD --dry-run", "what": "Runs a restore without writing to the rig."},
   {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the guide to copying a stash back with rsync when burrow is broken."},
   {"name": "stash manifest", "form": ".burrow-manifest in each stash folder", "what": "Lists the paths a stash holds and the rsync exit code; non-zero means partial."}
 ]},
 {"path": ["chores"], "sentence": "The recurring jobs, what they do, and when each last ran.", "rows": [
   {"name": "list chores", "form": "burrow chores list", "what": "Lists the names of the chores burrow knows."},
   {"name": "run a chore", "form": "burrow chores run <name>", "what": "Runs one chore now and records its result."},
   {"name": "last runs", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
   {"name": "nightly-stash", "form": "deploy/burrow.crontab (15 2 * * *)", "what": "Runs a stash of every rig at 02:15 each night, logged to /var/log/burrow/chores.log."},
   {"name": "disk-check", "form": "deploy/burrow.crontab (0 */6 * * *)", "what": "Runs the disk check every 6 hours and warns above 85 percent."},
   {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the porch page with each chore's last run."},
   {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Holds when each chore last ran and its result."},
   {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Shows the output of the chores that cron ran."},
   {"name": "install the chores crontab", "form": "crontab deploy/burrow.crontab", "what": "Installs the two chore lines, replacing the whole crontab."},
   {"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide: what each chore does and how to run it by hand."}
 ]},
 {"path": ["porch"], "sentence": "The porch, the web dashboard that shows the rigs, chores and stashes, and how it runs.", "rows": [
   {"name": "start the porch", "form": "burrow porch", "what": "Starts the porch on port 8470 and keeps it running in the foreground."},
   {"name": "porch front page", "form": "http://127.0.0.1:8470", "what": "Opens the front page with the rigs."},
   {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the page with each job's last run."},
   {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens one rig's stashes."},
   {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns the ok JSON while the porch is up."},
   {"name": "run as a service", "form": "deploy/burrow-porch.service", "what": "Runs the porch under systemd, restarted on failure, logged to /var/log/burrow/porch.log."},
   {"name": "install the service", "form": "make install-unit", "what": "Puts the service into systemd and starts it at boot."},
   {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Shows what the porch printed while it ran as a service."},
   {"name": "porch settings", "form": "config/burrow.toml [porch]", "what": "Sets the bind address, title and refresh seconds."}
 ]},
 {"path": ["metrics"], "sentence": "Graphs of rig temperatures and disk use, from pulse, Prometheus and Grafana.", "rows": [
   {"name": "start the metrics containers", "form": "make up", "what": "Starts pulse, Prometheus and Grafana in the background."},
   {"name": "stop the metrics containers", "form": "make down", "what": "Stops the three metrics containers."},
   {"name": "graphs", "form": "http://127.0.0.1:3000", "what": "Opens Grafana with the graphs of rig temperatures and disk use."},
   {"name": "pulse numbers", "form": "http://127.0.0.1:9188/metrics", "what": "Shows the temperature and disk-use numbers for Prometheus to read."},
   {"name": "pulse code", "form": "pulse/pulse.py", "what": "Polls each rig every 30 seconds; read_temp and read_disk still return 0.0."},
   {"name": "container setup", "form": "docker-compose.yml", "what": "Defines the three containers, their ports and 30 days of Prometheus retention."},
   {"name": "Prometheus config", "form": "docker-compose.yml (no prometheus.yml mounted)", "what": "Keeps readings from pulse, but the config file it expects is not in the repo."}
 ]},
 {"path": ["helpers"], "sentence": "The helper scripts in scripts/, each run by itself. Read the top of one before running it. A † marks a script whose purpose is inferred from its name because its file was not read.", "rows": [
   {"name": "battery report †", "form": "scripts/battery-report.sh", "what": "Reports the battery state of a rig."},
   {"name": "cert renew †", "form": "scripts/cert-renew.sh", "what": "Renews the certificates."},
   {"name": "check disks", "form": "scripts/check-disks.sh", "what": "Runs df on every rig in config/rigs.toml over ssh."},
   {"name": "dns flush †", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache."},
   {"name": "du stashes †", "form": "scripts/du-stashes.sh", "what": "Shows the space each stash takes."},
   {"name": "export chores †", "form": "scripts/export-chores.sh", "what": "Exports the chores' records to a file."},
   {"name": "fan curve †", "form": "scripts/fan-curve.sh", "what": "Sets the fan speed curve."},
   {"name": "gc docker †", "form": "scripts/gc-docker.sh", "what": "Removes unused Docker images and volumes."},
   {"name": "import rigs †", "form": "scripts/import-rigs.sh", "what": "Imports rigs into config/rigs.toml."},
   {"name": "list ports †", "form": "scripts/list-ports.sh", "what": "Lists the open network ports."},
   {"name": "mount nas †", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS share."},
   {"name": "net speed †", "form": "scripts/net-speed.sh", "what": "Measures the network speed."},
   {"name": "pihole update †", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole."},
   {"name": "reboot rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10 second countdown."},
   {"name": "rotate logs †", "form": "scripts/rotate-logs.sh", "what": "Rotates the log files."},
   {"name": "seed dev †", "form": "scripts/seed-dev.sh", "what": "Seeds development data; check the file before running it."},
   {"name": "smart report †", "form": "scripts/smart-report.sh", "what": "Reports the SMART health of the disks."},
   {"name": "ssh keys push †", "form": "scripts/ssh-keys-push.sh", "what": "Pushes SSH keys to the rigs."},
   {"name": "sync clock †", "form": "scripts/sync-clock.sh", "what": "Syncs the rigs' clocks."},
   {"name": "temp check †", "form": "scripts/temp-check.sh", "what": "Checks the rigs' temperatures."},
   {"name": "unmount nas †", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS share."},
   {"name": "update rigs †", "form": "scripts/update-rigs.sh", "what": "Updates the rigs' packages."},
   {"name": "ups status †", "form": "scripts/ups-status.sh", "what": "Shows the UPS status."},
   {"name": "verify stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks the newest stash of a rig is readable and not empty."},
   {"name": "zfs scrub †", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub."}
 ]},
 {"path": ["setup"], "sentence": "Installing, configuring, testing and developing burrow.", "rows": [
   {"name": "setup guide", "form": "docs/setup.md", "what": "Opens the setup steps: the burrow user, install, porch service and crontab."},
   {"name": "readme", "form": "README.md", "what": "Opens the overview: what burrow is and how to use it."},
   {"name": "install", "form": "make install", "what": "Creates the venv in /opt/burrow and installs burrow into it."},
   {"name": "porch service", "form": "make install-unit", "what": "Installs the porch service and starts it at boot, step 2 of the setup guide."},
   {"name": "chores crontab", "form": "crontab deploy/burrow.crontab", "what": "Installs the two chore lines into your crontab."},
   {"name": "weekly prune", "form": "make install-prune-cron", "what": "Adds the weekly stash prune to your crontab."},
   {"name": "metrics", "form": "make up", "what": "Starts the optional metrics containers, step 4 of the setup guide."},
   {"name": "burrow settings", "form": "config/burrow.toml", "what": "Sets the stash folder, rsync flags, chore state file, porch bind and ssh user."},
   {"name": "rig list", "form": "config/rigs.toml", "what": "Lists the rigs: name, address, MAC and paths."},
   {"name": "secrets", "form": ".env (copied from .env.example)", "what": "Holds the SSH key path, porch secret and ntfy topic."},
   {"name": "another config file", "form": "burrow --config <file>", "what": "Reads another config file in place of config/burrow.toml."},
   {"name": "tests", "form": "make test", "what": "Runs the test suite with pytest."},
   {"name": "lint", "form": "make lint", "what": "Checks burrow and its tests with ruff."},
   {"name": "clean", "form": "make clean", "what": "Removes .venv, build output and caches."}
 ]}
],
"questions": [
 "Give each rig its own screen (burrow rigs <rig> help, with its address, paths, stash, restore, wake and reboot)? Recommendation: yes, because those actions already belong to a rig and a new rig would then need no new help text. It adds a noun, so it is your call.",
 "The helpers screen lists 25 scripts on one screen. Split it by job into rigs, disks, network, power and dev? Recommendation: yes, after reading the 22 unread headers so each script lands in the right group. I placed none of them myself.",
 "Bare burrow stash and burrow restore error today, and bare burrow porch starts the server. Make stash and restore print their screens on a bare noun? Recommendation: yes for stash and restore. Porch keeps running, and its screen is burrow porch help.",
 "prune's --keep defaults to 8 in code and ignores stash.keep in config/burrow.toml. Make prune read the config? Recommendation: yes, so there is one source for the number.",
 "The metrics screen shows a Prometheus config the repo lacks and pulse readings that are all 0.0. Label the screen as not wired yet, or ship both first? Recommendation: label it now and fix the two next.",
 "chores.notify, BURROW_NTFY_TOPIC and BURROW_PORCH_SECRET are not read by any code in the dump. Implement them or remove them? Recommendation: remove them from the config and .env.example until something reads them."
]}
```

screen-decomposition, final · run 4 exit=0 seconds=113 · prompt

P1 Recall: 0.883P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 7P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 2
As terminal help
The home lab tool burrow: one group for each kind of thing you look after.
rigsburrow rigsPrints the rigs screen: each rig and whether it answers.
stashburrow stash helpPrints the stash screen: taking, listing, pruning and restoring stashes.
choresburrow chores helpPrints the chores screen: the recurring jobs and what each last did.
porchburrow porch helpPrints the porch screen: the dashboard, its pages and how to start it.
metricsburrow metrics help (to add)Prints the metrics screen: where the graphs are and how to start the containers.
helpersburrow helpers help (to add)Prints the helpers screen: the shell scripts in scripts/.
setupburrow setup help (to add)Prints the setup screen: installing, configuring and checking burrow.
rigs
The rigs burrow knows, and the files and tools that work on them.
wake a sleeping rigbin/rig-wake <rig-name>Sends a wake packet to a sleeping rig, using its MAC from config/rigs.toml.
rig listconfig/rigs.tomlOpens the file that lists each rig's name, address, MAC and paths.
adding a rigdocs/adding-a-rig.mdOpens the steps to add a rig and check that it answers.
stash
The stashes of each rig: taking them, listing them, pruning old ones and putting one back.
take a stash of one rigburrow stash <rig>Takes a stash of one rig now, into /srv/burrow/stashes.
take a stash of every rigburrow stash --all (make stash-all)Takes a stash of every rig now.
list stashesburrow stash list <rig>Prints the dated stashes kept for one rig.
prune old stashesburrow stash prune --keep 8 (make prune-stashes)Removes the oldest stashes, keeping the newest 8.
restore a stashburrow restore <rig> --from YYYY-MM-DDCopies a stash back onto its rig; --dry-run shows what would change without changing it.
verify the newest stashscripts/verify-stash.sh <rig>Checks that the newest stash of a rig is readable and not empty.
disk used by stashesscripts/du-stashes.shShows how much disk the stashes use.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the rsync steps to restore a stash when burrow is broken.
chores
The recurring jobs burrow runs, and when each one last ran.
nightly-stashburrow chores nightly-stash helpOpens the nightly-stash screen: what it does, when it runs and how to run it now.
disk-checkburrow chores disk-check helpOpens the disk-check screen: what it warns about, how often, and how to run it now.
chore namesburrow chores listPrints the names of the chores burrow knows.
last runsburrow chores statusPrints each chore's last run: when it finished and whether it worked.
scheduledeploy/burrow.crontabInstalls the schedule that runs both chores, nightly and every 6 hours.
chores page on the porchhttp://127.0.0.1:8470/choresOpens the chores page on the porch: each chore's last run.
last-run record/srv/burrow/state/last-run.jsonOpens the file that records each chore's last run.
chores guidedocs/chores.mdOpens the guide to the chores and where their record is kept.
chores › nightly-stash
The nightly-stash chore: a stash of every rig, at 02:15 each night.
run nowburrow chores run nightly-stashRuns the chore now: takes a stash of every rig.
scheduledeploy/burrow.crontab (line 2)Sets the time it runs: 02:15 every night.
codeburrow/chores.py (nightly_stash)Opens the code that takes the stash of each rig.
chores › disk-check
The disk-check chore: warns when a rig's root disk is more than 85% full, every 6 hours.
run nowburrow chores run disk-checkRuns the chore now: warns about any rig whose root disk is over 85%.
scheduledeploy/burrow.crontab (line 3)Sets it to run every 6 hours.
codeburrow/chores.py (disk_check)Opens the code that checks each rig's root disk.
disk reportscripts/check-disks.shShows disk use on every rig now.
porch
The porch: burrow's web dashboard for the rigs, chores and stashes.
start the porchburrow porchStarts the porch on port 8470 and keeps it running in this terminal.
front pagehttp://127.0.0.1:8470Opens the porch's front page, listing the rigs.
stashes page of a righttp://127.0.0.1:8470/stashes/<rig>Opens the stashes page for one rig.
health checkhttp://127.0.0.1:8470/healthzReturns the ok flag, true when the porch is up.
service unitdeploy/burrow-porch.serviceOpens the systemd unit that runs the porch and restarts it if it fails.
porch log/var/log/burrow/porch.logOpens the log file the porch writes to.
metrics
The metrics: graphs of rig temperatures and disk use, kept by the containers in docker-compose.yml.
start the containersmake upStarts the pulse, Prometheus and Grafana containers in the background.
stop the containersmake downStops and removes the containers.
graphshttp://127.0.0.1:3000Opens Grafana, the graphs of rig temperatures and disk use.
raw numbershttp://127.0.0.1:9188/metricsOpens the numbers pulse exposes for Prometheus.
compose filedocker-compose.ymlOpens the file that defines the three containers and their ports.
pulse sourcepulse/pulse.pyOpens the code that reads each rig's temperature and disk use.
helpers
The small shell helpers in scripts/, each to be read at the top before running.
battery-report.shscripts/battery-report.shReports battery state.
cert-renew.shscripts/cert-renew.shRenews the certificates.
check-disks.shscripts/check-disks.shShows disk use on every rig.
dns-flush.shscripts/dns-flush.shFlushes the DNS cache.
du-stashes.shscripts/du-stashes.shShows how much disk the stashes use.
export-chores.shscripts/export-chores.shExports the chore records.
fan-curve.shscripts/fan-curve.shSets the fan speed curve.
gc-docker.shscripts/gc-docker.shRemoves unused Docker leftovers.
import-rigs.shscripts/import-rigs.shImports rigs into config/rigs.toml.
list-ports.shscripts/list-ports.shLists the open ports.
mount-nas.shscripts/mount-nas.shMounts the NAS.
net-speed.shscripts/net-speed.shMeasures the network speed.
pihole-update.shscripts/pihole-update.shUpdates Pi-hole.
reboot-rig.shscripts/reboot-rig.sh <address>Reboots one rig after a 10 second countdown.
rotate-logs.shscripts/rotate-logs.shRotates the logs.
seed-dev.shscripts/seed-dev.shFills a development setup with sample data.
smart-report.shscripts/smart-report.shReports the SMART health of the disks.
ssh-keys-push.shscripts/ssh-keys-push.shPushes SSH keys to the rigs.
sync-clock.shscripts/sync-clock.shSyncs the clock.
temp-check.shscripts/temp-check.shChecks the temperatures.
unmount-nas.shscripts/unmount-nas.shUnmounts the NAS.
update-rigs.shscripts/update-rigs.shUpdates the software on the rigs.
ups-status.shscripts/ups-status.shShows the UPS status.
verify-stash.shscripts/verify-stash.sh <rig>Checks that the newest stash of a rig is readable and not empty.
zfs-scrub.shscripts/zfs-scrub.shStarts a ZFS scrub.
setup
Installing burrow, setting it up as a service and cron job, and its settings.
installmake installCreates the virtualenv in .venv/ and installs the burrow command into it.
install the porch servicemake install-unitCopies the porch service to systemd and starts it.
weekly prunemake install-prune-cronAdds the weekly stash prune to your crontab.
chores schedulecrontab deploy/burrow.crontabInstalls the chores schedule into your crontab.
settingsconfig/burrow.tomlOpens the settings file: where stashes go, how many to keep, and the porch address.
secrets.env.example (copy to .env)Opens the environment file to fill in the SSH key path, porch secret and alert topic.
setup guidedocs/setup.mdOpens the first-time setup steps and the check that it worked.
developmentburrow setup development help (to add)Opens the development screen: tests, lint and cleaning.
setup › development
Running burrow's tests and linter, and cleaning its build.
testmake testRuns the tests in tests/ with pytest.
lintmake lintChecks burrow and its tests with ruff.
cleanmake cleanDeletes the virtualenv, the pytest cache and build leftovers.
Questions
  • Bare nouns clash: `burrow porch` starts the dashboard and `burrow stash <rig>` takes a stash, so their screens are reached as `porch help` and `stash help`. Keep the existing forms, or make every noun print its screen? Recommend keeping the existing forms and reaching screens through help.
  • The helpers screen has 25 rows, too many for one list. Recommend five sub-screens by job: rig care (check-disks, reboot-rig, ssh-keys-push, update-rigs, import-rigs, temp-check, sync-clock), storage (mount-nas, unmount-nas, zfs-scrub, smart-report, du-stashes, verify-stash), network (dns-flush, list-ports, net-speed, pihole-update), power and cooling (battery-report, fan-curve, ups-status), and upkeep (cert-renew, gc-docker, rotate-logs, export-chores, seed-dev). Accept, or give a different split?
  • The schedules clash: `make install-prune-cron` appends the weekly prune to the crontab, but `crontab deploy/burrow.crontab` replaces the whole crontab and drops that line. Recommend adding the prune line to deploy/burrow.crontab so one file holds every schedule.
  • Metrics, helpers and setup have no command yet. Add `burrow metrics`, `burrow helpers` and `burrow setup` as thin help screens? Recommend yes.
  • Should each rig become its own screen (rigs › attic), holding its stashes, wake and paths? Recommend later, once the rig list is read from rigs.toml. Flat for now.
  • Is seed-dev.sh for your use, or only for development? It stays on the map unless you say you have left it out.
As phone screens

Home

The home lab tool burrow: one group for each kind of thing you look after.

rigsPrints the rigs screen: each rig and whether it answers.
›
stashPrints the stash screen: taking, listing, pruning and restoring stashes.
›
choresPrints the chores screen: the recurring jobs and what each last did.
›
porchPrints the porch screen: the dashboard, its pages and how to start it.
›
metricsPrints the metrics screen: where the graphs are and how to start the containers.
›
helpersPrints the helpers screen: the shell scripts in scripts/.
›
setupPrints the setup screen: installing, configuring and checking burrow.
›
‹ Home

rigs

The rigs burrow knows, and the files and tools that work on them.

wake a sleeping rigSends a wake packet to a sleeping rig, using its MAC from config/rigs.toml.
›
rig listOpens the file that lists each rig's name, address, MAC and paths.
›
adding a rigOpens the steps to add a rig and check that it answers.
›
‹ Home

stash

The stashes of each rig: taking them, listing them, pruning old ones and putting one back.

take a stash of one rigTakes a stash of one rig now, into /srv/burrow/stashes.
›
take a stash of every rigTakes a stash of every rig now.
›
list stashesPrints the dated stashes kept for one rig.
›
prune old stashesRemoves the oldest stashes, keeping the newest 8.
›
restore a stashCopies a stash back onto its rig; --dry-run shows what would change without changing it.
›
verify the newest stashChecks that the newest stash of a rig is readable and not empty.
›
disk used by stashesShows how much disk the stashes use.
›
restore by handOpens the rsync steps to restore a stash when burrow is broken.
›
‹ Home

chores

The recurring jobs burrow runs, and when each one last ran.

nightly-stashOpens the nightly-stash screen: what it does, when it runs and how to run it now.
›
disk-checkOpens the disk-check screen: what it warns about, how often, and how to run it now.
›
chore namesPrints the names of the chores burrow knows.
›
last runsPrints each chore's last run: when it finished and whether it worked.
›
scheduleInstalls the schedule that runs both chores, nightly and every 6 hours.
›
chores page on the porchOpens the chores page on the porch: each chore's last run.
›
last-run recordOpens the file that records each chore's last run.
›
chores guideOpens the guide to the chores and where their record is kept.
›
‹ chores

nightly-stash

The nightly-stash chore: a stash of every rig, at 02:15 each night.

run nowRuns the chore now: takes a stash of every rig.
›
scheduleSets the time it runs: 02:15 every night.
›
codeOpens the code that takes the stash of each rig.
›
‹ chores

disk-check

The disk-check chore: warns when a rig's root disk is more than 85% full, every 6 hours.

run nowRuns the chore now: warns about any rig whose root disk is over 85%.
›
scheduleSets it to run every 6 hours.
›
codeOpens the code that checks each rig's root disk.
›
disk reportShows disk use on every rig now.
›
‹ Home

porch

The porch: burrow's web dashboard for the rigs, chores and stashes.

start the porchStarts the porch on port 8470 and keeps it running in this terminal.
›
front pageOpens the porch's front page, listing the rigs.
›
stashes page of a rigOpens the stashes page for one rig.
›
health checkReturns the ok flag, true when the porch is up.
›
service unitOpens the systemd unit that runs the porch and restarts it if it fails.
›
porch logOpens the log file the porch writes to.
›
‹ Home

metrics

The metrics: graphs of rig temperatures and disk use, kept by the containers in docker-compose.yml.

start the containersStarts the pulse, Prometheus and Grafana containers in the background.
›
stop the containersStops and removes the containers.
›
graphsOpens Grafana, the graphs of rig temperatures and disk use.
›
raw numbersOpens the numbers pulse exposes for Prometheus.
›
compose fileOpens the file that defines the three containers and their ports.
›
pulse sourceOpens the code that reads each rig's temperature and disk use.
›
‹ Home

helpers

The small shell helpers in scripts/, each to be read at the top before running.

battery-report.shReports battery state.
›
cert-renew.shRenews the certificates.
›
check-disks.shShows disk use on every rig.
›
dns-flush.shFlushes the DNS cache.
›
du-stashes.shShows how much disk the stashes use.
›
export-chores.shExports the chore records.
›
fan-curve.shSets the fan speed curve.
›
gc-docker.shRemoves unused Docker leftovers.
›
import-rigs.shImports rigs into config/rigs.toml.
›
list-ports.shLists the open ports.
›
mount-nas.shMounts the NAS.
›
net-speed.shMeasures the network speed.
›
pihole-update.shUpdates Pi-hole.
›
reboot-rig.shReboots one rig after a 10 second countdown.
›
rotate-logs.shRotates the logs.
›
seed-dev.shFills a development setup with sample data.
›
smart-report.shReports the SMART health of the disks.
›
ssh-keys-push.shPushes SSH keys to the rigs.
›
sync-clock.shSyncs the clock.
›
temp-check.shChecks the temperatures.
›
unmount-nas.shUnmounts the NAS.
›
update-rigs.shUpdates the software on the rigs.
›
ups-status.shShows the UPS status.
›
verify-stash.shChecks that the newest stash of a rig is readable and not empty.
›
zfs-scrub.shStarts a ZFS scrub.
›
‹ Home

setup

Installing burrow, setting it up as a service and cron job, and its settings.

installCreates the virtualenv in .venv/ and installs the burrow command into it.
›
install the porch serviceCopies the porch service to systemd and starts it.
›
weekly pruneAdds the weekly stash prune to your crontab.
›
chores scheduleInstalls the chores schedule into your crontab.
›
settingsOpens the settings file: where stashes go, how many to keep, and the porch address.
›
secretsOpens the environment file to fill in the SSH key path, porch secret and alert topic.
›
setup guideOpens the first-time setup steps and the check that it worked.
›
developmentOpens the development screen: tests, lint and cleaning.
›
‹ setup

development

Running burrow's tests and linter, and cleaning its build.

testRuns the tests in tests/ with pytest.
›
lintChecks burrow and its tests with ruff.
›
cleanDeletes the virtualenv, the pytest cache and build leftovers.
›
Raw answer
## Scenario

Reasoning from the README and the code, not from anyone's stated habits: the owner runs burrow from a shell on the home network, mostly when something looks wrong. They want to know whether the rigs answer, whether the last chore ran, to take or restore a stash, to open the dashboard or graphs, or to run one of the helper scripts.

## Inventory

Every item below is on the map. Nothing in the dump is marked as left out by the owner.

- **CLI** (`burrow/cli.py`): `rigs`, `stash` (take, `--all`, `list`, `prune`), `restore`, `chores` (`list`, `run`, `status`), `porch`.
- **Make targets** (10): `install`, `install-unit`, `install-prune-cron`, `up`, `down`, `test`, `lint`, `clean`, `stash-all`, `prune-stashes`.
- **Chores** (2): `nightly-stash`, `disk-check`.
- **Porch pages** (4): `/`, `/chores`, `/stashes/<rig>`, `/healthz`.
- **Metrics:** Grafana on 3000, pulse on 9188, `docker-compose.yml`, `pulse/pulse.py`.
- **Helpers:** 25 files in `scripts/`, plus `bin/rig-wake`, which I placed under rigs.
- **Config and files:** `config/burrow.toml`, `config/rigs.toml`, `.env.example`, `deploy/burrow-porch.service`, `deploy/burrow.crontab`.
- **Docs** (4): each one sits on the screen it explains.

## Judgment calls

- **Restore sits under stash** because the README pairs "put a stash back" with taking stashes. The command stays `burrow restore`.
- **Each chore is a nested screen** (`chores › nightly-stash`, `chores › disk-check`) because each has its own schedule and last run.
- **Docs are not a group.** Each one sits on the screen of the thing it explains.
- **Helper lines:** I read `check-disks.sh`, `reboot-rig.sh` and `verify-stash.sh`. The other 22 lines come from file names only and must be checked against each script's header before building.
- **Metrics:** `pulse` returns 0.0 for temperature and disk (`read_temp`, `read_disk` are stubs). The metrics screen does not claim these are live. The Prometheus config is not in the repo.
- **Screens without a command yet** (`metrics`, `helpers`, `setup`) use forms marked "to add".
- **Unverified:** `burrow stash` with no arguments calls `rigs.get(cfg, None)`. I did not confirm what that does.

```json
{"screens": [
  {"path": [], "sentence": "The home lab tool burrow: one group for each kind of thing you look after.", "rows": [
    {"name": "rigs", "form": "burrow rigs", "what": "Prints the rigs screen: each rig and whether it answers."},
    {"name": "stash", "form": "burrow stash help", "what": "Prints the stash screen: taking, listing, pruning and restoring stashes."},
    {"name": "chores", "form": "burrow chores help", "what": "Prints the chores screen: the recurring jobs and what each last did."},
    {"name": "porch", "form": "burrow porch help", "what": "Prints the porch screen: the dashboard, its pages and how to start it."},
    {"name": "metrics", "form": "burrow metrics help (to add)", "what": "Prints the metrics screen: where the graphs are and how to start the containers."},
    {"name": "helpers", "form": "burrow helpers help (to add)", "what": "Prints the helpers screen: the shell scripts in scripts/."},
    {"name": "setup", "form": "burrow setup help (to add)", "what": "Prints the setup screen: installing, configuring and checking burrow."}
  ]},
  {"path": ["rigs"], "sentence": "The rigs burrow knows, and the files and tools that work on them.", "rows": [
    {"name": "wake a sleeping rig", "form": "bin/rig-wake <rig-name>", "what": "Sends a wake packet to a sleeping rig, using its MAC from config/rigs.toml."},
    {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the file that lists each rig's name, address, MAC and paths."},
    {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps to add a rig and check that it answers."}
  ]},
  {"path": ["stash"], "sentence": "The stashes of each rig: taking them, listing them, pruning old ones and putting one back.", "rows": [
    {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now, into /srv/burrow/stashes."},
    {"name": "take a stash of every rig", "form": "burrow stash --all (make stash-all)", "what": "Takes a stash of every rig now."},
    {"name": "list stashes", "form": "burrow stash list <rig>", "what": "Prints the dated stashes kept for one rig."},
    {"name": "prune old stashes", "form": "burrow stash prune --keep 8 (make prune-stashes)", "what": "Removes the oldest stashes, keeping the newest 8."},
    {"name": "restore a stash", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies a stash back onto its rig; --dry-run shows what would change without changing it."},
    {"name": "verify the newest stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks that the newest stash of a rig is readable and not empty."},
    {"name": "disk used by stashes", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use."},
    {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the rsync steps to restore a stash when burrow is broken."}
  ]},
  {"path": ["chores"], "sentence": "The recurring jobs burrow runs, and when each one last ran.", "rows": [
    {"name": "nightly-stash", "form": "burrow chores nightly-stash help", "what": "Opens the nightly-stash screen: what it does, when it runs and how to run it now."},
    {"name": "disk-check", "form": "burrow chores disk-check help", "what": "Opens the disk-check screen: what it warns about, how often, and how to run it now."},
    {"name": "chore names", "form": "burrow chores list", "what": "Prints the names of the chores burrow knows."},
    {"name": "last runs", "form": "burrow chores status", "what": "Prints each chore's last run: when it finished and whether it worked."},
    {"name": "schedule", "form": "deploy/burrow.crontab", "what": "Installs the schedule that runs both chores, nightly and every 6 hours."},
    {"name": "chores page on the porch", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page on the porch: each chore's last run."},
    {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the file that records each chore's last run."},
    {"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide to the chores and where their record is kept."}
  ]},
  {"path": ["chores", "nightly-stash"], "sentence": "The nightly-stash chore: a stash of every rig, at 02:15 each night.", "rows": [
    {"name": "run now", "form": "burrow chores run nightly-stash", "what": "Runs the chore now: takes a stash of every rig."},
    {"name": "schedule", "form": "deploy/burrow.crontab (line 2)", "what": "Sets the time it runs: 02:15 every night."},
    {"name": "code", "form": "burrow/chores.py (nightly_stash)", "what": "Opens the code that takes the stash of each rig."}
  ]},
  {"path": ["chores", "disk-check"], "sentence": "The disk-check chore: warns when a rig's root disk is more than 85% full, every 6 hours.", "rows": [
    {"name": "run now", "form": "burrow chores run disk-check", "what": "Runs the chore now: warns about any rig whose root disk is over 85%."},
    {"name": "schedule", "form": "deploy/burrow.crontab (line 3)", "what": "Sets it to run every 6 hours."},
    {"name": "code", "form": "burrow/chores.py (disk_check)", "what": "Opens the code that checks each rig's root disk."},
    {"name": "disk report", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig now."}
  ]},
  {"path": ["porch"], "sentence": "The porch: burrow's web dashboard for the rigs, chores and stashes.", "rows": [
    {"name": "start the porch", "form": "burrow porch", "what": "Starts the porch on port 8470 and keeps it running in this terminal."},
    {"name": "front page", "form": "http://127.0.0.1:8470", "what": "Opens the porch's front page, listing the rigs."},
    {"name": "stashes page of a rig", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens the stashes page for one rig."},
    {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns the ok flag, true when the porch is up."},
    {"name": "service unit", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that runs the porch and restarts it if it fails."},
    {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the log file the porch writes to."}
  ]},
  {"path": ["metrics"], "sentence": "The metrics: graphs of rig temperatures and disk use, kept by the containers in docker-compose.yml.", "rows": [
    {"name": "start the containers", "form": "make up", "what": "Starts the pulse, Prometheus and Grafana containers in the background."},
    {"name": "stop the containers", "form": "make down", "what": "Stops and removes the containers."},
    {"name": "graphs", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, the graphs of rig temperatures and disk use."},
    {"name": "raw numbers", "form": "http://127.0.0.1:9188/metrics", "what": "Opens the numbers pulse exposes for Prometheus."},
    {"name": "compose file", "form": "docker-compose.yml", "what": "Opens the file that defines the three containers and their ports."},
    {"name": "pulse source", "form": "pulse/pulse.py", "what": "Opens the code that reads each rig's temperature and disk use."}
  ]},
  {"path": ["helpers"], "sentence": "The small shell helpers in scripts/, each to be read at the top before running.", "rows": [
    {"name": "battery-report.sh", "form": "scripts/battery-report.sh", "what": "Reports battery state."},
    {"name": "cert-renew.sh", "form": "scripts/cert-renew.sh", "what": "Renews the certificates."},
    {"name": "check-disks.sh", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig."},
    {"name": "dns-flush.sh", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache."},
    {"name": "du-stashes.sh", "form": "scripts/du-stashes.sh", "what": "Shows how much disk the stashes use."},
    {"name": "export-chores.sh", "form": "scripts/export-chores.sh", "what": "Exports the chore records."},
    {"name": "fan-curve.sh", "form": "scripts/fan-curve.sh", "what": "Sets the fan speed curve."},
    {"name": "gc-docker.sh", "form": "scripts/gc-docker.sh", "what": "Removes unused Docker leftovers."},
    {"name": "import-rigs.sh", "form": "scripts/import-rigs.sh", "what": "Imports rigs into config/rigs.toml."},
    {"name": "list-ports.sh", "form": "scripts/list-ports.sh", "what": "Lists the open ports."},
    {"name": "mount-nas.sh", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS."},
    {"name": "net-speed.sh", "form": "scripts/net-speed.sh", "what": "Measures the network speed."},
    {"name": "pihole-update.sh", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole."},
    {"name": "reboot-rig.sh", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10 second countdown."},
    {"name": "rotate-logs.sh", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs."},
    {"name": "seed-dev.sh", "form": "scripts/seed-dev.sh", "what": "Fills a development setup with sample data."},
    {"name": "smart-report.sh", "form": "scripts/smart-report.sh", "what": "Reports the SMART health of the disks."},
    {"name": "ssh-keys-push.sh", "form": "scripts/ssh-keys-push.sh", "what": "Pushes SSH keys to the rigs."},
    {"name": "sync-clock.sh", "form": "scripts/sync-clock.sh", "what": "Syncs the clock."},
    {"name": "temp-check.sh", "form": "scripts/temp-check.sh", "what": "Checks the temperatures."},
    {"name": "unmount-nas.sh", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS."},
    {"name": "update-rigs.sh", "form": "scripts/update-rigs.sh", "what": "Updates the software on the rigs."},
    {"name": "ups-status.sh", "form": "scripts/ups-status.sh", "what": "Shows the UPS status."},
    {"name": "verify-stash.sh", "form": "scripts/verify-stash.sh <rig>", "what": "Checks that the newest stash of a rig is readable and not empty."},
    {"name": "zfs-scrub.sh", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub."}
  ]},
  {"path": ["setup"], "sentence": "Installing burrow, setting it up as a service and cron job, and its settings.", "rows": [
    {"name": "install", "form": "make install", "what": "Creates the virtualenv in .venv/ and installs the burrow command into it."},
    {"name": "install the porch service", "form": "make install-unit", "what": "Copies the porch service to systemd and starts it."},
    {"name": "weekly prune", "form": "make install-prune-cron", "what": "Adds the weekly stash prune to your crontab."},
    {"name": "chores schedule", "form": "crontab deploy/burrow.crontab", "what": "Installs the chores schedule into your crontab."},
    {"name": "settings", "form": "config/burrow.toml", "what": "Opens the settings file: where stashes go, how many to keep, and the porch address."},
    {"name": "secrets", "form": ".env.example (copy to .env)", "what": "Opens the environment file to fill in the SSH key path, porch secret and alert topic."},
    {"name": "setup guide", "form": "docs/setup.md", "what": "Opens the first-time setup steps and the check that it worked."},
    {"name": "development", "form": "burrow setup development help (to add)", "what": "Opens the development screen: tests, lint and cleaning."}
  ]},
  {"path": ["setup", "development"], "sentence": "Running burrow's tests and linter, and cleaning its build.", "rows": [
    {"name": "test", "form": "make test", "what": "Runs the tests in tests/ with pytest."},
    {"name": "lint", "form": "make lint", "what": "Checks burrow and its tests with ruff."},
    {"name": "clean", "form": "make clean", "what": "Deletes the virtualenv, the pytest cache and build leftovers."}
  ]}
],
"questions": [
  "Bare nouns clash: `burrow porch` starts the dashboard and `burrow stash <rig>` takes a stash, so their screens are reached as `porch help` and `stash help`. Keep the existing forms, or make every noun print its screen? Recommend keeping the existing forms and reaching screens through help.",
  "The helpers screen has 25 rows, too many for one list. Recommend five sub-screens by job: rig care (check-disks, reboot-rig, ssh-keys-push, update-rigs, import-rigs, temp-check, sync-clock), storage (mount-nas, unmount-nas, zfs-scrub, smart-report, du-stashes, verify-stash), network (dns-flush, list-ports, net-speed, pihole-update), power and cooling (battery-report, fan-curve, ups-status), and upkeep (cert-renew, gc-docker, rotate-logs, export-chores, seed-dev). Accept, or give a different split?",
  "The schedules clash: `make install-prune-cron` appends the weekly prune to the crontab, but `crontab deploy/burrow.crontab` replaces the whole crontab and drops that line. Recommend adding the prune line to deploy/burrow.crontab so one file holds every schedule.",
  "Metrics, helpers and setup have no command yet. Add `burrow metrics`, `burrow helpers` and `burrow setup` as thin help screens? Recommend yes.",
  "Should each rig become its own screen (rigs › attic), holding its stashes, wake and paths? Recommend later, once the rig list is read from rigs.toml. Flat for now.",
  "Is seed-dev.sh for your use, or only for development? It stays on the map unless you say you have left it out."
]}
```

No skill · run 5 exit=0 seconds=91 · prompt

P1 Recall: 0.5P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.448P5 Short top: 11P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
burrow looks after the home-lab rigs. Pick a topic below; add --help to any command for its options.
rigsburrow rigslist the rigs and whether each one answers
stashburrow stash (opens the stash screen)take a snapshot of rigs, list them, or prune old ones
restoreburrow restore (opens the restore screen)copy a stash back onto a rig
choresburrow chores (opens the chores screen)recurring jobs: list, run, status
porchburrow porch (opens the porch screen)run the web dashboard
config file option--config PATH (default config/burrow.toml)use a different settings file
settingsconfig/ and .env (opens the config screen)the files that set rigs, paths and secrets
metricsmake up (opens the metrics screen)graphs of rig temperature and disk use
make targetsmake <target> (opens the make screen)shortcuts for install, tests, stashes and containers
helpersbin/rig-wake and scripts/ (opens the helpers screen)small one-off tools outside the burrow command
docsdocs/ (opens the docs screen)written guides for setup, rigs, chores and restores
rigs
Lists every rig in config/rigs.toml with its address and whether it answers a ping. Takes no options.
add a rigdocs/adding-a-rig.mdhow to add a rig to config/rigs.toml
stash
Takes a stash, a dated snapshot of a rig's important folders. Give one rig name, or --all for every rig.
rigburrow stash <rig>the rig to stash; names come from config/rigs.toml
all rigsburrow stash --allstash every rig in one go (make stash-all does this)
listburrow stash list <rig> (opens the stash list screen)see the stashes kept for a rig
pruneburrow stash prune [--keep N] (opens the stash prune screen)delete old stashes
stash › list
Lists the stashes kept for one rig.
rig<rig> argumentthe rig whose stashes to list
restoreburrow restore (opens the restore screen)stash folders are named by date, so these names are the --from values
stash › prune
Deletes old stashes so that only the newest few are kept. make install-prune-cron schedules this weekly.
keep--keep N (default 8)how many stashes to keep
restore
Copies a stash from /srv/burrow/stashes back onto its rig. Needs a rig and a date. Try --dry-run first.
rig<rig> argumentthe rig to restore onto
date--from YYYY-MM-DD (required)which stash to restore; see stash list
dry run--dry-runtrial run; intended to change nothing on the rig
restore by handdocs/internals/stash/format/restore-by-hand.mdrestore with rsync if burrow itself is broken
chores
Recurring jobs that burrow runs from cron or by hand.
listburrow chores list (opens the chores list screen)the job names burrow knows
runburrow chores run <name> (opens the chores run screen)run one job now
statusburrow chores status (opens the chores status screen)when each job last finished and whether it worked
chores guidedocs/chores.mdwhat each job does and when it runs
chores › list
The names of the jobs burrow knows, with what each one does.
nightly-stashburrow chores run nightly-stashstash every rig; cron runs it at 02:15 each night
disk-checkburrow chores run disk-checkcheck each rig's root disk and warn above 85% full; cron runs it every 6 hours
chores › run
Runs one job now and records the result for chores status.
name<name> argumenta job name from chores list
chores › status
For each job: when it last finished and whether it said ok or failed.
porch chores pagehttp://127.0.0.1:8470/chores (opens the porch chores screen)the same status in the browser
record file/srv/burrow/state/last-run.jsonwhere the last-run record is kept
porch
Runs the web dashboard. It listens on the address in config/burrow.toml unless you pass --bind. From another machine on the LAN, use the rig's IP instead of 127.0.0.1.
bind--bind HOST:PORT (default 0.0.0.0:8470)address and port to listen on
home pagehttp://127.0.0.1:8470/the rigs at a glance
chores pagehttp://127.0.0.1:8470/chores (opens the porch chores screen)the last run of each job
stashes pagehttp://127.0.0.1:8470/stashes/<rig> (opens the porch stashes screen)the stashes kept for one rig
health checkhttp://127.0.0.1:8470/healthzreturns JSON with ok set to true when the porch is up
run as a servicemake install-unit (deploy/burrow-porch.service)start the porch under systemd so it comes back after a reboot
porch › chores
A web page with the last run of each chore: when it finished and whether it worked.
chores statusburrow chores statusthe same information in the terminal
porch › stashes
A web page listing the stashes kept for one rig. The rig name is part of the address.
rig/stashes/<rig>the rig to show
stash listburrow stash list <rig>the same list in the terminal
config
The files that set how burrow behaves. Copy .env.example to .env and fill it in first.
burrow.tomlconfig/burrow.tomlstash folder and how many to keep, chore state file, porch address and refresh, ssh user and key setting
rigs.tomlconfig/rigs.toml (guide: docs/adding-a-rig.md)the rigs: name, address, MAC, and folders to stash
environment file.env (from .env.example)secrets and paths: SSH key, porch secret, ntfy topic
metrics
Graphs of rig temperature and disk use, from the containers in docker-compose.yml.
startmake upstart the containers
stopmake downstop the containers
grafanahttp://127.0.0.1:3000graphs; opens without a login because anonymous access is on
raw metricshttp://127.0.0.1:9188/metricsthe numbers pulse exposes for Prometheus
prometheusno host portstores metrics for 30 days; reached only from inside the containers
make
Shortcuts run from the burrow folder. Each one is a make target.
installmake installcreate .venv and install burrow into it
install-unitmake install-unitinstall and start the porch service (uses sudo)
up and downmake up / make down (opens the metrics screen)start or stop the metrics containers
testmake testrun the test suite
lintmake lintrun ruff on burrow and tests
stash-allmake stash-allstash every rig
prune-stashesmake prune-stashesprune stashes, keeping 8
install-prune-cronmake install-prune-cronschedule the weekly prune for Sunday at 04:40
cleanmake cleanremove .venv, caches and build output
helpers
Small tools outside the burrow command. Read the top of a script before you run it.
wake a rigbin/rig-wake <rig>send a wake-on-LAN packet to a sleeping rig, using its MAC from config/rigs.toml
check disksscripts/check-disks.shshow disk use on every rig
verify a stashscripts/verify-stash.sh <rig>check the newest stash of a rig is readable and not empty
reboot a rigscripts/reboot-rig.sh <address>reboot a rig after a 10 second countdown
other scriptsscripts/<name>.sh (22 more)small one-screen helpers; their headers were not in the dump
docs
Written guides in the docs folder. The README links to most of them.
setupdocs/setup.mdfirst-time setup: rig user, install, service, crontab
adding a rigdocs/adding-a-rig.mdadd a rig and check that it answers
choresdocs/chores.mdwhat each chore does and how to run it
restore by handdocs/internals/stash/format/restore-by-hand.mdrestore a stash with rsync when burrow is broken
Questions
  • Cron runs burrow from the home folder with no cd, and the default --config is the relative config/burrow.toml, so the nightly and disk jobs will probably fail to find their settings. Recommend: start each line in deploy/burrow.crontab with 'cd /opt/burrow &&', as make install-prune-cron already does, or make the default config path absolute.
  • The porch binds 0.0.0.0:8470 with no login, and BURROW_PORCH_SECRET in .env.example is not used by any code in the dump. Should the porch require the secret? Recommend: confirm the intent. If the secret is meant to gate the porch, add that check. If not, remove the variable and say in the porch help that anyone on the LAN can open it.
  • The keep count is set twice. config/burrow.toml sets keep = 8, but 'stash prune' defaults to a hard-coded 8 and does not read the config. Which should win? Recommend: default prune to the config value so there is one number to change.
  • Is 'prune --keep N' per rig or across all rigs? stash.py was not in the dump. Recommend: decide it, then word the prune help to match. I would suggest per rig, since each rig has its own folder.
  • The metrics are placeholders: pulse's read_temp and read_disk return 0.0, so Grafana will show zeros. Recommend: keep the metrics screen but mark it as not yet working, or hide the metrics row until pulse reads real values.
  • Chore failures are easy to miss. A failed chore is recorded in last-run.json, but the CLI exits with status 0, and ntfy alerts are configured without any code in the dump that sends them. Recommend: point people to 'chores status' in the chores help, and leave alerting off the map until it exists.
  • Should make targets and helper scripts appear in burrow's own help, or in a separate topic? Recommend: a separate 'more' topic, so 'burrow --help' lists only the five burrow commands.
  • The 22 helper scripts without headers in the dump cannot be described accurately from here. Recommend: generate each row's 'what' from the first comment line of its script rather than writing them by hand.
  • A rig named 'list' or 'prune' cannot be stashed by name, because 'stash list' and 'stash prune' take those words first. Recommend: reject those two names when rigs.toml is loaded. It is a small check.
As phone screens

Home

burrow looks after the home-lab rigs. Pick a topic below; add --help to any command for its options.

rigslist the rigs and whether each one answers
›
stashtake a snapshot of rigs, list them, or prune old ones
›
restorecopy a stash back onto a rig
›
choresrecurring jobs: list, run, status
›
porchrun the web dashboard
›
config file optionuse a different settings file
›
settingsthe files that set rigs, paths and secrets
›
metricsgraphs of rig temperature and disk use
›
make targetsshortcuts for install, tests, stashes and containers
›
helperssmall one-off tools outside the burrow command
›
docswritten guides for setup, rigs, chores and restores
›
‹ Home

rigs

Lists every rig in config/rigs.toml with its address and whether it answers a ping. Takes no options.

add a righow to add a rig to config/rigs.toml
›
‹ Home

stash

Takes a stash, a dated snapshot of a rig's important folders. Give one rig name, or --all for every rig.

rigthe rig to stash; names come from config/rigs.toml
›
all rigsstash every rig in one go (make stash-all does this)
›
listsee the stashes kept for a rig
›
prunedelete old stashes
›
‹ stash

list

Lists the stashes kept for one rig.

rigthe rig whose stashes to list
›
restorestash folders are named by date, so these names are the --from values
›
‹ stash

prune

Deletes old stashes so that only the newest few are kept. make install-prune-cron schedules this weekly.

keephow many stashes to keep
›
‹ Home

restore

Copies a stash from /srv/burrow/stashes back onto its rig. Needs a rig and a date. Try --dry-run first.

rigthe rig to restore onto
›
datewhich stash to restore; see stash list
›
dry runtrial run; intended to change nothing on the rig
›
restore by handrestore with rsync if burrow itself is broken
›
‹ Home

chores

Recurring jobs that burrow runs from cron or by hand.

listthe job names burrow knows
›
runrun one job now
›
statuswhen each job last finished and whether it worked
›
chores guidewhat each job does and when it runs
›
‹ chores

list

The names of the jobs burrow knows, with what each one does.

nightly-stashstash every rig; cron runs it at 02:15 each night
›
disk-checkcheck each rig's root disk and warn above 85% full; cron runs it every 6 hours
›
‹ chores

run

Runs one job now and records the result for chores status.

namea job name from chores list
›
‹ chores

status

For each job: when it last finished and whether it said ok or failed.

porch chores pagethe same status in the browser
›
record filewhere the last-run record is kept
›
‹ Home

porch

Runs the web dashboard. It listens on the address in config/burrow.toml unless you pass --bind. From another machine on the LAN, use the rig's IP instead of 127.0.0.1.

bindaddress and port to listen on
›
home pagethe rigs at a glance
›
chores pagethe last run of each job
›
stashes pagethe stashes kept for one rig
›
health checkreturns JSON with ok set to true when the porch is up
›
run as a servicestart the porch under systemd so it comes back after a reboot
›
‹ porch

chores

A web page with the last run of each chore: when it finished and whether it worked.

chores statusthe same information in the terminal
›
‹ porch

stashes

A web page listing the stashes kept for one rig. The rig name is part of the address.

rigthe rig to show
›
stash listthe same list in the terminal
›
‹ Home

config

The files that set how burrow behaves. Copy .env.example to .env and fill it in first.

burrow.tomlstash folder and how many to keep, chore state file, porch address and refresh, ssh user and key setting
›
rigs.tomlthe rigs: name, address, MAC, and folders to stash
›
environment filesecrets and paths: SSH key, porch secret, ntfy topic
›
‹ Home

metrics

Graphs of rig temperature and disk use, from the containers in docker-compose.yml.

startstart the containers
›
stopstop the containers
›
grafanagraphs; opens without a login because anonymous access is on
›
raw metricsthe numbers pulse exposes for Prometheus
›
prometheusstores metrics for 30 days; reached only from inside the containers
›
‹ Home

make

Shortcuts run from the burrow folder. Each one is a make target.

installcreate .venv and install burrow into it
›
install-unitinstall and start the porch service (uses sudo)
›
up and downstart or stop the metrics containers
›
testrun the test suite
›
lintrun ruff on burrow and tests
›
stash-allstash every rig
›
prune-stashesprune stashes, keeping 8
›
install-prune-cronschedule the weekly prune for Sunday at 04:40
›
cleanremove .venv, caches and build output
›
‹ Home

helpers

Small tools outside the burrow command. Read the top of a script before you run it.

wake a rigsend a wake-on-LAN packet to a sleeping rig, using its MAC from config/rigs.toml
›
check disksshow disk use on every rig
›
verify a stashcheck the newest stash of a rig is readable and not empty
›
reboot a rigreboot a rig after a 10 second countdown
›
other scriptssmall one-screen helpers; their headers were not in the dump
›
‹ Home

docs

Written guides in the docs folder. The README links to most of them.

setupfirst-time setup: rig user, install, service, crontab
›
adding a rigadd a rig and check that it answers
›
choreswhat each chore does and how to run it
›
restore by handrestore a stash with rsync when burrow is broken
›
Raw answer
I read the CLI, the porch app, the config and deploy files, the Makefile, the compose file, and the docs. I did not have `stash.py`, `rigs.py`, `config.py`, the porch templates, or 22 of the scripts, so screens that depend on them describe what their names and callers imply. Three findings are in `questions`: the cron jobs probably run from the wrong folder, the porch has no login and listens on the LAN, and the metrics are stubs.

```json
{"screens": [
{"path": [], "sentence": "burrow looks after the home-lab rigs. Pick a topic below; add --help to any command for its options.", "rows": [
{"name": "rigs", "form": "burrow rigs", "what": "list the rigs and whether each one answers"},
{"name": "stash", "form": "burrow stash (opens the stash screen)", "what": "take a snapshot of rigs, list them, or prune old ones"},
{"name": "restore", "form": "burrow restore (opens the restore screen)", "what": "copy a stash back onto a rig"},
{"name": "chores", "form": "burrow chores (opens the chores screen)", "what": "recurring jobs: list, run, status"},
{"name": "porch", "form": "burrow porch (opens the porch screen)", "what": "run the web dashboard"},
{"name": "config file option", "form": "--config PATH (default config/burrow.toml)", "what": "use a different settings file"},
{"name": "settings", "form": "config/ and .env (opens the config screen)", "what": "the files that set rigs, paths and secrets"},
{"name": "metrics", "form": "make up (opens the metrics screen)", "what": "graphs of rig temperature and disk use"},
{"name": "make targets", "form": "make <target> (opens the make screen)", "what": "shortcuts for install, tests, stashes and containers"},
{"name": "helpers", "form": "bin/rig-wake and scripts/ (opens the helpers screen)", "what": "small one-off tools outside the burrow command"},
{"name": "docs", "form": "docs/ (opens the docs screen)", "what": "written guides for setup, rigs, chores and restores"}
]},
{"path": ["rigs"], "sentence": "Lists every rig in config/rigs.toml with its address and whether it answers a ping. Takes no options.", "rows": [
{"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "how to add a rig to config/rigs.toml"}
]},
{"path": ["stash"], "sentence": "Takes a stash, a dated snapshot of a rig's important folders. Give one rig name, or --all for every rig.", "rows": [
{"name": "rig", "form": "burrow stash <rig>", "what": "the rig to stash; names come from config/rigs.toml"},
{"name": "all rigs", "form": "burrow stash --all", "what": "stash every rig in one go (make stash-all does this)"},
{"name": "list", "form": "burrow stash list <rig> (opens the stash list screen)", "what": "see the stashes kept for a rig"},
{"name": "prune", "form": "burrow stash prune [--keep N] (opens the stash prune screen)", "what": "delete old stashes"}
]},
{"path": ["stash", "list"], "sentence": "Lists the stashes kept for one rig.", "rows": [
{"name": "rig", "form": "<rig> argument", "what": "the rig whose stashes to list"},
{"name": "restore", "form": "burrow restore (opens the restore screen)", "what": "stash folders are named by date, so these names are the --from values"}
]},
{"path": ["stash", "prune"], "sentence": "Deletes old stashes so that only the newest few are kept. make install-prune-cron schedules this weekly.", "rows": [
{"name": "keep", "form": "--keep N (default 8)", "what": "how many stashes to keep"}
]},
{"path": ["restore"], "sentence": "Copies a stash from /srv/burrow/stashes back onto its rig. Needs a rig and a date. Try --dry-run first.", "rows": [
{"name": "rig", "form": "<rig> argument", "what": "the rig to restore onto"},
{"name": "date", "form": "--from YYYY-MM-DD (required)", "what": "which stash to restore; see stash list"},
{"name": "dry run", "form": "--dry-run", "what": "trial run; intended to change nothing on the rig"},
{"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "restore with rsync if burrow itself is broken"}
]},
{"path": ["chores"], "sentence": "Recurring jobs that burrow runs from cron or by hand.", "rows": [
{"name": "list", "form": "burrow chores list (opens the chores list screen)", "what": "the job names burrow knows"},
{"name": "run", "form": "burrow chores run <name> (opens the chores run screen)", "what": "run one job now"},
{"name": "status", "form": "burrow chores status (opens the chores status screen)", "what": "when each job last finished and whether it worked"},
{"name": "chores guide", "form": "docs/chores.md", "what": "what each job does and when it runs"}
]},
{"path": ["chores", "list"], "sentence": "The names of the jobs burrow knows, with what each one does.", "rows": [
{"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "stash every rig; cron runs it at 02:15 each night"},
{"name": "disk-check", "form": "burrow chores run disk-check", "what": "check each rig's root disk and warn above 85% full; cron runs it every 6 hours"}
]},
{"path": ["chores", "run"], "sentence": "Runs one job now and records the result for chores status.", "rows": [
{"name": "name", "form": "<name> argument", "what": "a job name from chores list"}
]},
{"path": ["chores", "status"], "sentence": "For each job: when it last finished and whether it said ok or failed.", "rows": [
{"name": "porch chores page", "form": "http://127.0.0.1:8470/chores (opens the porch chores screen)", "what": "the same status in the browser"},
{"name": "record file", "form": "/srv/burrow/state/last-run.json", "what": "where the last-run record is kept"}
]},
{"path": ["porch"], "sentence": "Runs the web dashboard. It listens on the address in config/burrow.toml unless you pass --bind. From another machine on the LAN, use the rig's IP instead of 127.0.0.1.", "rows": [
{"name": "bind", "form": "--bind HOST:PORT (default 0.0.0.0:8470)", "what": "address and port to listen on"},
{"name": "home page", "form": "http://127.0.0.1:8470/", "what": "the rigs at a glance"},
{"name": "chores page", "form": "http://127.0.0.1:8470/chores (opens the porch chores screen)", "what": "the last run of each job"},
{"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/<rig> (opens the porch stashes screen)", "what": "the stashes kept for one rig"},
{"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "returns JSON with ok set to true when the porch is up"},
{"name": "run as a service", "form": "make install-unit (deploy/burrow-porch.service)", "what": "start the porch under systemd so it comes back after a reboot"}
]},
{"path": ["porch", "chores"], "sentence": "A web page with the last run of each chore: when it finished and whether it worked.", "rows": [
{"name": "chores status", "form": "burrow chores status", "what": "the same information in the terminal"}
]},
{"path": ["porch", "stashes"], "sentence": "A web page listing the stashes kept for one rig. The rig name is part of the address.", "rows": [
{"name": "rig", "form": "/stashes/<rig>", "what": "the rig to show"},
{"name": "stash list", "form": "burrow stash list <rig>", "what": "the same list in the terminal"}
]},
{"path": ["config"], "sentence": "The files that set how burrow behaves. Copy .env.example to .env and fill it in first.", "rows": [
{"name": "burrow.toml", "form": "config/burrow.toml", "what": "stash folder and how many to keep, chore state file, porch address and refresh, ssh user and key setting"},
{"name": "rigs.toml", "form": "config/rigs.toml (guide: docs/adding-a-rig.md)", "what": "the rigs: name, address, MAC, and folders to stash"},
{"name": "environment file", "form": ".env (from .env.example)", "what": "secrets and paths: SSH key, porch secret, ntfy topic"}
]},
{"path": ["metrics"], "sentence": "Graphs of rig temperature and disk use, from the containers in docker-compose.yml.", "rows": [
{"name": "start", "form": "make up", "what": "start the containers"},
{"name": "stop", "form": "make down", "what": "stop the containers"},
{"name": "grafana", "form": "http://127.0.0.1:3000", "what": "graphs; opens without a login because anonymous access is on"},
{"name": "raw metrics", "form": "http://127.0.0.1:9188/metrics", "what": "the numbers pulse exposes for Prometheus"},
{"name": "prometheus", "form": "no host port", "what": "stores metrics for 30 days; reached only from inside the containers"}
]},
{"path": ["make"], "sentence": "Shortcuts run from the burrow folder. Each one is a make target.", "rows": [
{"name": "install", "form": "make install", "what": "create .venv and install burrow into it"},
{"name": "install-unit", "form": "make install-unit", "what": "install and start the porch service (uses sudo)"},
{"name": "up and down", "form": "make up / make down (opens the metrics screen)", "what": "start or stop the metrics containers"},
{"name": "test", "form": "make test", "what": "run the test suite"},
{"name": "lint", "form": "make lint", "what": "run ruff on burrow and tests"},
{"name": "stash-all", "form": "make stash-all", "what": "stash every rig"},
{"name": "prune-stashes", "form": "make prune-stashes", "what": "prune stashes, keeping 8"},
{"name": "install-prune-cron", "form": "make install-prune-cron", "what": "schedule the weekly prune for Sunday at 04:40"},
{"name": "clean", "form": "make clean", "what": "remove .venv, caches and build output"}
]},
{"path": ["helpers"], "sentence": "Small tools outside the burrow command. Read the top of a script before you run it.", "rows": [
{"name": "wake a rig", "form": "bin/rig-wake <rig>", "what": "send a wake-on-LAN packet to a sleeping rig, using its MAC from config/rigs.toml"},
{"name": "check disks", "form": "scripts/check-disks.sh", "what": "show disk use on every rig"},
{"name": "verify a stash", "form": "scripts/verify-stash.sh <rig>", "what": "check the newest stash of a rig is readable and not empty"},
{"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "reboot a rig after a 10 second countdown"},
{"name": "other scripts", "form": "scripts/<name>.sh (22 more)", "what": "small one-screen helpers; their headers were not in the dump"}
]},
{"path": ["docs"], "sentence": "Written guides in the docs folder. The README links to most of them.", "rows": [
{"name": "setup", "form": "docs/setup.md", "what": "first-time setup: rig user, install, service, crontab"},
{"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "add a rig and check that it answers"},
{"name": "chores", "form": "docs/chores.md", "what": "what each chore does and how to run it"},
{"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "restore a stash with rsync when burrow is broken"}
]}
],
"questions": [
"Cron runs burrow from the home folder with no cd, and the default --config is the relative config/burrow.toml, so the nightly and disk jobs will probably fail to find their settings. Recommend: start each line in deploy/burrow.crontab with 'cd /opt/burrow &&', as make install-prune-cron already does, or make the default config path absolute.",
"The porch binds 0.0.0.0:8470 with no login, and BURROW_PORCH_SECRET in .env.example is not used by any code in the dump. Should the porch require the secret? Recommend: confirm the intent. If the secret is meant to gate the porch, add that check. If not, remove the variable and say in the porch help that anyone on the LAN can open it.",
"The keep count is set twice. config/burrow.toml sets keep = 8, but 'stash prune' defaults to a hard-coded 8 and does not read the config. Which should win? Recommend: default prune to the config value so there is one number to change.",
"Is 'prune --keep N' per rig or across all rigs? stash.py was not in the dump. Recommend: decide it, then word the prune help to match. I would suggest per rig, since each rig has its own folder.",
"The metrics are placeholders: pulse's read_temp and read_disk return 0.0, so Grafana will show zeros. Recommend: keep the metrics screen but mark it as not yet working, or hide the metrics row until pulse reads real values.",
"Chore failures are easy to miss. A failed chore is recorded in last-run.json, but the CLI exits with status 0, and ntfy alerts are configured without any code in the dump that sends them. Recommend: point people to 'chores status' in the chores help, and leave alerting off the map until it exists.",
"Should make targets and helper scripts appear in burrow's own help, or in a separate topic? Recommend: a separate 'more' topic, so 'burrow --help' lists only the five burrow commands.",
"The 22 helper scripts without headers in the dump cannot be described accurately from here. Recommend: generate each row's 'what' from the first comment line of its script rather than writing them by hand.",
"A rig named 'list' or 'prune' cannot be stashed by name, because 'stash list' and 'stash prune' take those words first. Recommend: reject those two names when rigs.toml is loaded. It is a small check."
]}
```

Today's skills · run 5 exit=0 seconds=115 · prompt

P1 Recall: 0.867P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.969P5 Short top: 9P6 Own words: 0.923P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
What burrow reaches: the rigs, their stashes, the chores, the porch dashboard, the metrics, setup, the helper scripts and the files.
Rigsburrow rigsLists the rigs and whether each one answers.
Stashesburrow stashPrints the stash screen: taking, listing and pruning stashes.
Restoreburrow restore <rig> --from DATECopies a stash back onto its rig.
Choresburrow choresPrints the chores screen: the recurring jobs and when each last ran.
Porchburrow porchStarts the porch dashboard on port 8470.
Metricsburrow metricsPrints the metrics screen: the containers that graph rig temperatures and disk use.
Setupburrow setupPrints the setup screen: installing, testing and cleaning burrow.
Scriptsburrow scriptsPrints the scripts screen: the helper scripts, grouped by job.
Filesburrow filesPrints the files screen: settings, logs, code and guides.
rigs
The machines burrow looks after, and whether each one answers.
attic192.168.1.20 (ssh as burrow)Stashes its /etc, /home and /var/lib/docker/volumes.
cellar192.168.1.21 (ssh as burrow)Stashes its /etc and /tank/photos.
garden192.168.1.22 (ssh as burrow)Stashes its /etc and /opt/homeassistant.
Wake a rigbin/rig-wakeWakes a sleeping rig with a magic packet, using its MAC from rigs.toml.
Adding a rigdocs/adding-a-rig.mdOpens the guide for adding a rig to rigs.toml.
stash
Snapshots of each rig's important folders, pulled over rsync, one dated folder per stash.
Take one stashburrow stash <rig>Takes a stash of the named rig now.
Take every stashburrow stash --allTakes a stash of every rig now.
List a rig's stashesburrow stash list <rig>Lists the stashes kept for the named rig.
Prune old stashesburrow stash prune --keep 8Removes old stashes, keeping the newest 8.
Stashes folder/srv/burrow/stashesOpens the folder that holds every stash, one per rig and date.
A stash's manifest/srv/burrow/stashes/<rig>/<date>/.burrow-manifestOpens a stash's manifest: its paths and the rsync exit code.
Verify newest stashscripts/verify-stash.shRuns a check that a rig's newest stash is readable and not empty.
Stash disk usescripts/du-stashes.shRuns a report of the disk the stashes use (described from its name).
Restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the guide for restoring a stash by hand, when burrow is broken.
chores
The recurring jobs burrow runs, when each last ran and whether it worked.
List choresburrow chores listLists the chore names burrow knows.
Run a choreburrow chores run <name>Runs one chore now, by hand.
Chore statusburrow chores statusShows when each chore last ran and whether it worked.
nightly-stashburrow chores run nightly-stashTakes a stash of every rig, at 02:15 each night.
disk-checkburrow chores run disk-checkWarns when a rig's root disk is over 85 percent, every six hours.
Last-run record/srv/burrow/state/last-run.jsonOpens the record of when each chore last ran.
Chores log/var/log/burrow/chores.logOpens the output of the cron chores.
Chore scheduledeploy/burrow.crontabOpens the schedule that runs the chores.
Chore registryburrow/chores.pyOpens the chore registry, where a new chore is added.
Chores guidedocs/chores.mdOpens the guide to chores.
porch
The dashboard in a browser: the rigs, the chores and each rig's stashes.
Start the porchburrow porchStarts the porch dashboard on port 8470, the one bare command that starts instead of printing a screen.
Porch home pagehttp://127.0.0.1:8470Opens the porch home page with every rig.
Chores pagehttp://127.0.0.1:8470/choresOpens the chores page: when each chore last ran.
A rig's stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens one rig's stashes on the porch.
Health checkhttp://127.0.0.1:8470/healthzShows ok when the porch is up.
Porch servicedeploy/burrow-porch.serviceOpens the systemd unit that keeps the porch running.
Porch log/var/log/burrow/porch.logOpens the porch's output.
Page templatesburrow/porch/templates/Opens the page templates: index, chores and stashes.
metrics
The containers that graph rig temperatures and disk use, with Grafana for the graphs.
Start metricsmake upStarts the metrics containers in the background.
Stop metricsmake downStops the metrics containers.
Grafana graphshttp://127.0.0.1:3000Opens the Grafana graphs of rig temperatures and disk use.
Raw readingshttp://127.0.0.1:9188/metricsShows the raw readings pulse serves to Prometheus.
Prometheus storagedocker volume prom-dataHolds 30 days of stored readings.
Grafana storagedocker volume grafana-dataHolds Grafana's dashboards and settings.
Container definitionsdocker-compose.ymlOpens the file that defines the three containers.
Pulse codepulse/pulse.pyOpens the code that serves the readings to Prometheus; its read functions are stubs for now.
setup
Installing, testing and cleaning up burrow on a machine.
Installmake installCreates the virtualenv and installs the burrow command.
Install the porch servicemake install-unitInstalls and starts the porch as a systemd service.
Install the chores schedulecrontab deploy/burrow.crontabInstalls the nightly stash and disk-check schedule.
Install the weekly prunemake install-prune-cronInstalls the weekly job that prunes old stashes.
Run testsmake testRuns the test suite.
Check code stylemake lintChecks the code with ruff.
Clean upmake cleanDeletes the virtualenv and build leftovers.
Setup guidedocs/setup.mdOpens the steps for setting up burrow on a new rig.
Project filepyproject.tomlOpens the version, dependencies and command name.
Make targetsMakefileOpens the list of make targets.
scripts
Small shell helpers, grouped by job. Read the top of each one before running it.
Checksburrow scripts checksPrints the checks screen: scripts that look at rigs and report.
Rigsburrow scripts rigsPrints the rigs screen: scripts that change or reach rigs.
Upkeepburrow scripts upkeepPrints the upkeep screen: scripts that keep the machines tidy and current.
Databurrow scripts dataPrints the data screen: scripts that export or seed data.
scripts › checks
Helpers that look at a rig and report what they find, without changing anything.
Disk use on every rigscripts/check-disks.shRuns a disk-use report for every rig in rigs.toml, over ssh.
Rig temperaturesscripts/temp-check.shRuns a temperature check on the rigs (described from its name).
Disk healthscripts/smart-report.shRuns a SMART disk health report (described from its name).
Battery healthscripts/battery-report.shRuns a battery health report (described from its name).
UPS statusscripts/ups-status.shRuns a status check on the UPS battery backup (described from its name).
Network speedscripts/net-speed.shRuns a network speed test (described from its name).
Open portsscripts/list-ports.shLists the network ports open on a machine (described from its name).
scripts › rigs
Helpers that act on the rigs: reboot them, update them, share keys and mount storage.
Reboot a rigscripts/reboot-rig.shReboots one rig after a 10 second countdown.
Update rigsscripts/update-rigs.shRuns updates on the rigs (described from its name).
Push ssh keysscripts/ssh-keys-push.shPushes an ssh key to the rigs (described from its name).
Import rigsscripts/import-rigs.shImports rigs from another list (described from its name).
Mount the NASscripts/mount-nas.shMounts the NAS on a machine (described from its name).
Unmount the NASscripts/unmount-nas.shUnmounts the NAS (described from its name).
scripts › upkeep
Helpers that keep the machines tidy, current and their clocks right.
Rotate logsscripts/rotate-logs.shRotates the logs (described from its name).
Clean up Dockerscripts/gc-docker.shRemoves unused Docker data (described from its name).
ZFS scrubscripts/zfs-scrub.shStarts a ZFS scrub, which checks the pool for errors (described from its name).
Renew certificatesscripts/cert-renew.shRenews certificates (described from its name).
Update Pi-holescripts/pihole-update.shUpdates Pi-hole (described from its name).
Flush DNSscripts/dns-flush.shFlushes the DNS cache (described from its name).
Sync clockscripts/sync-clock.shSyncs the clock with a time server (described from its name).
Fan curvescripts/fan-curve.shSets the fan speed curve (described from its name).
scripts › data
Helpers that move data in and out of burrow, or fill a dev setup.
Export choresscripts/export-chores.shExports the chores to a file (described from its name).
Seed dev datascripts/seed-dev.shFills a dev setup with sample data (described from its name).
files
The settings, logs, code and guides that make burrow work.
Settingsconfig/burrow.tomlOpens the settings file: stash, chore, porch and ssh values.
Rig listconfig/rigs.tomlOpens the list of rigs, with addresses, MACs and paths.
Secrets.envOpens the secrets file: ssh key path, porch secret and alert topic.
Secrets template.env.exampleOpens the template to copy into .env.
Logs folder/var/log/burrowOpens the logs folder: chores and porch output.
Command definitionsburrow/cli.pyOpens the file that defines every command and option.
Teststests/Opens the tests that make test runs.
Docs folderdocs/Opens the docs folder: setup, adding a rig and chores.
READMEREADME.mdOpens the README: install, use and the chores.
LicenseLICENSEOpens the MIT license.
Questions
  • Porch: the bare command `burrow porch` starts the server, so it breaks the rule that a bare noun prints its screen. Recommend `burrow porch start` as the command, with the bare noun printing the porch screen, and changing the ExecStart line in deploy/burrow-porch.service to match. Do you agree?
  • Restore: should `burrow restore` move under stash as `burrow stash restore`, since it puts back what stash takes? Recommend yes, with `burrow restore` kept as an alias so the README still works.
  • Make and Docker: should the burrow command wrap the make targets and the docker compose containers (for example `burrow metrics up`, `burrow setup install`), so every route goes through one command? Recommend yes; the Makefile stays as it is underneath.
  • Scripts: do you agree with the split into checks, rigs, upkeep and data, which is my call and needs your confirmation since the list is long? Should the scripts screen run a script with its arguments, or only show its path? Recommend running it. Also send the headers of the 22 scripts whose bodies are not in the dump if you want their lines exact.
  • Metrics: the pulse read functions return 0.0, and prometheus.yml is not in the repo. Should the metrics screen be built now and the pulse readings fixed afterwards, or should pulse be fixed first? Recommend building the map now and fixing pulse before the first build.
As phone screens

Home

What burrow reaches: the rigs, their stashes, the chores, the porch dashboard, the metrics, setup, the helper scripts and the files.

RigsLists the rigs and whether each one answers.
›
StashesPrints the stash screen: taking, listing and pruning stashes.
›
RestoreCopies a stash back onto its rig.
›
ChoresPrints the chores screen: the recurring jobs and when each last ran.
›
PorchStarts the porch dashboard on port 8470.
›
MetricsPrints the metrics screen: the containers that graph rig temperatures and disk use.
›
SetupPrints the setup screen: installing, testing and cleaning burrow.
›
ScriptsPrints the scripts screen: the helper scripts, grouped by job.
›
FilesPrints the files screen: settings, logs, code and guides.
›
‹ Home

rigs

The machines burrow looks after, and whether each one answers.

atticStashes its /etc, /home and /var/lib/docker/volumes.
›
cellarStashes its /etc and /tank/photos.
›
gardenStashes its /etc and /opt/homeassistant.
›
Wake a rigWakes a sleeping rig with a magic packet, using its MAC from rigs.toml.
›
Adding a rigOpens the guide for adding a rig to rigs.toml.
›
‹ Home

stash

Snapshots of each rig's important folders, pulled over rsync, one dated folder per stash.

Take one stashTakes a stash of the named rig now.
›
Take every stashTakes a stash of every rig now.
›
List a rig's stashesLists the stashes kept for the named rig.
›
Prune old stashesRemoves old stashes, keeping the newest 8.
›
Stashes folderOpens the folder that holds every stash, one per rig and date.
›
A stash's manifestOpens a stash's manifest: its paths and the rsync exit code.
›
Verify newest stashRuns a check that a rig's newest stash is readable and not empty.
›
Stash disk useRuns a report of the disk the stashes use (described from its name).
›
Restore by handOpens the guide for restoring a stash by hand, when burrow is broken.
›
‹ Home

chores

The recurring jobs burrow runs, when each last ran and whether it worked.

List choresLists the chore names burrow knows.
›
Run a choreRuns one chore now, by hand.
›
Chore statusShows when each chore last ran and whether it worked.
›
nightly-stashTakes a stash of every rig, at 02:15 each night.
›
disk-checkWarns when a rig's root disk is over 85 percent, every six hours.
›
Last-run recordOpens the record of when each chore last ran.
›
Chores logOpens the output of the cron chores.
›
Chore scheduleOpens the schedule that runs the chores.
›
Chore registryOpens the chore registry, where a new chore is added.
›
Chores guideOpens the guide to chores.
›
‹ Home

porch

The dashboard in a browser: the rigs, the chores and each rig's stashes.

Start the porchStarts the porch dashboard on port 8470, the one bare command that starts instead of printing a screen.
›
Porch home pageOpens the porch home page with every rig.
›
Chores pageOpens the chores page: when each chore last ran.
›
A rig's stashes pageOpens one rig's stashes on the porch.
›
Health checkShows ok when the porch is up.
›
Porch serviceOpens the systemd unit that keeps the porch running.
›
Porch logOpens the porch's output.
›
Page templatesOpens the page templates: index, chores and stashes.
›
‹ Home

metrics

The containers that graph rig temperatures and disk use, with Grafana for the graphs.

Start metricsStarts the metrics containers in the background.
›
Stop metricsStops the metrics containers.
›
Grafana graphsOpens the Grafana graphs of rig temperatures and disk use.
›
Raw readingsShows the raw readings pulse serves to Prometheus.
›
Prometheus storageHolds 30 days of stored readings.
›
Grafana storageHolds Grafana's dashboards and settings.
›
Container definitionsOpens the file that defines the three containers.
›
Pulse codeOpens the code that serves the readings to Prometheus; its read functions are stubs for now.
›
‹ Home

setup

Installing, testing and cleaning up burrow on a machine.

InstallCreates the virtualenv and installs the burrow command.
›
Install the porch serviceInstalls and starts the porch as a systemd service.
›
Install the chores scheduleInstalls the nightly stash and disk-check schedule.
›
Install the weekly pruneInstalls the weekly job that prunes old stashes.
›
Run testsRuns the test suite.
›
Check code styleChecks the code with ruff.
›
Clean upDeletes the virtualenv and build leftovers.
›
Setup guideOpens the steps for setting up burrow on a new rig.
›
Project fileOpens the version, dependencies and command name.
›
Make targetsOpens the list of make targets.
›
‹ Home

scripts

Small shell helpers, grouped by job. Read the top of each one before running it.

ChecksPrints the checks screen: scripts that look at rigs and report.
›
RigsPrints the rigs screen: scripts that change or reach rigs.
›
UpkeepPrints the upkeep screen: scripts that keep the machines tidy and current.
›
DataPrints the data screen: scripts that export or seed data.
›
‹ scripts

checks

Helpers that look at a rig and report what they find, without changing anything.

Disk use on every rigRuns a disk-use report for every rig in rigs.toml, over ssh.
›
Rig temperaturesRuns a temperature check on the rigs (described from its name).
›
Disk healthRuns a SMART disk health report (described from its name).
›
Battery healthRuns a battery health report (described from its name).
›
UPS statusRuns a status check on the UPS battery backup (described from its name).
›
Network speedRuns a network speed test (described from its name).
›
Open portsLists the network ports open on a machine (described from its name).
›
‹ scripts

rigs

Helpers that act on the rigs: reboot them, update them, share keys and mount storage.

Reboot a rigReboots one rig after a 10 second countdown.
›
Update rigsRuns updates on the rigs (described from its name).
›
Push ssh keysPushes an ssh key to the rigs (described from its name).
›
Import rigsImports rigs from another list (described from its name).
›
Mount the NASMounts the NAS on a machine (described from its name).
›
Unmount the NASUnmounts the NAS (described from its name).
›
‹ scripts

upkeep

Helpers that keep the machines tidy, current and their clocks right.

Rotate logsRotates the logs (described from its name).
›
Clean up DockerRemoves unused Docker data (described from its name).
›
ZFS scrubStarts a ZFS scrub, which checks the pool for errors (described from its name).
›
Renew certificatesRenews certificates (described from its name).
›
Update Pi-holeUpdates Pi-hole (described from its name).
›
Flush DNSFlushes the DNS cache (described from its name).
›
Sync clockSyncs the clock with a time server (described from its name).
›
Fan curveSets the fan speed curve (described from its name).
›
‹ scripts

data

Helpers that move data in and out of burrow, or fill a dev setup.

Export choresExports the chores to a file (described from its name).
›
Seed dev dataFills a dev setup with sample data (described from its name).
›
‹ Home

files

The settings, logs, code and guides that make burrow work.

SettingsOpens the settings file: stash, chore, porch and ssh values.
›
Rig listOpens the list of rigs, with addresses, MACs and paths.
›
SecretsOpens the secrets file: ssh key path, porch secret and alert topic.
›
Secrets templateOpens the template to copy into .env.
›
Logs folderOpens the logs folder: chores and porch output.
›
Command definitionsOpens the file that defines every command and option.
›
TestsOpens the tests that make test runs.
›
Docs folderOpens the docs folder: setup, adding a rig and chores.
›
READMEOpens the README: install, use and the chores.
›
LicenseOpens the MIT license.
›
Raw answer
The map is below. Forms marked with a `burrow` command that isn't in `cli.py` yet (metrics, setup, scripts, files) are proposed.

Three findings affect the map:
- **Stub metrics.** `pulse/pulse.py` `read_temp` and `read_disk` return `0.0`, so the metrics screen will show zeros until they are filled in.
- **Missing Prometheus config.** `docker-compose.yml` points Prometheus at `/etc/prometheus/prometheus.yml`, which is not in the repo.
- **Scripts described from names.** Only `check-disks.sh`, `verify-stash.sh` and `reboot-rig.sh` have their bodies in the dump. The other 22 one-line descriptions are read from their names and need confirming.

```json
{"screens": [
{"path": [], "sentence": "What burrow reaches: the rigs, their stashes, the chores, the porch dashboard, the metrics, setup, the helper scripts and the files.", "rows": [
{"name": "Rigs", "form": "burrow rigs", "what": "Lists the rigs and whether each one answers."},
{"name": "Stashes", "form": "burrow stash", "what": "Prints the stash screen: taking, listing and pruning stashes."},
{"name": "Restore", "form": "burrow restore <rig> --from DATE", "what": "Copies a stash back onto its rig."},
{"name": "Chores", "form": "burrow chores", "what": "Prints the chores screen: the recurring jobs and when each last ran."},
{"name": "Porch", "form": "burrow porch", "what": "Starts the porch dashboard on port 8470."},
{"name": "Metrics", "form": "burrow metrics", "what": "Prints the metrics screen: the containers that graph rig temperatures and disk use."},
{"name": "Setup", "form": "burrow setup", "what": "Prints the setup screen: installing, testing and cleaning burrow."},
{"name": "Scripts", "form": "burrow scripts", "what": "Prints the scripts screen: the helper scripts, grouped by job."},
{"name": "Files", "form": "burrow files", "what": "Prints the files screen: settings, logs, code and guides."}
]},
{"path": ["rigs"], "sentence": "The machines burrow looks after, and whether each one answers.", "rows": [
{"name": "attic", "form": "192.168.1.20 (ssh as burrow)", "what": "Stashes its /etc, /home and /var/lib/docker/volumes."},
{"name": "cellar", "form": "192.168.1.21 (ssh as burrow)", "what": "Stashes its /etc and /tank/photos."},
{"name": "garden", "form": "192.168.1.22 (ssh as burrow)", "what": "Stashes its /etc and /opt/homeassistant."},
{"name": "Wake a rig", "form": "bin/rig-wake", "what": "Wakes a sleeping rig with a magic packet, using its MAC from rigs.toml."},
{"name": "Adding a rig", "form": "docs/adding-a-rig.md", "what": "Opens the guide for adding a rig to rigs.toml."}
]},
{"path": ["stash"], "sentence": "Snapshots of each rig's important folders, pulled over rsync, one dated folder per stash.", "rows": [
{"name": "Take one stash", "form": "burrow stash <rig>", "what": "Takes a stash of the named rig now."},
{"name": "Take every stash", "form": "burrow stash --all", "what": "Takes a stash of every rig now."},
{"name": "List a rig's stashes", "form": "burrow stash list <rig>", "what": "Lists the stashes kept for the named rig."},
{"name": "Prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes old stashes, keeping the newest 8."},
{"name": "Stashes folder", "form": "/srv/burrow/stashes", "what": "Opens the folder that holds every stash, one per rig and date."},
{"name": "A stash's manifest", "form": "/srv/burrow/stashes/<rig>/<date>/.burrow-manifest", "what": "Opens a stash's manifest: its paths and the rsync exit code."},
{"name": "Verify newest stash", "form": "scripts/verify-stash.sh", "what": "Runs a check that a rig's newest stash is readable and not empty."},
{"name": "Stash disk use", "form": "scripts/du-stashes.sh", "what": "Runs a report of the disk the stashes use (described from its name)."},
{"name": "Restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the guide for restoring a stash by hand, when burrow is broken."}
]},
{"path": ["chores"], "sentence": "The recurring jobs burrow runs, when each last ran and whether it worked.", "rows": [
{"name": "List chores", "form": "burrow chores list", "what": "Lists the chore names burrow knows."},
{"name": "Run a chore", "form": "burrow chores run <name>", "what": "Runs one chore now, by hand."},
{"name": "Chore status", "form": "burrow chores status", "what": "Shows when each chore last ran and whether it worked."},
{"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Takes a stash of every rig, at 02:15 each night."},
{"name": "disk-check", "form": "burrow chores run disk-check", "what": "Warns when a rig's root disk is over 85 percent, every six hours."},
{"name": "Last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of when each chore last ran."},
{"name": "Chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the output of the cron chores."},
{"name": "Chore schedule", "form": "deploy/burrow.crontab", "what": "Opens the schedule that runs the chores."},
{"name": "Chore registry", "form": "burrow/chores.py", "what": "Opens the chore registry, where a new chore is added."},
{"name": "Chores guide", "form": "docs/chores.md", "what": "Opens the guide to chores."}
]},
{"path": ["porch"], "sentence": "The dashboard in a browser: the rigs, the chores and each rig's stashes.", "rows": [
{"name": "Start the porch", "form": "burrow porch", "what": "Starts the porch dashboard on port 8470, the one bare command that starts instead of printing a screen."},
{"name": "Porch home page", "form": "http://127.0.0.1:8470", "what": "Opens the porch home page with every rig."},
{"name": "Chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page: when each chore last ran."},
{"name": "A rig's stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens one rig's stashes on the porch."},
{"name": "Health check", "form": "http://127.0.0.1:8470/healthz", "what": "Shows ok when the porch is up."},
{"name": "Porch service", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that keeps the porch running."},
{"name": "Porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the porch's output."},
{"name": "Page templates", "form": "burrow/porch/templates/", "what": "Opens the page templates: index, chores and stashes."}
]},
{"path": ["metrics"], "sentence": "The containers that graph rig temperatures and disk use, with Grafana for the graphs.", "rows": [
{"name": "Start metrics", "form": "make up", "what": "Starts the metrics containers in the background."},
{"name": "Stop metrics", "form": "make down", "what": "Stops the metrics containers."},
{"name": "Grafana graphs", "form": "http://127.0.0.1:3000", "what": "Opens the Grafana graphs of rig temperatures and disk use."},
{"name": "Raw readings", "form": "http://127.0.0.1:9188/metrics", "what": "Shows the raw readings pulse serves to Prometheus."},
{"name": "Prometheus storage", "form": "docker volume prom-data", "what": "Holds 30 days of stored readings."},
{"name": "Grafana storage", "form": "docker volume grafana-data", "what": "Holds Grafana's dashboards and settings."},
{"name": "Container definitions", "form": "docker-compose.yml", "what": "Opens the file that defines the three containers."},
{"name": "Pulse code", "form": "pulse/pulse.py", "what": "Opens the code that serves the readings to Prometheus; its read functions are stubs for now."}
]},
{"path": ["setup"], "sentence": "Installing, testing and cleaning up burrow on a machine.", "rows": [
{"name": "Install", "form": "make install", "what": "Creates the virtualenv and installs the burrow command."},
{"name": "Install the porch service", "form": "make install-unit", "what": "Installs and starts the porch as a systemd service."},
{"name": "Install the chores schedule", "form": "crontab deploy/burrow.crontab", "what": "Installs the nightly stash and disk-check schedule."},
{"name": "Install the weekly prune", "form": "make install-prune-cron", "what": "Installs the weekly job that prunes old stashes."},
{"name": "Run tests", "form": "make test", "what": "Runs the test suite."},
{"name": "Check code style", "form": "make lint", "what": "Checks the code with ruff."},
{"name": "Clean up", "form": "make clean", "what": "Deletes the virtualenv and build leftovers."},
{"name": "Setup guide", "form": "docs/setup.md", "what": "Opens the steps for setting up burrow on a new rig."},
{"name": "Project file", "form": "pyproject.toml", "what": "Opens the version, dependencies and command name."},
{"name": "Make targets", "form": "Makefile", "what": "Opens the list of make targets."}
]},
{"path": ["scripts"], "sentence": "Small shell helpers, grouped by job. Read the top of each one before running it.", "rows": [
{"name": "Checks", "form": "burrow scripts checks", "what": "Prints the checks screen: scripts that look at rigs and report."},
{"name": "Rigs", "form": "burrow scripts rigs", "what": "Prints the rigs screen: scripts that change or reach rigs."},
{"name": "Upkeep", "form": "burrow scripts upkeep", "what": "Prints the upkeep screen: scripts that keep the machines tidy and current."},
{"name": "Data", "form": "burrow scripts data", "what": "Prints the data screen: scripts that export or seed data."}
]},
{"path": ["scripts", "checks"], "sentence": "Helpers that look at a rig and report what they find, without changing anything.", "rows": [
{"name": "Disk use on every rig", "form": "scripts/check-disks.sh", "what": "Runs a disk-use report for every rig in rigs.toml, over ssh."},
{"name": "Rig temperatures", "form": "scripts/temp-check.sh", "what": "Runs a temperature check on the rigs (described from its name)."},
{"name": "Disk health", "form": "scripts/smart-report.sh", "what": "Runs a SMART disk health report (described from its name)."},
{"name": "Battery health", "form": "scripts/battery-report.sh", "what": "Runs a battery health report (described from its name)."},
{"name": "UPS status", "form": "scripts/ups-status.sh", "what": "Runs a status check on the UPS battery backup (described from its name)."},
{"name": "Network speed", "form": "scripts/net-speed.sh", "what": "Runs a network speed test (described from its name)."},
{"name": "Open ports", "form": "scripts/list-ports.sh", "what": "Lists the network ports open on a machine (described from its name)."}
]},
{"path": ["scripts", "rigs"], "sentence": "Helpers that act on the rigs: reboot them, update them, share keys and mount storage.", "rows": [
{"name": "Reboot a rig", "form": "scripts/reboot-rig.sh", "what": "Reboots one rig after a 10 second countdown."},
{"name": "Update rigs", "form": "scripts/update-rigs.sh", "what": "Runs updates on the rigs (described from its name)."},
{"name": "Push ssh keys", "form": "scripts/ssh-keys-push.sh", "what": "Pushes an ssh key to the rigs (described from its name)."},
{"name": "Import rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs from another list (described from its name)."},
{"name": "Mount the NAS", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS on a machine (described from its name)."},
{"name": "Unmount the NAS", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS (described from its name)."}
]},
{"path": ["scripts", "upkeep"], "sentence": "Helpers that keep the machines tidy, current and their clocks right.", "rows": [
{"name": "Rotate logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs (described from its name)."},
{"name": "Clean up Docker", "form": "scripts/gc-docker.sh", "what": "Removes unused Docker data (described from its name)."},
{"name": "ZFS scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub, which checks the pool for errors (described from its name)."},
{"name": "Renew certificates", "form": "scripts/cert-renew.sh", "what": "Renews certificates (described from its name)."},
{"name": "Update Pi-hole", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole (described from its name)."},
{"name": "Flush DNS", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache (described from its name)."},
{"name": "Sync clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock with a time server (described from its name)."},
{"name": "Fan curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan speed curve (described from its name)."}
]},
{"path": ["scripts", "data"], "sentence": "Helpers that move data in and out of burrow, or fill a dev setup.", "rows": [
{"name": "Export chores", "form": "scripts/export-chores.sh", "what": "Exports the chores to a file (described from its name)."},
{"name": "Seed dev data", "form": "scripts/seed-dev.sh", "what": "Fills a dev setup with sample data (described from its name)."}
]},
{"path": ["files"], "sentence": "The settings, logs, code and guides that make burrow work.", "rows": [
{"name": "Settings", "form": "config/burrow.toml", "what": "Opens the settings file: stash, chore, porch and ssh values."},
{"name": "Rig list", "form": "config/rigs.toml", "what": "Opens the list of rigs, with addresses, MACs and paths."},
{"name": "Secrets", "form": ".env", "what": "Opens the secrets file: ssh key path, porch secret and alert topic."},
{"name": "Secrets template", "form": ".env.example", "what": "Opens the template to copy into .env."},
{"name": "Logs folder", "form": "/var/log/burrow", "what": "Opens the logs folder: chores and porch output."},
{"name": "Command definitions", "form": "burrow/cli.py", "what": "Opens the file that defines every command and option."},
{"name": "Tests", "form": "tests/", "what": "Opens the tests that make test runs."},
{"name": "Docs folder", "form": "docs/", "what": "Opens the docs folder: setup, adding a rig and chores."},
{"name": "README", "form": "README.md", "what": "Opens the README: install, use and the chores."},
{"name": "License", "form": "LICENSE", "what": "Opens the MIT license."}
]}
],
"questions": [
"Porch: the bare command `burrow porch` starts the server, so it breaks the rule that a bare noun prints its screen. Recommend `burrow porch start` as the command, with the bare noun printing the porch screen, and changing the ExecStart line in deploy/burrow-porch.service to match. Do you agree?",
"Restore: should `burrow restore` move under stash as `burrow stash restore`, since it puts back what stash takes? Recommend yes, with `burrow restore` kept as an alias so the README still works.",
"Make and Docker: should the burrow command wrap the make targets and the docker compose containers (for example `burrow metrics up`, `burrow setup install`), so every route goes through one command? Recommend yes; the Makefile stays as it is underneath.",
"Scripts: do you agree with the split into checks, rigs, upkeep and data, which is my call and needs your confirmation since the list is long? Should the scripts screen run a script with its arguments, or only show its path? Recommend running it. Also send the headers of the 22 scripts whose bodies are not in the dump if you want their lines exact.",
"Metrics: the pulse read functions return 0.0, and prometheus.yml is not in the repo. Should the metrics screen be built now and the pulse readings fixed afterwards, or should pulse be fixed first? Recommend building the map now and fixing pulse before the first build."
]}
```

screen-decomposition, first draft · run 5 exit=0 seconds=100 · prompt

P1 Recall: 0.9P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.988P5 Short top: 7P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 1
As terminal help
What burrow looks after on your home-lab rigs, and where each part is.
rigsburrow rigsShows the rigs and whether each one answers.
stashburrow stash --helpShows the stash actions: take, list, restore and prune.
choresburrow chores --helpShows the recurring jobs and when each last ran.
porchburrow porch --helpShows the porch's pages and how to start it.
metricsdocker-compose.ymlShows the metrics containers and their graphs.
setupMakefileShows how to install, configure, test and document burrow.
helpersscripts/Shows the helper scripts kept in scripts/.
rigs
The rigs burrow knows, and the tools for waking, rebooting and checking them.
wake a sleeping rigbin/rig-wake <rig>Sends a magic packet that wakes a sleeping rig, using its MAC address.
reboot a rigscripts/reboot-rig.sh <address>Reboots one rig after a 10 second countdown.
disk use on every rigscripts/check-disks.shShows disk use on every rig, over ssh.
rig listconfig/rigs.tomlOpens the list of rigs: name, address, MAC and the paths each stash takes.
add a rigdocs/adding-a-rig.mdOpens the steps to add a rig to config/rigs.toml.
stash
The stashes of each rig: snapshots of its important folders, pulled over rsync.
take a stash of one rigburrow stash <rig>Takes a stash of one rig now and prints where it was written.
take a stash of every rigburrow stash --all (or make stash-all)Takes a stash of every rig, one after another.
list a rig's stashesburrow stash list <rig>Prints the dated stashes kept for one rig.
restore a stashburrow restore <rig> --from <YYYY-MM-DD>Copies a dated stash back onto its rig; add --dry-run to see it first.
prune old stashesburrow stash prune --keep 8Removes old stashes, keeping the newest eight.
verify the newest stashscripts/verify-stash.sh <rig>Checks the newest stash of a rig is readable and not empty.
stash folder/srv/burrow/stashesOpens the folder that holds every stash, one folder per rig and one dated folder per stash.
restore by handdocs/internals/stash/format/restore-by-hand.mdOpens the steps to restore a stash with rsync when burrow itself is broken.
stash settingsconfig/burrow.toml [stash]Opens the stash settings: the root folder, rsync flags and how many to keep.
chores
The recurring jobs that cron runs, and when each one last ran.
nightly-stashburrow chores run nightly-stashStashes every rig, every night at 02:15.
disk-checkburrow chores run disk-checkWarns when a rig's root disk is over 85 percent, every six hours.
list choresburrow chores listPrints the name of each chore burrow knows.
run a chore nowburrow chores run <name>Runs one chore now and records its result.
last runsburrow chores statusPrints when each chore last finished and whether it worked.
chores pagehttp://127.0.0.1:8470/choresOpens the porch page with each chore's last run.
cron scheduledeploy/burrow.crontabHolds the cron lines that run nightly-stash and disk-check.
chores log/var/log/burrow/chores.logOpens the output of every chore run from cron.
last-run record/srv/burrow/state/last-run.jsonOpens the record of each chore's last run.
chores guidedocs/chores.mdOpens the guide to chores.
porch
The porch, burrow's web dashboard of rigs, stashes and chores, on port 8470.
start the porchburrow porchStarts the web server on 0.0.0.0:8470 and keeps it in the foreground.
open the porchhttp://127.0.0.1:8470Opens the dashboard of rigs in a browser; use a rig's IP from another machine.
chores pagehttp://127.0.0.1:8470/choresOpens each chore's last run.
one rig's stasheshttp://127.0.0.1:8470/stashes/<rig>Opens the stashes of one rig.
health checkhttp://127.0.0.1:8470/healthzReturns the ok reply when the porch is up.
porch servicedeploy/burrow-porch.serviceRuns the porch under systemd and restarts it when it fails.
porch log/var/log/burrow/porch.logOpens the porch's output.
metrics
The metrics containers: rig temperatures and disk use, collected and graphed.
start the metricsmake upStarts pulse, Prometheus and Grafana in the background.
stop the metricsmake downStops and removes the metrics containers.
Grafana graphshttp://127.0.0.1:3000Opens graphs of rig temperatures and disk use.
pulse metricshttp://127.0.0.1:9188/metricsReturns rig temperatures and disk use for Prometheus.
compose filedocker-compose.ymlDefines the three containers, their ports and their volumes.
pulse sourcepulse/pulse.pyOpens the code that exposes the metrics.
setup
Installing, configuring, testing and documenting burrow itself.
install burrowmake installCreates .venv, installs the burrow command into it, and makes the stash and log folders.
install the porch servicemake install-unitCopies the porch unit into systemd and starts it now and at every boot.
install the chores crontabcrontab deploy/burrow.crontabReplaces your whole crontab with the burrow chores; this drops the prune line.
install the weekly prunemake install-prune-cronAdds a weekly prune of old stashes to your crontab, Sundays at 04:40.
prune stashes nowmake prune-stashesRemoves old stashes, keeping the newest eight.
run the testsmake testRuns the test suite with pytest.
lintmake lintChecks burrow and its tests with ruff.
cleanmake cleanRemoves .venv, caches and build files.
settingsconfig/burrow.tomlOpens the settings: stash root, rsync flags, keep, chores state file, porch bind and ssh user.
secrets.env (copied from .env.example)Holds the SSH key path, the porch secret and the ntfy topic.
setup guidedocs/setup.mdOpens the steps to set up burrow on a host.
version and dependenciespyproject.tomlShows the package version and its dependencies.
readmeREADME.mdOpens the overview of burrow.
licenseLICENSEShows the MIT license.
helpers
Small shell scripts for one-off jobs; read the top of each before running it.
battery-reportscripts/battery-report.shReports the battery state.
cert-renewscripts/cert-renew.shRenews certificates.
check-disksscripts/check-disks.shShows disk use on every rig, over ssh.
dns-flushscripts/dns-flush.shFlushes the DNS cache.
du-stashesscripts/du-stashes.shShows how much space the stashes use.
export-choresscripts/export-chores.shExports the chores.
fan-curvescripts/fan-curve.shSets the fan curve.
gc-dockerscripts/gc-docker.shCleans up unused Docker data.
import-rigsscripts/import-rigs.shImports rigs.
list-portsscripts/list-ports.shLists the open ports.
mount-nasscripts/mount-nas.shMounts the NAS.
net-speedscripts/net-speed.shMeasures network speed.
pihole-updatescripts/pihole-update.shUpdates Pi-hole.
reboot-rigscripts/reboot-rig.shReboots one rig after a 10 second countdown.
rotate-logsscripts/rotate-logs.shRotates the logs.
seed-devscripts/seed-dev.shSeeds development data.
smart-reportscripts/smart-report.shReports SMART disk health.
ssh-keys-pushscripts/ssh-keys-push.shPushes SSH keys to the rigs.
sync-clockscripts/sync-clock.shSyncs the clock.
temp-checkscripts/temp-check.shChecks temperatures.
unmount-nasscripts/unmount-nas.shUnmounts the NAS.
update-rigsscripts/update-rigs.shUpdates the rigs.
ups-statusscripts/ups-status.shShows the UPS status.
verify-stashscripts/verify-stash.shChecks the newest stash of a rig is readable and not empty.
zfs-scrubscripts/zfs-scrub.shStarts a ZFS scrub.
Questions
  • Bare `burrow stash <rig>` takes a stash today, while the screen rule says a bare noun prints its screen. Recommendation: keep it as the take action (the README uses it) and list stashes with `burrow stash list <rig>`. Or should it print a rig screen, with take moved to `burrow stash take <rig>`?
  • The helpers screen holds 25 scripts, and I have read only 3. Recommendation: let me read the other 22 headers, then split helpers into groups by job (for example disks and temperatures, network, NAS and mounts, house services). Do you approve the split?
  • `crontab deploy/burrow.crontab` replaces the whole crontab and drops the weekly prune line that `make install-prune-cron` adds. Recommendation: move the prune line into deploy/burrow.crontab, so one install covers both. Approve?
  • The cron lines and the default `--config config/burrow.toml` are relative, and cron does not `cd /opt/burrow`. Recommendation: make the cron lines `cd /opt/burrow && ...`, and make the default config path absolute. Which do you want?
  • Are pulse's `read_temp` and `read_disk` still stubs returning 0.0? Recommendation: if so, the metrics screen should say the values are not real yet until they are filled in.
As phone screens

Home

What burrow looks after on your home-lab rigs, and where each part is.

rigsShows the rigs and whether each one answers.
›
stashShows the stash actions: take, list, restore and prune.
›
choresShows the recurring jobs and when each last ran.
›
porchShows the porch's pages and how to start it.
›
metricsShows the metrics containers and their graphs.
›
setupShows how to install, configure, test and document burrow.
›
helpersShows the helper scripts kept in scripts/.
›
‹ Home

rigs

The rigs burrow knows, and the tools for waking, rebooting and checking them.

wake a sleeping rigSends a magic packet that wakes a sleeping rig, using its MAC address.
›
reboot a rigReboots one rig after a 10 second countdown.
›
disk use on every rigShows disk use on every rig, over ssh.
›
rig listOpens the list of rigs: name, address, MAC and the paths each stash takes.
›
add a rigOpens the steps to add a rig to config/rigs.toml.
›
‹ Home

stash

The stashes of each rig: snapshots of its important folders, pulled over rsync.

take a stash of one rigTakes a stash of one rig now and prints where it was written.
›
take a stash of every rigTakes a stash of every rig, one after another.
›
list a rig's stashesPrints the dated stashes kept for one rig.
›
restore a stashCopies a dated stash back onto its rig; add --dry-run to see it first.
›
prune old stashesRemoves old stashes, keeping the newest eight.
›
verify the newest stashChecks the newest stash of a rig is readable and not empty.
›
stash folderOpens the folder that holds every stash, one folder per rig and one dated folder per stash.
›
restore by handOpens the steps to restore a stash with rsync when burrow itself is broken.
›
stash settingsOpens the stash settings: the root folder, rsync flags and how many to keep.
›
‹ Home

chores

The recurring jobs that cron runs, and when each one last ran.

nightly-stashStashes every rig, every night at 02:15.
›
disk-checkWarns when a rig's root disk is over 85 percent, every six hours.
›
list choresPrints the name of each chore burrow knows.
›
run a chore nowRuns one chore now and records its result.
›
last runsPrints when each chore last finished and whether it worked.
›
chores pageOpens the porch page with each chore's last run.
›
cron scheduleHolds the cron lines that run nightly-stash and disk-check.
›
chores logOpens the output of every chore run from cron.
›
last-run recordOpens the record of each chore's last run.
›
chores guideOpens the guide to chores.
›
‹ Home

porch

The porch, burrow's web dashboard of rigs, stashes and chores, on port 8470.

start the porchStarts the web server on 0.0.0.0:8470 and keeps it in the foreground.
›
open the porchOpens the dashboard of rigs in a browser; use a rig's IP from another machine.
›
chores pageOpens each chore's last run.
›
one rig's stashesOpens the stashes of one rig.
›
health checkReturns the ok reply when the porch is up.
›
porch serviceRuns the porch under systemd and restarts it when it fails.
›
porch logOpens the porch's output.
›
‹ Home

metrics

The metrics containers: rig temperatures and disk use, collected and graphed.

start the metricsStarts pulse, Prometheus and Grafana in the background.
›
stop the metricsStops and removes the metrics containers.
›
Grafana graphsOpens graphs of rig temperatures and disk use.
›
pulse metricsReturns rig temperatures and disk use for Prometheus.
›
compose fileDefines the three containers, their ports and their volumes.
›
pulse sourceOpens the code that exposes the metrics.
›
‹ Home

setup

Installing, configuring, testing and documenting burrow itself.

install burrowCreates .venv, installs the burrow command into it, and makes the stash and log folders.
›
install the porch serviceCopies the porch unit into systemd and starts it now and at every boot.
›
install the chores crontabReplaces your whole crontab with the burrow chores; this drops the prune line.
›
install the weekly pruneAdds a weekly prune of old stashes to your crontab, Sundays at 04:40.
›
prune stashes nowRemoves old stashes, keeping the newest eight.
›
run the testsRuns the test suite with pytest.
›
lintChecks burrow and its tests with ruff.
›
cleanRemoves .venv, caches and build files.
›
settingsOpens the settings: stash root, rsync flags, keep, chores state file, porch bind and ssh user.
›
secretsHolds the SSH key path, the porch secret and the ntfy topic.
›
setup guideOpens the steps to set up burrow on a host.
›
version and dependenciesShows the package version and its dependencies.
›
readmeOpens the overview of burrow.
›
licenseShows the MIT license.
›
‹ Home

helpers

Small shell scripts for one-off jobs; read the top of each before running it.

battery-reportReports the battery state.
›
cert-renewRenews certificates.
›
check-disksShows disk use on every rig, over ssh.
›
dns-flushFlushes the DNS cache.
›
du-stashesShows how much space the stashes use.
›
export-choresExports the chores.
›
fan-curveSets the fan curve.
›
gc-dockerCleans up unused Docker data.
›
import-rigsImports rigs.
›
list-portsLists the open ports.
›
mount-nasMounts the NAS.
›
net-speedMeasures network speed.
›
pihole-updateUpdates Pi-hole.
›
reboot-rigReboots one rig after a 10 second countdown.
›
rotate-logsRotates the logs.
›
seed-devSeeds development data.
›
smart-reportReports SMART disk health.
›
ssh-keys-pushPushes SSH keys to the rigs.
›
sync-clockSyncs the clock.
›
temp-checkChecks temperatures.
›
unmount-nasUnmounts the NAS.
›
update-rigsUpdates the rigs.
›
ups-statusShows the UPS status.
›
verify-stashChecks the newest stash of a rig is readable and not empty.
›
zfs-scrubStarts a ZFS scrub.
›
Raw answer
**Scenario** (reasoning from experience, not observed use): a home-lab owner checks whether a rig answers, whether last night's stash and chores ran, and how to put back a folder. Less often they set up a new rig or redeploy. Every choice below is judged against this.

**Inventory:** 6 CLI commands and groups (`rigs`, `stash`, `restore`, `chores`, `porch`), 10 make targets, 2 chores, 4 porch routes, 3 containers, 25 scripts plus `bin/rig-wake`, 4 docs, 3 config files, and the service unit and crontab.

**Judgment calls**
- The top screen has 7 groups, named by the README and code: rigs, stash, chores, porch, metrics, setup, helpers.
- `restore` sits under `stash`, so backing up and putting back share one screen. `restore-by-hand.md` sits there too.
- Groups use the CLI's own nouns. `burrow stash <rig>` takes a stash, so I did not create a per-rig screen (see question 1).
- For the 22 scripts I did not read, the "what" lines come from their file names only. Treat them as provisional.
- Items that appear on more than one screen are worded for each screen. Examples: `verify-stash.sh`, `reboot-rig.sh`, `check-disks.sh`.

**Findings to check**
- Bare `burrow stash` has no screen. It would try to take a stash with no rig. Shown here as `--help`.
- `make install-prune-cron` adds a weekly prune line to the user crontab. `crontab deploy/burrow.crontab` replaces the whole crontab, so it removes that line. The setup guide does not mention this.
- The `--config` default is the relative path `config/burrow.toml`, and the crontab lines do not `cd /opt/burrow`. Cron runs in the home directory, so the chores would probably fail to find the config. I have not run this to confirm it.
- `pulse` returns 0.0 for temperature and disk (`read_temp` and `read_disk` are stubs in this snapshot). The metrics rows describe the intent.
- Prometheus has no published port and no `prometheus.yml` in the dump.
- `.env.example` defines `BURROW_PORCH_SECRET`, but no code in the dump reads it, and the porch binds to `0.0.0.0` with no visible auth.
- I could not read `stash.py`, `rigs.py` or `chores.py` beyond what `cli.py` calls. Whether `prune` keeps N per rig or N in total is unverified.

```json
{"screens": [
  {"path": [], "sentence": "What burrow looks after on your home-lab rigs, and where each part is.", "rows": [
    {"name": "rigs", "form": "burrow rigs", "what": "Shows the rigs and whether each one answers."},
    {"name": "stash", "form": "burrow stash --help", "what": "Shows the stash actions: take, list, restore and prune."},
    {"name": "chores", "form": "burrow chores --help", "what": "Shows the recurring jobs and when each last ran."},
    {"name": "porch", "form": "burrow porch --help", "what": "Shows the porch's pages and how to start it."},
    {"name": "metrics", "form": "docker-compose.yml", "what": "Shows the metrics containers and their graphs."},
    {"name": "setup", "form": "Makefile", "what": "Shows how to install, configure, test and document burrow."},
    {"name": "helpers", "form": "scripts/", "what": "Shows the helper scripts kept in scripts/."}
  ]},
  {"path": ["rigs"], "sentence": "The rigs burrow knows, and the tools for waking, rebooting and checking them.", "rows": [
    {"name": "wake a sleeping rig", "form": "bin/rig-wake <rig>", "what": "Sends a magic packet that wakes a sleeping rig, using its MAC address."},
    {"name": "reboot a rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10 second countdown."},
    {"name": "disk use on every rig", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig, over ssh."},
    {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the list of rigs: name, address, MAC and the paths each stash takes."},
    {"name": "add a rig", "form": "docs/adding-a-rig.md", "what": "Opens the steps to add a rig to config/rigs.toml."}
  ]},
  {"path": ["stash"], "sentence": "The stashes of each rig: snapshots of its important folders, pulled over rsync.", "rows": [
    {"name": "take a stash of one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now and prints where it was written."},
    {"name": "take a stash of every rig", "form": "burrow stash --all (or make stash-all)", "what": "Takes a stash of every rig, one after another."},
    {"name": "list a rig's stashes", "form": "burrow stash list <rig>", "what": "Prints the dated stashes kept for one rig."},
    {"name": "restore a stash", "form": "burrow restore <rig> --from <YYYY-MM-DD>", "what": "Copies a dated stash back onto its rig; add --dry-run to see it first."},
    {"name": "prune old stashes", "form": "burrow stash prune --keep 8", "what": "Removes old stashes, keeping the newest eight."},
    {"name": "verify the newest stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks the newest stash of a rig is readable and not empty."},
    {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the folder that holds every stash, one folder per rig and one dated folder per stash."},
    {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Opens the steps to restore a stash with rsync when burrow itself is broken."},
    {"name": "stash settings", "form": "config/burrow.toml [stash]", "what": "Opens the stash settings: the root folder, rsync flags and how many to keep."}
  ]},
  {"path": ["chores"], "sentence": "The recurring jobs that cron runs, and when each one last ran.", "rows": [
    {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Stashes every rig, every night at 02:15."},
    {"name": "disk-check", "form": "burrow chores run disk-check", "what": "Warns when a rig's root disk is over 85 percent, every six hours."},
    {"name": "list chores", "form": "burrow chores list", "what": "Prints the name of each chore burrow knows."},
    {"name": "run a chore now", "form": "burrow chores run <name>", "what": "Runs one chore now and records its result."},
    {"name": "last runs", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
    {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the porch page with each chore's last run."},
    {"name": "cron schedule", "form": "deploy/burrow.crontab", "what": "Holds the cron lines that run nightly-stash and disk-check."},
    {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the output of every chore run from cron."},
    {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of each chore's last run."},
    {"name": "chores guide", "form": "docs/chores.md", "what": "Opens the guide to chores."}
  ]},
  {"path": ["porch"], "sentence": "The porch, burrow's web dashboard of rigs, stashes and chores, on port 8470.", "rows": [
    {"name": "start the porch", "form": "burrow porch", "what": "Starts the web server on 0.0.0.0:8470 and keeps it in the foreground."},
    {"name": "open the porch", "form": "http://127.0.0.1:8470", "what": "Opens the dashboard of rigs in a browser; use a rig's IP from another machine."},
    {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens each chore's last run."},
    {"name": "one rig's stashes", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens the stashes of one rig."},
    {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns the ok reply when the porch is up."},
    {"name": "porch service", "form": "deploy/burrow-porch.service", "what": "Runs the porch under systemd and restarts it when it fails."},
    {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the porch's output."}
  ]},
  {"path": ["metrics"], "sentence": "The metrics containers: rig temperatures and disk use, collected and graphed.", "rows": [
    {"name": "start the metrics", "form": "make up", "what": "Starts pulse, Prometheus and Grafana in the background."},
    {"name": "stop the metrics", "form": "make down", "what": "Stops and removes the metrics containers."},
    {"name": "Grafana graphs", "form": "http://127.0.0.1:3000", "what": "Opens graphs of rig temperatures and disk use."},
    {"name": "pulse metrics", "form": "http://127.0.0.1:9188/metrics", "what": "Returns rig temperatures and disk use for Prometheus."},
    {"name": "compose file", "form": "docker-compose.yml", "what": "Defines the three containers, their ports and their volumes."},
    {"name": "pulse source", "form": "pulse/pulse.py", "what": "Opens the code that exposes the metrics."}
  ]},
  {"path": ["setup"], "sentence": "Installing, configuring, testing and documenting burrow itself.", "rows": [
    {"name": "install burrow", "form": "make install", "what": "Creates .venv, installs the burrow command into it, and makes the stash and log folders."},
    {"name": "install the porch service", "form": "make install-unit", "what": "Copies the porch unit into systemd and starts it now and at every boot."},
    {"name": "install the chores crontab", "form": "crontab deploy/burrow.crontab", "what": "Replaces your whole crontab with the burrow chores; this drops the prune line."},
    {"name": "install the weekly prune", "form": "make install-prune-cron", "what": "Adds a weekly prune of old stashes to your crontab, Sundays at 04:40."},
    {"name": "prune stashes now", "form": "make prune-stashes", "what": "Removes old stashes, keeping the newest eight."},
    {"name": "run the tests", "form": "make test", "what": "Runs the test suite with pytest."},
    {"name": "lint", "form": "make lint", "what": "Checks burrow and its tests with ruff."},
    {"name": "clean", "form": "make clean", "what": "Removes .venv, caches and build files."},
    {"name": "settings", "form": "config/burrow.toml", "what": "Opens the settings: stash root, rsync flags, keep, chores state file, porch bind and ssh user."},
    {"name": "secrets", "form": ".env (copied from .env.example)", "what": "Holds the SSH key path, the porch secret and the ntfy topic."},
    {"name": "setup guide", "form": "docs/setup.md", "what": "Opens the steps to set up burrow on a host."},
    {"name": "version and dependencies", "form": "pyproject.toml", "what": "Shows the package version and its dependencies."},
    {"name": "readme", "form": "README.md", "what": "Opens the overview of burrow."},
    {"name": "license", "form": "LICENSE", "what": "Shows the MIT license."}
  ]},
  {"path": ["helpers"], "sentence": "Small shell scripts for one-off jobs; read the top of each before running it.", "rows": [
    {"name": "battery-report", "form": "scripts/battery-report.sh", "what": "Reports the battery state."},
    {"name": "cert-renew", "form": "scripts/cert-renew.sh", "what": "Renews certificates."},
    {"name": "check-disks", "form": "scripts/check-disks.sh", "what": "Shows disk use on every rig, over ssh."},
    {"name": "dns-flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache."},
    {"name": "du-stashes", "form": "scripts/du-stashes.sh", "what": "Shows how much space the stashes use."},
    {"name": "export-chores", "form": "scripts/export-chores.sh", "what": "Exports the chores."},
    {"name": "fan-curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan curve."},
    {"name": "gc-docker", "form": "scripts/gc-docker.sh", "what": "Cleans up unused Docker data."},
    {"name": "import-rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs."},
    {"name": "list-ports", "form": "scripts/list-ports.sh", "what": "Lists the open ports."},
    {"name": "mount-nas", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS."},
    {"name": "net-speed", "form": "scripts/net-speed.sh", "what": "Measures network speed."},
    {"name": "pihole-update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole."},
    {"name": "reboot-rig", "form": "scripts/reboot-rig.sh", "what": "Reboots one rig after a 10 second countdown."},
    {"name": "rotate-logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs."},
    {"name": "seed-dev", "form": "scripts/seed-dev.sh", "what": "Seeds development data."},
    {"name": "smart-report", "form": "scripts/smart-report.sh", "what": "Reports SMART disk health."},
    {"name": "ssh-keys-push", "form": "scripts/ssh-keys-push.sh", "what": "Pushes SSH keys to the rigs."},
    {"name": "sync-clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock."},
    {"name": "temp-check", "form": "scripts/temp-check.sh", "what": "Checks temperatures."},
    {"name": "unmount-nas", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS."},
    {"name": "update-rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs."},
    {"name": "ups-status", "form": "scripts/ups-status.sh", "what": "Shows the UPS status."},
    {"name": "verify-stash", "form": "scripts/verify-stash.sh", "what": "Checks the newest stash of a rig is readable and not empty."},
    {"name": "zfs-scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub."}
  ]}
 ],
 "questions": [
  "Bare `burrow stash <rig>` takes a stash today, while the screen rule says a bare noun prints its screen. Recommendation: keep it as the take action (the README uses it) and list stashes with `burrow stash list <rig>`. Or should it print a rig screen, with take moved to `burrow stash take <rig>`?",
  "The helpers screen holds 25 scripts, and I have read only 3. Recommendation: let me read the other 22 headers, then split helpers into groups by job (for example disks and temperatures, network, NAS and mounts, house services). Do you approve the split?",
  "`crontab deploy/burrow.crontab` replaces the whole crontab and drops the weekly prune line that `make install-prune-cron` adds. Recommendation: move the prune line into deploy/burrow.crontab, so one install covers both. Approve?",
  "The cron lines and the default `--config config/burrow.toml` are relative, and cron does not `cd /opt/burrow`. Recommendation: make the cron lines `cd /opt/burrow && ...`, and make the default config path absolute. Which do you want?",
  "Are pulse's `read_temp` and `read_disk` still stubs returning 0.0? Recommendation: if so, the metrics screen should say the values are not real yet until they are filled in."
 ]}
```

screen-decomposition, final · run 5 exit=0 seconds=145 · prompt

P1 Recall: 0.9P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 8P6 Own words: 1.0P7 Splits asked: askedP8 Worded per screen: 0
As terminal help
The burrow map: everything burrow looks after in the home lab, grouped by what you are trying to do.
rigsburrow rigsOpens the rigs screen: each rig and whether it answers.
stashburrow stash (bare form to add; today it errors)Opens the stash screen: taking, listing, pruning and restoring stashes.
choresburrow choresOpens the chores screen: the recurring jobs, running them and their status.
porchburrow porch (today this starts the server; see question 1)Opens the porch screen: the dashboard pages and the service behind them.
metricsburrow metrics (new)Opens the metrics screen: the graphs of rig temperatures and disk use, and the containers behind them.
scriptsburrow scripts (new; today the scripts/ folder)Opens the scripts screen: the helper scripts in scripts/.
setupburrow setup (new)Opens the setup screen: installing burrow, its service and schedule, and its settings.
developmentburrow development (new)Opens the development screen: tests, lint, clean and the source.
rigs
The rigs burrow looks after, each with its address and whether it answers.
attic192.168.1.20Shows attic at 192.168.1.20 and whether it answers.
cellar192.168.1.21Shows cellar at 192.168.1.21 and whether it answers.
garden192.168.1.22Shows garden at 192.168.1.22 and whether it answers.
wakebin/rig-wake <rig>Sends a wake packet to a sleeping rig, using its MAC from rigs.toml.
rig listconfig/rigs.tomlOpens the rig list, where each rig's address, MAC and paths are set.
adding a rigdocs/adding-a-rig.mdReads the steps to add a rig and check that it answers.
stash
The stashes burrow keeps of each rig, and how to take, list, prune and restore them.
take one rigburrow stash <rig>Takes a stash of one rig now and prints where it went.
take every rigburrow stash --all (or make stash-all)Takes a stash of every rig at once.
list one rig's stashesburrow stash list <rig>Lists the dated stashes of one rig.
pruneburrow stash prune --keep 8 (or make prune-stashes)Removes old stashes, keeping the newest 8 by default.
weekly prunemake install-prune-cronInstalls the weekly prune into crontab, Sundays at 04:40.
restoreburrow restore <rig> --from YYYY-MM-DDCopies a stash back onto its rig; --dry-run copies nothing.
stash folder/srv/burrow/stashesOpens the stash folder: one folder per rig, one dated folder per stash.
restore by handdocs/internals/stash/format/restore-by-hand.mdReads how to restore a stash by hand, for when burrow itself is broken.
chores
The recurring jobs burrow runs from cron, with their logs and last runs.
nightly-stashburrow chores run nightly-stashTakes a stash of every rig; cron runs it at 02:15 each night.
disk-checkburrow chores run disk-checkWarns when a rig's root disk is over 85%; cron runs it every 6 hours.
run a chore by nameburrow chores run <name>Runs one chore now and records its result.
listburrow chores listLists the names of the chores burrow knows.
statusburrow chores statusPrints when each chore last finished and whether it worked.
scheduledeploy/burrow.crontabOpens the schedule that runs the chores from cron.
chores log/var/log/burrow/chores.logOpens the log where the scheduled chore runs write their output.
last-run record/srv/burrow/state/last-run.jsonOpens the record of each chore's last run.
chores docdocs/chores.mdReads how chores work and how to add one.
porch
The porch, burrow's web dashboard on port 8470, with its pages, its log and the service that runs it.
run the porchburrow porch --bind ADDR:PORTStarts the porch server in the foreground, on the address in burrow.toml unless --bind is given.
rigs pagehttp://127.0.0.1:8470Opens the porch's front page, listing the rigs.
chores pagehttp://127.0.0.1:8470/choresOpens the chores page, with each chore's last run.
stashes pagehttp://127.0.0.1:8470/stashes/<rig>Opens one rig's stashes on the porch.
health checkhttp://127.0.0.1:8470/healthzReturns ok: true when the porch is up.
service unitdeploy/burrow-porch.serviceOpens the systemd unit that runs the porch and restarts it on failure.
porch log/var/log/burrow/porch.logOpens the porch's log, where its output goes.
metrics
The metrics burrow collects for graphs: rig temperatures and disk use, and the containers that hold them.
start the containersmake upStarts the metrics containers in the background.
stop the containersmake downStops the metrics containers.
Grafanahttp://127.0.0.1:3000Opens Grafana, with graphs of rig temperatures and disk use.
pulsehttp://127.0.0.1:9188/metricsReturns the raw temperature and disk numbers pulse exposes for Prometheus.
Prometheusdocker-compose.ymlKeeps 30 days of metrics; no port is published for it.
compose filedocker-compose.ymlOpens the file that defines the three containers and how they start.
scripts
The helper scripts in scripts/, each a small job run by hand.
battery-reportscripts/battery-report.shPrints a battery report (by name; not read).
cert-renewscripts/cert-renew.shRenews the certificates (by name; not read).
check-disksscripts/check-disks.shPrints disk use on every rig in rigs.toml.
dns-flushscripts/dns-flush.shFlushes the DNS cache (by name; not read).
du-stashesscripts/du-stashes.shPrints how much space the stashes use (by name; not read).
export-choresscripts/export-chores.shExports the chores (by name; not read).
fan-curvescripts/fan-curve.shSets the fan curve (by name; not read).
gc-dockerscripts/gc-docker.shCleans up unused Docker data (by name; not read).
import-rigsscripts/import-rigs.shImports rigs into rigs.toml (by name; not read).
list-portsscripts/list-ports.shLists the open ports (by name; not read).
mount-nasscripts/mount-nas.shMounts the NAS (by name; not read).
net-speedscripts/net-speed.shMeasures network speed (by name; not read).
pihole-updatescripts/pihole-update.shUpdates Pi-hole (by name; not read).
reboot-rigscripts/reboot-rig.sh <address>Reboots one rig after a 10-second countdown.
rotate-logsscripts/rotate-logs.shRotates the logs (by name; not read).
seed-devscripts/seed-dev.shFills a development setup with sample data (by name; not read).
smart-reportscripts/smart-report.shPrints a SMART disk-health report (by name; not read).
ssh-keys-pushscripts/ssh-keys-push.shPushes SSH keys to the rigs (by name; not read).
sync-clockscripts/sync-clock.shSyncs the clock on the rigs (by name; not read).
temp-checkscripts/temp-check.shChecks rig temperatures (by name; not read).
unmount-nasscripts/unmount-nas.shUnmounts the NAS (by name; not read).
update-rigsscripts/update-rigs.shUpdates the rigs (by name; not read).
ups-statusscripts/ups-status.shPrints the UPS status (by name; not read).
verify-stashscripts/verify-stash.sh <rig>Checks that the newest stash of a rig is readable and not empty.
zfs-scrubscripts/zfs-scrub.shStarts a ZFS scrub (by name; not read).
setup
Installing burrow and wiring it up: the install, the porch service, the chores schedule and the settings.
installmake installCreates the virtualenv in .venv, installs burrow into it, and makes the stash folders.
porch servicemake install-unitInstalls the porch service into systemd and starts it now.
chores schedulecrontab deploy/burrow.crontabInstalls the chores schedule into crontab, replacing the whole crontab (see question 4).
settingsconfig/burrow.tomlOpens the settings: stash root and keep count, porch address, SSH user.
secrets template.env.exampleOpens the template for .env; copy it to .env and fill it in.
setup docdocs/setup.mdReads the first-time setup steps and how to check them.
development
Tests, lint, clean-up and the source code, for changing burrow.
testsmake testRuns the test suite with pytest.
test filestests/Opens the test files, one per module.
lintmake lintChecks burrow and tests with ruff, without changing them.
cleanmake cleanDeletes the virtualenv, caches and build output.
sourceburrow/Opens the burrow package: the CLI, config, stash, chores, rigs and porch.
pulsepulse/pulse.pyOpens pulse, the program that exposes rig temperatures and disk use.
Questions
  • burrow porch starts the server today, and the systemd unit calls it. Move the server to 'burrow porch run', make bare 'burrow porch' print the porch screen, and update ExecStart in the unit? Recommended: yes.
  • The scripts screen lists 25 scripts flat. May I read the 22 I only know by name, then split the list into four job screens (disks and power; network and DNS; storage and stashes; rigs and setup)? Recommended: yes, read first, then split.
  • Move reboot-reboot-rig and check-disks to the rigs screen, since that is where a user looks when a rig is down? Recommended: yes.
  • crontab deploy/burrow.crontab replaces the whole crontab and drops the weekly prune line from make install-prune-cron. Add the prune line to deploy/burrow.crontab and drop install-prune-cron? Recommended: yes.
  • Approve the top screen with its eight groups (rigs, stash, chores, porch, metrics, scripts, setup, development) and their new command names (burrow metrics, burrow scripts, burrow setup, burrow development)? Recommended: yes.
As phone screens

Home

The burrow map: everything burrow looks after in the home lab, grouped by what you are trying to do.

rigsOpens the rigs screen: each rig and whether it answers.
›
stashOpens the stash screen: taking, listing, pruning and restoring stashes.
›
choresOpens the chores screen: the recurring jobs, running them and their status.
›
porchOpens the porch screen: the dashboard pages and the service behind them.
›
metricsOpens the metrics screen: the graphs of rig temperatures and disk use, and the containers behind them.
›
scriptsOpens the scripts screen: the helper scripts in scripts/.
›
setupOpens the setup screen: installing burrow, its service and schedule, and its settings.
›
developmentOpens the development screen: tests, lint, clean and the source.
›
‹ Home

rigs

The rigs burrow looks after, each with its address and whether it answers.

atticShows attic at 192.168.1.20 and whether it answers.
›
cellarShows cellar at 192.168.1.21 and whether it answers.
›
gardenShows garden at 192.168.1.22 and whether it answers.
›
wakeSends a wake packet to a sleeping rig, using its MAC from rigs.toml.
›
rig listOpens the rig list, where each rig's address, MAC and paths are set.
›
adding a rigReads the steps to add a rig and check that it answers.
›
‹ Home

stash

The stashes burrow keeps of each rig, and how to take, list, prune and restore them.

take one rigTakes a stash of one rig now and prints where it went.
›
take every rigTakes a stash of every rig at once.
›
list one rig's stashesLists the dated stashes of one rig.
›
pruneRemoves old stashes, keeping the newest 8 by default.
›
weekly pruneInstalls the weekly prune into crontab, Sundays at 04:40.
›
restoreCopies a stash back onto its rig; --dry-run copies nothing.
›
stash folderOpens the stash folder: one folder per rig, one dated folder per stash.
›
restore by handReads how to restore a stash by hand, for when burrow itself is broken.
›
‹ Home

chores

The recurring jobs burrow runs from cron, with their logs and last runs.

nightly-stashTakes a stash of every rig; cron runs it at 02:15 each night.
›
disk-checkWarns when a rig's root disk is over 85%; cron runs it every 6 hours.
›
run a chore by nameRuns one chore now and records its result.
›
listLists the names of the chores burrow knows.
›
statusPrints when each chore last finished and whether it worked.
›
scheduleOpens the schedule that runs the chores from cron.
›
chores logOpens the log where the scheduled chore runs write their output.
›
last-run recordOpens the record of each chore's last run.
›
chores docReads how chores work and how to add one.
›
‹ Home

porch

The porch, burrow's web dashboard on port 8470, with its pages, its log and the service that runs it.

run the porchStarts the porch server in the foreground, on the address in burrow.toml unless --bind is given.
›
rigs pageOpens the porch's front page, listing the rigs.
›
chores pageOpens the chores page, with each chore's last run.
›
stashes pageOpens one rig's stashes on the porch.
›
health checkReturns ok: true when the porch is up.
›
service unitOpens the systemd unit that runs the porch and restarts it on failure.
›
porch logOpens the porch's log, where its output goes.
›
‹ Home

metrics

The metrics burrow collects for graphs: rig temperatures and disk use, and the containers that hold them.

start the containersStarts the metrics containers in the background.
›
stop the containersStops the metrics containers.
›
GrafanaOpens Grafana, with graphs of rig temperatures and disk use.
›
pulseReturns the raw temperature and disk numbers pulse exposes for Prometheus.
›
PrometheusKeeps 30 days of metrics; no port is published for it.
›
compose fileOpens the file that defines the three containers and how they start.
›
‹ Home

scripts

The helper scripts in scripts/, each a small job run by hand.

battery-reportPrints a battery report (by name; not read).
›
cert-renewRenews the certificates (by name; not read).
›
check-disksPrints disk use on every rig in rigs.toml.
›
dns-flushFlushes the DNS cache (by name; not read).
›
du-stashesPrints how much space the stashes use (by name; not read).
›
export-choresExports the chores (by name; not read).
›
fan-curveSets the fan curve (by name; not read).
›
gc-dockerCleans up unused Docker data (by name; not read).
›
import-rigsImports rigs into rigs.toml (by name; not read).
›
list-portsLists the open ports (by name; not read).
›
mount-nasMounts the NAS (by name; not read).
›
net-speedMeasures network speed (by name; not read).
›
pihole-updateUpdates Pi-hole (by name; not read).
›
reboot-rigReboots one rig after a 10-second countdown.
›
rotate-logsRotates the logs (by name; not read).
›
seed-devFills a development setup with sample data (by name; not read).
›
smart-reportPrints a SMART disk-health report (by name; not read).
›
ssh-keys-pushPushes SSH keys to the rigs (by name; not read).
›
sync-clockSyncs the clock on the rigs (by name; not read).
›
temp-checkChecks rig temperatures (by name; not read).
›
unmount-nasUnmounts the NAS (by name; not read).
›
update-rigsUpdates the rigs (by name; not read).
›
ups-statusPrints the UPS status (by name; not read).
›
verify-stashChecks that the newest stash of a rig is readable and not empty.
›
zfs-scrubStarts a ZFS scrub (by name; not read).
›
‹ Home

setup

Installing burrow and wiring it up: the install, the porch service, the chores schedule and the settings.

installCreates the virtualenv in .venv, installs burrow into it, and makes the stash folders.
›
porch serviceInstalls the porch service into systemd and starts it now.
›
chores scheduleInstalls the chores schedule into crontab, replacing the whole crontab (see question 4).
›
settingsOpens the settings: stash root and keep count, porch address, SSH user.
›
secrets templateOpens the template for .env; copy it to .env and fill it in.
›
setup docReads the first-time setup steps and how to check them.
›
‹ Home

development

Tests, lint, clean-up and the source code, for changing burrow.

testsRuns the test suite with pytest.
›
test filesOpens the test files, one per module.
›
lintChecks burrow and tests with ruff, without changing them.
›
cleanDeletes the virtualenv, caches and build output.
›
sourceOpens the burrow package: the CLI, config, stash, chores, rigs and porch.
›
pulseOpens pulse, the program that exposes rig temperatures and disk use.
›
Raw answer
## Scenario

Reasoning from experience, from the README and the cron setup, not observed use: the owner runs three home-lab rigs. They reach for burrow when a rig stops answering, a chore reports a failure, a file needs a stash restored, or they want to see the porch or Grafana graphs. They usually come from a shell, often in a hurry.

## Inventory

- **`burrow/cli.py`:** `rigs`, `stash [rig]`, `stash --all`, `stash list`, `stash prune`, `restore`, `chores list|run|status`, `porch`.
- **`Makefile`:** `install`, `install-unit`, `up`, `down`, `test`, `lint`, `stash-all`, `prune-stashes`, `install-prune-cron`, `clean`.
- **`bin/rig-wake`** and **`scripts/`** (25 shell helpers).
- **`burrow/porch/app.py`:** `/`, `/chores`, `/stashes/<rig>`, `/healthz`, on port 8470.
- **`pulse/pulse.py`:** `/metrics` on port 9188. **`docker-compose.yml`:** pulse, Prometheus, Grafana (port 3000).
- **`config/`:** `burrow.toml`, `rigs.toml` (attic, cellar, garden), `.env.example`.
- **`deploy/`:** `burrow-porch.service`, `burrow.crontab`.
- **Docs:** `setup.md`, `adding-a-rig.md`, `chores.md`, `internals/stash/format/restore-by-hand.md`.
- **Live state:** rig up/down, `/srv/burrow/stashes/`, `/srv/burrow/state/last-run.json`, `/var/log/burrow/*.log`.
- **Tests:** `tests/`.

## Screen tree

```
burrow map
├── rigs
├── stash
├── chores
├── porch
├── metrics
├── scripts
├── setup
└── development
```

The full screens, with paths, sentences and rows, are in the JSON block at the end.

## Questions for you

1. **`burrow porch` is a name clash.** Today it starts the server, and the systemd unit calls it. A bare noun is meant to print its screen. **Recommendation:** move the server to `burrow porch run`, make bare `burrow porch` print the porch screen, and update `ExecStart` in the unit. That means re-running `make install-unit`.
2. **The scripts screen is a flat list of 25.** I could only read three of them (`check-disks`, `reboot-rig`, `verify-stash`); the other 22 are described from their names alone, and each row says so. **Recommendation:** let me read the 22 before the help text is written, then split the list by job into four screens: disks and power (`check-disks`, `smart-report`, `temp-check`, `fan-curve`, `ups-status`, `battery-report`, `zfs-scrub`); network and DNS (`net-speed`, `list-ports`, `dns-flush`, `pihole-update`, `cert-renew`); storage and stashes (`mount-nas`, `unmount-nas`, `du-stashes`, `verify-stash`, `gc-docker`, `rotate-logs`); rigs and setup (`update-rigs`, `sync-clock`, `ssh-keys-push`, `import-rigs`, `export-chores`, `seed-dev`). I won't split without your go-ahead.
3. **Where do `reboot-rig` and `check-disks` belong?** When a rig is down, the owner will look under `rigs`. **Recommendation:** move both to the rigs screen, with `reboot-rig` and `check-disks` removed from the scripts list so each appears once.
4. **The crontab install overwrites the prune job.** `crontab deploy/burrow.crontab` replaces the whole crontab, which drops the weekly line that `make install-prune-cron` adds. **Recommendation:** add the prune line to `deploy/burrow.crontab` so there is one schedule file, then drop `install-prune-cron`.
5. **Approve the top screen.** It has eight groups. Four are new screens (`setup`, `metrics`, `scripts`, `development`), and `porch` and `stash` need their bare forms to work. **Recommendation:** approve the eight as listed, with `burrow <group>` as the command for each.

## Judgment calls

- **LICENSE is left off.** It isn't something anyone reaches for a job.
- **`.venv` is left off.** It is reached only through `burrow` and `make`.
- **The Dockerfile is folded into the compose row.** Compose builds it, so nobody reaches it on its own.
- **Each doc sits on the one screen where it's used.** `chores.md` is on chores, `setup.md` on setup, `adding-a-rig.md` on rigs, and `restore-by-hand.md` on stash. A separate docs group would make a ninth top-level group.
- **`rigs.toml` is on the rigs screen, not setup,** so each thing is in one place.
- **Rig rows should come from `config/rigs.toml`,** not from typed names (principle 10). A new rig such as `shed` would then appear on its own. The three names here are copied from the dump.
- **Bare `burrow stash` errors today,** because `rigs.get` receives no rig. The map assumes it prints the stash screen, which needs a code change.
- **Grafana graphs will show zeros.** `read_temp` and `read_disk` in `pulse.py` return `0.0`. The metrics rows are listed as they are, and this is flagged here.
- **Some `.env` and config settings aren't read by any code in the dump.** `BURROW_PORCH_SECRET`, `BURROW_NTFY_TOPIC` and `notify = "ntfy"` are listed only as template and config entries. I haven't claimed they work.
- **The porch rows use `127.0.0.1`.** The README says to use the rig's LAN IP from other machines.
- **Install-time items are on setup, and runtime items are on their own screens.** The `crontab` install is on setup, and the schedule file is on chores, each worded for its reason.

```json
{"screens": [
 {"path": [], "sentence": "The burrow map: everything burrow looks after in the home lab, grouped by what you are trying to do.", "rows": [
  {"name": "rigs", "form": "burrow rigs", "what": "Opens the rigs screen: each rig and whether it answers."},
  {"name": "stash", "form": "burrow stash (bare form to add; today it errors)", "what": "Opens the stash screen: taking, listing, pruning and restoring stashes."},
  {"name": "chores", "form": "burrow chores", "what": "Opens the chores screen: the recurring jobs, running them and their status."},
  {"name": "porch", "form": "burrow porch (today this starts the server; see question 1)", "what": "Opens the porch screen: the dashboard pages and the service behind them."},
  {"name": "metrics", "form": "burrow metrics (new)", "what": "Opens the metrics screen: the graphs of rig temperatures and disk use, and the containers behind them."},
  {"name": "scripts", "form": "burrow scripts (new; today the scripts/ folder)", "what": "Opens the scripts screen: the helper scripts in scripts/."},
  {"name": "setup", "form": "burrow setup (new)", "what": "Opens the setup screen: installing burrow, its service and schedule, and its settings."},
  {"name": "development", "form": "burrow development (new)", "what": "Opens the development screen: tests, lint, clean and the source."}
 ]},
 {"path": ["rigs"], "sentence": "The rigs burrow looks after, each with its address and whether it answers.", "rows": [
  {"name": "attic", "form": "192.168.1.20", "what": "Shows attic at 192.168.1.20 and whether it answers."},
  {"name": "cellar", "form": "192.168.1.21", "what": "Shows cellar at 192.168.1.21 and whether it answers."},
  {"name": "garden", "form": "192.168.1.22", "what": "Shows garden at 192.168.1.22 and whether it answers."},
  {"name": "wake", "form": "bin/rig-wake <rig>", "what": "Sends a wake packet to a sleeping rig, using its MAC from rigs.toml."},
  {"name": "rig list", "form": "config/rigs.toml", "what": "Opens the rig list, where each rig's address, MAC and paths are set."},
  {"name": "adding a rig", "form": "docs/adding-a-rig.md", "what": "Reads the steps to add a rig and check that it answers."}
 ]},
 {"path": ["stash"], "sentence": "The stashes burrow keeps of each rig, and how to take, list, prune and restore them.", "rows": [
  {"name": "take one rig", "form": "burrow stash <rig>", "what": "Takes a stash of one rig now and prints where it went."},
  {"name": "take every rig", "form": "burrow stash --all (or make stash-all)", "what": "Takes a stash of every rig at once."},
  {"name": "list one rig's stashes", "form": "burrow stash list <rig>", "what": "Lists the dated stashes of one rig."},
  {"name": "prune", "form": "burrow stash prune --keep 8 (or make prune-stashes)", "what": "Removes old stashes, keeping the newest 8 by default."},
  {"name": "weekly prune", "form": "make install-prune-cron", "what": "Installs the weekly prune into crontab, Sundays at 04:40."},
  {"name": "restore", "form": "burrow restore <rig> --from YYYY-MM-DD", "what": "Copies a stash back onto its rig; --dry-run copies nothing."},
  {"name": "stash folder", "form": "/srv/burrow/stashes", "what": "Opens the stash folder: one folder per rig, one dated folder per stash."},
  {"name": "restore by hand", "form": "docs/internals/stash/format/restore-by-hand.md", "what": "Reads how to restore a stash by hand, for when burrow itself is broken."}
 ]},
 {"path": ["chores"], "sentence": "The recurring jobs burrow runs from cron, with their logs and last runs.", "rows": [
  {"name": "nightly-stash", "form": "burrow chores run nightly-stash", "what": "Takes a stash of every rig; cron runs it at 02:15 each night."},
  {"name": "disk-check", "form": "burrow chores run disk-check", "what": "Warns when a rig's root disk is over 85%; cron runs it every 6 hours."},
  {"name": "run a chore by name", "form": "burrow chores run <name>", "what": "Runs one chore now and records its result."},
  {"name": "list", "form": "burrow chores list", "what": "Lists the names of the chores burrow knows."},
  {"name": "status", "form": "burrow chores status", "what": "Prints when each chore last finished and whether it worked."},
  {"name": "schedule", "form": "deploy/burrow.crontab", "what": "Opens the schedule that runs the chores from cron."},
  {"name": "chores log", "form": "/var/log/burrow/chores.log", "what": "Opens the log where the scheduled chore runs write their output."},
  {"name": "last-run record", "form": "/srv/burrow/state/last-run.json", "what": "Opens the record of each chore's last run."},
  {"name": "chores doc", "form": "docs/chores.md", "what": "Reads how chores work and how to add one."}
 ]},
 {"path": ["porch"], "sentence": "The porch, burrow's web dashboard on port 8470, with its pages, its log and the service that runs it.", "rows": [
  {"name": "run the porch", "form": "burrow porch --bind ADDR:PORT", "what": "Starts the porch server in the foreground, on the address in burrow.toml unless --bind is given."},
  {"name": "rigs page", "form": "http://127.0.0.1:8470", "what": "Opens the porch's front page, listing the rigs."},
  {"name": "chores page", "form": "http://127.0.0.1:8470/chores", "what": "Opens the chores page, with each chore's last run."},
  {"name": "stashes page", "form": "http://127.0.0.1:8470/stashes/<rig>", "what": "Opens one rig's stashes on the porch."},
  {"name": "health check", "form": "http://127.0.0.1:8470/healthz", "what": "Returns ok: true when the porch is up."},
  {"name": "service unit", "form": "deploy/burrow-porch.service", "what": "Opens the systemd unit that runs the porch and restarts it on failure."},
  {"name": "porch log", "form": "/var/log/burrow/porch.log", "what": "Opens the porch's log, where its output goes."}
 ]},
 {"path": ["metrics"], "sentence": "The metrics burrow collects for graphs: rig temperatures and disk use, and the containers that hold them.", "rows": [
  {"name": "start the containers", "form": "make up", "what": "Starts the metrics containers in the background."},
  {"name": "stop the containers", "form": "make down", "what": "Stops the metrics containers."},
  {"name": "Grafana", "form": "http://127.0.0.1:3000", "what": "Opens Grafana, with graphs of rig temperatures and disk use."},
  {"name": "pulse", "form": "http://127.0.0.1:9188/metrics", "what": "Returns the raw temperature and disk numbers pulse exposes for Prometheus."},
  {"name": "Prometheus", "form": "docker-compose.yml", "what": "Keeps 30 days of metrics; no port is published for it."},
  {"name": "compose file", "form": "docker-compose.yml", "what": "Opens the file that defines the three containers and how they start."}
 ]},
 {"path": ["scripts"], "sentence": "The helper scripts in scripts/, each a small job run by hand.", "rows": [
  {"name": "battery-report", "form": "scripts/battery-report.sh", "what": "Prints a battery report (by name; not read)."},
  {"name": "cert-renew", "form": "scripts/cert-renew.sh", "what": "Renews the certificates (by name; not read)."},
  {"name": "check-disks", "form": "scripts/check-disks.sh", "what": "Prints disk use on every rig in rigs.toml."},
  {"name": "dns-flush", "form": "scripts/dns-flush.sh", "what": "Flushes the DNS cache (by name; not read)."},
  {"name": "du-stashes", "form": "scripts/du-stashes.sh", "what": "Prints how much space the stashes use (by name; not read)."},
  {"name": "export-chores", "form": "scripts/export-chores.sh", "what": "Exports the chores (by name; not read)."},
  {"name": "fan-curve", "form": "scripts/fan-curve.sh", "what": "Sets the fan curve (by name; not read)."},
  {"name": "gc-docker", "form": "scripts/gc-docker.sh", "what": "Cleans up unused Docker data (by name; not read)."},
  {"name": "import-rigs", "form": "scripts/import-rigs.sh", "what": "Imports rigs into rigs.toml (by name; not read)."},
  {"name": "list-ports", "form": "scripts/list-ports.sh", "what": "Lists the open ports (by name; not read)."},
  {"name": "mount-nas", "form": "scripts/mount-nas.sh", "what": "Mounts the NAS (by name; not read)."},
  {"name": "net-speed", "form": "scripts/net-speed.sh", "what": "Measures network speed (by name; not read)."},
  {"name": "pihole-update", "form": "scripts/pihole-update.sh", "what": "Updates Pi-hole (by name; not read)."},
  {"name": "reboot-rig", "form": "scripts/reboot-rig.sh <address>", "what": "Reboots one rig after a 10-second countdown."},
  {"name": "rotate-logs", "form": "scripts/rotate-logs.sh", "what": "Rotates the logs (by name; not read)."},
  {"name": "seed-dev", "form": "scripts/seed-dev.sh", "what": "Fills a development setup with sample data (by name; not read)."},
  {"name": "smart-report", "form": "scripts/smart-report.sh", "what": "Prints a SMART disk-health report (by name; not read)."},
  {"name": "ssh-keys-push", "form": "scripts/ssh-keys-push.sh", "what": "Pushes SSH keys to the rigs (by name; not read)."},
  {"name": "sync-clock", "form": "scripts/sync-clock.sh", "what": "Syncs the clock on the rigs (by name; not read)."},
  {"name": "temp-check", "form": "scripts/temp-check.sh", "what": "Checks rig temperatures (by name; not read)."},
  {"name": "unmount-nas", "form": "scripts/unmount-nas.sh", "what": "Unmounts the NAS (by name; not read)."},
  {"name": "update-rigs", "form": "scripts/update-rigs.sh", "what": "Updates the rigs (by name; not read)."},
  {"name": "ups-status", "form": "scripts/ups-status.sh", "what": "Prints the UPS status (by name; not read)."},
  {"name": "verify-stash", "form": "scripts/verify-stash.sh <rig>", "what": "Checks that the newest stash of a rig is readable and not empty."},
  {"name": "zfs-scrub", "form": "scripts/zfs-scrub.sh", "what": "Starts a ZFS scrub (by name; not read)."}
 ]},
 {"path": ["setup"], "sentence": "Installing burrow and wiring it up: the install, the porch service, the chores schedule and the settings.", "rows": [
  {"name": "install", "form": "make install", "what": "Creates the virtualenv in .venv, installs burrow into it, and makes the stash folders."},
  {"name": "porch service", "form": "make install-unit", "what": "Installs the porch service into systemd and starts it now."},
  {"name": "chores schedule", "form": "crontab deploy/burrow.crontab", "what": "Installs the chores schedule into crontab, replacing the whole crontab (see question 4)."},
  {"name": "settings", "form": "config/burrow.toml", "what": "Opens the settings: stash root and keep count, porch address, SSH user."},
  {"name": "secrets template", "form": ".env.example", "what": "Opens the template for .env; copy it to .env and fill it in."},
  {"name": "setup doc", "form": "docs/setup.md", "what": "Reads the first-time setup steps and how to check them."}
 ]},
 {"path": ["development"], "sentence": "Tests, lint, clean-up and the source code, for changing burrow.", "rows": [
  {"name": "tests", "form": "make test", "what": "Runs the test suite with pytest."},
  {"name": "test files", "form": "tests/", "what": "Opens the test files, one per module."},
  {"name": "lint", "form": "make lint", "what": "Checks burrow and tests with ruff, without changing them."},
  {"name": "clean", "form": "make clean", "what": "Deletes the virtualenv, caches and build output."},
  {"name": "source", "form": "burrow/", "what": "Opens the burrow package: the CLI, config, stash, chores, rigs and porch."},
  {"name": "pulse", "form": "pulse/pulse.py", "what": "Opens pulse, the program that exposes rig temperatures and disk use."}
 ]}
],
"questions": [
 "burrow porch starts the server today, and the systemd unit calls it. Move the server to 'burrow porch run', make bare 'burrow porch' print the porch screen, and update ExecStart in the unit? Recommended: yes.",
 "The scripts screen lists 25 scripts flat. May I read the 22 I only know by name, then split the list into four job screens (disks and power; network and DNS; storage and stashes; rigs and setup)? Recommended: yes, read first, then split.",
 "Move reboot-reboot-rig and check-disks to the rigs screen, since that is where a user looks when a rig is down? Recommended: yes.",
 "crontab deploy/burrow.crontab replaces the whole crontab and drops the weekly prune line from make install-prune-cron. Add the prune line to deploy/burrow.crontab and drop install-prune-cron? Recommended: yes.",
 "Approve the top screen with its eight groups (rigs, stash, chores, porch, metrics, scripts, setup, development) and their new command names (burrow metrics, burrow scripts, burrow setup, burrow development)? Recommended: yes."
]}
```

technicians app (UI)

The approved map (ground truth)
The jobs of an org technician.
My jobssrc/app/(tabs)/index.js
The jobsrc/app/jobs/[id]/index.js
Work reportsrc/app/jobs/[id]/report.js
New jobsrc/app/jobs/new.js
Settingssrc/app/settings.js

Home

The jobs of an org technician.

My jobs
›
The job
›
Work report
›
New job
›
Settings
›
Show:
No skill
Today's skills
screen-decomposition, first draft
screen-decomposition, final

No skill · run 1 exit=0 seconds=69 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.455P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 2
As terminal help
Home after login. The technician's jobs, newest first, a page at a time: jobs assigned to them, and the jobs they sent to the office that no technician has yet (shown as sent, read only). A sent job leaves this list once the office assigns it to someone else. Each row shows the job's state.
Settingscog in the header, opens /settingssee who is logged in, log out
New job+ in the title row, opens /jobs/newsend a new job to the office, or, for an admin, name who does it
A joba row, opens /jobs/[id]open a job to work it, read it, or see a sent job read only
More jobsscroll to the end, loads the next page (listMyJobs)see older jobs
my jobs
Who is logged in, and logging out.
Log outbutton, calls logout, then opens the login screenend the session
my jobs
One job. The state is in the header. Cards in order: planned day, description and tags, client (name, phone, address), then the work (parts, photos) while it is being worked. A done job and a sent job still waiting for the office are read only.
+ menu+ in the header, opens a menustart a new job or a related job from this one
New job from the menumenu item, opens /jobs/new (empty)a job with nothing filled in
Related jobmenu item, opens /jobs/new with relatedJobId set and this job's client name, phone and address filled ina job the office sees as found in this one
Continue to the reportbutton, opens /jobs/[id]/reportreview, sign and send the report; this finishes the job (only while assigned to them and not done)
Job already in progressnamed in the work area, opens /jobs/[runningId]switch to another job the technician has running
my jobs
A new job: what is wanted, the client's name and phone (address optional), and the planned day if known. Saved with no technician, it waits for the office to assign it. An admin can also name who does it, themselves included. Save opens the job.
Planned dayday chooser, shown on this screenpick the day agreed with the client (optional)
Who does itadmin only: search box listing company technicians (listCompanyTechnicians, at most 50)name who does the job; left blank, it goes to the office
Savebutton, creates the job and opens /jobs/[id]send the job
Backback arrow, to My jobsleave without saving
my jobs › job
The same form as a new job, titled related job, with the client filled in from the job it was opened from. Saving records which job it came from, so the office's ticket says where it was found.
Planned dayday chooser, shown on this screenpick the day agreed with the client (optional)
Who does itadmin only: search box listing company technicians (listCompanyTechnicians, at most 50)name who does the job; left blank, it goes to the office
Savebutton, creates the job and opens /jobs/[id]send the related job
Backback arrow, to the job it came fromleave without saving
my jobs › job
Review minutes, parts and photos, write an optional note, have the client sign, then send. Sending finishes the job and returns to My jobs.
Client signaturesignature pad, on this screenthe client signs; send stays off until they do
Sendbutton, sends the report, then opens /finish the job and go back to My jobs
Backback arrow, opens /jobs/[id]keep working on the job
my jobs › settings
Shown when nobody is logged in: first launch, or after log out. It opens filled in with the demo login, for testing.
Log inbutton, calls login(email, password, company code), then opens My jobsstart a session as a technician
Questions
  • What the list calls a sent job still waiting for the office. The owner wrote 'sent'. Recommend the list says 'sent to the office' so it matches the job header.
  • Where Back goes from a new or related job opened from a job's menu: back to that job, or to My jobs. Recommend back to the job it came from. I could not read backOrTo to confirm current behaviour.
  • Should the + menu appear on a sent job still waiting for the office, and on a done job? Recommend yes on both: a related job can be found in any job.
  • Should the admin's 'who does it' picker also appear on the related-job screen? Recommend yes: it is the same form, and an admin names who does a job in both cases.
  • Can the creator withdraw a sent job before the office assigns it? The decisions do not say. Recommend no for now; add it later if it is needed.
As phone screens

Home

Home after login. The technician's jobs, newest first, a page at a time: jobs assigned to them, and the jobs they sent to the office that no technician has yet (shown as sent, read only). A sent job leaves this list once the office assigns it to someone else. Each row shows the job's state.

Settingssee who is logged in, log out
›
New jobsend a new job to the office, or, for an admin, name who does it
›
A jobopen a job to work it, read it, or see a sent job read only
›
More jobssee older jobs
›
‹ Home

my jobs

Who is logged in, and logging out.

Log outend the session
›
‹ Home

my jobs

One job. The state is in the header. Cards in order: planned day, description and tags, client (name, phone, address), then the work (parts, photos) while it is being worked. A done job and a sent job still waiting for the office are read only.

+ menustart a new job or a related job from this one
›
New job from the menua job with nothing filled in
›
Related joba job the office sees as found in this one
›
Continue to the reportreview, sign and send the report; this finishes the job (only while assigned to them and not done)
›
Job already in progressswitch to another job the technician has running
›
‹ Home

my jobs

A new job: what is wanted, the client's name and phone (address optional), and the planned day if known. Saved with no technician, it waits for the office to assign it. An admin can also name who does it, themselves included. Save opens the job.

Planned daypick the day agreed with the client (optional)
›
Who does itname who does the job; left blank, it goes to the office
›
Savesend the job
›
Backleave without saving
›
‹ my jobs

job

The same form as a new job, titled related job, with the client filled in from the job it was opened from. Saving records which job it came from, so the office's ticket says where it was found.

Planned daypick the day agreed with the client (optional)
›
Who does itname who does the job; left blank, it goes to the office
›
Savesend the related job
›
Backleave without saving
›
‹ my jobs

job

Review minutes, parts and photos, write an optional note, have the client sign, then send. Sending finishes the job and returns to My jobs.

Client signaturethe client signs; send stays off until they do
›
Sendfinish the job and go back to My jobs
›
Backkeep working on the job
›
‹ my jobs

settings

Shown when nobody is logged in: first launch, or after log out. It opens filled in with the demo login, for testing.

Log instart a session as a technician
›
Raw answer
The map below covers the org-technician app as the 2026-10-21 decisions describe it. The Leads tab and self-worker screens are left out: the owner keeps them in code but unused, so they are not reachable in this navigation.

**Choices I made**
- A job the creator sent and nobody has taken yet appears in My jobs as sent, read only. It drops off the list once the office assigns it to someone else.
- The related-job screen is its own entry, because it opens with the client filled in. It has the same fields and admin picker as the new-job screen.
- The job's + menu has "new job" and "related job" only. "Add as lead" is left out, as decided.
- Back arrows are not listed as rows.

**What I could not read**
- Several components are not in the dump: `JobWorkspace`, `ClientCard`, `Menu`, `TechnicianPicker`, `LoginScreen`, `backOrTo`, `relatedJobParams`. Their rows come from the page code and the contract only. The "job already in progress" row is inferred from the `onOpenJob` prop.
- `contract.js` is cut off partway through, so I used the data calls it names.

```json
{"screens": [
{"path": [], "sentence": "Home after login. The technician's jobs, newest first, a page at a time: jobs assigned to them, and the jobs they sent to the office that no technician has yet (shown as sent, read only). A sent job leaves this list once the office assigns it to someone else. Each row shows the job's state.", "rows": [
{"name": "Settings", "form": "cog in the header, opens /settings", "what": "see who is logged in, log out"},
{"name": "New job", "form": "+ in the title row, opens /jobs/new", "what": "send a new job to the office, or, for an admin, name who does it"},
{"name": "A job", "form": "a row, opens /jobs/[id]", "what": "open a job to work it, read it, or see a sent job read only"},
{"name": "More jobs", "form": "scroll to the end, loads the next page (listMyJobs)", "what": "see older jobs"}
]},
{"path": ["my jobs"], "sentence": "Who is logged in, and logging out.", "rows": [
{"name": "Log out", "form": "button, calls logout, then opens the login screen", "what": "end the session"}
]},
{"path": ["my jobs"], "sentence": "One job. The state is in the header. Cards in order: planned day, description and tags, client (name, phone, address), then the work (parts, photos) while it is being worked. A done job and a sent job still waiting for the office are read only.", "rows": [
{"name": "+ menu", "form": "+ in the header, opens a menu", "what": "start a new job or a related job from this one"},
{"name": "New job from the menu", "form": "menu item, opens /jobs/new (empty)", "what": "a job with nothing filled in"},
{"name": "Related job", "form": "menu item, opens /jobs/new with relatedJobId set and this job's client name, phone and address filled in", "what": "a job the office sees as found in this one"},
{"name": "Continue to the report", "form": "button, opens /jobs/[id]/report", "what": "review, sign and send the report; this finishes the job (only while assigned to them and not done)"},
{"name": "Job already in progress", "form": "named in the work area, opens /jobs/[runningId]", "what": "switch to another job the technician has running"}
]},
{"path": ["my jobs"], "sentence": "A new job: what is wanted, the client's name and phone (address optional), and the planned day if known. Saved with no technician, it waits for the office to assign it. An admin can also name who does it, themselves included. Save opens the job.", "rows": [
{"name": "Planned day", "form": "day chooser, shown on this screen", "what": "pick the day agreed with the client (optional)"},
{"name": "Who does it", "form": "admin only: search box listing company technicians (listCompanyTechnicians, at most 50)", "what": "name who does the job; left blank, it goes to the office"},
{"name": "Save", "form": "button, creates the job and opens /jobs/[id]", "what": "send the job"},
{"name": "Back", "form": "back arrow, to My jobs", "what": "leave without saving"}
]},
{"path": ["my jobs", "job"], "sentence": "The same form as a new job, titled related job, with the client filled in from the job it was opened from. Saving records which job it came from, so the office's ticket says where it was found.", "rows": [
{"name": "Planned day", "form": "day chooser, shown on this screen", "what": "pick the day agreed with the client (optional)"},
{"name": "Who does it", "form": "admin only: search box listing company technicians (listCompanyTechnicians, at most 50)", "what": "name who does the job; left blank, it goes to the office"},
{"name": "Save", "form": "button, creates the job and opens /jobs/[id]", "what": "send the related job"},
{"name": "Back", "form": "back arrow, to the job it came from", "what": "leave without saving"}
]},
{"path": ["my jobs", "job"], "sentence": "Review minutes, parts and photos, write an optional note, have the client sign, then send. Sending finishes the job and returns to My jobs.", "rows": [
{"name": "Client signature", "form": "signature pad, on this screen", "what": "the client signs; send stays off until they do"},
{"name": "Send", "form": "button, sends the report, then opens /", "what": "finish the job and go back to My jobs"},
{"name": "Back", "form": "back arrow, opens /jobs/[id]", "what": "keep working on the job"}
]},
{"path": ["my jobs", "settings"], "sentence": "Shown when nobody is logged in: first launch, or after log out. It opens filled in with the demo login, for testing.", "rows": [
{"name": "Log in", "form": "button, calls login(email, password, company code), then opens My jobs", "what": "start a session as a technician"}
]}
],
"questions": [
"What the list calls a sent job still waiting for the office. The owner wrote 'sent'. Recommend the list says 'sent to the office' so it matches the job header.",
"Where Back goes from a new or related job opened from a job's menu: back to that job, or to My jobs. Recommend back to the job it came from. I could not read backOrTo to confirm current behaviour.",
"Should the + menu appear on a sent job still waiting for the office, and on a done job? Recommend yes on both: a related job can be found in any job.",
"Should the admin's 'who does it' picker also appear on the related-job screen? Recommend yes: it is the same form, and an admin names who does a job in both cases.",
"Can the creator withdraw a sent job before the office assigns it? The decisions do not say. Recommend no for now; add it later if it is needed."
]}
```

Today's skills · run 1 exit=0 seconds=47 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.522P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 1
As terminal help
Every job this technician can see, newest first, a page at a time: the jobs assigned to them, and the jobs they sent to the office that no technician has taken yet (read only until then).
A jobscreen jobs/[id]open one job to read it or work it
New job (+ in the title row)screen jobs/newsend a new job to the office, or to a technician an admin names
Settings (cog in the header)screen settingssee who is logged in, and log out
settings
Who is logged in, and a button to log out.
Log outdata.logout, then the login gate (no route)end the session and return to login
Backscreen / (My jobs)return to My jobs
job
One job: its state in the header, the planned day, the description and tags, the client's name, phone and address, the parts, and while working the photos. Read only when done, and only read when waiting for the office (no technician yet).
Backscreen / (My jobs)return to My jobs
Job menu (+ in the header)menu on jobs/[id]choose a related job or a new job
Related jobscreen jobs/new with relatedJobId = this job's id, client filled in from this jobopen a job found while doing this one; the office's ticket says where it came from
New jobscreen jobs/newopen an empty new job
Another job still in progressscreen jobs/[runningId]switch to a job whose work is still running (can't confirm when this shows)
Continue to reportscreen jobs/[id]/reportfinish the job: review, sign and send
Client card (name, phone, address)ClientCard component (can't confirm whether phone or address are tappable)see who the client is and how to reach them
Parts, photos, start and stop workJobWorkspace component (can't confirm the details); start and stop save the state to the office (saveWorkState)pick parts from the catalog, add photos, and tell the office when work starts or stops
job › report
Review the minutes, parts and photos, add a note, get the client's signature, then send. Sending finishes the job and returns to My jobs. If the job is already done, it opens the job page instead.
Back to the jobscreen jobs/[id]return to the job without sending
Client signaturesignature pad (input, not a screen)the client signs; send stays off until it is signed
Notetext input (not a screen)an optional note on the report
Senddata.sendReport, then tech_send_report (Supabase function)save the report, mark the job done; for an org technician, take the parts off the office's stock
new job
Describe a new job for the office: the description, the client's name and phone (address optional), and the planned day if known. Opened from a job's menu as a related job, the title says so and the client is already filled in. Admins also choose who does the job.
Description, client name, phone, addresstext inputs (not screens)what is wanted and how to reach the client; name, phone and description are required
Planned day (optional)DayChoice component (input)the day agreed with the client
Who does it (admins only, optional)TechnicianPicker, then tech_list_company_technicians (Supabase function)name a technician of the admin's company, themselves included; left empty, the job waits for the office
Savedata.createJob, then tech_create_job (Supabase function)save the job; a non-admin's job waits for the office as a ticket
The saved jobscreen jobs/[id]open the job just saved
Backprevious screen, or / (My jobs)leave without saving
Questions
  • Leave the Leads screens (the tab, a new lead, a lead, the Excel import) out of the map? Recommendation: yes. The owner's decision keeps them in code for self-workers, who will never be used, and the tab bar is already hidden for org technicians.
  • Which Hebrew labels for the job menu? The code says 'עבודה קשורה' (related job) and 'עבודה חדשה' (new job); the owner wrote 'Create related job' and 'Create a new job'. Recommendation: keep the code's Hebrew, since it is what the approved Vercel build shows, and confirm it with the owner in one word.
  • Leave out the 'Add as lead' item in the job menu? Recommendation: yes, as the owner decided, since an org technician has no Leads screen to show the lead on.
  • Should the 'another job still in progress' row stay on the job page? Recommendation: keep it only if more than one job can be running at once; the code path exists, but I could not confirm when it shows (JobWorkspace was not in the dump).
  • Keep Settings as its own screen behind the cog, holding only the name and log out? Recommendation: yes; the cog is the place the app's rules name for account actions, and it leaves the header with one icon instead of a text link.
As phone screens

Home

Every job this technician can see, newest first, a page at a time: the jobs assigned to them, and the jobs they sent to the office that no technician has taken yet (read only until then).

A jobopen one job to read it or work it
›
New job (+ in the title row)send a new job to the office, or to a technician an admin names
›
Settings (cog in the header)see who is logged in, and log out
›
‹ Home

settings

Who is logged in, and a button to log out.

Log outend the session and return to login
›
Backreturn to My jobs
›
‹ Home

job

One job: its state in the header, the planned day, the description and tags, the client's name, phone and address, the parts, and while working the photos. Read only when done, and only read when waiting for the office (no technician yet).

Backreturn to My jobs
›
Job menu (+ in the header)choose a related job or a new job
›
Related jobopen a job found while doing this one; the office's ticket says where it came from
›
New jobopen an empty new job
›
Another job still in progressswitch to a job whose work is still running (can't confirm when this shows)
›
Continue to reportfinish the job: review, sign and send
›
Client card (name, phone, address)see who the client is and how to reach them
›
Parts, photos, start and stop workpick parts from the catalog, add photos, and tell the office when work starts or stops
›
‹ job

report

Review the minutes, parts and photos, add a note, get the client's signature, then send. Sending finishes the job and returns to My jobs. If the job is already done, it opens the job page instead.

Back to the jobreturn to the job without sending
›
Client signaturethe client signs; send stays off until it is signed
›
Notean optional note on the report
›
Sendsave the report, mark the job done; for an org technician, take the parts off the office's stock
›
‹ Home

new job

Describe a new job for the office: the description, the client's name and phone (address optional), and the planned day if known. Opened from a job's menu as a related job, the title says so and the client is already filled in. Admins also choose who does the job.

Description, client name, phone, addresswhat is wanted and how to reach the client; name, phone and description are required
›
Planned day (optional)the day agreed with the client
›
Who does it (admins only, optional)name a technician of the admin's company, themselves included; left empty, the job waits for the office
›
Savesave the job; a non-admin's job waits for the office as a ticket
›
The saved jobopen the job just saved
›
Backleave without saving
›
Raw answer
I read the 11 route files in the dump and built the map from them. The components (`JobWorkspace`, `ClientCard`, `Menu`, `TechnicianPicker`, `DayChoice`) and the rest of `contract.js` were not in the dump, so rows that depend on them say "can't confirm". The login gate is shown by `_layout.js` when nobody is logged in, so it is not a route and is not in the map. The Leads screens are left out because the owner's 2026-10-21 decisions keep them in code for self-workers, who will never be used. Questions are in the JSON.

```json
{"screens": [
  {"path": [],
   "sentence": "Every job this technician can see, newest first, a page at a time: the jobs assigned to them, and the jobs they sent to the office that no technician has taken yet (read only until then).",
   "rows": [
     {"name": "A job", "form": "screen jobs/[id]", "what": "open one job to read it or work it"},
     {"name": "New job (+ in the title row)", "form": "screen jobs/new", "what": "send a new job to the office, or to a technician an admin names"},
     {"name": "Settings (cog in the header)", "form": "screen settings", "what": "see who is logged in, and log out"}
   ]},
  {"path": ["settings"],
   "sentence": "Who is logged in, and a button to log out.",
   "rows": [
     {"name": "Log out", "form": "data.logout, then the login gate (no route)", "what": "end the session and return to login"},
     {"name": "Back", "form": "screen / (My jobs)", "what": "return to My jobs"}
   ]},
  {"path": ["job"],
   "sentence": "One job: its state in the header, the planned day, the description and tags, the client's name, phone and address, the parts, and while working the photos. Read only when done, and only read when waiting for the office (no technician yet).",
   "rows": [
     {"name": "Back", "form": "screen / (My jobs)", "what": "return to My jobs"},
     {"name": "Job menu (+ in the header)", "form": "menu on jobs/[id]", "what": "choose a related job or a new job"},
     {"name": "Related job", "form": "screen jobs/new with relatedJobId = this job's id, client filled in from this job", "what": "open a job found while doing this one; the office's ticket says where it came from"},
     {"name": "New job", "form": "screen jobs/new", "what": "open an empty new job"},
     {"name": "Another job still in progress", "form": "screen jobs/[runningId]", "what": "switch to a job whose work is still running (can't confirm when this shows)"},
     {"name": "Continue to report", "form": "screen jobs/[id]/report", "what": "finish the job: review, sign and send"},
     {"name": "Client card (name, phone, address)", "form": "ClientCard component (can't confirm whether phone or address are tappable)", "what": "see who the client is and how to reach them"},
     {"name": "Parts, photos, start and stop work", "form": "JobWorkspace component (can't confirm the details); start and stop save the state to the office (saveWorkState)", "what": "pick parts from the catalog, add photos, and tell the office when work starts or stops"}
   ]},
  {"path": ["job", "report"],
   "sentence": "Review the minutes, parts and photos, add a note, get the client's signature, then send. Sending finishes the job and returns to My jobs. If the job is already done, it opens the job page instead.",
   "rows": [
     {"name": "Back to the job", "form": "screen jobs/[id]", "what": "return to the job without sending"},
     {"name": "Client signature", "form": "signature pad (input, not a screen)", "what": "the client signs; send stays off until it is signed"},
     {"name": "Note", "form": "text input (not a screen)", "what": "an optional note on the report"},
     {"name": "Send", "form": "data.sendReport, then tech_send_report (Supabase function)", "what": "save the report, mark the job done; for an org technician, take the parts off the office's stock"}
   ]},
  {"path": ["new job"],
   "sentence": "Describe a new job for the office: the description, the client's name and phone (address optional), and the planned day if known. Opened from a job's menu as a related job, the title says so and the client is already filled in. Admins also choose who does the job.",
   "rows": [
     {"name": "Description, client name, phone, address", "form": "text inputs (not screens)", "what": "what is wanted and how to reach the client; name, phone and description are required"},
     {"name": "Planned day (optional)", "form": "DayChoice component (input)", "what": "the day agreed with the client"},
     {"name": "Who does it (admins only, optional)", "form": "TechnicianPicker, then tech_list_company_technicians (Supabase function)", "what": "name a technician of the admin's company, themselves included; left empty, the job waits for the office"},
     {"name": "Save", "form": "data.createJob, then tech_create_job (Supabase function)", "what": "save the job; a non-admin's job waits for the office as a ticket"},
     {"name": "The saved job", "form": "screen jobs/[id]", "what": "open the job just saved"},
     {"name": "Back", "form": "previous screen, or / (My jobs)", "what": "leave without saving"}
   ]}
 ],
 "questions": [
   "Leave the Leads screens (the tab, a new lead, a lead, the Excel import) out of the map? Recommendation: yes. The owner's decision keeps them in code for self-workers, who will never be used, and the tab bar is already hidden for org technicians.",
   "Which Hebrew labels for the job menu? The code says 'עבודה קשורה' (related job) and 'עבודה חדשה' (new job); the owner wrote 'Create related job' and 'Create a new job'. Recommendation: keep the code's Hebrew, since it is what the approved Vercel build shows, and confirm it with the owner in one word.",
   "Leave out the 'Add as lead' item in the job menu? Recommendation: yes, as the owner decided, since an org technician has no Leads screen to show the lead on.",
   "Should the 'another job still in progress' row stay on the job page? Recommendation: keep it only if more than one job can be running at once; the code path exists, but I could not confirm when it shows (JobWorkspace was not in the dump).",
   "Keep Settings as its own screen behind the cog, holding only the name and log out? Recommendation: yes; the cog is the place the app's rules name for account actions, and it leaves the header with one icon instead of a text link."
 ]}
```

screen-decomposition, first draft · run 1 exit=0 seconds=57 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
The jobs this technician has, and the jobs they sent to the office that are still waiting.
Job/jobs/[id] (tap a row)Opens one job to work on or read.
New job/jobs/new (the + in the title row)Opens the form to send a new job to the office.
Settings/settings (the cog in the header)Opens who is logged in, and logging out.
Leads/(tabs)/leads (tab bar, self-worker accounts only)Opens the self-worker's leads; not shown to org technicians.
Settings
The technician who is logged in.
Log outdata.logout(), then /loginLogs the technician out and returns to the login screen.
Login
The login form, shown when nobody is logged in.
Email, password and company codefields on /loginTypes the login details.
Log indata.login(email, password, companyId)Logs the technician in and opens My jobs.
Job
One job: its planned day, what the office wrote, the client, and the work on it while it is in progress.
Planned dayshown on this pageShows the day agreed with the client.
Description and tagsshown on this pageShows what the office wrote about the job.
Clientshown on this pageShows the client's name, phone and address.
Start work / Stop workdata.saveWorkState(jobId, 'in_progress' | 'awaiting_signature')Starts or stops the work, and tells the office.
Partsdata.listPartsCatalog() (picked from the catalog)Lists the office's parts so the technician can add them to the job.
Photosexpo-image-picker, shrunk to 1280px JPEGAdds photos of the work to the job.
Report/jobs/[id]/reportOpens the report to sign and send.
Related job/jobs/new with this job's client and id (the + menu)Opens the new-job form with this client filled in and the job it came from.
New job/jobs/new (the + menu)Opens an empty new-job form.
Job › Report
The report of this job, to sign and send.
Work summaryshown on this pageShows the minutes worked, the parts and the photos.
Notestext field on this pageTypes a note that goes with the report.
Client signatureSignaturePad, saved as a PNG data URLDraws the client's signature.
Senddata.sendReport({jobId, minutes, photos, parts, signature, notes})Sends the report, marks the job done, takes the parts off stock for an org technician, and returns to My jobs.
New job
A form to open a new job for the office, or a related job found in another one.
Descriptiontext field on this pageTypes what the job is.
Client name, phone and addresstext fields on this page (address optional)Types who the client is and where to reach them.
Planned dayDayChoice on this page (optional)Picks the day agreed with the client.
Who does itdata.listCompanyTechnicians(search) (admins only)Lists the company's technicians to name who does the job.
Savedata.createJob(input), or data.openJobFromLead(leadId, input)Saves the job for the office or the named technician, and opens it.
Leads
This self-worker's leads, open or closed, in the order of the day.
Opentab on /(tabs)/leadsLists the open leads still to call.
Closedtab on /(tabs)/leadsLists the converted and lost leads, read only.
Lead/leads/[id] (tap a row)Opens one lead to call back, close, or open a job from.
New lead/leads/new (the + in the title row)Opens the form to write down a new lead.
Import from Excel/leads/import (the floating button)Opens the Excel import of leads.
Leads › Lead
One lead: what they want, how to reach them, and what to do after the call.
Lead detailsshown on this pageShows the lead's name, status, what they want, and how to reach them.
Call back on a daydata.setCallBack(leadId, 'YYYY-MM-DD')Saves the day to call back, and returns to Leads.
Not relevantCloseLeadDialog, then data.closeLead(leadId, reason?)Asks for an optional reason, then closes the lead as lost.
Open a job/jobs/new with this lead's details (leadId)Opens the new-job form filled in from the lead; saving converts the lead.
Leads › New lead
A form to write down a lead from a call.
Name, phone and what they wanttext fields on this page (all required)Types the lead's name, phone and what they want.
Addresstext field on this page (optional)Types the lead's address if they gave one.
More detailsexpandable section on this page (budget, source, email, notes)Types the optional details.
Savedata.createLead(lead)Saves the lead as new and returns to Leads.
Leads › Import from Excel
The Excel file of leads to import, and the rows that will not be imported.
Choose fileexpo-document-picker, xlsxPicks an Excel file from the phone.
Change filebutton on this pagePicks another file.
Skipped rowsshown on this pageLists the rows with no name or phone, and what is missing.
Import N leadsdata.importLeads(rows)Saves the ready leads in one step and returns to Leads.
Questions
  • Should Leads appear in the map at all? Recommend: keep it, shown only to self-worker accounts, and off any new user's navigation, since you asked to keep it in the code.
  • Related job: its own screen or the same form? Recommend: the same New job screen with a different title, as in the map.
  • "Add as lead" from a job's menu. Recommend: leave it out, since org technicians have no Leads screen to show it on.
  • Admin technician picker: a field on New job, or its own screen? Recommend: a field on New job, shown only to admins.
  • The demo login pre-filled on the login screen. Recommend: keep it in test builds only and remove it from the release.
As phone screens

Home

The jobs this technician has, and the jobs they sent to the office that are still waiting.

JobOpens one job to work on or read.
›
New jobOpens the form to send a new job to the office.
›
SettingsOpens who is logged in, and logging out.
›
LeadsOpens the self-worker's leads; not shown to org technicians.
›
‹ Home

Settings

The technician who is logged in.

Log outLogs the technician out and returns to the login screen.
›
‹ Home

Login

The login form, shown when nobody is logged in.

Email, password and company codeTypes the login details.
›
Log inLogs the technician in and opens My jobs.
›
‹ Home

Job

One job: its planned day, what the office wrote, the client, and the work on it while it is in progress.

Planned dayShows the day agreed with the client.
›
Description and tagsShows what the office wrote about the job.
›
ClientShows the client's name, phone and address.
›
Start work / Stop workStarts or stops the work, and tells the office.
›
PartsLists the office's parts so the technician can add them to the job.
›
PhotosAdds photos of the work to the job.
›
ReportOpens the report to sign and send.
›
Related jobOpens the new-job form with this client filled in and the job it came from.
›
New jobOpens an empty new-job form.
›
‹ Job

Report

The report of this job, to sign and send.

Work summaryShows the minutes worked, the parts and the photos.
›
NotesTypes a note that goes with the report.
›
Client signatureDraws the client's signature.
›
SendSends the report, marks the job done, takes the parts off stock for an org technician, and returns to My jobs.
›
‹ Home

New job

A form to open a new job for the office, or a related job found in another one.

DescriptionTypes what the job is.
›
Client name, phone and addressTypes who the client is and where to reach them.
›
Planned dayPicks the day agreed with the client.
›
Who does itLists the company's technicians to name who does the job.
›
SaveSaves the job for the office or the named technician, and opens it.
›
‹ Home

Leads

This self-worker's leads, open or closed, in the order of the day.

OpenLists the open leads still to call.
›
ClosedLists the converted and lost leads, read only.
›
LeadOpens one lead to call back, close, or open a job from.
›
New leadOpens the form to write down a new lead.
›
Import from ExcelOpens the Excel import of leads.
›
‹ Leads

Lead

One lead: what they want, how to reach them, and what to do after the call.

Lead detailsShows the lead's name, status, what they want, and how to reach them.
›
Call back on a daySaves the day to call back, and returns to Leads.
›
Not relevantAsks for an optional reason, then closes the lead as lost.
›
Open a jobOpens the new-job form filled in from the lead; saving converts the lead.
›
‹ Leads

New lead

A form to write down a lead from a call.

Name, phone and what they wantTypes the lead's name, phone and what they want.
›
AddressTypes the lead's address if they gave one.
›
More detailsTypes the optional details.
›
SaveSaves the lead as new and returns to Leads.
›
‹ Leads

Import from Excel

The Excel file of leads to import, and the rows that will not be imported.

Choose filePicks an Excel file from the phone.
›
Change filePicks another file.
›
Skipped rowsLists the rows with no name or phone, and what is missing.
›
Import N leadsSaves the ready leads in one step and returns to Leads.
›
Raw answer
**Scenario (reasoning from the README and the owner's 2026-10-21 decisions):** A technician is on a job site. The office has sent them a job, or they found work in the field. They open the job, start work, add photos and parts, get the client's signature, and send the report. Org technicians send new work to the office; an admin can name who does it. Self-workers also keep leads and call them back.

**Inventory and where it is defined:**
- Jobs: `src/app/(tabs)/index.js`, `src/app/jobs/new.js`, `src/app/jobs/[id]/index.js`, `src/app/jobs/[id]/report.js`
- Leads (self-workers only): `src/app/(tabs)/leads.js`, `src/app/leads/new.js`, `src/app/leads/[id].js`, `src/app/leads/import.js`
- Account: `src/app/settings.js`, the login gate in `src/app/_layout.js`
- Data calls: `src/data/contract.js` (every `data.*` call named in the rows)

**Judgment calls:**
- The top screen has no path and only a sentence. It holds three rows for org technicians and four for self-workers. The Settings cog appears on every logged-in header, so it is listed once, on the top screen.
- The job screen has no title. Its sentence stands in for the h1, and its state sits in the header. Done and waiting-for-office jobs are read-only, so they have no work rows.
- The + menus (New job, Related job) are not path nouns. Related job opens the same "New job" screen with the client filled in, so it is not a separate screen.
- The labels to use are the Hebrew strings in the code (עבודות שלי, עבודה חדשה, דוח עבודה, לידים, ייבוא מאקסל, הגדרות). The English names below are glosses.
- Not traced: `JobWorkspace`, `ClientCard`, `Menu`, `CloseLeadDialog`, `DayChoice`, `PageShell`, and the `leads/[id]` rows for a closed lead. The dump cut off before them. Their rows come from how the screen files call them.
- Error screens for a missing job or lead are not mapped.

**Questions for you:**
1. **Should Leads appear in the map at all?** Recommend: keep it, shown only to self-worker accounts, and leave it off any new user's navigation. You said to keep it in the code.
2. **Related job: its own screen or the same form?** Recommend: the same "New job" screen with a different title, as in the map.
3. **"Add as lead" from a job's menu.** Recommend: leave it out, since org technicians have no Leads screen to show it on.
4. **Admin technician picker: a field or its own screen?** Recommend: a field on New job, shown only to admins.
5. **The demo login pre-filled on the login screen.** Recommend: keep it in test builds only and remove it from the release.

```json
{"screens": [
 {"path": [], "sentence": "The jobs this technician has, and the jobs they sent to the office that are still waiting.", "rows": [
   {"name": "Job", "form": "/jobs/[id] (tap a row)", "what": "Opens one job to work on or read."},
   {"name": "New job", "form": "/jobs/new (the + in the title row)", "what": "Opens the form to send a new job to the office."},
   {"name": "Settings", "form": "/settings (the cog in the header)", "what": "Opens who is logged in, and logging out."},
   {"name": "Leads", "form": "/(tabs)/leads (tab bar, self-worker accounts only)", "what": "Opens the self-worker's leads; not shown to org technicians."}
 ]},
 {"path": ["Settings"], "sentence": "The technician who is logged in.", "rows": [
   {"name": "Log out", "form": "data.logout(), then /login", "what": "Logs the technician out and returns to the login screen."}
 ]},
 {"path": ["Login"], "sentence": "The login form, shown when nobody is logged in.", "rows": [
   {"name": "Email, password and company code", "form": "fields on /login", "what": "Types the login details."},
   {"name": "Log in", "form": "data.login(email, password, companyId)", "what": "Logs the technician in and opens My jobs."}
 ]},
 {"path": ["Job"], "sentence": "One job: its planned day, what the office wrote, the client, and the work on it while it is in progress.", "rows": [
   {"name": "Planned day", "form": "shown on this page", "what": "Shows the day agreed with the client."},
   {"name": "Description and tags", "form": "shown on this page", "what": "Shows what the office wrote about the job."},
   {"name": "Client", "form": "shown on this page", "what": "Shows the client's name, phone and address."},
   {"name": "Start work / Stop work", "form": "data.saveWorkState(jobId, 'in_progress' | 'awaiting_signature')", "what": "Starts or stops the work, and tells the office."},
   {"name": "Parts", "form": "data.listPartsCatalog() (picked from the catalog)", "what": "Lists the office's parts so the technician can add them to the job."},
   {"name": "Photos", "form": "expo-image-picker, shrunk to 1280px JPEG", "what": "Adds photos of the work to the job."},
   {"name": "Report", "form": "/jobs/[id]/report", "what": "Opens the report to sign and send."},
   {"name": "Related job", "form": "/jobs/new with this job's client and id (the + menu)", "what": "Opens the new-job form with this client filled in and the job it came from."},
   {"name": "New job", "form": "/jobs/new (the + menu)", "what": "Opens an empty new-job form."}
 ]},
 {"path": ["Job", "Report"], "sentence": "The report of this job, to sign and send.", "rows": [
   {"name": "Work summary", "form": "shown on this page", "what": "Shows the minutes worked, the parts and the photos."},
   {"name": "Notes", "form": "text field on this page", "what": "Types a note that goes with the report."},
   {"name": "Client signature", "form": "SignaturePad, saved as a PNG data URL", "what": "Draws the client's signature."},
   {"name": "Send", "form": "data.sendReport({jobId, minutes, photos, parts, signature, notes})", "what": "Sends the report, marks the job done, takes the parts off stock for an org technician, and returns to My jobs."}
 ]},
 {"path": ["New job"], "sentence": "A form to open a new job for the office, or a related job found in another one.", "rows": [
   {"name": "Description", "form": "text field on this page", "what": "Types what the job is."},
   {"name": "Client name, phone and address", "form": "text fields on this page (address optional)", "what": "Types who the client is and where to reach them."},
   {"name": "Planned day", "form": "DayChoice on this page (optional)", "what": "Picks the day agreed with the client."},
   {"name": "Who does it", "form": "data.listCompanyTechnicians(search) (admins only)", "what": "Lists the company's technicians to name who does the job."},
   {"name": "Save", "form": "data.createJob(input), or data.openJobFromLead(leadId, input)", "what": "Saves the job for the office or the named technician, and opens it."}
 ]},
 {"path": ["Leads"], "sentence": "This self-worker's leads, open or closed, in the order of the day.", "rows": [
   {"name": "Open", "form": "tab on /(tabs)/leads", "what": "Lists the open leads still to call."},
   {"name": "Closed", "form": "tab on /(tabs)/leads", "what": "Lists the converted and lost leads, read only."},
   {"name": "Lead", "form": "/leads/[id] (tap a row)", "what": "Opens one lead to call back, close, or open a job from."},
   {"name": "New lead", "form": "/leads/new (the + in the title row)", "what": "Opens the form to write down a new lead."},
   {"name": "Import from Excel", "form": "/leads/import (the floating button)", "what": "Opens the Excel import of leads."}
 ]},
 {"path": ["Leads", "Lead"], "sentence": "One lead: what they want, how to reach them, and what to do after the call.", "rows": [
   {"name": "Lead details", "form": "shown on this page", "what": "Shows the lead's name, status, what they want, and how to reach them."},
   {"name": "Call back on a day", "form": "data.setCallBack(leadId, 'YYYY-MM-DD')", "what": "Saves the day to call back, and returns to Leads."},
   {"name": "Not relevant", "form": "CloseLeadDialog, then data.closeLead(leadId, reason?)", "what": "Asks for an optional reason, then closes the lead as lost."},
   {"name": "Open a job", "form": "/jobs/new with this lead's details (leadId)", "what": "Opens the new-job form filled in from the lead; saving converts the lead."}
 ]},
 {"path": ["Leads", "New lead"], "sentence": "A form to write down a lead from a call.", "rows": [
   {"name": "Name, phone and what they want", "form": "text fields on this page (all required)", "what": "Types the lead's name, phone and what they want."},
   {"name": "Address", "form": "text field on this page (optional)", "what": "Types the lead's address if they gave one."},
   {"name": "More details", "form": "expandable section on this page (budget, source, email, notes)", "what": "Types the optional details."},
   {"name": "Save", "form": "data.createLead(lead)", "what": "Saves the lead as new and returns to Leads."}
 ]},
 {"path": ["Leads", "Import from Excel"], "sentence": "The Excel file of leads to import, and the rows that will not be imported.", "rows": [
   {"name": "Choose file", "form": "expo-document-picker, xlsx", "what": "Picks an Excel file from the phone."},
   {"name": "Change file", "form": "button on this page", "what": "Picks another file."},
   {"name": "Skipped rows", "form": "shown on this page", "what": "Lists the rows with no name or phone, and what is missing."},
   {"name": "Import N leads", "form": "data.importLeads(rows)", "what": "Saves the ready leads in one step and returns to Leads."}
 ]}
],
"questions": [
 "Should Leads appear in the map at all? Recommend: keep it, shown only to self-worker accounts, and off any new user's navigation, since you asked to keep it in the code.",
 "Related job: its own screen or the same form? Recommend: the same New job screen with a different title, as in the map.",
 "\"Add as lead\" from a job's menu. Recommend: leave it out, since org technicians have no Leads screen to show it on.",
 "Admin technician picker: a field on New job, or its own screen? Recommend: a field on New job, shown only to admins.",
 "The demo login pre-filled on the login screen. Recommend: keep it in test builds only and remove it from the release."
]}
```

screen-decomposition, final · run 1 exit=0 seconds=95 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.733P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
The technician's jobs, newest first, a page at a time, each with its state.
new job+ in the title row, opens /jobs/newopens a new job form with nothing filled in; saving sends it to the office, or assigns it if the technician is an admin who names someone
settingscog in the header, opens /settingsopens Settings: who is logged in, and log out
a job in the lista row, opens /jobs/[id]opens that job; a job still waiting for the office opens read only
My jobs
The form for a new job, or for a related job with the client already filled in.
descriptiontext field, requiredsays what the work is; the kind of work and area are read from it later
client nametext field, requiredthe client's name
client phonetext field, requiredhow to reach the client
client addresstext field, optionalwhere the work is
planned dayday picker, optionalthe day the work is planned for, if known
who does ittechnician picker, admins only, at most 50 namesnames who does the job from the admin's company, themselves included; left empty, the job waits for the office
savebutton, data.createJobsaves the job and opens it; a related job keeps the link to the job it came from
My jobs › job
One job: its planned day, description, client, and the work on it, in the order the technician needs them.
stateheader, in the middleshows the job's state in words
planned daycard, read onlyshows the day the work is planned for, when the job has one
descriptioncard, with its tags under itshows what the office wrote about the work, and its tags
clientclient cardshows the client's name, phone and address
workJobWorkspace component (its controls are not in the dump; exact labels can't confirm)starts and stops the work, adds parts and photos while working, and continues to the report
finished workDoneJobSummary component, shown when the job is doneshows what was reported on the finished job; read only
related job+ menu in the header, opens /jobs/new with this job's clientopens a new job with this job's client filled in; the new job remembers this job
new job+ menu in the header, opens /jobs/newopens a new job with nothing filled in
My jobs › job › report
The report: the work's time, parts and photos, the notes, and the client's signature.
time workedsummary, WorkSummary componentshows the minutes worked
parts usedsummary, WorkSummary componentshows the parts taken for the job
photossummary, WorkSummary componentshows the job's photos
notestext field, optionaladds a note for the office
client signaturesignature pad, required to sendthe client signs here
sendbutton, data.sendReportsends the report, marks the job done and returns to My jobs; the parts come off the office's stock
My jobs › settings
Settings: who is logged in, and logging out.
signed-in techniciandata.currentTechnicianshows the name of who is logged in
log outbutton, data.logoutlogs out; the log-in form comes back
log in
The log-in form, shown instead of the app when nobody is logged in.
emailtext field, data.loginthe technician's email
passwordtext field, data.loginthe technician's password
company codetext field, data.loginthe code the technician's company gave; a wrong code fails like a wrong password
log inbutton, data.loginsigns in and opens My jobs
Questions
  • Breadcrumb noun for a job: 'job' (recommended: the sentence already names the client, and a client's name can change) or the client's name?
  • Word for a job the office has not assigned yet: 'waiting for the office' (recommended: the code's word, one word everywhere) or 'sent' (your word from 2026-10-21)?
  • My jobs as one list with each job's state (recommended, since your decisions did not ask for a split) or two lists: mine, and sent to the office?
As phone screens

Home

The technician's jobs, newest first, a page at a time, each with its state.

new jobopens a new job form with nothing filled in; saving sends it to the office, or assigns it if the technician is an admin who names someone
›
settingsopens Settings: who is logged in, and log out
›
a job in the listopens that job; a job still waiting for the office opens read only
›
‹ Home

My jobs

The form for a new job, or for a related job with the client already filled in.

descriptionsays what the work is; the kind of work and area are read from it later
›
client namethe client's name
›
client phonehow to reach the client
›
client addresswhere the work is
›
planned daythe day the work is planned for, if known
›
who does itnames who does the job from the admin's company, themselves included; left empty, the job waits for the office
›
savesaves the job and opens it; a related job keeps the link to the job it came from
›
‹ My jobs

job

One job: its planned day, description, client, and the work on it, in the order the technician needs them.

stateshows the job's state in words
›
planned dayshows the day the work is planned for, when the job has one
›
descriptionshows what the office wrote about the work, and its tags
›
clientshows the client's name, phone and address
›
workstarts and stops the work, adds parts and photos while working, and continues to the report
›
finished workshows what was reported on the finished job; read only
›
related jobopens a new job with this job's client filled in; the new job remembers this job
›
new jobopens a new job with nothing filled in
›
‹ job

report

The report: the work's time, parts and photos, the notes, and the client's signature.

time workedshows the minutes worked
›
parts usedshows the parts taken for the job
›
photosshows the job's photos
›
notesadds a note for the office
›
client signaturethe client signs here
›
sendsends the report, marks the job done and returns to My jobs; the parts come off the office's stock
›
‹ My jobs

settings

Settings: who is logged in, and logging out.

signed-in technicianshows the name of who is logged in
›
log outlogs out; the log-in form comes back
›
‹ Home

log in

The log-in form, shown instead of the app when nobody is logged in.

emailthe technician's email
›
passwordthe technician's password
›
company codethe code the technician's company gave; a wrong code fails like a wrong password
›
log insigns in and opens My jobs
›
Raw answer
## Scenario

Reasoned from experience and from the owner's 2026-10-21 decisions, not from the code. A technician is at a client's site. They open **My jobs** to see what is next, start a job, add parts and photos, take the client's signature, and send the report. On site they find more work, so they open a **related job** from this job, which carries the client and records where the work was found. The office assigns it in the dashboard. An admin can name who does a new job from the app.

## Read

- Read 11 of 11 route files (`src/app/`). The dump was cut at 9,000 characters, so I could not read `JobWorkspace`, `ClientCard`, `SignaturePad`, `WorkSummary`, `DoneJobSummary`, `LoginScreen`, `TechnicianPicker`, `DayChoice`, or the rest of `contract.js`. Their controls are marked "can't confirm" in the map.

## Inventory (what the technician reaches, and where it is defined)

| Thing | Form | Defined in |
|---|---|---|
| My jobs | top screen | `src/app/(tabs)/index.js` |
| New job (and related job) | `/jobs/new` | `src/app/jobs/new.js` |
| Job | `/jobs/[id]` | `src/app/jobs/[id]/index.js` |
| Report | `/jobs/[id]/report` | `src/app/jobs/[id]/report.js` |
| Settings | `/settings` | `src/app/settings.js` |
| Log in | the gate, `data.login` | `src/app/_layout.js`, `LoginScreen` |
| Job state: assigned, in progress, awaiting signature, done | a word in the header | `JobState` in `contract.js` |
| Waiting for the office | `job.waitingForOffice` (no state word of its own) | `contract.js` |
| Admin picker | `data.listCompanyTechnicians`, at most 50 names | `contract.js` |
| Parts, photos, notes, signature, time worked | fields inside job and report | `JobWorkspace`, `report.js` |

## Questions for you

1. **Breadcrumb noun for a job.** I recommend "job", with the client's name in the sentence. A client's name is a person's name and can change, and the sentence already names the client. Say if you want the name in the path instead.
2. **Word for a job the office has not assigned.** The code says "waiting for the office". Your 2026-10-21 message says "sent". I recommend "waiting for the office", one word everywhere, since the code already uses it. Confirm or pick "sent".
3. **One list or two on My jobs.** I recommend one list, newest first, with the state on each row. Splitting it into "mine" and "sent to the office" would add a top-level group, and your decisions did not ask for one.

## Judgment calls

- **Leads, the self-worker concept, "Add as lead": off the map.** Your 2026-10-21 decision: "don't remove it just abandon it. leave it for 'self' workers which will never be used." The code stays; the map does not show it.
- **Developer items off the map:** npm, Expo commands, SQL scripts, the APK releases, test logins. The technician never reaches them.
- **The office's dashboard is off the map.** It is the other repo. The map only shows its effect: "waiting for the office" until it is assigned.
- **Login is a gate, shown first, not part of the tree.** It is still an entry, with path `["log in"]`, so every reachable thing has one.
- **Settings is listed on My jobs only.** The cog in every other header is the same action, so it is not repeated.
- **Related job and new job share one screen.** A related job is the same form with the client filled in and the source job recorded. The job's + menu gives each its own line, worded for that place.
- **The job page has no title.** The state word sits in the header, following the minimal-UX rule that a job is titled by its state, not by an invented name.
- **A waiting job has no work controls.** `job.waitingForOffice` hides them, so the page is read only.
- **Report is reached only through "continue" on a job.** It is not on My jobs.
- **Word clashes to settle:** "org worker" (code and README) vs "org technician" (your words). The map says "technician". The README and contract still describe the 2026-10-19 model; the map follows 2026-10-21.
- **Generated map (principle 10):** route files should be checked against this map by a test, so a new screen cannot go missing.

```json
{"screens": [
{"path": [], "sentence": "The technician's jobs, newest first, a page at a time, each with its state.", "rows": [
{"name": "new job", "form": "+ in the title row, opens /jobs/new", "what": "opens a new job form with nothing filled in; saving sends it to the office, or assigns it if the technician is an admin who names someone"},
{"name": "settings", "form": "cog in the header, opens /settings", "what": "opens Settings: who is logged in, and log out"},
{"name": "a job in the list", "form": "a row, opens /jobs/[id]", "what": "opens that job; a job still waiting for the office opens read only"}
]},
{"path": ["My jobs"], "sentence": "The form for a new job, or for a related job with the client already filled in.", "rows": [
{"name": "description", "form": "text field, required", "what": "says what the work is; the kind of work and area are read from it later"},
{"name": "client name", "form": "text field, required", "what": "the client's name"},
{"name": "client phone", "form": "text field, required", "what": "how to reach the client"},
{"name": "client address", "form": "text field, optional", "what": "where the work is"},
{"name": "planned day", "form": "day picker, optional", "what": "the day the work is planned for, if known"},
{"name": "who does it", "form": "technician picker, admins only, at most 50 names", "what": "names who does the job from the admin's company, themselves included; left empty, the job waits for the office"},
{"name": "save", "form": "button, data.createJob", "what": "saves the job and opens it; a related job keeps the link to the job it came from"}
]},
{"path": ["My jobs", "job"], "sentence": "One job: its planned day, description, client, and the work on it, in the order the technician needs them.", "rows": [
{"name": "state", "form": "header, in the middle", "what": "shows the job's state in words"},
{"name": "planned day", "form": "card, read only", "what": "shows the day the work is planned for, when the job has one"},
{"name": "description", "form": "card, with its tags under it", "what": "shows what the office wrote about the work, and its tags"},
{"name": "client", "form": "client card", "what": "shows the client's name, phone and address"},
{"name": "work", "form": "JobWorkspace component (its controls are not in the dump; exact labels can't confirm)", "what": "starts and stops the work, adds parts and photos while working, and continues to the report"},
{"name": "finished work", "form": "DoneJobSummary component, shown when the job is done", "what": "shows what was reported on the finished job; read only"},
{"name": "related job", "form": "+ menu in the header, opens /jobs/new with this job's client", "what": "opens a new job with this job's client filled in; the new job remembers this job"},
{"name": "new job", "form": "+ menu in the header, opens /jobs/new", "what": "opens a new job with nothing filled in"}
]},
{"path": ["My jobs", "job", "report"], "sentence": "The report: the work's time, parts and photos, the notes, and the client's signature.", "rows": [
{"name": "time worked", "form": "summary, WorkSummary component", "what": "shows the minutes worked"},
{"name": "parts used", "form": "summary, WorkSummary component", "what": "shows the parts taken for the job"},
{"name": "photos", "form": "summary, WorkSummary component", "what": "shows the job's photos"},
{"name": "notes", "form": "text field, optional", "what": "adds a note for the office"},
{"name": "client signature", "form": "signature pad, required to send", "what": "the client signs here"},
{"name": "send", "form": "button, data.sendReport", "what": "sends the report, marks the job done and returns to My jobs; the parts come off the office's stock"}
]},
{"path": ["My jobs", "settings"], "sentence": "Settings: who is logged in, and logging out.", "rows": [
{"name": "signed-in technician", "form": "data.currentTechnician", "what": "shows the name of who is logged in"},
{"name": "log out", "form": "button, data.logout", "what": "logs out; the log-in form comes back"}
]},
{"path": ["log in"], "sentence": "The log-in form, shown instead of the app when nobody is logged in.", "rows": [
{"name": "email", "form": "text field, data.login", "what": "the technician's email"},
{"name": "password", "form": "text field, data.login", "what": "the technician's password"},
{"name": "company code", "form": "text field, data.login", "what": "the code the technician's company gave; a wrong code fails like a wrong password"},
{"name": "log in", "form": "button, data.login", "what": "signs in and opens My jobs"}
]}
],
"questions": [
"Breadcrumb noun for a job: 'job' (recommended: the sentence already names the client, and a client's name can change) or the client's name?",
"Word for a job the office has not assigned yet: 'waiting for the office' (recommended: the code's word, one word everywhere) or 'sent' (your word from 2026-10-21)?",
"My jobs as one list with each job's state (recommended, since your decisions did not ask for a split) or two lists: mine, and sent to the office?"
]}
```

No skill · run 2 exit=0 seconds=45 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.417P5 Short top: 4P6 Own words: 0.857P8 Worded per screen: 0
As terminal help
Home after login: this technician's jobs, newest first, a page at a time, each with its state. A job sent to the office and not yet assigned shows as waiting and is read only. The cog opens Settings and the + opens a new job.
Settings/settingsOpens who is logged in and the log out button; the cog in the header.
New job/jobs/newThe + in the title row. Opens an empty new-job screen; every technician can use it.
Open a job/jobs/[id]Tap a row to open that job; id is the job's id.
Next page of jobsdata.listMyJobs({ offset, limit }), counted by data.countMyJobs()Loads the next page as the list is scrolled.
settings
Shows the name of the logged-in technician and a log out button.
Log outaction: data.logout(), then back to the login screen (no technician)Ends the session on this phone.
new job
Opens a job for the office to assign: description, client name, phone, address (optional), planned day (optional). Opened from a job's + menu as a related job, the client name, phone and address come filled in from that job and the new job remembers it (its ticket says where it was found). An admin also picks who does it, from their company, themselves included. Save opens the saved job. An org technician's job with no one picked waits for the office.
Descriptiontext field on the screenWhat the job is; required.
Client nametext field on the screenRequired.
Client phonephone field on the screenRequired.
Client addresstext field on the screenOptional.
Planned dayday picker on the screen, stored as YYYY-MM-DDOptional; the day agreed with the client.
Who does itpicker on the screen (admins only), fed by tech_list_company_technicians(search, limit up to 50)Admins pick a technician of their company, themselves first; left empty the job goes to the office.
Saveaction: data.createJob(input) calling tech_create_job, or data.openJobFromLead for the lead branch (unused)Saves the job and opens it.
job
One job, shown in order: the state in the header, the planned day (if any), the description with its tags, the client card, the parts and, while working, the photos. A done job is read only. A waiting job is read only too, since there is no work on it until the office assigns it. The + in the header opens a menu.
Create a new job/jobs/new (empty)From the + menu; opens an empty new-job screen.
Create related job/jobs/new with params from relatedJobParams(job): relatedJobId, name, phone, addressFrom the + menu; the new job comes with this job's client and remembers this job.
Start or stop workaction: data.saveWorkState(jobId, 'in_progress' or 'awaiting_signature'), saved by tech_set_job_state (inferred: JobWorkspace not in the dump)Tells the office the technician started or stopped.
Add partsdata.listPartsCatalog(), the office's parts by number (inferred: JobWorkspace not in the dump)Pick the parts used on the job, with quantities.
Add photoscamera or gallery through expo-image-picker, shrunk to a 1280px JPEG (inferred: JobWorkspace not in the dump)Optional photos of the work.
Continue to the report/jobs/[id]/reportMoves on to the report once the work is done.
job › report
Review the work time, parts and photos, add an optional note, and have the client sign. Send finishes the job and returns to My jobs.
Notetext field on the screenOptional note on the report.
Client signaturesignature pad on the screen, saved as a PNG data URLThe client's signature; required before sending.
Send reportaction: data.sendReport(input) calling tech_send_report, then /Saves the report, marks the job done and, for an org worker, takes the parts used off the office stock.
login
Shown instead of My jobs when nobody is logged in. Company code, email and password; it opens filled in with the demo login.
Company codetext field on the screenThe code the company gave the technician.
Email and passwordtext fields on the screenThe technician's login.
Log inaction: data.login(email, password, companyId)Logs in; a wrong password or company code gives the same error.
Questions
  • Remove the demo login before release? The login screen opens filled in with user100@gmail.com / 100 (DEMO_LOGIN), and the test logins are in the seed. Recommendation: keep the prefill and test logins in development builds only; a real release shows an empty login.
  • Can a technician withdraw a job they sent? Today a sent job can only be seen until assigned, and there is no way to cancel it. Recommendation: let the creator remove it while it has no technician, since the office sees it as a ticket and a withdrawn one would otherwise stay there.
  • Should org technicians have a tab bar? Today My jobs is their only screen, so the bar is hidden. Recommendation: no bar; the header with the + and the cog is enough until a second main screen exists.
  • Confirm the inferred job-screen rows (start or stop work, parts, photos). They come from the data contract because JobWorkspace was not in the dump. Recommendation: check them against JobWorkspace before the navigation is built.
As phone screens

Home

Home after login: this technician's jobs, newest first, a page at a time, each with its state. A job sent to the office and not yet assigned shows as waiting and is read only. The cog opens Settings and the + opens a new job.

SettingsOpens who is logged in and the log out button; the cog in the header.
›
New jobThe + in the title row. Opens an empty new-job screen; every technician can use it.
›
Open a jobTap a row to open that job; id is the job's id.
›
Next page of jobsLoads the next page as the list is scrolled.
›
‹ Home

settings

Shows the name of the logged-in technician and a log out button.

Log outEnds the session on this phone.
›
‹ Home

new job

Opens a job for the office to assign: description, client name, phone, address (optional), planned day (optional). Opened from a job's + menu as a related job, the client name, phone and address come filled in from that job and the new job remembers it (its ticket says where it was found). An admin also picks who does it, from their company, themselves included. Save opens the saved job. An org technician's job with no one picked waits for the office.

DescriptionWhat the job is; required.
›
Client nameRequired.
›
Client phoneRequired.
›
Client addressOptional.
›
Planned dayOptional; the day agreed with the client.
›
Who does itAdmins pick a technician of their company, themselves first; left empty the job goes to the office.
›
SaveSaves the job and opens it.
›
‹ Home

job

One job, shown in order: the state in the header, the planned day (if any), the description with its tags, the client card, the parts and, while working, the photos. A done job is read only. A waiting job is read only too, since there is no work on it until the office assigns it. The + in the header opens a menu.

Create a new jobFrom the + menu; opens an empty new-job screen.
›
Create related jobFrom the + menu; the new job comes with this job's client and remembers this job.
›
Start or stop workTells the office the technician started or stopped.
›
Add partsPick the parts used on the job, with quantities.
›
Add photosOptional photos of the work.
›
Continue to the reportMoves on to the report once the work is done.
›
‹ job

report

Review the work time, parts and photos, add an optional note, and have the client sign. Send finishes the job and returns to My jobs.

NoteOptional note on the report.
›
Client signatureThe client's signature; required before sending.
›
Send reportSaves the report, marks the job done and, for an org worker, takes the parts used off the office stock.
›
‹ Home

login

Shown instead of My jobs when nobody is logged in. Company code, email and password; it opens filled in with the demo login.

Company codeThe code the company gave the technician.
›
Email and passwordThe technician's login.
›
Log inLogs in; a wrong password or company code gives the same error.
›
Raw answer
This map covers the org technician's screens, the one model the owner settled on 2026-10-21. The Leads screens and the self-worker rules stay in the code but are left out of navigation, since no user will be a self-worker. The dump is cut at 9000 characters, so `JobWorkspace`, `ClientCard`, `usePagedList`, `session` and the Supabase SQL weren't visible. The job screen's start/stop, parts and photo rows are inferred from the data contract and the route files. Back arrows on pushed screens are implied and not listed as rows. The new-job screen is one screen reached from two places, so it appears once.

```json
{"screens": [
  {"path": [], "sentence": "Home after login: this technician's jobs, newest first, a page at a time, each with its state. A job sent to the office and not yet assigned shows as waiting and is read only. The cog opens Settings and the + opens a new job.",
   "rows": [
     {"name": "Settings", "form": "/settings", "what": "Opens who is logged in and the log out button; the cog in the header."},
     {"name": "New job", "form": "/jobs/new", "what": "The + in the title row. Opens an empty new-job screen; every technician can use it."},
     {"name": "Open a job", "form": "/jobs/[id]", "what": "Tap a row to open that job; id is the job's id."},
     {"name": "Next page of jobs", "form": "data.listMyJobs({ offset, limit }), counted by data.countMyJobs()", "what": "Loads the next page as the list is scrolled."}
   ]},

  {"path": ["settings"], "sentence": "Shows the name of the logged-in technician and a log out button.",
   "rows": [
     {"name": "Log out", "form": "action: data.logout(), then back to the login screen (no technician)", "what": "Ends the session on this phone."}
   ]},

  {"path": ["new job"], "sentence": "Opens a job for the office to assign: description, client name, phone, address (optional), planned day (optional). Opened from a job's + menu as a related job, the client name, phone and address come filled in from that job and the new job remembers it (its ticket says where it was found). An admin also picks who does it, from their company, themselves included. Save opens the saved job. An org technician's job with no one picked waits for the office.",
   "rows": [
     {"name": "Description", "form": "text field on the screen", "what": "What the job is; required."},
     {"name": "Client name", "form": "text field on the screen", "what": "Required."},
     {"name": "Client phone", "form": "phone field on the screen", "what": "Required."},
     {"name": "Client address", "form": "text field on the screen", "what": "Optional."},
     {"name": "Planned day", "form": "day picker on the screen, stored as YYYY-MM-DD", "what": "Optional; the day agreed with the client."},
     {"name": "Who does it", "form": "picker on the screen (admins only), fed by tech_list_company_technicians(search, limit up to 50)", "what": "Admins pick a technician of their company, themselves first; left empty the job goes to the office."},
     {"name": "Save", "form": "action: data.createJob(input) calling tech_create_job, or data.openJobFromLead for the lead branch (unused)", "what": "Saves the job and opens it."}
   ]},

  {"path": ["job"], "sentence": "One job, shown in order: the state in the header, the planned day (if any), the description with its tags, the client card, the parts and, while working, the photos. A done job is read only. A waiting job is read only too, since there is no work on it until the office assigns it. The + in the header opens a menu.",
   "rows": [
     {"name": "Create a new job", "form": "/jobs/new (empty)", "what": "From the + menu; opens an empty new-job screen."},
     {"name": "Create related job", "form": "/jobs/new with params from relatedJobParams(job): relatedJobId, name, phone, address", "what": "From the + menu; the new job comes with this job's client and remembers this job."},
     {"name": "Start or stop work", "form": "action: data.saveWorkState(jobId, 'in_progress' or 'awaiting_signature'), saved by tech_set_job_state (inferred: JobWorkspace not in the dump)", "what": "Tells the office the technician started or stopped."},
     {"name": "Add parts", "form": "data.listPartsCatalog(), the office's parts by number (inferred: JobWorkspace not in the dump)", "what": "Pick the parts used on the job, with quantities."},
     {"name": "Add photos", "form": "camera or gallery through expo-image-picker, shrunk to a 1280px JPEG (inferred: JobWorkspace not in the dump)", "what": "Optional photos of the work."},
     {"name": "Continue to the report", "form": "/jobs/[id]/report", "what": "Moves on to the report once the work is done."}
   ]},

  {"path": ["job", "report"], "sentence": "Review the work time, parts and photos, add an optional note, and have the client sign. Send finishes the job and returns to My jobs.",
   "rows": [
     {"name": "Note", "form": "text field on the screen", "what": "Optional note on the report."},
     {"name": "Client signature", "form": "signature pad on the screen, saved as a PNG data URL", "what": "The client's signature; required before sending."},
     {"name": "Send report", "form": "action: data.sendReport(input) calling tech_send_report, then /", "what": "Saves the report, marks the job done and, for an org worker, takes the parts used off the office stock."}
   ]},

  {"path": ["login"], "sentence": "Shown instead of My jobs when nobody is logged in. Company code, email and password; it opens filled in with the demo login.",
   "rows": [
     {"name": "Company code", "form": "text field on the screen", "what": "The code the company gave the technician."},
     {"name": "Email and password", "form": "text fields on the screen", "what": "The technician's login."},
     {"name": "Log in", "form": "action: data.login(email, password, companyId)", "what": "Logs in; a wrong password or company code gives the same error."}
   ]}
 ],
 "questions": [
   "Remove the demo login before release? The login screen opens filled in with user100@gmail.com / 100 (DEMO_LOGIN), and the test logins are in the seed. Recommendation: keep the prefill and test logins in development builds only; a real release shows an empty login.",
   "Can a technician withdraw a job they sent? Today a sent job can only be seen until assigned, and there is no way to cancel it. Recommendation: let the creator remove it while it has no technician, since the office sees it as a ticket and a withdrawn one would otherwise stay there.",
   "Should org technicians have a tab bar? Today My jobs is their only screen, so the bar is hidden. Recommendation: no bar; the header with the + and the cog is enough until a second main screen exists.",
   "Confirm the inferred job-screen rows (start or stop work, parts, photos). They come from the data contract because JobWorkspace was not in the dump. Recommendation: check them against JobWorkspace before the navigation is built."
 ]}
```

Today's skills · run 2 exit=0 seconds=49 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.25P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
Your jobs, newest first, one page at a time, each with its state. The + in the title row opens a new job; the cog opens Settings. Jobs you sent that are still waiting for the office show here too, read only.
a job/jobs/[id]open it to work it, or to read it when it is done or still waiting for the office
new job/jobs/newopen a new job (the + in the title row)
settings/settingsthe cog: who is logged in, and log out
log in
Shown instead of the app when nobody is logged in: email, password and company code. It opens filled in with the demo login.
my jobs/the first screen after a successful login
settings
Who is logged in, and a log out button. Opened from the cog in the header.
back/back to My jobs
log outdata.logout(), then /signs out and returns to log in
new job
Open a job: description, client name, phone, optional address and planned day. An admin also picks who does it, from their own company, themselves included. Opened from a job's + menu as a related job, it is titled that way and comes with the client filled in. Saving opens the job. Without an admin's pick, the job waits for the office to assign it.
the saved job/jobs/[new id]opened after save, replacing this screen
my jobs/back to the list
job
One job: planned day, description with its tags, the client, then, while the job is open to work, the parts, photos and start or stop. A done job is read only. A job waiting for the office shows its details only. The + in the header opens a menu: related job or new job.
my jobs/back to the list
settings/settingsthe cog in the header
related job/jobs/new (params: relatedJobId, client name, phone, address)a new job for the same client, recording the job it was found in
new job/jobs/newfrom the + menu: a new job with nothing filled in
another job in progress/jobs/[runningId]open the other job the technician is working on (not confirmed: JobWorkspace not read)
report/jobs/[id]/reportcontinue to the report, to sign and send (not confirmed: JobWorkspace not read)
job › report
Review the minutes, parts and photos, add an optional note, take the client's signature, then send. Sending finishes the job.
job/jobs/[id]back to the job
my jobs/ (replace)after sending: the job is done, back to the list
Questions
  • Leads are left out of this map: the Leads tab, the lead pages, the import and the new-lead page. No user reaches them under the 2026-10-21 decision, and they stay in the code. Recommendation: leave them out. Should they be mapped anyway, for the old self-worker login user200?
  • Related job and new job are one screen with different parameters, as the code has them. Recommendation: keep one screen and switch its title. Confirm?
  • The report page has no cog, so Settings is reached only from My jobs and the job page. Recommendation: leave the cog off the report, so the page has one job (send). Confirm, or add it?
  • The README's first paragraph still describes two kinds of technician and links the 2026-10-19 model, which the 2026-10-21 decision replaced. Recommendation: correct it in a separate change. Do it now, or later?
As phone screens

Home

Your jobs, newest first, one page at a time, each with its state. The + in the title row opens a new job; the cog opens Settings. Jobs you sent that are still waiting for the office show here too, read only.

a jobopen it to work it, or to read it when it is done or still waiting for the office
›
new jobopen a new job (the + in the title row)
›
settingsthe cog: who is logged in, and log out
›
‹ Home

log in

Shown instead of the app when nobody is logged in: email, password and company code. It opens filled in with the demo login.

my jobsthe first screen after a successful login
›
‹ Home

settings

Who is logged in, and a log out button. Opened from the cog in the header.

backback to My jobs
›
log outsigns out and returns to log in
›
‹ Home

new job

Open a job: description, client name, phone, optional address and planned day. An admin also picks who does it, from their own company, themselves included. Opened from a job's + menu as a related job, it is titled that way and comes with the client filled in. Saving opens the job. Without an admin's pick, the job waits for the office to assign it.

the saved jobopened after save, replacing this screen
›
my jobsback to the list
›
‹ Home

job

One job: planned day, description with its tags, the client, then, while the job is open to work, the parts, photos and start or stop. A done job is read only. A job waiting for the office shows its details only. The + in the header opens a menu: related job or new job.

my jobsback to the list
›
settingsthe cog in the header
›
related joba new job for the same client, recording the job it was found in
›
new jobfrom the + menu: a new job with nothing filled in
›
another job in progressopen the other job the technician is working on (not confirmed: JobWorkspace not read)
›
reportcontinue to the report, to sign and send (not confirmed: JobWorkspace not read)
›
‹ job

report

Review the minutes, parts and photos, add an optional note, take the client's signature, then send. Sending finishes the job.

jobback to the job
›
my jobsafter sending: the job is done, back to the list
›
Raw answer
Read 11 of 11 route files in `src/app` from the dump. Not traced: the login form's fields, the job workspace (photos, parts, start and stop), the client card's actions, the technician picker and the job menu. Rows that depend on those are marked "not confirmed".

The map follows the 2026-10-21 decision: every technician uses one flow (My jobs, a job, the report). Leads and the self-worker pages are left out because no user reaches them. They stay in the code.

```json
{"screens": [
{"path": [], "sentence": "Your jobs, newest first, one page at a time, each with its state. The + in the title row opens a new job; the cog opens Settings. Jobs you sent that are still waiting for the office show here too, read only.", "rows": [
{"name": "a job", "form": "/jobs/[id]", "what": "open it to work it, or to read it when it is done or still waiting for the office"},
{"name": "new job", "form": "/jobs/new", "what": "open a new job (the + in the title row)"},
{"name": "settings", "form": "/settings", "what": "the cog: who is logged in, and log out"}]},
{"path": ["log in"], "sentence": "Shown instead of the app when nobody is logged in: email, password and company code. It opens filled in with the demo login.", "rows": [
{"name": "my jobs", "form": "/", "what": "the first screen after a successful login"}]},
{"path": ["settings"], "sentence": "Who is logged in, and a log out button. Opened from the cog in the header.", "rows": [
{"name": "back", "form": "/", "what": "back to My jobs"},
{"name": "log out", "form": "data.logout(), then /", "what": "signs out and returns to log in"}]},
{"path": ["new job"], "sentence": "Open a job: description, client name, phone, optional address and planned day. An admin also picks who does it, from their own company, themselves included. Opened from a job's + menu as a related job, it is titled that way and comes with the client filled in. Saving opens the job. Without an admin's pick, the job waits for the office to assign it.", "rows": [
{"name": "the saved job", "form": "/jobs/[new id]", "what": "opened after save, replacing this screen"},
{"name": "my jobs", "form": "/", "what": "back to the list"}]},
{"path": ["job"], "sentence": "One job: planned day, description with its tags, the client, then, while the job is open to work, the parts, photos and start or stop. A done job is read only. A job waiting for the office shows its details only. The + in the header opens a menu: related job or new job.", "rows": [
{"name": "my jobs", "form": "/", "what": "back to the list"},
{"name": "settings", "form": "/settings", "what": "the cog in the header"},
{"name": "related job", "form": "/jobs/new (params: relatedJobId, client name, phone, address)", "what": "a new job for the same client, recording the job it was found in"},
{"name": "new job", "form": "/jobs/new", "what": "from the + menu: a new job with nothing filled in"},
{"name": "another job in progress", "form": "/jobs/[runningId]", "what": "open the other job the technician is working on (not confirmed: JobWorkspace not read)"},
{"name": "report", "form": "/jobs/[id]/report", "what": "continue to the report, to sign and send (not confirmed: JobWorkspace not read)"}]},
{"path": ["job", "report"], "sentence": "Review the minutes, parts and photos, add an optional note, take the client's signature, then send. Sending finishes the job.", "rows": [
{"name": "job", "form": "/jobs/[id]", "what": "back to the job"},
{"name": "my jobs", "form": "/ (replace)", "what": "after sending: the job is done, back to the list"}]}
],
"questions": [
"Leads are left out of this map: the Leads tab, the lead pages, the import and the new-lead page. No user reaches them under the 2026-10-21 decision, and they stay in the code. Recommendation: leave them out. Should they be mapped anyway, for the old self-worker login user200?",
"Related job and new job are one screen with different parameters, as the code has them. Recommendation: keep one screen and switch its title. Confirm?",
"The report page has no cog, so Settings is reached only from My jobs and the job page. Recommendation: leave the cog off the report, so the page has one job (send). Confirm, or add it?",
"The README's first paragraph still describes two kinds of technician and links the 2026-10-19 model, which the 2026-10-21 decision replaced. Recommendation: correct it in a separate change. Do it now, or later?"
]}
```

screen-decomposition, first draft · run 2 exit=0 seconds=71 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 1
As terminal help
My jobs: the jobs given to you and the jobs you sent to the office, newest first, a page at a time.
A job in the list/jobs/[id]opens the job to see it and work on it
New job (+ in the title row)/jobs/newopens the form to send a new job to the office, or to name who does it if you are an admin
Settings (cog)/settingsopens who is logged in, and log out
Leads (tab, self-worker only)/leadsopens your leads; hidden for org technicians
log in
Log in: shown instead of the app when nobody is logged in.
Company code, email, passwordLoginScreen, shown by src/app/_layout.jssigns you in; the screen opens filled in with the demo login
My jobs › job
One job: its state in the header, the description, the client, and the work on it, which is read only once done or while waiting for the office.
Work on this job (time, parts, photos)JobWorkspace in jobs/[id]/index.jsrecords the time, the parts and the photos of the work; not shown when done or waiting
Continue to the report/jobs/[id]/reportopens the report to sign and send this job
Job already running/jobs/[runningId]opens the other job that is already being worked
Related job (+ menu)/jobs/new with this job's clientopens the new-job form for a job found here, with the client filled in
New job (+ menu)/jobs/newopens an empty new-job form
ClientClientCard in jobs/[id]/index.jsshows the client's name, phone and address; tap behaviour can't be confirmed from the dump
Done summaryDoneJobSummary in jobs/[id]/index.jsshows the report of a finished job, read only
My jobs › job › report
The report for this job: the work summary, a note, and the client's signature before it is sent.
Work summaryWorkSummary in jobs/[id]/report.jsshows the time, parts and photos that go in the report
Notetext field in jobs/[id]/report.jsadds a note that goes with the report
Client's signatureSignaturePad in jobs/[id]/report.jsrecords the client's signature, which is needed before sending
Senddata.sendReportsends the report, marks the job done, and returns to My jobs
new job
The form to open a new job: what is wanted, the client, the planned day, and for an admin who does it; from a job, the client is already filled in.
Descriptiontext field in jobs/new.jssays what the job is; required
Client name, phone, addresstext fields in jobs/new.jsgives who to call and where; name and phone are required, address is not
Planned dayDayChoice in jobs/new.jssets the day agreed with the client; optional
Who does itTechnicianPicker in jobs/new.js, admins onlynames a technician of your company, yourself included; left out, the job waits for the office
Savedata.createJobsaves the job and opens it; a job with no technician waits for the office to assign it
settings
Settings: the technician who is logged in, and log out.
Logged-in namedata.currentTechnician in settings.jsshows who is logged in
Log outdata.logout, then the log-in screenlogs you out and returns to log in
leads
Your leads, open ones first, with tabs for open and closed, a page at a time.
Open tabtab in leads.js, data.listMyLeads with closed falseshows the leads still to call, in the order of the day
Closed tabtab in leads.js, data.listMyLeads with closed trueshows converted and lost leads, read only
A lead in the list/leads/[id]opens the lead to call back, close it, or open a job from it
New lead (+)/leads/newopens the form to write down a new lead
Import from Excel/leads/importopens the import of an Excel file of leads
My jobs (tab)/opens your jobs
Settings (cog)/settingsopens who is logged in, and log out
leads › lead
One lead: the person, what they want, how to reach them, and what to do after the call; a closed lead is read only.
Call-back dayDayChoice in leads/[id].js, data.setCallBacksets the day to call back, and returns to Leads
Not relevantCloseLeadDialog, data.closeLeadasks, with an optional reason, then closes the lead as lost
Open a job/jobs/new with the lead filled inopens the new-job form from this lead; saving marks the lead converted
Contact detailsClientCard in leads/[id].jsshows the lead's contact details; tap behaviour can't be confirmed from the dump
leads › new lead
The form to write down a new lead: name, phone and what they want are needed; the rest is optional.
Name, phone, what they wanttext fields in leads/new.jsrecords the lead in the words of the call; all three are required
Addresstext field in leads/new.jsrecords where they are; optional
More detailstoggle in leads/new.jsopens budget, source, email and notes, all optional
Savedata.createLeadsaves the lead as new and returns to Leads
leads › import from Excel
Pick an Excel file of leads; the screen shows how many are ready and which rows are skipped, and why.
Choose fileDocumentPicker, xlsxopens the phone's file picker for an .xlsx file
Ready and skipped countsleads/import.jsshows how many leads will import and how many rows will not
Skipped rowsleads/import.jsshows which rows will not import and what they are missing
Import N leadsdata.importLeadssaves the ready leads in one step and returns to Leads
Questions
  • A job waiting for the office has no action for its creator: it is read only until the office assigns it. Should the creator be able to withdraw it? Recommendation: no, for now. Your decisions give no such step, so it stays off the map until you ask.
  • Leads and its screens stay in the code for self-workers, but no new user is one. Keep them on the map marked self-worker only, or leave them off? Recommendation: keep them, marked. You said not to remove them, and the map should cover what the code can reach.
  • The log-in screen opens filled in with the demo login. Should that stop before a real release? Recommendation: yes. Keep the prefill for local demo runs only.
As phone screens

Home

My jobs: the jobs given to you and the jobs you sent to the office, newest first, a page at a time.

A job in the listopens the job to see it and work on it
›
New job (+ in the title row)opens the form to send a new job to the office, or to name who does it if you are an admin
›
Settings (cog)opens who is logged in, and log out
›
Leads (tab, self-worker only)opens your leads; hidden for org technicians
›
‹ Home

log in

Log in: shown instead of the app when nobody is logged in.

Company code, email, passwordsigns you in; the screen opens filled in with the demo login
›
‹ My jobs

job

One job: its state in the header, the description, the client, and the work on it, which is read only once done or while waiting for the office.

Work on this job (time, parts, photos)records the time, the parts and the photos of the work; not shown when done or waiting
›
Continue to the reportopens the report to sign and send this job
›
Job already runningopens the other job that is already being worked
›
Related job (+ menu)opens the new-job form for a job found here, with the client filled in
›
New job (+ menu)opens an empty new-job form
›
Clientshows the client's name, phone and address; tap behaviour can't be confirmed from the dump
›
Done summaryshows the report of a finished job, read only
›
‹ job

report

The report for this job: the work summary, a note, and the client's signature before it is sent.

Work summaryshows the time, parts and photos that go in the report
›
Noteadds a note that goes with the report
›
Client's signaturerecords the client's signature, which is needed before sending
›
Sendsends the report, marks the job done, and returns to My jobs
›
‹ Home

new job

The form to open a new job: what is wanted, the client, the planned day, and for an admin who does it; from a job, the client is already filled in.

Descriptionsays what the job is; required
›
Client name, phone, addressgives who to call and where; name and phone are required, address is not
›
Planned daysets the day agreed with the client; optional
›
Who does itnames a technician of your company, yourself included; left out, the job waits for the office
›
Savesaves the job and opens it; a job with no technician waits for the office to assign it
›
‹ Home

settings

Settings: the technician who is logged in, and log out.

Logged-in nameshows who is logged in
›
Log outlogs you out and returns to log in
›
‹ Home

leads

Your leads, open ones first, with tabs for open and closed, a page at a time.

Open tabshows the leads still to call, in the order of the day
›
Closed tabshows converted and lost leads, read only
›
A lead in the listopens the lead to call back, close it, or open a job from it
›
New lead (+)opens the form to write down a new lead
›
Import from Excelopens the import of an Excel file of leads
›
My jobs (tab)opens your jobs
›
Settings (cog)opens who is logged in, and log out
›
‹ leads

lead

One lead: the person, what they want, how to reach them, and what to do after the call; a closed lead is read only.

Call-back daysets the day to call back, and returns to Leads
›
Not relevantasks, with an optional reason, then closes the lead as lost
›
Open a jobopens the new-job form from this lead; saving marks the lead converted
›
Contact detailsshows the lead's contact details; tap behaviour can't be confirmed from the dump
›
‹ leads

new lead

The form to write down a new lead: name, phone and what they want are needed; the rest is optional.

Name, phone, what they wantrecords the lead in the words of the call; all three are required
›
Addressrecords where they are; optional
›
More detailsopens budget, source, email and notes, all optional
›
Savesaves the lead as new and returns to Leads
›
‹ leads

import from Excel

Pick an Excel file of leads; the screen shows how many are ready and which rows are skipped, and why.

Choose fileopens the phone's file picker for an .xlsx file
›
Ready and skipped countsshows how many leads will import and how many rows will not
›
Skipped rowsshows which rows will not import and what they are missing
›
Import N leadssaves the ready leads in one step and returns to Leads
›
Raw answer
## Scenario (reasoning from experience, not from the code)

An org technician is at a client's site and finds a second problem. They send it to the office as a new job, and an admin may name who does it. Later they open a job, start the work, add parts and photos, have the client sign, and send the report. A self-worker, between calls, writes or imports leads, sets a day to call back, closes a lead that is not relevant, or opens a job from a lead.

## Inventory

The phone reaches these things:

- **Screens (the Expo routes):** `index` (My jobs), `jobs/new`, `jobs/[id]`, `jobs/[id]/report`, `leads` (tabs), `leads/new`, `leads/[id]`, `leads/import`, `settings`, and the log-in screen the root layout shows when nobody is logged in.
- **Actions with a form on screen:** log in, log out, save a job, send a report, call back, close a lead, open a job from a lead, import leads.
- **Live state:** the logged-in name, the job's state, the open and closed lead counts.

Left off the map, because no phone user reaches them: the SQL files and tests, the APK release page, the dashboard (the office's side), the web app, and the `.env` values.

Hebrew titles in the app, which the map uses as the project's own words: My jobs = העבודות שלי, Leads = לידים, New job = עבודה חדשה, Related job = עבודה קשורה, Report = דוח עבודה, Settings = הגדרות, Import from Excel = ייבוא מאקסל.

## Judgment calls

- **One model.** Org and self-worker share every screen. The Leads tab shows only for `kind = 'self'`, as the code already does. "Add as lead" is left out, per the 2026-10-21 decision.
- **Leads is a tab root,** a peer of My jobs. It gets path `["leads"]`, because only the top screen has the empty path.
- **Log in is its own screen,** `["log in"]`, because it has a form and a sign-in action, even though it is shown only when logged out.
- **New job is one screen with two entries** (the + on My jobs and the + menu on a job). A related job is the same screen with parameters.
- **Components not in the dump:** `JobWorkspace`, `ClientCard`, `WorkSummary`, `SignaturePad`, `DoneJobSummary`, `CloseLeadDialog`, `TechnicianPicker`, `DayChoice`. Their rows come from the screen that uses them. Their exact controls and tap targets can't be confirmed from the dump.
- **The cog and the Back control** appear on every screen that has them. They are listed on the top screens only, per principle 8.

## Questions for you

1. **A waiting job has no action for its creator.** It is read only until the office assigns it. Should the creator be able to withdraw it? *Recommendation: no, for now. Your decisions give no such step, so it stays off the map until you ask.*
2. **Leads for self-workers.** The code keeps them, but no new user is one. Keep them on the map marked self-worker only, or leave them off? *Recommendation: keep them, marked. You said not to remove them, and the map should cover what the code can reach.*
3. **The log-in screen opens filled in with the demo login.** Should that stop before a real release? *Recommendation: yes. Keep the prefill for local demo runs only.*

```json
{"screens": [
{"path": [], "sentence": "My jobs: the jobs given to you and the jobs you sent to the office, newest first, a page at a time.", "rows": [
{"name": "A job in the list", "form": "/jobs/[id]", "what": "opens the job to see it and work on it"},
{"name": "New job (+ in the title row)", "form": "/jobs/new", "what": "opens the form to send a new job to the office, or to name who does it if you are an admin"},
{"name": "Settings (cog)", "form": "/settings", "what": "opens who is logged in, and log out"},
{"name": "Leads (tab, self-worker only)", "form": "/leads", "what": "opens your leads; hidden for org technicians"}]},
{"path": ["log in"], "sentence": "Log in: shown instead of the app when nobody is logged in.", "rows": [
{"name": "Company code, email, password", "form": "LoginScreen, shown by src/app/_layout.js", "what": "signs you in; the screen opens filled in with the demo login"}]},
{"path": ["My jobs", "job"], "sentence": "One job: its state in the header, the description, the client, and the work on it, which is read only once done or while waiting for the office.", "rows": [
{"name": "Work on this job (time, parts, photos)", "form": "JobWorkspace in jobs/[id]/index.js", "what": "records the time, the parts and the photos of the work; not shown when done or waiting"},
{"name": "Continue to the report", "form": "/jobs/[id]/report", "what": "opens the report to sign and send this job"},
{"name": "Job already running", "form": "/jobs/[runningId]", "what": "opens the other job that is already being worked"},
{"name": "Related job (+ menu)", "form": "/jobs/new with this job's client", "what": "opens the new-job form for a job found here, with the client filled in"},
{"name": "New job (+ menu)", "form": "/jobs/new", "what": "opens an empty new-job form"},
{"name": "Client", "form": "ClientCard in jobs/[id]/index.js", "what": "shows the client's name, phone and address; tap behaviour can't be confirmed from the dump"},
{"name": "Done summary", "form": "DoneJobSummary in jobs/[id]/index.js", "what": "shows the report of a finished job, read only"}]},
{"path": ["My jobs", "job", "report"], "sentence": "The report for this job: the work summary, a note, and the client's signature before it is sent.", "rows": [
{"name": "Work summary", "form": "WorkSummary in jobs/[id]/report.js", "what": "shows the time, parts and photos that go in the report"},
{"name": "Note", "form": "text field in jobs/[id]/report.js", "what": "adds a note that goes with the report"},
{"name": "Client's signature", "form": "SignaturePad in jobs/[id]/report.js", "what": "records the client's signature, which is needed before sending"},
{"name": "Send", "form": "data.sendReport", "what": "sends the report, marks the job done, and returns to My jobs"}]},
{"path": ["new job"], "sentence": "The form to open a new job: what is wanted, the client, the planned day, and for an admin who does it; from a job, the client is already filled in.", "rows": [
{"name": "Description", "form": "text field in jobs/new.js", "what": "says what the job is; required"},
{"name": "Client name, phone, address", "form": "text fields in jobs/new.js", "what": "gives who to call and where; name and phone are required, address is not"},
{"name": "Planned day", "form": "DayChoice in jobs/new.js", "what": "sets the day agreed with the client; optional"},
{"name": "Who does it", "form": "TechnicianPicker in jobs/new.js, admins only", "what": "names a technician of your company, yourself included; left out, the job waits for the office"},
{"name": "Save", "form": "data.createJob", "what": "saves the job and opens it; a job with no technician waits for the office to assign it"}]},
{"path": ["settings"], "sentence": "Settings: the technician who is logged in, and log out.", "rows": [
{"name": "Logged-in name", "form": "data.currentTechnician in settings.js", "what": "shows who is logged in"},
{"name": "Log out", "form": "data.logout, then the log-in screen", "what": "logs you out and returns to log in"}]},
{"path": ["leads"], "sentence": "Your leads, open ones first, with tabs for open and closed, a page at a time.", "rows": [
{"name": "Open tab", "form": "tab in leads.js, data.listMyLeads with closed false", "what": "shows the leads still to call, in the order of the day"},
{"name": "Closed tab", "form": "tab in leads.js, data.listMyLeads with closed true", "what": "shows converted and lost leads, read only"},
{"name": "A lead in the list", "form": "/leads/[id]", "what": "opens the lead to call back, close it, or open a job from it"},
{"name": "New lead (+)", "form": "/leads/new", "what": "opens the form to write down a new lead"},
{"name": "Import from Excel", "form": "/leads/import", "what": "opens the import of an Excel file of leads"},
{"name": "My jobs (tab)", "form": "/", "what": "opens your jobs"},
{"name": "Settings (cog)", "form": "/settings", "what": "opens who is logged in, and log out"}]},
{"path": ["leads", "lead"], "sentence": "One lead: the person, what they want, how to reach them, and what to do after the call; a closed lead is read only.", "rows": [
{"name": "Call-back day", "form": "DayChoice in leads/[id].js, data.setCallBack", "what": "sets the day to call back, and returns to Leads"},
{"name": "Not relevant", "form": "CloseLeadDialog, data.closeLead", "what": "asks, with an optional reason, then closes the lead as lost"},
{"name": "Open a job", "form": "/jobs/new with the lead filled in", "what": "opens the new-job form from this lead; saving marks the lead converted"},
{"name": "Contact details", "form": "ClientCard in leads/[id].js", "what": "shows the lead's contact details; tap behaviour can't be confirmed from the dump"}]},
{"path": ["leads", "new lead"], "sentence": "The form to write down a new lead: name, phone and what they want are needed; the rest is optional.", "rows": [
{"name": "Name, phone, what they want", "form": "text fields in leads/new.js", "what": "records the lead in the words of the call; all three are required"},
{"name": "Address", "form": "text field in leads/new.js", "what": "records where they are; optional"},
{"name": "More details", "form": "toggle in leads/new.js", "what": "opens budget, source, email and notes, all optional"},
{"name": "Save", "form": "data.createLead", "what": "saves the lead as new and returns to Leads"}]},
{"path": ["leads", "import from Excel"], "sentence": "Pick an Excel file of leads; the screen shows how many are ready and which rows are skipped, and why.", "rows": [
{"name": "Choose file", "form": "DocumentPicker, xlsx", "what": "opens the phone's file picker for an .xlsx file"},
{"name": "Ready and skipped counts", "form": "leads/import.js", "what": "shows how many leads will import and how many rows will not"},
{"name": "Skipped rows", "form": "leads/import.js", "what": "shows which rows will not import and what they are missing"},
{"name": "Import N leads", "form": "data.importLeads", "what": "saves the ready leads in one step and returns to Leads"}]}
],
"questions": [
"A job waiting for the office has no action for its creator: it is read only until the office assigns it. Should the creator be able to withdraw it? Recommendation: no, for now. Your decisions give no such step, so it stays off the map until you ask.",
"Leads and its screens stay in the code for self-workers, but no new user is one. Keep them on the map marked self-worker only, or leave them off? Recommendation: keep them, marked. You said not to remove them, and the map should cover what the code can reach.",
"The log-in screen opens filled in with the demo login. Should that stop before a real release? Recommendation: yes. Keep the prefill for local demo runs only."
]}
```

screen-decomposition, final · run 2 exit=0 seconds=74 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.941P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
The technician's jobs, newest first, each with its state; jobs sent to the office and not yet assigned are listed too.
job/jobs/[id]opens the job: its state, planned day, description, client and the work on it.
new job/jobs/newopens the new job form, from the + at the end of the title row.
settings/settingsopens Settings: who is logged in and log out, from the cog in the header.
job
One job: its state in the header, then its planned day, description, client and work; a done job or one waiting for the office is read only.
start workdata.saveWorkState(jobId, 'in_progress')starts work on the job, so the office sees it in progress.
partsdata.listPartsCatalog (on this screen)adds parts from the catalog to this job.
photoscamera (on this screen)adds photos of the work; optional.
report/jobs/[id]/reportopens the report to sign and send; this is the way out of working on the job.
running job/jobs/[runningId]opens the other job already in progress, when one is running.
new job/jobs/newopens an empty new job form, from the + menu in the header.
related job/jobs/new?relatedJobId=[id]opens the new job form with this job's client filled in and linked to this job, so the office's ticket says where it was found.
job › report
The report of this job: the work's time, parts and photos, a note, and the client's signature.
signaturesignature pad (on this screen)the client signs here; send stays off until they do.
notetext field (on this screen)adds a note to the report.
senddata.sendReportsends the report, marks the job done and returns to My jobs.
new job
The form to open a job: what is wanted, the client, and the planned day, plus who does it for an admin; opened from a job it is a related job with the client already filled in.
technicianautocomplete over data.listCompanyTechnicians (admins only)picks who does the job from the company, themselves included; left empty, the job waits for the office.
planned dayday choice (on this screen)sets the day the job is planned for; optional.
savedata.createJobsaves the job and opens it.
settings
Settings: who is logged in, and logging out.
log outdata.logoutlogs the technician out and returns to the login screen.
Questions
  • Labels: the screens and buttons are in Hebrew (עבודה חדשה, עבודה קשורה, דוח עבודה, הגדרות, יציאה), and this map names them in English. Recommend keeping the Hebrew on screen, with one word per thing: 'new job' and 'related job' as the owner wrote them, matching the screen titles. Confirm?
  • Is there a separate stop-work control besides the continue-to-report action? Recommend none: one way out of work (the report), so two buttons never mean 'I'm done'. Please confirm there isn't one.
  • The admin's technician pick: inline on the new job form (recommended), or its own picker screen?
  • Login: keep it as the gate before My jobs and off the map (recommended), or list it as a screen?
  • Settings holds only who is logged in and log out. Keep it as its own screen behind the cog (recommended), or move log out into a menu on the cog?
  • The components not in the dump were not read, so rows that come from them are from the screen code only. Please confirm them, or send those files so the map can be checked.
As phone screens

Home

The technician's jobs, newest first, each with its state; jobs sent to the office and not yet assigned are listed too.

jobopens the job: its state, planned day, description, client and the work on it.
›
new jobopens the new job form, from the + at the end of the title row.
›
settingsopens Settings: who is logged in and log out, from the cog in the header.
›
‹ Home

job

One job: its state in the header, then its planned day, description, client and work; a done job or one waiting for the office is read only.

start workstarts work on the job, so the office sees it in progress.
›
partsadds parts from the catalog to this job.
›
photosadds photos of the work; optional.
›
reportopens the report to sign and send; this is the way out of working on the job.
›
running jobopens the other job already in progress, when one is running.
›
new jobopens an empty new job form, from the + menu in the header.
›
related jobopens the new job form with this job's client filled in and linked to this job, so the office's ticket says where it was found.
›
‹ job

report

The report of this job: the work's time, parts and photos, a note, and the client's signature.

signaturethe client signs here; send stays off until they do.
›
noteadds a note to the report.
›
sendsends the report, marks the job done and returns to My jobs.
›
‹ Home

new job

The form to open a job: what is wanted, the client, and the planned day, plus who does it for an admin; opened from a job it is a related job with the client already filled in.

technicianpicks who does the job from the company, themselves included; left empty, the job waits for the office.
›
planned daysets the day the job is planned for; optional.
›
savesaves the job and opens it.
›
‹ Home

settings

Settings: who is logged in, and logging out.

log outlogs the technician out and returns to the login screen.
›
Raw answer
## Map notes

**Scenario** (reasoning from the README and the owner's 2026-10-21 decisions): a technician opens My jobs, starts a job, adds parts and photos, gets the client's signature, and sends the report. In the field they find work and send it to the office as a job, and an admin may name who does it.

**Coverage:** the dump cuts off inside `contract.js`, and the components (JobWorkspace, ClientCard, Menu, TechnicianPicker, SignaturePad, DoneJobSummary, LoginScreen) aren't included. Rows that come from them are taken from the screen code only, and I haven't checked them against the components.

**Judgment calls:**
- **Leads left off.** The Leads tab, lead screens, Excel import and "Add as lead" are off the map. The owner wrote: "don't remove it just abandon it. leave it for 'self' workers which will never be used."
- **Login left off.** It is the gate shown before My jobs, not a place a user navigates to.
- **Settings listed once.** The cog appears in every header, so Settings is listed under the top screen only.
- **Outside the app, off the map:** the dashboard's office assignment, the GitHub release page, the web preview, and the SQL.
- **Parts, photos and the unsent draft** live inside the job screen, not on screens of their own.
- **Done and waiting jobs** are read only. The job sentence says so, and no work rows are listed for them.
- **One screen per thing.** "new job" appears under the top screen and again on the job screen's menu, worded for each place.

```json
{"screens": [
 {"path": [], "sentence": "The technician's jobs, newest first, each with its state; jobs sent to the office and not yet assigned are listed too.",
  "rows": [
   {"name": "job", "form": "/jobs/[id]", "what": "opens the job: its state, planned day, description, client and the work on it."},
   {"name": "new job", "form": "/jobs/new", "what": "opens the new job form, from the + at the end of the title row."},
   {"name": "settings", "form": "/settings", "what": "opens Settings: who is logged in and log out, from the cog in the header."}
  ]},
 {"path": ["job"], "sentence": "One job: its state in the header, then its planned day, description, client and work; a done job or one waiting for the office is read only.",
  "rows": [
   {"name": "start work", "form": "data.saveWorkState(jobId, 'in_progress')", "what": "starts work on the job, so the office sees it in progress."},
   {"name": "parts", "form": "data.listPartsCatalog (on this screen)", "what": "adds parts from the catalog to this job."},
   {"name": "photos", "form": "camera (on this screen)", "what": "adds photos of the work; optional."},
   {"name": "report", "form": "/jobs/[id]/report", "what": "opens the report to sign and send; this is the way out of working on the job."},
   {"name": "running job", "form": "/jobs/[runningId]", "what": "opens the other job already in progress, when one is running."},
   {"name": "new job", "form": "/jobs/new", "what": "opens an empty new job form, from the + menu in the header."},
   {"name": "related job", "form": "/jobs/new?relatedJobId=[id]", "what": "opens the new job form with this job's client filled in and linked to this job, so the office's ticket says where it was found."}
  ]},
 {"path": ["job", "report"], "sentence": "The report of this job: the work's time, parts and photos, a note, and the client's signature.",
  "rows": [
   {"name": "signature", "form": "signature pad (on this screen)", "what": "the client signs here; send stays off until they do."},
   {"name": "note", "form": "text field (on this screen)", "what": "adds a note to the report."},
   {"name": "send", "form": "data.sendReport", "what": "sends the report, marks the job done and returns to My jobs."}
  ]},
 {"path": ["new job"], "sentence": "The form to open a job: what is wanted, the client, and the planned day, plus who does it for an admin; opened from a job it is a related job with the client already filled in.",
  "rows": [
   {"name": "technician", "form": "autocomplete over data.listCompanyTechnicians (admins only)", "what": "picks who does the job from the company, themselves included; left empty, the job waits for the office."},
   {"name": "planned day", "form": "day choice (on this screen)", "what": "sets the day the job is planned for; optional."},
   {"name": "save", "form": "data.createJob", "what": "saves the job and opens it."}
  ]},
 {"path": ["settings"], "sentence": "Settings: who is logged in, and logging out.",
  "rows": [
   {"name": "log out", "form": "data.logout", "what": "logs the technician out and returns to the login screen."}
  ]}
],
"questions": [
 "Labels: the screens and buttons are in Hebrew (עבודה חדשה, עבודה קשורה, דוח עבודה, הגדרות, יציאה), and this map names them in English. Recommend keeping the Hebrew on screen, with one word per thing: 'new job' and 'related job' as the owner wrote them, matching the screen titles. Confirm?",
 "Is there a separate stop-work control besides the continue-to-report action? Recommend none: one way out of work (the report), so two buttons never mean 'I'm done'. Please confirm there isn't one.",
 "The admin's technician pick: inline on the new job form (recommended), or its own picker screen?",
 "Login: keep it as the gate before My jobs and off the map (recommended), or list it as a screen?",
 "Settings holds only who is logged in and log out. Keep it as its own screen behind the cog (recommended), or move log out into a menu on the cog?",
 "The components not in the dump were not read, so rows that come from them are from the screen code only. Please confirm them, or send those files so the map can be checked."
]}
```

No skill · run 3 exit=0 seconds=38 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.235P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
My jobs: the technician's jobs, newest first, a page at a time, each with its state. This is the top screen after login. Every technician has the + to open a new job here.
Job/jobs/[id]open one job from the list
New job/jobs/newthe + at the top; opens an empty new-job screen
Settings/settingsthe cog in the header: who is logged in, and log out
login
Login: shown in place of the app when nobody is logged in. The technician enters email, password and company code.
My jobs/after a successful login, the first screen
settings
Settings: shows the logged-in technician's name and a log-out button.
My jobs/back
Log outbutton; no route, ends in the login screenends the session
job
One job: its state in the header, then the planned day, description and tags, the client's name, phone and address, the parts, and while working the photos. A done job is read only, with a summary. A job still waiting for the office is read only, with no work to do.
My jobs/back to the list
Related job/jobs/new with relatedJobId set to this jobthe + menu: a new job that comes with this job's client and remembers where it was found
New job/jobs/newthe + menu: an empty new-job screen
Settings/settingsthe cog in the header
Report/jobs/[id]/reportcontinue when the work is done, to sign and send
Other job in progress/jobs/[runningId]jumps to the other job the technician has running, as JobWorkspace opens it
job › report
Report: a summary of time, parts and photos, an optional note, the client's signature, and Send. Sending finishes the job.
Job/jobs/[id]back to the job
My jobs/where the app goes after a report is sent
new job
New job: description, client name and phone, optional address and planned day. An admin also picks who does it, or leaves it for the office. Saved, the job opens.
Saved job/jobs/[id]opened after saving; a job with no technician shows as waiting for the office
My jobs/back, when the screen was not opened from a job
Who does it (admins only)picker on this screen, lists the company's technicians through listCompanyTechnicianslets an admin name the technician, themselves included; left empty, the office assigns it
Questions
  • Should the Leads tab, leads, new lead and import screens be left out of the map entirely, as they are here? Recommendation: yes, since no org technician reaches them; they stay in the code.
  • How should a job the office has not assigned yet look on its page (the creator's 'sent' view)? Recommendation: a title reading 'waiting for the office' and no work buttons, so the creator knows it is with the office.
  • After saving a new job, should the app open the job (as now) or return to My jobs? Recommendation: keep opening the job, so the creator sees it as sent.
  • The login screen, the parts picker, the photo view and the client card were not in the dump. If any of them opens its own screen rather than a sheet on the job page, it needs a row here. Recommendation: send the components' files so the map can be checked.
As phone screens

Home

My jobs: the technician's jobs, newest first, a page at a time, each with its state. This is the top screen after login. Every technician has the + to open a new job here.

Jobopen one job from the list
›
New jobthe + at the top; opens an empty new-job screen
›
Settingsthe cog in the header: who is logged in, and log out
›
‹ Home

login

Login: shown in place of the app when nobody is logged in. The technician enters email, password and company code.

My jobsafter a successful login, the first screen
›
‹ Home

settings

Settings: shows the logged-in technician's name and a log-out button.

My jobsback
›
Log outends the session
›
‹ Home

job

One job: its state in the header, then the planned day, description and tags, the client's name, phone and address, the parts, and while working the photos. A done job is read only, with a summary. A job still waiting for the office is read only, with no work to do.

My jobsback to the list
›
Related jobthe + menu: a new job that comes with this job's client and remembers where it was found
›
New jobthe + menu: an empty new-job screen
›
Settingsthe cog in the header
›
Reportcontinue when the work is done, to sign and send
›
Other job in progressjumps to the other job the technician has running, as JobWorkspace opens it
›
‹ job

report

Report: a summary of time, parts and photos, an optional note, the client's signature, and Send. Sending finishes the job.

Jobback to the job
›
My jobswhere the app goes after a report is sent
›
‹ Home

new job

New job: description, client name and phone, optional address and planned day. An admin also picks who does it, or leaves it for the office. Saved, the job opens.

Saved jobopened after saving; a job with no technician shows as waiting for the office
›
My jobsback, when the screen was not opened from a job
›
Who does it (admins only)lets an admin name the technician, themselves included; left empty, the office assigns it
›
Raw answer
The map covers the org technician's screens under the 2026-10-21 decisions. Leads, the lead screens, and the import screen are left out because no org technician reaches them. The project dump was cut at 9000 characters, so I did not read the LoginScreen, JobWorkspace, ClientCard, Menu, or TechnicianPicker components. Their rows come from the screens that call them, and the login question below covers the gap.

```json
{"screens": [
  {"path": [], "sentence": "My jobs: the technician's jobs, newest first, a page at a time, each with its state. This is the top screen after login. Every technician has the + to open a new job here.", "rows": [
    {"name": "Job", "form": "/jobs/[id]", "what": "open one job from the list"},
    {"name": "New job", "form": "/jobs/new", "what": "the + at the top; opens an empty new-job screen"},
    {"name": "Settings", "form": "/settings", "what": "the cog in the header: who is logged in, and log out"}
  ]},
  {"path": ["login"], "sentence": "Login: shown in place of the app when nobody is logged in. The technician enters email, password and company code.", "rows": [
    {"name": "My jobs", "form": "/", "what": "after a successful login, the first screen"}
  ]},
  {"path": ["settings"], "sentence": "Settings: shows the logged-in technician's name and a log-out button.", "rows": [
    {"name": "My jobs", "form": "/", "what": "back"},
    {"name": "Log out", "form": "button; no route, ends in the login screen", "what": "ends the session"}
  ]},
  {"path": ["job"], "sentence": "One job: its state in the header, then the planned day, description and tags, the client's name, phone and address, the parts, and while working the photos. A done job is read only, with a summary. A job still waiting for the office is read only, with no work to do.", "rows": [
    {"name": "My jobs", "form": "/", "what": "back to the list"},
    {"name": "Related job", "form": "/jobs/new with relatedJobId set to this job", "what": "the + menu: a new job that comes with this job's client and remembers where it was found"},
    {"name": "New job", "form": "/jobs/new", "what": "the + menu: an empty new-job screen"},
    {"name": "Settings", "form": "/settings", "what": "the cog in the header"},
    {"name": "Report", "form": "/jobs/[id]/report", "what": "continue when the work is done, to sign and send"},
    {"name": "Other job in progress", "form": "/jobs/[runningId]", "what": "jumps to the other job the technician has running, as JobWorkspace opens it"}
  ]},
  {"path": ["job", "report"], "sentence": "Report: a summary of time, parts and photos, an optional note, the client's signature, and Send. Sending finishes the job.", "rows": [
    {"name": "Job", "form": "/jobs/[id]", "what": "back to the job"},
    {"name": "My jobs", "form": "/", "what": "where the app goes after a report is sent"}
  ]},
  {"path": ["new job"], "sentence": "New job: description, client name and phone, optional address and planned day. An admin also picks who does it, or leaves it for the office. Saved, the job opens.", "rows": [
    {"name": "Saved job", "form": "/jobs/[id]", "what": "opened after saving; a job with no technician shows as waiting for the office"},
    {"name": "My jobs", "form": "/", "what": "back, when the screen was not opened from a job"},
    {"name": "Who does it (admins only)", "form": "picker on this screen, lists the company's technicians through listCompanyTechnicians", "what": "lets an admin name the technician, themselves included; left empty, the office assigns it"}
  ]}
],
"questions": [
  "Should the Leads tab, leads, new lead and import screens be left out of the map entirely, as they are here? Recommendation: yes, since no org technician reaches them; they stay in the code.",
  "How should a job the office has not assigned yet look on its page (the creator's 'sent' view)? Recommendation: a title reading 'waiting for the office' and no work buttons, so the creator knows it is with the office.",
  "After saving a new job, should the app open the job (as now) or return to My jobs? Recommendation: keep opening the job, so the creator sees it as sent.",
  "The login screen, the parts picker, the photo view and the client card were not in the dump. If any of them opens its own screen rather than a sheet on the job page, it needs a row here. Recommendation: send the components' files so the map can be checked."
]}
```

Today's skills · run 3 exit=0 seconds=45 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.643P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 3
As terminal help
nobody logged in
Log in with email, password and company code. Shown before anything else; the root layout renders it, it is not a route.
Log indata.login, then My jobsgets the technician into the app
Your jobs, newest first, a page at a time, each with its state. The top screen after login.
Job/jobs/[id]open one job to work it or read it
New job (+)/jobs/newopen a new job for the office to assign, or assign it yourself if admin
Settings (cog)/settingssee who is logged in, log out
Leads tab/leads (tab bar, shown to self-workers only)the self-worker's lead list
Leads tab
Your leads, open ones first in call-back order, or closed ones; loads a page at a time.
Open / Closed tabsin-screen tab switchswitch between open and closed leads
Lead/leads/[id]open a lead to call back, close it, or turn it into a job
New lead (+)/leads/newadd a lead from a call
Excel import/leads/importbring many leads in from a spreadsheet
Settings (cog)/settingssee who is logged in, log out
My jobs tab/back to jobs
My jobs › Job
One job: its state in the header, planned day, description and tags, client, and while working the parts and photos. Done or waiting-for-office jobs are read only.
Work controls (start, stop, parts, photos)JobWorkspace component (not read)do the work while the job is not done or waiting
Client cardClientCard component (not read)see the client's name, phone and address
Related job (+ menu)/jobs/new with relatedJobIdopen a job for the same client, found on this one
New job (+ menu)/jobs/newopen a separate new job
Another running job/jobs/[runningId]jump to the job already being worked
Continue to report/jobs/[id]/reportfinish the work and get the client's signature
Settings (cog)/settingssee who is logged in, log out
Back/return to My jobs
My jobs › Job › Continue to report
Review time, parts and photos, add a note, get the client's signature, send. Sending finishes the job and returns to My jobs.
Senddata.sendReport, then /send the report and finish the job
Notein-screen text inputadd a note to the report
Signaturein-screen SignaturePadthe client signs
Back/jobs/[id]return to the job without sending
My jobs › New job (+)
A new job: description, client name, phone, optional address and planned day. An admin also picks who does it. Saved, then opened.
Savedata.createJob, then /jobs/[id] (replaces this screen)save and open the new job
Who does it (admin only)data.listCompanyTechnicians (picker, no route)choose a technician of the company
Back/return to My jobs
My jobs › Job › Related job (+ menu)
The new job form, titled as a related job, with the client, phone and address already filled from this job.
Savedata.createJob with relatedJobId, then /jobs/[id]save the related job; the office sees where it was found
Back/jobs/[id]return to the job without saving
Leads tab › Lead › Open a job
The new job form, filled from the lead. Saving also marks the lead as converted.
Savedata.openJobFromLead, then /jobs/[id]open the job and convert the lead together
Back/leads/[id]return to the lead
Leads tab › Lead
One lead: its name and status, what they want, how to reach them. Open leads can be called back on a day, closed as not relevant, or turned into a job.
Call back on a daydata.setCallBack, then /leadsset the day to call back
Not relevantCloseLeadDialog, then data.closeLead, then /leadsclose the lead, with an optional reason
Open a job/jobs/new with leadId, name, phone, address, descriptionturn the lead into a job
Back/leadsreturn to the list
Leads tab › New lead (+)
Write down someone who might become a client: name, phone, what they want, optional address. Budget, source, email and notes sit under more details.
Savedata.createLead, then /leadssave the lead at the top of the list
More detailsin-screen expandbudget, source, email, notes
Back/leadsreturn to the list without saving
Leads tab › Excel import
Pick an Excel file: how many leads are ready, which rows are skipped and why. Import the ready ones in one go.
Pick filesystem file picker (expo-document-picker)choose the .xlsx file
Import N leadsdata.importLeads, then /leadssave the ready leads
Back/leadsreturn to the list
My jobs › Settings (cog)
Who is logged in, and a log out button.
Log outdata.logout, then login screenend the session
Back/return to My jobs
Questions
  • Leave 'Add as lead' out of a job's + menu, as the owner decided on 2026-10-21, or add it back later? Recommendation: leave it out; an org technician has no Leads screen to show it on.
  • Keep the Leads tab hidden for org technicians, as now? Recommendation: yes; the owner said to keep it for self-workers only.
  • Keep the 'who does it' picker on the new-job screen for admins, or always send new jobs to the office? Recommendation: keep the picker; it is the owner's decision of 2026-10-21.
  • After a report is sent the app returns to My jobs with no confirmation; the job just shows as done. Add a confirmation? Recommendation: no; the job's state already shows the result.
As phone screens
‹ Home

nobody logged in

Log in with email, password and company code. Shown before anything else; the root layout renders it, it is not a route.

Log ingets the technician into the app
›

Home

Your jobs, newest first, a page at a time, each with its state. The top screen after login.

Jobopen one job to work it or read it
›
New job (+)open a new job for the office to assign, or assign it yourself if admin
›
Settings (cog)see who is logged in, log out
›
Leads tabthe self-worker's lead list
›
‹ Home

Leads tab

Your leads, open ones first in call-back order, or closed ones; loads a page at a time.

Open / Closed tabsswitch between open and closed leads
›
Leadopen a lead to call back, close it, or turn it into a job
›
New lead (+)add a lead from a call
›
Excel importbring many leads in from a spreadsheet
›
Settings (cog)see who is logged in, log out
›
My jobs tabback to jobs
›
‹ My jobs

Job

One job: its state in the header, planned day, description and tags, client, and while working the parts and photos. Done or waiting-for-office jobs are read only.

Work controls (start, stop, parts, photos)do the work while the job is not done or waiting
›
Client cardsee the client's name, phone and address
›
Related job (+ menu)open a job for the same client, found on this one
›
New job (+ menu)open a separate new job
›
Another running jobjump to the job already being worked
›
Continue to reportfinish the work and get the client's signature
›
Settings (cog)see who is logged in, log out
›
Backreturn to My jobs
›
‹ Job

Continue to report

Review time, parts and photos, add a note, get the client's signature, send. Sending finishes the job and returns to My jobs.

Sendsend the report and finish the job
›
Noteadd a note to the report
›
Signaturethe client signs
›
Backreturn to the job without sending
›
‹ My jobs

New job (+)

A new job: description, client name, phone, optional address and planned day. An admin also picks who does it. Saved, then opened.

Savesave and open the new job
›
Who does it (admin only)choose a technician of the company
›
Backreturn to My jobs
›
‹ Job

Related job (+ menu)

The new job form, titled as a related job, with the client, phone and address already filled from this job.

Savesave the related job; the office sees where it was found
›
Backreturn to the job without saving
›
‹ Lead

Open a job

The new job form, filled from the lead. Saving also marks the lead as converted.

Saveopen the job and convert the lead together
›
Backreturn to the lead
›
‹ Leads tab

Lead

One lead: its name and status, what they want, how to reach them. Open leads can be called back on a day, closed as not relevant, or turned into a job.

Call back on a dayset the day to call back
›
Not relevantclose the lead, with an optional reason
›
Open a jobturn the lead into a job
›
Backreturn to the list
›
‹ Leads tab

New lead (+)

Write down someone who might become a client: name, phone, what they want, optional address. Budget, source, email and notes sit under more details.

Savesave the lead at the top of the list
›
More detailsbudget, source, email, notes
›
Backreturn to the list without saving
›
‹ Leads tab

Excel import

Pick an Excel file: how many leads are ready, which rows are skipped and why. Import the ready ones in one go.

Pick filechoose the .xlsx file
›
Import N leadssave the ready leads
›
Backreturn to the list
›
‹ My jobs

Settings (cog)

Who is logged in, and a log out button.

Log outend the session
›
Backreturn to My jobs
›
Raw answer
**Read 11 of 11 route files.** The components, the session code and the data adapter were cut from the dump, so rows that depend on them are marked "not read." The map uses the owner's decisions of 2026-10-21 (every technician is an org technician; the self-worker's Leads stay unused).

- **What the app is:** a Hebrew phone app where a technician works their jobs (start, parts, photos, client signature, report) and can open new jobs for the office to assign. Self-workers also keep a list of leads.
- **Top screen:** My jobs. Login shows before it and is rendered by the root layout, not a route.
- **Outside the flow:** Leads and its screens exist for self-workers only, and Settings is a side screen.

```json
{"screens": [
 {"path": ["nobody logged in"], "sentence": "Log in with email, password and company code. Shown before anything else; the root layout renders it, it is not a route.", "rows": [
  {"name": "Log in", "form": "data.login, then My jobs", "what": "gets the technician into the app"}
 ]},
 {"path": [], "sentence": "Your jobs, newest first, a page at a time, each with its state. The top screen after login.", "rows": [
  {"name": "Job", "form": "/jobs/[id]", "what": "open one job to work it or read it"},
  {"name": "New job (+)", "form": "/jobs/new", "what": "open a new job for the office to assign, or assign it yourself if admin"},
  {"name": "Settings (cog)", "form": "/settings", "what": "see who is logged in, log out"},
  {"name": "Leads tab", "form": "/leads (tab bar, shown to self-workers only)", "what": "the self-worker's lead list"}
 ]},
 {"path": ["Leads tab"], "sentence": "Your leads, open ones first in call-back order, or closed ones; loads a page at a time.", "rows": [
  {"name": "Open / Closed tabs", "form": "in-screen tab switch", "what": "switch between open and closed leads"},
  {"name": "Lead", "form": "/leads/[id]", "what": "open a lead to call back, close it, or turn it into a job"},
  {"name": "New lead (+)", "form": "/leads/new", "what": "add a lead from a call"},
  {"name": "Excel import", "form": "/leads/import", "what": "bring many leads in from a spreadsheet"},
  {"name": "Settings (cog)", "form": "/settings", "what": "see who is logged in, log out"},
  {"name": "My jobs tab", "form": "/", "what": "back to jobs"}
 ]},
 {"path": ["My jobs", "Job"], "sentence": "One job: its state in the header, planned day, description and tags, client, and while working the parts and photos. Done or waiting-for-office jobs are read only.", "rows": [
  {"name": "Work controls (start, stop, parts, photos)", "form": "JobWorkspace component (not read)", "what": "do the work while the job is not done or waiting"},
  {"name": "Client card", "form": "ClientCard component (not read)", "what": "see the client's name, phone and address"},
  {"name": "Related job (+ menu)", "form": "/jobs/new with relatedJobId", "what": "open a job for the same client, found on this one"},
  {"name": "New job (+ menu)", "form": "/jobs/new", "what": "open a separate new job"},
  {"name": "Another running job", "form": "/jobs/[runningId]", "what": "jump to the job already being worked"},
  {"name": "Continue to report", "form": "/jobs/[id]/report", "what": "finish the work and get the client's signature"},
  {"name": "Settings (cog)", "form": "/settings", "what": "see who is logged in, log out"},
  {"name": "Back", "form": "/", "what": "return to My jobs"}
 ]},
 {"path": ["My jobs", "Job", "Continue to report"], "sentence": "Review time, parts and photos, add a note, get the client's signature, send. Sending finishes the job and returns to My jobs.", "rows": [
  {"name": "Send", "form": "data.sendReport, then /", "what": "send the report and finish the job"},
  {"name": "Note", "form": "in-screen text input", "what": "add a note to the report"},
  {"name": "Signature", "form": "in-screen SignaturePad", "what": "the client signs"},
  {"name": "Back", "form": "/jobs/[id]", "what": "return to the job without sending"}
 ]},
 {"path": ["My jobs", "New job (+)"], "sentence": "A new job: description, client name, phone, optional address and planned day. An admin also picks who does it. Saved, then opened.", "rows": [
  {"name": "Save", "form": "data.createJob, then /jobs/[id] (replaces this screen)", "what": "save and open the new job"},
  {"name": "Who does it (admin only)", "form": "data.listCompanyTechnicians (picker, no route)", "what": "choose a technician of the company"},
  {"name": "Back", "form": "/", "what": "return to My jobs"}
 ]},
 {"path": ["My jobs", "Job", "Related job (+ menu)"], "sentence": "The new job form, titled as a related job, with the client, phone and address already filled from this job.", "rows": [
  {"name": "Save", "form": "data.createJob with relatedJobId, then /jobs/[id]", "what": "save the related job; the office sees where it was found"},
  {"name": "Back", "form": "/jobs/[id]", "what": "return to the job without saving"}
 ]},
 {"path": ["Leads tab", "Lead", "Open a job"], "sentence": "The new job form, filled from the lead. Saving also marks the lead as converted.", "rows": [
  {"name": "Save", "form": "data.openJobFromLead, then /jobs/[id]", "what": "open the job and convert the lead together"},
  {"name": "Back", "form": "/leads/[id]", "what": "return to the lead"}
 ]},
 {"path": ["Leads tab", "Lead"], "sentence": "One lead: its name and status, what they want, how to reach them. Open leads can be called back on a day, closed as not relevant, or turned into a job.", "rows": [
  {"name": "Call back on a day", "form": "data.setCallBack, then /leads", "what": "set the day to call back"},
  {"name": "Not relevant", "form": "CloseLeadDialog, then data.closeLead, then /leads", "what": "close the lead, with an optional reason"},
  {"name": "Open a job", "form": "/jobs/new with leadId, name, phone, address, description", "what": "turn the lead into a job"},
  {"name": "Back", "form": "/leads", "what": "return to the list"}
 ]},
 {"path": ["Leads tab", "New lead (+)"], "sentence": "Write down someone who might become a client: name, phone, what they want, optional address. Budget, source, email and notes sit under more details.", "rows": [
  {"name": "Save", "form": "data.createLead, then /leads", "what": "save the lead at the top of the list"},
  {"name": "More details", "form": "in-screen expand", "what": "budget, source, email, notes"},
  {"name": "Back", "form": "/leads", "what": "return to the list without saving"}
 ]},
 {"path": ["Leads tab", "Excel import"], "sentence": "Pick an Excel file: how many leads are ready, which rows are skipped and why. Import the ready ones in one go.", "rows": [
  {"name": "Pick file", "form": "system file picker (expo-document-picker)", "what": "choose the .xlsx file"},
  {"name": "Import N leads", "form": "data.importLeads, then /leads", "what": "save the ready leads"},
  {"name": "Back", "form": "/leads", "what": "return to the list"}
 ]},
 {"path": ["My jobs", "Settings (cog)"], "sentence": "Who is logged in, and a log out button.", "rows": [
  {"name": "Log out", "form": "data.logout, then login screen", "what": "end the session"},
  {"name": "Back", "form": "/", "what": "return to My jobs"}
 ]}
 ],
 "questions": [
  "Leave 'Add as lead' out of a job's + menu, as the owner decided on 2026-10-21, or add it back later? Recommendation: leave it out; an org technician has no Leads screen to show it on.",
  "Keep the Leads tab hidden for org technicians, as now? Recommendation: yes; the owner said to keep it for self-workers only.",
  "Keep the 'who does it' picker on the new-job screen for admins, or always send new jobs to the office? Recommendation: keep the picker; it is the owner's decision of 2026-10-21.",
  "After a report is sent the app returns to My jobs with no confirmation; the job just shows as done. Add a confirmation? Recommendation: no; the job's state already shows the result."
 ]}
```

screen-decomposition, first draft · run 3 exit=0 seconds=79 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.973P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 1
As terminal help
My jobs: the jobs assigned to this technician, and the ones they sent to the office that are not yet assigned, newest first, a page at a time.
עבודה (each job in the list)/jobs/[id]opens the job: its work, client, parts and photos
עבודה חדשה (+)/jobs/newopens the new-job form; saved, it waits for the office, or goes to the technician an admin names
הגדרות (cog)/settingsopens settings: who is logged in, and log out
לידים (tab, self-worker only)/leadsopens the Leads list; not used by org technicians
העבודות שלי › עבודה
One job: its planned day, description and client, then the work on it (timer, parts, photos), and the report; read only when done or waiting for the office.
התחלה / עצירה של העבודה (timer)JobWorkspace → saveWorkState('in_progress' | 'awaiting_signature')starts or stops the work timer and tells the office
חלקיםJobWorkspace → listPartsCatalogadds parts from the catalog to the job, with their quantity
תמונותJobWorkspace → expo-image-pickeradds photos of the work, shrunk to 1280px
המשך לדוח/jobs/[id]/reportopens the report of the job, to sign and send
עבודה קשורה (from +)/jobs/new?relatedJobId=<id>opens a new job with this client's details; the office sees where it was found
עבודה חדשה (from +)/jobs/newopens a blank new-job form
חזרה/goes back to My jobs
העבודות שלי › עבודה › דוח עבודה
The report of one job, before sending: time worked, parts, photos, a note and the client's signature.
הערהTextInput on the reportadds a note to the report
חתימת הלקוחSignaturePadthe client signs; the signature is required before sending
שלחdata.sendReport → /sends the report, marks the job done, and returns to My jobs
חזרה/jobs/[id]goes back to the job without sending
העבודות שלי › עבודה חדשה
The form to open a job: description, client name, phone, address and planned day; an admin also names who does it.
פרטי העבודה והלקוחFormField ×4 and DayChoicefills in the job the office sees
מי מבצע (admins only)TechnicianPicker → listCompanyTechniciansnames who does the job from your company, you included; without it the job waits for the office
שמורdata.createJob → /jobs/[id]saves the job and opens it
חזרה/goes back to My jobs without saving
הגדרות
Settings: the technician who is logged in, and log out.
יציאהdata.logout → login screenlogs out and shows the login screen
חזרה/goes back to My jobs
לידים
The Leads list for a self-worker: the open leads in call-back order, or the closed ones, a page at a time.
פתוחים (tab)listMyLeads({closed: false})shows the open leads
סגורים (tab)listMyLeads({closed: true})shows the converted and lost leads, read only
ליד (each lead in the list)/leads/[id]opens the lead: call back, not relevant, or open a job
ליד חדש (+)/leads/newopens the form to add a lead by hand
ייבוא מאקסל/leads/importopens the Excel import of leads
הגדרות (cog)/settingsopens settings
לידים › ליד
One lead: what they want, how to reach them, and the next step after the call.
חזרה ביוםdata.setCallBack(id, day)sets the day to call back, and returns to Leads
לא רלוונטיCloseLeadDialog → data.closeLead(id, reason?)closes the lead as lost, with an optional reason
פתח עבודה/jobs/new?leadId=<id>opens the new-job form filled from the lead; saving makes the lead converted
חזרה/leadsgoes back to Leads
לידים › ליד חדש
The form to add a lead: name, phone and what they want are required; address and more details are optional.
שמורdata.createLead → /leadssaves the lead as new and goes back to Leads
פרטים נוספיםexpands in placeshows budget, source, email and notes
חזרה/leadsgoes back to Leads without saving
לידים › ייבוא מאקסל
The Excel import: how many leads are ready, and which rows are skipped and why.
בחירת קובץ / החלפהexpo-document-picker (xlsx)chooses an Excel file of leads
ייבוא N לידיםdata.importLeads → /leadssaves the ready leads in one call
חזרה/leadsgoes back to Leads
Questions
  • The login screen opens filled in with the demo admin login (DEMO_LOGIN, user100). Should a production build keep this? Recommendation: no; keep the pre-fill behind the dev flag.
  • What name does a job's row show, given a job has no title? Recommendation: client name on line 1, description on line 2, to keep the two-line rule. JobRow was not in the dump, so confirm its current text first.
  • Should jobs sent to the office that have no technician carry a label in My jobs? Recommendation: yes, a small 'waiting for the office' label, so the creator can tell a sent job from one assigned to them.
As phone screens

Home

My jobs: the jobs assigned to this technician, and the ones they sent to the office that are not yet assigned, newest first, a page at a time.

עבודה (each job in the list)opens the job: its work, client, parts and photos
›
עבודה חדשה (+)opens the new-job form; saved, it waits for the office, or goes to the technician an admin names
›
הגדרות (cog)opens settings: who is logged in, and log out
›
לידים (tab, self-worker only)opens the Leads list; not used by org technicians
›
‹ העבודות שלי

עבודה

One job: its planned day, description and client, then the work on it (timer, parts, photos), and the report; read only when done or waiting for the office.

התחלה / עצירה של העבודה (timer)starts or stops the work timer and tells the office
›
חלקיםadds parts from the catalog to the job, with their quantity
›
תמונותadds photos of the work, shrunk to 1280px
›
המשך לדוחopens the report of the job, to sign and send
›
עבודה קשורה (from +)opens a new job with this client's details; the office sees where it was found
›
עבודה חדשה (from +)opens a blank new-job form
›
חזרהgoes back to My jobs
›
‹ עבודה

דוח עבודה

The report of one job, before sending: time worked, parts, photos, a note and the client's signature.

הערהadds a note to the report
›
חתימת הלקוחthe client signs; the signature is required before sending
›
שלחsends the report, marks the job done, and returns to My jobs
›
חזרהgoes back to the job without sending
›
‹ העבודות שלי

עבודה חדשה

The form to open a job: description, client name, phone, address and planned day; an admin also names who does it.

פרטי העבודה והלקוחfills in the job the office sees
›
מי מבצע (admins only)names who does the job from your company, you included; without it the job waits for the office
›
שמורsaves the job and opens it
›
חזרהgoes back to My jobs without saving
›
‹ Home

הגדרות

Settings: the technician who is logged in, and log out.

יציאהlogs out and shows the login screen
›
חזרהgoes back to My jobs
›
‹ Home

לידים

The Leads list for a self-worker: the open leads in call-back order, or the closed ones, a page at a time.

פתוחים (tab)shows the open leads
›
סגורים (tab)shows the converted and lost leads, read only
›
ליד (each lead in the list)opens the lead: call back, not relevant, or open a job
›
ליד חדש (+)opens the form to add a lead by hand
›
ייבוא מאקסלopens the Excel import of leads
›
הגדרות (cog)opens settings
›
‹ לידים

ליד

One lead: what they want, how to reach them, and the next step after the call.

חזרה ביוםsets the day to call back, and returns to Leads
›
לא רלוונטיcloses the lead as lost, with an optional reason
›
פתח עבודהopens the new-job form filled from the lead; saving makes the lead converted
›
חזרהgoes back to Leads
›
‹ לידים

ליד חדש

The form to add a lead: name, phone and what they want are required; address and more details are optional.

שמורsaves the lead as new and goes back to Leads
›
פרטים נוספיםshows budget, source, email and notes
›
חזרהgoes back to Leads without saving
›
‹ לידים

ייבוא מאקסל

The Excel import: how many leads are ready, and which rows are skipped and why.

בחירת קובץ / החלפהchooses an Excel file of leads
›
ייבוא N לידיםsaves the ready leads in one call
›
חזרהgoes back to Leads
›
Raw answer
## Scenario

Reasoning from experience, not from the code: a technician is at a client's home with a phone. They open the app to see their jobs, start one, add parts and photos, have the client sign, and send the report. On site they find more work, so they open a new job, which goes to the office unless an admin names who does it. A self-worker, who is no longer being onboarded, would also work through their Leads.

## Inventory

| Thing | Technical form | Where it lives |
|---|---|---|
| Login (email, password, company code) | `LoginScreen`, shown by `_layout.js` when logged out | Gate, outside the tree |
| My jobs | `/` (`(tabs)/index.js`) | Top screen |
| Job | `/jobs/[id]` | Opened from My jobs |
| Job workspace (timer, parts, photos) | `JobWorkspace`, on the job screen | Inside the job |
| Report | `/jobs/[id]/report` | Inside the job |
| New job (and related job) | `/jobs/new` | From My jobs, a job's + menu, or a lead |
| Settings | `/settings` | From the cog on every screen |
| Leads, lead, new lead, Excel import | `/leads`, `/leads/[id]`, `/leads/new`, `/leads/import` | Self-worker only, unused for new users |
| Parts catalog | `data.listPartsCatalog`, picked inside the job | Inside the job |
| Signature | `SignaturePad`, on the report | Inside the report |

Left out of the map, because no technician reaches them on the phone: the SQL files and tests, the demo logins in the README, the GitHub Releases page, the web repo, and the dashboard.

## Judgment calls

- **Login is the gate, not a place.** It has no path, so it is not in the tree.
- **The new-job screen is reached from three places** (My jobs, a job's + menu, a lead). It has one screen entry, and its path shows the place it was opened from first (My jobs). The title changes to "עבודה קשורה" for a related job, and a lead's version comes prefilled.
- **A job's + menu is not a path.** Its two choices are rows on the job screen, as the menu is a menu, not a place.
- **Leads stays in the map, marked self-worker only.** You said to keep it in code, and it is still reachable for existing self-worker accounts.
- **The 2026-10-21 decisions govern.** Every technician can create a job, and an admin names the technician. The "Add as lead" option is left out, because org technicians have no Leads screen.
- **The dump was cut at 9,000 characters, and several components were not included** (`JobWorkspace`, `ClientCard`, `JobRow`, `PageShell`, `TabBar`, `LoginScreen`, `Menu`, `CloseLeadDialog`, `TechnicianPicker`, and the rest of `contract.js`). The job-workspace rows (timer, parts, photos) are read from the props and comments of the screens that use them. Confirm them in those files before building.
- **Names are the app's Hebrew words; the sentences and "what" lines are English.** No word here was invented.
- **The map is hand-written from these files.** Once the route table is read, the map should be generated from it, so a new screen cannot be missed.

## Questions

1. **Login pre-fills the demo admin login** (`DEMO_LOGIN`, `user100`). Should a production build keep this? My recommendation: no. Keep the pre-fill only behind the dev flag, so an admin login is not shipped on the login screen.
2. **What name does a job's row show?** A job has no title, so the list row needs the client's name or the description. My recommendation: client name on line 1, description on line 2, which is the two-line rule. I could not read `JobRow` to confirm what it does now.
3. **Should jobs sent to the office, with no technician, be labelled in My jobs?** The creator sees them until they are assigned. My recommendation: yes, with a small label such as "waiting for the office", so the creator can tell a sent job from one assigned to them.

```json
{"screens": [
 {"path": [], "sentence": "My jobs: the jobs assigned to this technician, and the ones they sent to the office that are not yet assigned, newest first, a page at a time.", "rows": [
   {"name": "עבודה (each job in the list)", "form": "/jobs/[id]", "what": "opens the job: its work, client, parts and photos"},
   {"name": "עבודה חדשה (+)", "form": "/jobs/new", "what": "opens the new-job form; saved, it waits for the office, or goes to the technician an admin names"},
   {"name": "הגדרות (cog)", "form": "/settings", "what": "opens settings: who is logged in, and log out"},
   {"name": "לידים (tab, self-worker only)", "form": "/leads", "what": "opens the Leads list; not used by org technicians"}
 ]},
 {"path": ["העבודות שלי", "עבודה"], "sentence": "One job: its planned day, description and client, then the work on it (timer, parts, photos), and the report; read only when done or waiting for the office.", "rows": [
   {"name": "התחלה / עצירה של העבודה (timer)", "form": "JobWorkspace → saveWorkState('in_progress' | 'awaiting_signature')", "what": "starts or stops the work timer and tells the office"},
   {"name": "חלקים", "form": "JobWorkspace → listPartsCatalog", "what": "adds parts from the catalog to the job, with their quantity"},
   {"name": "תמונות", "form": "JobWorkspace → expo-image-picker", "what": "adds photos of the work, shrunk to 1280px"},
   {"name": "המשך לדוח", "form": "/jobs/[id]/report", "what": "opens the report of the job, to sign and send"},
   {"name": "עבודה קשורה (from +)", "form": "/jobs/new?relatedJobId=<id>", "what": "opens a new job with this client's details; the office sees where it was found"},
   {"name": "עבודה חדשה (from +)", "form": "/jobs/new", "what": "opens a blank new-job form"},
   {"name": "חזרה", "form": "/", "what": "goes back to My jobs"}
 ]},
 {"path": ["העבודות שלי", "עבודה", "דוח עבודה"], "sentence": "The report of one job, before sending: time worked, parts, photos, a note and the client's signature.", "rows": [
   {"name": "הערה", "form": "TextInput on the report", "what": "adds a note to the report"},
   {"name": "חתימת הלקוח", "form": "SignaturePad", "what": "the client signs; the signature is required before sending"},
   {"name": "שלח", "form": "data.sendReport → /", "what": "sends the report, marks the job done, and returns to My jobs"},
   {"name": "חזרה", "form": "/jobs/[id]", "what": "goes back to the job without sending"}
 ]},
 {"path": ["העבודות שלי", "עבודה חדשה"], "sentence": "The form to open a job: description, client name, phone, address and planned day; an admin also names who does it.", "rows": [
   {"name": "פרטי העבודה והלקוח", "form": "FormField ×4 and DayChoice", "what": "fills in the job the office sees"},
   {"name": "מי מבצע (admins only)", "form": "TechnicianPicker → listCompanyTechnicians", "what": "names who does the job from your company, you included; without it the job waits for the office"},
   {"name": "שמור", "form": "data.createJob → /jobs/[id]", "what": "saves the job and opens it"},
   {"name": "חזרה", "form": "/", "what": "goes back to My jobs without saving"}
 ]},
 {"path": ["הגדרות"], "sentence": "Settings: the technician who is logged in, and log out.", "rows": [
   {"name": "יציאה", "form": "data.logout → login screen", "what": "logs out and shows the login screen"},
   {"name": "חזרה", "form": "/", "what": "goes back to My jobs"}
 ]},
 {"path": ["לידים"], "sentence": "The Leads list for a self-worker: the open leads in call-back order, or the closed ones, a page at a time.", "rows": [
   {"name": "פתוחים (tab)", "form": "listMyLeads({closed: false})", "what": "shows the open leads"},
   {"name": "סגורים (tab)", "form": "listMyLeads({closed: true})", "what": "shows the converted and lost leads, read only"},
   {"name": "ליד (each lead in the list)", "form": "/leads/[id]", "what": "opens the lead: call back, not relevant, or open a job"},
   {"name": "ליד חדש (+)", "form": "/leads/new", "what": "opens the form to add a lead by hand"},
   {"name": "ייבוא מאקסל", "form": "/leads/import", "what": "opens the Excel import of leads"},
   {"name": "הגדרות (cog)", "form": "/settings", "what": "opens settings"}
 ]},
 {"path": ["לידים", "ליד"], "sentence": "One lead: what they want, how to reach them, and the next step after the call.", "rows": [
   {"name": "חזרה ביום", "form": "data.setCallBack(id, day)", "what": "sets the day to call back, and returns to Leads"},
   {"name": "לא רלוונטי", "form": "CloseLeadDialog → data.closeLead(id, reason?)", "what": "closes the lead as lost, with an optional reason"},
   {"name": "פתח עבודה", "form": "/jobs/new?leadId=<id>", "what": "opens the new-job form filled from the lead; saving makes the lead converted"},
   {"name": "חזרה", "form": "/leads", "what": "goes back to Leads"}
 ]},
 {"path": ["לידים", "ליד חדש"], "sentence": "The form to add a lead: name, phone and what they want are required; address and more details are optional.", "rows": [
   {"name": "שמור", "form": "data.createLead → /leads", "what": "saves the lead as new and goes back to Leads"},
   {"name": "פרטים נוספים", "form": "expands in place", "what": "shows budget, source, email and notes"},
   {"name": "חזרה", "form": "/leads", "what": "goes back to Leads without saving"}
 ]},
 {"path": ["לידים", "ייבוא מאקסל"], "sentence": "The Excel import: how many leads are ready, and which rows are skipped and why.", "rows": [
   {"name": "בחירת קובץ / החלפה", "form": "expo-document-picker (xlsx)", "what": "chooses an Excel file of leads"},
   {"name": "ייבוא N לידים", "form": "data.importLeads → /leads", "what": "saves the ready leads in one call"},
   {"name": "חזרה", "form": "/leads", "what": "goes back to Leads"}
 ]}
],
"questions": [
 "The login screen opens filled in with the demo admin login (DEMO_LOGIN, user100). Should a production build keep this? Recommendation: no; keep the pre-fill behind the dev flag.",
 "What name does a job's row show, given a job has no title? Recommendation: client name on line 1, description on line 2, to keep the two-line rule. JobRow was not in the dump, so confirm its current text first.",
 "Should jobs sent to the office that have no technician carry a label in My jobs? Recommendation: yes, a small 'waiting for the office' label, so the creator can tell a sent job from one assigned to them."
]}
```

screen-decomposition, final · run 3 exit=0 seconds=77 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.81P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
Your jobs, newest first, each with its state, a page at a time; the title row holds the + to open a new job.
עבודה (a job in the list)/jobs/[id]opens the job's page to start, work on and finish it
עבודה חדשה (+ in the title row)/jobs/newopens the new-job form: saved for the office to assign, or for the technician an admin names
הגדרות (cog in the header)/settingsopens who is logged in and the log-out button
עבודה
One job: its state in the header, then its planned day, description, client and, while it is being worked, its parts and photos; a job still waiting for the office, or one that is done, is read only.
עבודה קשורה (+ menu in the header)/jobs/new with this job's client and originopens the new-job form filled in with this job's client, for work found here
עבודה חדשה (+ menu in the header)/jobs/newopens an empty new-job form
לקוח (client name, phone, address)ClientCard, job.clientshows who the job is for; can't confirm whether tapping the name opens more
חלקים (parts)JobWorkspace, listPartsCatalogadds the catalog parts used on this job and their amounts, while it is being worked
תמונות (photos)JobWorkspace, cameraadds photos of the work, shrunk to 1280 px
דוח עבודה (continue)/jobs/[id]/reportopens the report to check it, add a note, sign and send
עבודה שכבר בביצוע (another running job)/jobs/[runningId]opens the other job already being worked; can't confirm when this appears
עבודה › דוח עבודה
The report for one job: its minutes, parts and photos, a note, and the client's signature, before it is sent.
הערה (note)TextInput, report notesadds a free note to the report
חתימת הלקוח (client signature)SignaturePadthe client signs here; saved as a PNG image
שלח (send)data.sendReport, then /sends the report, marks the job done and returns to My jobs; needs a signature first
עבודה חדשה
The form for a new job: what is wanted, the client, the planned day, and, for an admin, who does it.
תיאור (description)FormFieldsays what the job is about; required
שם הלקוח (client name)FormFieldthe client's name; required
טלפון (phone)FormFieldthe client's phone; required
כתובת (address)FormFieldwhere the job is; optional
יום ביצוע (planned day)DayChoicesets the day agreed with the client; optional
מי מבצע (who does it, admins only)TechnicianPicker, listCompanyTechniciansnames a technician in the company; left empty, the job waits for the office
שמור (save)data.createJob, then /jobs/[id]saves the job and opens it
הגדרות
Who is logged in, and logging out.
יציאה (log out)data.logout, then loginlogs out and shows the login screen
Questions
  • What word should a job waiting for the office carry on the list row and the job page? The owner's word is 'sent'. Recommendation: use 'sent' and keep the state word for jobs that have a technician.
  • Should a related job show the job it was found in, as one row labelled with the origin job's client name? Recommendation: yes, so the technician can get back to it.
  • Should the + menu keep the app's labels 'עבודה חדשה' and 'עבודה קשורה', or use the owner's English 'Create a new job' and 'Create related job'? Recommendation: keep the app's labels.
  • Is opening another job while one is in progress meant to send the technician to the running job (onOpenJob)? I can't see the rule in the dump. If it is intended, what is the rule?
As phone screens

Home

Your jobs, newest first, each with its state, a page at a time; the title row holds the + to open a new job.

עבודה (a job in the list)opens the job's page to start, work on and finish it
›
עבודה חדשה (+ in the title row)opens the new-job form: saved for the office to assign, or for the technician an admin names
›
הגדרות (cog in the header)opens who is logged in and the log-out button
›
‹ Home

עבודה

One job: its state in the header, then its planned day, description, client and, while it is being worked, its parts and photos; a job still waiting for the office, or one that is done, is read only.

עבודה קשורה (+ menu in the header)opens the new-job form filled in with this job's client, for work found here
›
עבודה חדשה (+ menu in the header)opens an empty new-job form
›
לקוח (client name, phone, address)shows who the job is for; can't confirm whether tapping the name opens more
›
חלקים (parts)adds the catalog parts used on this job and their amounts, while it is being worked
›
תמונות (photos)adds photos of the work, shrunk to 1280 px
›
דוח עבודה (continue)opens the report to check it, add a note, sign and send
›
עבודה שכבר בביצוע (another running job)opens the other job already being worked; can't confirm when this appears
›
‹ עבודה

דוח עבודה

The report for one job: its minutes, parts and photos, a note, and the client's signature, before it is sent.

הערה (note)adds a free note to the report
›
חתימת הלקוח (client signature)the client signs here; saved as a PNG image
›
שלח (send)sends the report, marks the job done and returns to My jobs; needs a signature first
›
‹ Home

עבודה חדשה

The form for a new job: what is wanted, the client, the planned day, and, for an admin, who does it.

תיאור (description)says what the job is about; required
›
שם הלקוח (client name)the client's name; required
›
טלפון (phone)the client's phone; required
›
כתובת (address)where the job is; optional
›
יום ביצוע (planned day)sets the day agreed with the client; optional
›
מי מבצע (who does it, admins only)names a technician in the company; left empty, the job waits for the office
›
שמור (save)saves the job and opens it
›
‹ Home

הגדרות

Who is logged in, and logging out.

יציאה (log out)logs out and shows the login screen
›
Raw answer
## Scenario

*Reasoning from experience, not from the code:* A technician on a phone is at a client's site, or between sites. They open the app to see their jobs, start one, take photos and note parts, have the client sign on the phone, and send the report back to the office. When they find more work on site, they open a new job (or a related job from the one they're on) and the office assigns it. An admin can also name who does it.

## Inventory

| Thing | Technical form | Defined in |
|---|---|---|
| My jobs (list, paged) | `(tabs)/index.js`, `listMyJobs` | `src/app/(tabs)/index.js` |
| Job page | `/jobs/[id]`, `src/app/jobs/[id]/index.js` | same |
| Report | `/jobs/[id]/report` | `src/app/jobs/[id]/report.js` |
| New job (and related job) | `/jobs/new` | `src/app/jobs/new.js` |
| Settings | `/settings` | `src/app/settings.js` |
| Login (gate, no route) | shown by `src/app/_layout.js` | `src/app/_layout.js` |
| Parts catalog, photos, signature | inside the job page's work area and the report | `listPartsCatalog`, `JobWorkspace`, `SignaturePad` |
| Company technicians (admin picker) | `listCompanyTechnicians` | `src/data/contract.js` |

Off the map, by the owner's decisions (see judgment calls): Leads, lead screens, Excel import, and the self-worker's own jobs.

## Questions for the user

1. **Word for a job waiting for the office.** The list row and the job page both need a label for a job with no technician yet. The owner's word is "sent". *Recommendation:* use "sent" on the list row and the job page, and keep the state word for jobs that have a technician. The state words are in `jobStateWords.js`, which I did not see.
2. **Showing where a related job came from.** The related job stores the job it was found in, but no screen shows it. *Recommendation:* add one row on the related job's page, "found in job", labelled with the origin job's client name and opening it. No id appears, per the list rule.
3. **Menu labels.** The app says "עבודה חדשה" and "עבודה קשורה". The owner's note says "Create a new job" and "Create related job". *Recommendation:* keep the app's labels. The owner's English read as a description, not as label text.
4. **Opening another running job.** The job page passes an `onOpenJob` callback, which suggests a technician with a job in progress is sent to it. I can't see the rule in the dump. Is this intended, and when does it happen?

## Judgment calls

- **Leads left off the map.** The Leads tab, the new lead, the lead page, Excel import, and "open a job from a lead" stay in the code but are off the map. The owner, 2026-10-21: "don't remove it just abandon it. leave it for 'self' workers which will never be used." "Add as lead" is also left out, per the owner's decision.
- **Login is the gate, not a tree node.** It is shown in place of the app when nobody is logged in. Its fields live in `LoginScreen`, which is not in the dump, so I can't list them.
- **The cog** is in the header of every screen. I listed it once, on My jobs, and did not repeat it on each screen.
- **The + menu on the job page is a menu,** not a place, so it is in no path. Its two choices are rows on the job page.
- **Paths include the screen's own noun, last.** A job's noun is "עבודה", not its id. The job page has no title, and rows never show ids.
- **New job from a job page** is the same screen as the top-level new job, with the title and fields changed. The map gives it the static path.
- **Read-only facts go in the sentences, not the rows,** because nothing on them can be reached: the state, the planned day, the description and tags, the done job's summary, the report's work summary.
- **A waiting job** is read only and shows no work area. It is not a separate screen.
- **"Ticket"** is the office's word in the owner's notes. The app says "עבודה" (job), so the app uses "job" throughout.
- **Names are the app's Hebrew labels,** taken from the code, with English in brackets. I have not seen the rendered screens.
- **Can't confirm:** `JobWorkspace`, `ClientCard`, `JobRow`, `DoneJobSummary`, `DayChoice`, `TechnicianPicker`, `FormField`, `SignaturePad`, `LoginScreen`, the data adapters beyond `contract.js`, and the Hebrew state words. Where a row depends on these, the `what` says so.

```json
{"screens": [
 {"path": [],
  "sentence": "Your jobs, newest first, each with its state, a page at a time; the title row holds the + to open a new job.",
  "rows": [
   {"name": "עבודה (a job in the list)", "form": "/jobs/[id]", "what": "opens the job's page to start, work on and finish it"},
   {"name": "עבודה חדשה (+ in the title row)", "form": "/jobs/new", "what": "opens the new-job form: saved for the office to assign, or for the technician an admin names"},
   {"name": "הגדרות (cog in the header)", "form": "/settings", "what": "opens who is logged in and the log-out button"}
  ]},
 {"path": ["עבודה"],
  "sentence": "One job: its state in the header, then its planned day, description, client and, while it is being worked, its parts and photos; a job still waiting for the office, or one that is done, is read only.",
  "rows": [
   {"name": "עבודה קשורה (+ menu in the header)", "form": "/jobs/new with this job's client and origin", "what": "opens the new-job form filled in with this job's client, for work found here"},
   {"name": "עבודה חדשה (+ menu in the header)", "form": "/jobs/new", "what": "opens an empty new-job form"},
   {"name": "לקוח (client name, phone, address)", "form": "ClientCard, job.client", "what": "shows who the job is for; can't confirm whether tapping the name opens more"},
   {"name": "חלקים (parts)", "form": "JobWorkspace, listPartsCatalog", "what": "adds the catalog parts used on this job and their amounts, while it is being worked"},
   {"name": "תמונות (photos)", "form": "JobWorkspace, camera", "what": "adds photos of the work, shrunk to 1280 px"},
   {"name": "דוח עבודה (continue)", "form": "/jobs/[id]/report", "what": "opens the report to check it, add a note, sign and send"},
   {"name": "עבודה שכבר בביצוע (another running job)", "form": "/jobs/[runningId]", "what": "opens the other job already being worked; can't confirm when this appears"}
  ]},
 {"path": ["עבודה", "דוח עבודה"],
  "sentence": "The report for one job: its minutes, parts and photos, a note, and the client's signature, before it is sent.",
  "rows": [
   {"name": "הערה (note)", "form": "TextInput, report notes", "what": "adds a free note to the report"},
   {"name": "חתימת הלקוח (client signature)", "form": "SignaturePad", "what": "the client signs here; saved as a PNG image"},
   {"name": "שלח (send)", "form": "data.sendReport, then /", "what": "sends the report, marks the job done and returns to My jobs; needs a signature first"}
  ]},
 {"path": ["עבודה חדשה"],
  "sentence": "The form for a new job: what is wanted, the client, the planned day, and, for an admin, who does it.",
  "rows": [
   {"name": "תיאור (description)", "form": "FormField", "what": "says what the job is about; required"},
   {"name": "שם הלקוח (client name)", "form": "FormField", "what": "the client's name; required"},
   {"name": "טלפון (phone)", "form": "FormField", "what": "the client's phone; required"},
   {"name": "כתובת (address)", "form": "FormField", "what": "where the job is; optional"},
   {"name": "יום ביצוע (planned day)", "form": "DayChoice", "what": "sets the day agreed with the client; optional"},
   {"name": "מי מבצע (who does it, admins only)", "form": "TechnicianPicker, listCompanyTechnicians", "what": "names a technician in the company; left empty, the job waits for the office"},
   {"name": "שמור (save)", "form": "data.createJob, then /jobs/[id]", "what": "saves the job and opens it"}
  ]},
 {"path": ["הגדרות"],
  "sentence": "Who is logged in, and logging out.",
  "rows": [
   {"name": "יציאה (log out)", "form": "data.logout, then login", "what": "logs out and shows the login screen"}
  ]}
],
"questions": [
 "What word should a job waiting for the office carry on the list row and the job page? The owner's word is 'sent'. Recommendation: use 'sent' and keep the state word for jobs that have a technician.",
 "Should a related job show the job it was found in, as one row labelled with the origin job's client name? Recommendation: yes, so the technician can get back to it.",
 "Should the + menu keep the app's labels 'עבודה חדשה' and 'עבודה קשורה', or use the owner's English 'Create a new job' and 'Create related job'? Recommendation: keep the app's labels.",
 "Is opening another job while one is in progress meant to send the technician to the running job (onOpenJob)? I can't see the rule in the dump. If it is intended, what is the rule?"
]}
```

No skill · run 4 exit=0 seconds=41 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.63P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 1
As terminal help
My jobs: the technician's jobs, newest first, a page at a time, each with its state. A job sent to the office and still waiting for assignment shows as sent, read only. The + in the title row opens a new job.
A job/jobs/[id]Opens one job to work on, or to read if it is done or still waiting.
New job (+)/jobs/newSends a new job: to the office to assign, or to a named technician if the user is an admin.
Settings (cog)/settingsShows who is logged in and offers logging out.
log in
Login: shown in place of the rest of the app when nobody is logged in. Email, password and company code.
Log in/ (My jobs)Signs the technician in and opens My jobs.
new job
New job: what is wanted, the client, and the planned day if known. Opened empty from My jobs or the job's + menu, or filled in with the client of the job it came from (a related job, which the office's ticket shows as found in that job). An admin also picks who does it. Saving opens the new job.
Descriptiontext field on this screenWhat the work is. Required.
Client nametext field on this screenRequired.
Client phonephone field on this screenRequired.
Client addresstext field on this screenOptional.
Planned dayday picker on this screen (YYYY-MM-DD)The day agreed with the client. Optional.
Who does itsearch picker on this screen, admins only (data.listCompanyTechnicians, at most 50 names, themselves first)An admin names a technician of their own company, themselves included. Left empty, the job waits for the office to assign it.
Save/jobs/[id] (replaces this screen)Saves the job and opens it.
Back/ (My jobs)Leaves without saving.
job
One job, in the order the technician needs it: its state in the header, then the planned day, the description with its tags, the client's name, phone and address, the parts, and, while it is being worked, the photos. A done job is read only; so is a job still waiting for the office, which has no work to do yet.
Job menu (+)menu on this screenOpens the two choices below.
Related job/jobs/new with the client and the relatedJobId of this jobA new job for the same client, which the office's ticket shows as found in this job.
New job/jobs/new (empty)A new job with nothing filled in.
Partsparts picker on this screen, from the office's catalog (data.listPartsCatalog)Adds parts used on the job. Shown while the job is being worked.
Photoscamera on this screen (expo-image-picker)Adds photos of the work. Shown while the job is being worked.
Continue to report/jobs/[id]/reportGoes on to the report, signature and sending. Shown while the job is being worked.
Job in progress/jobs/[runningId]Opens another job the technician has in progress.
Back/ (My jobs)Returns to My jobs.
Settings (cog)/settingsShows who is logged in and offers logging out.
job › report
Report: review the time and parts and photos, add an optional note, have the client sign, then send. Sending finishes the job and goes back to My jobs. If sending fails, the draft is kept and the technician can try again.
Notetext field on this screenAn optional note for the office.
Client signaturesignature pad on this screenRequired before sending.
Send/ (My jobs, replaces the stack)Saves the report, finishes the job, returns to My jobs.
Back/jobs/[id]Returns to the job without sending.
settings
Settings: who is logged in, and logging out.
Log out/ (shows the login screen)Logs the technician out.
Back/ (My jobs)Returns to My jobs.
Questions
  • The login screen opens filled in with a demo login (DEMO_LOGIN in src/data/seed.js). Should that be removed from the production build? Recommendation: yes, keep it only in test builds.
  • A job the technician sent that is still waiting for the office: what should its state word say in My jobs? Recommendation: a short 'sent' label (in Hebrew, to match the app), shown read only, with no action.
  • The bottom tab bar is shown only for self-workers, so with none left it would never appear. Recommendation: drop it, and make My jobs the only screen at the top. Leads stays in the code, with no route linked to it.
  • The owner's decision covers an admin naming the technician only on the new-job screen. Should an admin also be able to change who does a job later, from the job screen? Recommendation: not now, since the decision did not ask for it; add it later if needed.
As phone screens

Home

My jobs: the technician's jobs, newest first, a page at a time, each with its state. A job sent to the office and still waiting for assignment shows as sent, read only. The + in the title row opens a new job.

A jobOpens one job to work on, or to read if it is done or still waiting.
›
New job (+)Sends a new job: to the office to assign, or to a named technician if the user is an admin.
›
Settings (cog)Shows who is logged in and offers logging out.
›
‹ Home

log in

Login: shown in place of the rest of the app when nobody is logged in. Email, password and company code.

Log inSigns the technician in and opens My jobs.
›
‹ Home

new job

New job: what is wanted, the client, and the planned day if known. Opened empty from My jobs or the job's + menu, or filled in with the client of the job it came from (a related job, which the office's ticket shows as found in that job). An admin also picks who does it. Saving opens the new job.

DescriptionWhat the work is. Required.
›
Client nameRequired.
›
Client phoneRequired.
›
Client addressOptional.
›
Planned dayThe day agreed with the client. Optional.
›
Who does itAn admin names a technician of their own company, themselves included. Left empty, the job waits for the office to assign it.
›
SaveSaves the job and opens it.
›
BackLeaves without saving.
›
‹ Home

job

One job, in the order the technician needs it: its state in the header, then the planned day, the description with its tags, the client's name, phone and address, the parts, and, while it is being worked, the photos. A done job is read only; so is a job still waiting for the office, which has no work to do yet.

Job menu (+)Opens the two choices below.
›
Related jobA new job for the same client, which the office's ticket shows as found in this job.
›
New jobA new job with nothing filled in.
›
PartsAdds parts used on the job. Shown while the job is being worked.
›
PhotosAdds photos of the work. Shown while the job is being worked.
›
Continue to reportGoes on to the report, signature and sending. Shown while the job is being worked.
›
Job in progressOpens another job the technician has in progress.
›
BackReturns to My jobs.
›
Settings (cog)Shows who is logged in and offers logging out.
›
‹ job

report

Report: review the time and parts and photos, add an optional note, have the client sign, then send. Sending finishes the job and goes back to My jobs. If sending fails, the draft is kept and the technician can try again.

NoteAn optional note for the office.
›
Client signatureRequired before sending.
›
SendSaves the report, finishes the job, returns to My jobs.
›
BackReturns to the job without sending.
›
‹ Home

settings

Settings: who is logged in, and logging out.

Log outLogs the technician out.
›
BackReturns to My jobs.
›
Raw answer
Planned from the owner's 2026-10-21 model: every technician is an org technician, and only admins can name who does a new job. Leads, the Leads tab and the self-worker screens are left out because no new user gets `kind = 'self'`. The components for the parts picker, photos, client card and technician picker were not in the dump, so their rows are inferred from how the screens use them. The contract file was cut off, so I did not see its full text.

```json
{"screens": [
  {"path": [],
   "sentence": "My jobs: the technician's jobs, newest first, a page at a time, each with its state. A job sent to the office and still waiting for assignment shows as sent, read only. The + in the title row opens a new job.",
   "rows": [
     {"name": "A job", "form": "/jobs/[id]", "what": "Opens one job to work on, or to read if it is done or still waiting."},
     {"name": "New job (+)", "form": "/jobs/new", "what": "Sends a new job: to the office to assign, or to a named technician if the user is an admin."},
     {"name": "Settings (cog)", "form": "/settings", "what": "Shows who is logged in and offers logging out."}
   ]},
  {"path": ["log in"],
   "sentence": "Login: shown in place of the rest of the app when nobody is logged in. Email, password and company code.",
   "rows": [
     {"name": "Log in", "form": "/ (My jobs)", "what": "Signs the technician in and opens My jobs."}
   ]},
  {"path": ["new job"],
   "sentence": "New job: what is wanted, the client, and the planned day if known. Opened empty from My jobs or the job's + menu, or filled in with the client of the job it came from (a related job, which the office's ticket shows as found in that job). An admin also picks who does it. Saving opens the new job.",
   "rows": [
     {"name": "Description", "form": "text field on this screen", "what": "What the work is. Required."},
     {"name": "Client name", "form": "text field on this screen", "what": "Required."},
     {"name": "Client phone", "form": "phone field on this screen", "what": "Required."},
     {"name": "Client address", "form": "text field on this screen", "what": "Optional."},
     {"name": "Planned day", "form": "day picker on this screen (YYYY-MM-DD)", "what": "The day agreed with the client. Optional."},
     {"name": "Who does it", "form": "search picker on this screen, admins only (data.listCompanyTechnicians, at most 50 names, themselves first)", "what": "An admin names a technician of their own company, themselves included. Left empty, the job waits for the office to assign it."},
     {"name": "Save", "form": "/jobs/[id] (replaces this screen)", "what": "Saves the job and opens it."},
     {"name": "Back", "form": "/ (My jobs)", "what": "Leaves without saving."}
   ]},
  {"path": ["job"],
   "sentence": "One job, in the order the technician needs it: its state in the header, then the planned day, the description with its tags, the client's name, phone and address, the parts, and, while it is being worked, the photos. A done job is read only; so is a job still waiting for the office, which has no work to do yet.",
   "rows": [
     {"name": "Job menu (+)", "form": "menu on this screen", "what": "Opens the two choices below."},
     {"name": "Related job", "form": "/jobs/new with the client and the relatedJobId of this job", "what": "A new job for the same client, which the office's ticket shows as found in this job."},
     {"name": "New job", "form": "/jobs/new (empty)", "what": "A new job with nothing filled in."},
     {"name": "Parts", "form": "parts picker on this screen, from the office's catalog (data.listPartsCatalog)", "what": "Adds parts used on the job. Shown while the job is being worked."},
     {"name": "Photos", "form": "camera on this screen (expo-image-picker)", "what": "Adds photos of the work. Shown while the job is being worked."},
     {"name": "Continue to report", "form": "/jobs/[id]/report", "what": "Goes on to the report, signature and sending. Shown while the job is being worked."},
     {"name": "Job in progress", "form": "/jobs/[runningId]", "what": "Opens another job the technician has in progress."},
     {"name": "Back", "form": "/ (My jobs)", "what": "Returns to My jobs."},
     {"name": "Settings (cog)", "form": "/settings", "what": "Shows who is logged in and offers logging out."}
   ]},
  {"path": ["job", "report"],
   "sentence": "Report: review the time and parts and photos, add an optional note, have the client sign, then send. Sending finishes the job and goes back to My jobs. If sending fails, the draft is kept and the technician can try again.",
   "rows": [
     {"name": "Note", "form": "text field on this screen", "what": "An optional note for the office."},
     {"name": "Client signature", "form": "signature pad on this screen", "what": "Required before sending."},
     {"name": "Send", "form": "/ (My jobs, replaces the stack)", "what": "Saves the report, finishes the job, returns to My jobs."},
     {"name": "Back", "form": "/jobs/[id]", "what": "Returns to the job without sending."}
   ]},
  {"path": ["settings"],
   "sentence": "Settings: who is logged in, and logging out.",
   "rows": [
     {"name": "Log out", "form": "/ (shows the login screen)", "what": "Logs the technician out."},
     {"name": "Back", "form": "/ (My jobs)", "what": "Returns to My jobs."}
   ]}
 ],
 "questions": [
  "The login screen opens filled in with a demo login (DEMO_LOGIN in src/data/seed.js). Should that be removed from the production build? Recommendation: yes, keep it only in test builds.",
  "A job the technician sent that is still waiting for the office: what should its state word say in My jobs? Recommendation: a short 'sent' label (in Hebrew, to match the app), shown read only, with no action.",
  "The bottom tab bar is shown only for self-workers, so with none left it would never appear. Recommendation: drop it, and make My jobs the only screen at the top. Leads stays in the code, with no route linked to it.",
  "The owner's decision covers an admin naming the technician only on the new-job screen. Should an admin also be able to change who does a job later, from the job screen? Recommendation: not now, since the decision did not ask for it; add it later if needed."
 ]}
```

Today's skills · run 4 exit=0 seconds=45 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.848P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
My jobs: the technician's jobs with their state, a page at a time, with placeholder rows while the next page loads. Leads tab appears only for self-workers.
Settings/settingsOpens the cog: who is logged in, and log out.
New job/jobs/newThe + in the title row: opens a new job for the office to assign.
Job/jobs/[id]Opens one job from the list.
Leads tab/leadsSelf-workers only (kept, unused): their leads.
settings
Settings: who is logged in, and the log out button.
Log outdata.logout(), then the login screenEnds the session.
Back to My jobs/Returns to the top screen.
new job
New job: description, client name and phone, optional address and planned day. Opened from My jobs (+), or from a job's + menu as a related job with the client filled in. Admins also see a picker for who does it.
Who does it (admins only)data.listCompanyTechnicians() pickerNames a technician of their own company, themselves included; left empty, the job waits for the office.
Planned dayDayChoice component (can't confirm the internals)Sets the day the job is agreed for, optional.
Savedata.createJob(), then /jobs/[id]Saves the job and opens it.
Back/ (or the lead, when opened from one)Leaves without saving.
job
One job: its state in the header, then the planned day, the description with its tags, the client, and while the job is being worked its parts and photos. A job still waiting for the office, or done, is read only.
+ menu/jobs/new with related-job paramsCreate a related job (client carried over) or a new job.
Work controls (parts, photos, start, stop)JobWorkspace component (can't confirm)Does the work on the job, and tells the office when it starts or stops.
Continue to report/jobs/[id]/reportOpens the report once the work is done.
Another running job/jobs/[runningId]Goes to a different job the technician is working on.
Back/ (dismissTo)Returns to My jobs.
job › report
Report: time worked, parts, photos, a note, and the client's signature. Sending finishes the job.
Notetext field on this screenA free note for the report.
Client signatureSignaturePad component (can't confirm)The client signs here.
Senddata.sendReport(), then /Saves the report, marks the job done, returns to My jobs.
Back/jobs/[id]Returns to the job without sending.
leads
Leads (self-workers only, kept, unused): open and closed leads as tabs, in the order of the day, a page at a time.
Open / Closed tabsin-screen tabs (data.listMyLeads with closed flag)Switches between open and closed leads.
New lead/leads/newAdds a lead by hand.
Import from Excel/leads/importAdds many leads from a file.
Lead/leads/[id]Opens one lead.
Settings/settingsThe cog.
leads › new lead
New lead: name, phone, what they want; address, budget, source, email and notes under More details.
More detailsin-screen expandShows the optional fields.
Savedata.createLead(), then /leadsSaves the lead as new.
leads › import
Import leads: pick an Excel file, see how many rows are ready and which are skipped and why, then import.
Choose fileDocumentPicker, then readLeadFilePicks the .xlsx file.
Replace filesame as Choose filePicks a different file.
Import N leadsdata.importLeads(), then /leadsSaves all ready rows in one call.
leads › lead
One lead: name, its status, what they want, how to reach them. Open leads can be called back on a day, closed as not relevant, or turned into a job. Closed leads are read only.
Call back daydata.setCallBack(), then /leadsSets the day to call again.
Not relevantCloseLeadDialog, then data.closeLead(), then /leadsCloses the lead, with an optional reason.
Open a job/jobs/new with lead paramsOpens a new job filled in from the lead; saving converts the lead.
Back/leadsReturns to the leads list.
Questions
  • Leave the Leads screens out of the phone navigation build, keeping their code? Recommend yes.
  • Confirm 'Add as lead' stays out of the job menu. Recommend yes.
  • How should a sent job still waiting for the office look in My jobs? Recommend a visible line such as 'waiting for the office' on the row.
As phone screens

Home

My jobs: the technician's jobs with their state, a page at a time, with placeholder rows while the next page loads. Leads tab appears only for self-workers.

SettingsOpens the cog: who is logged in, and log out.
›
New jobThe + in the title row: opens a new job for the office to assign.
›
JobOpens one job from the list.
›
Leads tabSelf-workers only (kept, unused): their leads.
›
‹ Home

settings

Settings: who is logged in, and the log out button.

Log outEnds the session.
›
Back to My jobsReturns to the top screen.
›
‹ Home

new job

New job: description, client name and phone, optional address and planned day. Opened from My jobs (+), or from a job's + menu as a related job with the client filled in. Admins also see a picker for who does it.

Who does it (admins only)Names a technician of their own company, themselves included; left empty, the job waits for the office.
›
Planned daySets the day the job is agreed for, optional.
›
SaveSaves the job and opens it.
›
BackLeaves without saving.
›
‹ Home

job

One job: its state in the header, then the planned day, the description with its tags, the client, and while the job is being worked its parts and photos. A job still waiting for the office, or done, is read only.

+ menuCreate a related job (client carried over) or a new job.
›
Work controls (parts, photos, start, stop)Does the work on the job, and tells the office when it starts or stops.
›
Continue to reportOpens the report once the work is done.
›
Another running jobGoes to a different job the technician is working on.
›
BackReturns to My jobs.
›
‹ job

report

Report: time worked, parts, photos, a note, and the client's signature. Sending finishes the job.

NoteA free note for the report.
›
Client signatureThe client signs here.
›
SendSaves the report, marks the job done, returns to My jobs.
›
BackReturns to the job without sending.
›
‹ Home

leads

Leads (self-workers only, kept, unused): open and closed leads as tabs, in the order of the day, a page at a time.

Open / Closed tabsSwitches between open and closed leads.
›
New leadAdds a lead by hand.
›
Import from ExcelAdds many leads from a file.
›
LeadOpens one lead.
›
SettingsThe cog.
›
‹ leads

new lead

New lead: name, phone, what they want; address, budget, source, email and notes under More details.

More detailsShows the optional fields.
›
SaveSaves the lead as new.
›
‹ leads

import

Import leads: pick an Excel file, see how many rows are ready and which are skipped and why, then import.

Choose filePicks the .xlsx file.
›
Replace filePicks a different file.
›
Import N leadsSaves all ready rows in one call.
›
‹ leads

lead

One lead: name, its status, what they want, how to reach them. Open leads can be called back on a day, closed as not relevant, or turned into a job. Closed leads are read only.

Call back daySets the day to call again.
›
Not relevantCloses the lead, with an optional reason.
›
Open a jobOpens a new job filled in from the lead; saving converts the lead.
›
BackReturns to the leads list.
›
Raw answer
## Model

**What it is:** An Android app (Expo, Hebrew, right-to-left) for Betec technicians. They receive jobs from the office, work them with the client, and send a signed report back. Leads belong to self-workers, a kind no new user will get, so their screens are kept in code but unused.

**Read:** 8 of 8 screens in `src/app` (plus 2 layouts). Components such as `JobWorkspace` and `ClientCard`, and the SQL, were not in the dump, so rows that depend on them are marked "can't confirm". The dump also cuts `contract.js` off mid-file.

**The day (org technician):**
1. **Work reaches the phone.** Today: My jobs lists the technician's jobs, a page at a time. Assignment happens in the dashboard, not here.
2. **Technician reads the job.** Description, client, planned day. Today: the job screen shows them.
3. **Technician works the job.** Parts, photos, start and stop. Today: the job workspace; can't confirm its controls, since the component was not in the dump.
4. **Client signs, report is sent, the office sees it done.** Today: the report screen sends it and returns to My jobs.
5. **Found work goes to the office.** Today: the + on My jobs, or the job's + menu for a related job. Both open the same new-job screen.

**Parts outside the flow:** Settings does only log out. The Leads screens (tab, new lead, import, lead page) belong to self-workers and write only to their own leads.

**What a newcomer should take from it:** The day is complete in the app. Two pieces need care: the creator's view of a sent job that is still waiting (the screen can show it, but the list label isn't confirmed), and the rule that a creator loses sight of a job once someone else is assigned it. That rule should be in `supabase/16_*`, which was not in the dump, so I can't confirm it.

I can't write files here, so `data-model.md` and `flow-card.md` are not written. The map below is the output.

## Questions

1. **Leave the Leads screens out of the phone navigation build?** Recommend yes: keep the code, don't route to it from the org navigation, matching "abandon, don't remove".
2. **Confirm "Add as lead" stays out.** An org technician has no Leads screen to show it on. Recommend yes, as you decided.
3. **How should a sent job that is still waiting for the office look in My jobs?** Recommend a short visible line ("waiting for the office") on the row, so the creator knows why it has no actions. This is not a state the app has today.

```json
{"screens": [
 {"path": [], "sentence": "My jobs: the technician's jobs with their state, a page at a time, with placeholder rows while the next page loads. Leads tab appears only for self-workers.", "rows": [
   {"name": "Settings", "form": "/settings", "what": "Opens the cog: who is logged in, and log out."},
   {"name": "New job", "form": "/jobs/new", "what": "The + in the title row: opens a new job for the office to assign."},
   {"name": "Job", "form": "/jobs/[id]", "what": "Opens one job from the list."},
   {"name": "Leads tab", "form": "/leads", "what": "Self-workers only (kept, unused): their leads."}
 ]},
 {"path": ["settings"], "sentence": "Settings: who is logged in, and the log out button.", "rows": [
   {"name": "Log out", "form": "data.logout(), then the login screen", "what": "Ends the session."},
   {"name": "Back to My jobs", "form": "/", "what": "Returns to the top screen."}
 ]},
 {"path": ["new job"], "sentence": "New job: description, client name and phone, optional address and planned day. Opened from My jobs (+), or from a job's + menu as a related job with the client filled in. Admins also see a picker for who does it.", "rows": [
   {"name": "Who does it (admins only)", "form": "data.listCompanyTechnicians() picker", "what": "Names a technician of their own company, themselves included; left empty, the job waits for the office."},
   {"name": "Planned day", "form": "DayChoice component (can't confirm the internals)", "what": "Sets the day the job is agreed for, optional."},
   {"name": "Save", "form": "data.createJob(), then /jobs/[id]", "what": "Saves the job and opens it."},
   {"name": "Back", "form": "/ (or the lead, when opened from one)", "what": "Leaves without saving."}
 ]},
 {"path": ["job"], "sentence": "One job: its state in the header, then the planned day, the description with its tags, the client, and while the job is being worked its parts and photos. A job still waiting for the office, or done, is read only.", "rows": [
   {"name": "+ menu", "form": "/jobs/new with related-job params", "what": "Create a related job (client carried over) or a new job."},
   {"name": "Work controls (parts, photos, start, stop)", "form": "JobWorkspace component (can't confirm)", "what": "Does the work on the job, and tells the office when it starts or stops."},
   {"name": "Continue to report", "form": "/jobs/[id]/report", "what": "Opens the report once the work is done."},
   {"name": "Another running job", "form": "/jobs/[runningId]", "what": "Goes to a different job the technician is working on."},
   {"name": "Back", "form": "/ (dismissTo)", "what": "Returns to My jobs."}
 ]},
 {"path": ["job", "report"], "sentence": "Report: time worked, parts, photos, a note, and the client's signature. Sending finishes the job.", "rows": [
   {"name": "Note", "form": "text field on this screen", "what": "A free note for the report."},
   {"name": "Client signature", "form": "SignaturePad component (can't confirm)", "what": "The client signs here."},
   {"name": "Send", "form": "data.sendReport(), then /", "what": "Saves the report, marks the job done, returns to My jobs."},
   {"name": "Back", "form": "/jobs/[id]", "what": "Returns to the job without sending."}
 ]},
 {"path": ["leads"], "sentence": "Leads (self-workers only, kept, unused): open and closed leads as tabs, in the order of the day, a page at a time.", "rows": [
   {"name": "Open / Closed tabs", "form": "in-screen tabs (data.listMyLeads with closed flag)", "what": "Switches between open and closed leads."},
   {"name": "New lead", "form": "/leads/new", "what": "Adds a lead by hand."},
   {"name": "Import from Excel", "form": "/leads/import", "what": "Adds many leads from a file."},
   {"name": "Lead", "form": "/leads/[id]", "what": "Opens one lead."},
   {"name": "Settings", "form": "/settings", "what": "The cog."}
 ]},
 {"path": ["leads", "new lead"], "sentence": "New lead: name, phone, what they want; address, budget, source, email and notes under More details.", "rows": [
   {"name": "More details", "form": "in-screen expand", "what": "Shows the optional fields."},
   {"name": "Save", "form": "data.createLead(), then /leads", "what": "Saves the lead as new."}
 ]},
 {"path": ["leads", "import"], "sentence": "Import leads: pick an Excel file, see how many rows are ready and which are skipped and why, then import.", "rows": [
   {"name": "Choose file", "form": "DocumentPicker, then readLeadFile", "what": "Picks the .xlsx file."},
   {"name": "Replace file", "form": "same as Choose file", "what": "Picks a different file."},
   {"name": "Import N leads", "form": "data.importLeads(), then /leads", "what": "Saves all ready rows in one call."}
 ]},
 {"path": ["leads", "lead"], "sentence": "One lead: name, its status, what they want, how to reach them. Open leads can be called back on a day, closed as not relevant, or turned into a job. Closed leads are read only.", "rows": [
   {"name": "Call back day", "form": "data.setCallBack(), then /leads", "what": "Sets the day to call again."},
   {"name": "Not relevant", "form": "CloseLeadDialog, then data.closeLead(), then /leads", "what": "Closes the lead, with an optional reason."},
   {"name": "Open a job", "form": "/jobs/new with lead params", "what": "Opens a new job filled in from the lead; saving converts the lead."},
   {"name": "Back", "form": "/leads", "what": "Returns to the leads list."}
 ]}
],
"questions": [
 "Leave the Leads screens out of the phone navigation build, keeping their code? Recommend yes.",
 "Confirm 'Add as lead' stays out of the job menu. Recommend yes.",
 "How should a sent job still waiting for the office look in My jobs? Recommend a visible line such as 'waiting for the office' on the row."
]}
```

screen-decomposition, first draft · run 4 exit=0 seconds=94 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.981P5 Short top: 4P6 Own words: 0.75P8 Worded per screen: 0
As terminal help
Your jobs, the first screen after sign-in: the jobs you work on, and the ones you sent to the office and are waiting to be assigned.
עבודה חדשה/jobs/newOpens the new-job form, from the + on the title row.
הגדרות/settingsOpens settings, from the cog in the header: who is logged in, and log out.
עבודה ברשימה/jobs/[id]Opens that job from the list.
לידים/leadsOpens the Leads tab; shown to self-workers only.
עבודה
One job: its state at the top, then its day, description, client, parts, and photos while working.
מצב העבודהJobStateTitle in the headerShows the job's state in bold in the header.
יום ביצועjob.plannedDay (job page)Shows the day agreed with the client, when there is one.
תיאורjob.description and job.tags (job page)Shows the office's description and the tags under it.
פרטי הלקוחClientCard (can't confirm the file contents)Shows the client's name, phone and address.
חלקיםJobWorkspace, from listPartsCatalog (can't confirm the add control)Adds parts from the catalog, with quantity, that were used on the job.
תמונותexpo-image-picker (camera)Adds photos of the work; optional, so last on the page.
התחלה ועצירהsaveWorkState(jobId, in_progress | awaiting_signature)Starts or stops the work, so the office sees it. The on-screen label can't be confirmed.
דוח/jobs/[id]/reportOpens the report, to check the work, have the client sign, and send.
עבודה חדשה או קשורה+ in the header, opens a menuOpens a menu with the two items below.
עבודה קשורה/jobs/new?relatedJobId=<this job>Opens the new-job form with this job's client filled in, linked to this job.
עבודה חדשה/jobs/newOpens an empty new-job form from the job's menu.
עבודה פתוחה אחרת/jobs/[runningId]Opens another job that is still being worked on, when there is one (can't confirm when it shows).
עבודה › דוח
The report of one job: the work summary, an optional note, the client's signature, and the send button.
סיכום העבודהWorkSummary (minutes, parts, photos)Shows the minutes worked, the parts, and the photos that go in the report.
הערהnotes fieldTypes a note for the report (optional).
חתימת הלקוחSignaturePad (saved as a PNG data URL)Has the client sign on the phone; send needs it.
שלחdata.sendReport, tech_send_reportSends the report, marks the job done, and returns to My jobs.
עבודה חדשה
A form to open a new job, or a related job from another job with its client filled in.
תיאורdescription fieldTypes what the job is about (required).
שם הלקוחclient name fieldTypes the client's name (required).
טלפוןclient phone fieldTypes the client's phone (required).
כתובתclient address fieldTypes the client's address (optional).
יום ביצועDayChoicePicks the day the client agreed to (optional).
מי מבצעTechnicianPicker, admins onlyPicks who does the job from the company; left empty, the office assigns it.
שמורdata.createJob, or data.openJobFromLead when opened from a leadSaves the job and opens it.
הגדרות
Settings: who is logged in, and logging out.
מחוברdata.currentTechnician()Shows the name of the logged-in technician.
יציאהdata.logout, then the sign-in screenLogs out and shows the sign-in screen.
כניסה
The sign-in screen, shown instead of the rest of the app when nobody is logged in.
אימיילLoginScreen field (can't confirm the label)Types the technician's email.
סיסמהLoginScreen fieldTypes the password.
קוד חברהLoginScreen fieldTypes the company code.
כניסהdata.login(email, password, companyId)Signs in and opens My jobs.
לידים
The Leads list for self-workers: open leads, or closed ones, each with its call-back day.
פתוחים/leads (open tab)Shows the open leads, in call-back order.
סגורים/leads (closed tab)Shows the converted and lost leads, read only.
ליד/leads/[id]Opens that lead.
ליד חדש/leads/newOpens the new-lead form, from the + on the title row.
ייבוא מאקסל/leads/importOpens the Excel import, the button at the bottom of the list.
לידים › ליד
One lead: how to reach the person, what they want, and what to do after the call.
יצירת קשרClientCard (name hidden)Shows how to reach the lead: phone and address.
מה רוצהlead.interestedIn and lead.notesShows what the lead wants, with notes.
סיבהlead.lostReasonShows why a lost lead was lost, when a reason was given.
חזרה ביוםdata.setCallBack(leadId, day)Sets the day to call back; saves and returns to Leads.
לא רלוונטיCloseLeadDialog, then data.closeLeadAsks for an optional reason, then closes the lead as lost.
פתח עבודה/jobs/new with leadId params, then data.openJobFromLeadOpens the new-job form filled from the lead; saving marks the lead converted.
לידים › ליד חדש
The form to add a lead, with budget, source, email and notes under more details.
שם, טלפון, מה רוצהlead fields (required)Types the name, phone and what the lead wants.
כתובתlead.address fieldTypes the address (optional).
פרטים נוספיםexpander in the formShows the budget, source, email and notes fields, all optional.
שמורdata.createLeadSaves the lead as new, and returns to Leads.
לידים › ייבוא מאקסל
Import leads from an Excel file: how many are ready, and which rows are skipped and why.
בחירת קובץexpo-document-picker (xlsx)Picks the Excel file.
החלפהexpo-document-picker (xlsx)Picks a different file.
שורות שלא ייובאוskipped rows from readLeadFileShows the rows that will be skipped, and the missing name or phone.
ייבוא לידיםdata.importLeads(rows)Imports the ready leads in one step, and returns to Leads.
Questions
  • Leads tab: keep it hidden for org technicians and shown only to self-workers? Recommend yes, as decided.
  • State word for a job waiting for the office (not confirmed in the dump): recommend one pill, 'waiting for the office'.
  • Demo login pre-filled on the sign-in screen (user100@gmail.com / 100): recommend removing it from production builds and keeping it for dev only.
  • 'Add as lead' from a job: recommend keeping it out, since org technicians have no Leads screen.
  • Done jobs show their report summary on the job page, and the report screen redirects there: recommend that is enough; say if a separate read-only report view is wanted.
As phone screens

Home

Your jobs, the first screen after sign-in: the jobs you work on, and the ones you sent to the office and are waiting to be assigned.

עבודה חדשהOpens the new-job form, from the + on the title row.
›
הגדרותOpens settings, from the cog in the header: who is logged in, and log out.
›
עבודה ברשימהOpens that job from the list.
›
לידיםOpens the Leads tab; shown to self-workers only.
›
‹ Home

עבודה

One job: its state at the top, then its day, description, client, parts, and photos while working.

מצב העבודהShows the job's state in bold in the header.
›
יום ביצועShows the day agreed with the client, when there is one.
›
תיאורShows the office's description and the tags under it.
›
פרטי הלקוחShows the client's name, phone and address.
›
חלקיםAdds parts from the catalog, with quantity, that were used on the job.
›
תמונותAdds photos of the work; optional, so last on the page.
›
התחלה ועצירהStarts or stops the work, so the office sees it. The on-screen label can't be confirmed.
›
דוחOpens the report, to check the work, have the client sign, and send.
›
עבודה חדשה או קשורהOpens a menu with the two items below.
›
עבודה קשורהOpens the new-job form with this job's client filled in, linked to this job.
›
עבודה חדשהOpens an empty new-job form from the job's menu.
›
עבודה פתוחה אחרתOpens another job that is still being worked on, when there is one (can't confirm when it shows).
›
‹ עבודה

דוח

The report of one job: the work summary, an optional note, the client's signature, and the send button.

סיכום העבודהShows the minutes worked, the parts, and the photos that go in the report.
›
הערהTypes a note for the report (optional).
›
חתימת הלקוחHas the client sign on the phone; send needs it.
›
שלחSends the report, marks the job done, and returns to My jobs.
›
‹ Home

עבודה חדשה

A form to open a new job, or a related job from another job with its client filled in.

תיאורTypes what the job is about (required).
›
שם הלקוחTypes the client's name (required).
›
טלפוןTypes the client's phone (required).
›
כתובתTypes the client's address (optional).
›
יום ביצועPicks the day the client agreed to (optional).
›
מי מבצעPicks who does the job from the company; left empty, the office assigns it.
›
שמורSaves the job and opens it.
›
‹ Home

הגדרות

Settings: who is logged in, and logging out.

מחוברShows the name of the logged-in technician.
›
יציאהLogs out and shows the sign-in screen.
›
‹ Home

כניסה

The sign-in screen, shown instead of the rest of the app when nobody is logged in.

אימיילTypes the technician's email.
›
סיסמהTypes the password.
›
קוד חברהTypes the company code.
›
כניסהSigns in and opens My jobs.
›
‹ Home

לידים

The Leads list for self-workers: open leads, or closed ones, each with its call-back day.

פתוחיםShows the open leads, in call-back order.
›
סגוריםShows the converted and lost leads, read only.
›
לידOpens that lead.
›
ליד חדשOpens the new-lead form, from the + on the title row.
›
ייבוא מאקסלOpens the Excel import, the button at the bottom of the list.
›
‹ לידים

ליד

One lead: how to reach the person, what they want, and what to do after the call.

יצירת קשרShows how to reach the lead: phone and address.
›
מה רוצהShows what the lead wants, with notes.
›
סיבהShows why a lost lead was lost, when a reason was given.
›
חזרה ביוםSets the day to call back; saves and returns to Leads.
›
לא רלוונטיAsks for an optional reason, then closes the lead as lost.
›
פתח עבודהOpens the new-job form filled from the lead; saving marks the lead converted.
›
‹ לידים

ליד חדש

The form to add a lead, with budget, source, email and notes under more details.

שם, טלפון, מה רוצהTypes the name, phone and what the lead wants.
›
כתובתTypes the address (optional).
›
פרטים נוספיםShows the budget, source, email and notes fields, all optional.
›
שמורSaves the lead as new, and returns to Leads.
›
‹ לידים

ייבוא מאקסל

Import leads from an Excel file: how many are ready, and which rows are skipped and why.

בחירת קובץPicks the Excel file.
›
החלפהPicks a different file.
›
שורות שלא ייובאוShows the rows that will be skipped, and the missing name or phone.
›
ייבוא לידיםImports the ready leads in one step, and returns to Leads.
›
Raw answer
**Read so far:** the dump cut off at 9,000 characters. I read the tab layout, every screen under `src/app/`, and the start of the contract. I did not read the 44 components, `JobWorkspace`, `ClientCard`, `LoginScreen`, `TabBar`, `JobState`, the SQL, or the adapters. Labels from those files are marked "can't confirm" below.

## Scenario (reasoning from field-service experience, not the code)

A technician on site is given a job by the office, or finds one. They open it and see the day and the client. They start the work, add parts and photos, stop, have the client sign on the phone, and send the report, which closes the job. If they find work the office did not give them, they open a new job from the phone, and it waits in the office until someone assigns it. An admin can name who does it.

## Inventory

- **Job data:** `tech_jobs`. Fields are description, tags, client, planned day, parts, and report. Created by `tech_create_job`, sent by `tech_send_report`, state changed by `tech_set_job_state` (`src/app/`, `src/contract.js`).
- **Parts catalog:** `listPartsCatalog`, `src/data/partsCatalog.js` (from `xl/tmn-devices.xlsx`), pictures in `src/data/partPicture.js`.
- **Photos:** camera through `expo-image-picker`, shrunk to a 1280px JPEG (`src/draft/downscalePhoto.js`).
- **Signature:** `SignaturePad`, saved as a PNG data URL.
- **Technicians:** `tech_profiles` with `can_assign`. Company list for admins: `tech_list_company_technicians`.
- **Leads (self-worker only):** `tech_leads`, the Excel import (`src/leadSheet.js`).
- **Phone-only state:** unsent work in `src/draft/` (`draftStore.js`), with a storage-full warning.
- **Session:** `data.login`, `data.logout`, `src/session`.
- **Not for the technician, so left out of the map:** `supabase/` SQL 01–17 and tests, `npm test`, `expo start` and `expo run:android`, the APK Releases page, the office dashboard (separate repo, Vercel), the `EXPO_PUBLIC_DEMO_*` flags, and the demo logins in `seed.js`.

## Screens

The map has ten screens: a top screen (My jobs), a job, the job's report, the new-job form, settings, sign-in, and five for self-workers (Leads list, lead, new lead, import, and the lead's "open a job" path through the new-job form). The complete map is in the JSON at the end.

## Questions for you

1. **Leads tab for org technicians:** I recommend it stays hidden for them and shows only for self-workers, as you decided. Org technicians see no trace of it.
2. **Waiting jobs:** what state word should My jobs show for a job waiting for the office? I recommend one pill reading "waiting for the office", the same style as the other states. I can't confirm the current label, because `src/jobStateWords.js` was not in the dump.
3. **Demo login:** the login screen opens filled with `user100@gmail.com` / `100`. I recommend removing that before real technicians use the app, and keeping it only in dev builds.
4. **"Add as lead" from a job:** you left it out. I recommend keeping it out, since org technicians have no Leads screen to show it on.
5. **Done jobs:** a done job shows its report summary on the job page, and the report screen redirects back. I recommend that is enough. Say if you want a separate read-only report view.

## Judgment calls

- **Names:** I used the app's Hebrew labels from the code, with English in the sentences. Where a label was not in the files I read, I gave the code's word and marked it.
- **One model:** org and self-worker screens are in one map. Self-only screens are marked by who sees them, so the top screen stays short for org technicians.
- **Leads gets a path (`["לידים"]`):** it is a second top-level tab, so it is not a child of My jobs. This is the one place the tab-root rule bends.
- **Login has a path (`["כניסה"]`):** it is not reached by navigation, but it is a screen the user sees, so it says where it is.
- **New job is one screen:** the related-job variant comes from the job's menu with the same screen, title and fields changed. Two screens would duplicate the form.
- **Parts and photos stay on the job page:** I could not confirm that `JobWorkspace` opens sub-screens, so I listed them as rows of the job screen.
- **Word clash:** the dashboard and code comments say "ticket" and "issue"; the app says "עבודה" (job). I used "job" throughout.

```json
{"screens": [
 {"path": [], "sentence": "Your jobs, the first screen after sign-in: the jobs you work on, and the ones you sent to the office and are waiting to be assigned.", "rows": [
  {"name": "עבודה חדשה", "form": "/jobs/new", "what": "Opens the new-job form, from the + on the title row."},
  {"name": "הגדרות", "form": "/settings", "what": "Opens settings, from the cog in the header: who is logged in, and log out."},
  {"name": "עבודה ברשימה", "form": "/jobs/[id]", "what": "Opens that job from the list."},
  {"name": "לידים", "form": "/leads", "what": "Opens the Leads tab; shown to self-workers only."}
 ]},
 {"path": ["עבודה"], "sentence": "One job: its state at the top, then its day, description, client, parts, and photos while working.", "rows": [
  {"name": "מצב העבודה", "form": "JobStateTitle in the header", "what": "Shows the job's state in bold in the header."},
  {"name": "יום ביצוע", "form": "job.plannedDay (job page)", "what": "Shows the day agreed with the client, when there is one."},
  {"name": "תיאור", "form": "job.description and job.tags (job page)", "what": "Shows the office's description and the tags under it."},
  {"name": "פרטי הלקוח", "form": "ClientCard (can't confirm the file contents)", "what": "Shows the client's name, phone and address."},
  {"name": "חלקים", "form": "JobWorkspace, from listPartsCatalog (can't confirm the add control)", "what": "Adds parts from the catalog, with quantity, that were used on the job."},
  {"name": "תמונות", "form": "expo-image-picker (camera)", "what": "Adds photos of the work; optional, so last on the page."},
  {"name": "התחלה ועצירה", "form": "saveWorkState(jobId, in_progress | awaiting_signature)", "what": "Starts or stops the work, so the office sees it. The on-screen label can't be confirmed."},
  {"name": "דוח", "form": "/jobs/[id]/report", "what": "Opens the report, to check the work, have the client sign, and send."},
  {"name": "עבודה חדשה או קשורה", "form": "+ in the header, opens a menu", "what": "Opens a menu with the two items below."},
  {"name": "עבודה קשורה", "form": "/jobs/new?relatedJobId=<this job>", "what": "Opens the new-job form with this job's client filled in, linked to this job."},
  {"name": "עבודה חדשה", "form": "/jobs/new", "what": "Opens an empty new-job form from the job's menu."},
  {"name": "עבודה פתוחה אחרת", "form": "/jobs/[runningId]", "what": "Opens another job that is still being worked on, when there is one (can't confirm when it shows)."}
 ]},
 {"path": ["עבודה", "דוח"], "sentence": "The report of one job: the work summary, an optional note, the client's signature, and the send button.", "rows": [
  {"name": "סיכום העבודה", "form": "WorkSummary (minutes, parts, photos)", "what": "Shows the minutes worked, the parts, and the photos that go in the report."},
  {"name": "הערה", "form": "notes field", "what": "Types a note for the report (optional)."},
  {"name": "חתימת הלקוח", "form": "SignaturePad (saved as a PNG data URL)", "what": "Has the client sign on the phone; send needs it."},
  {"name": "שלח", "form": "data.sendReport, tech_send_report", "what": "Sends the report, marks the job done, and returns to My jobs."}
 ]},
 {"path": ["עבודה חדשה"], "sentence": "A form to open a new job, or a related job from another job with its client filled in.", "rows": [
  {"name": "תיאור", "form": "description field", "what": "Types what the job is about (required)."},
  {"name": "שם הלקוח", "form": "client name field", "what": "Types the client's name (required)."},
  {"name": "טלפון", "form": "client phone field", "what": "Types the client's phone (required)."},
  {"name": "כתובת", "form": "client address field", "what": "Types the client's address (optional)."},
  {"name": "יום ביצוע", "form": "DayChoice", "what": "Picks the day the client agreed to (optional)."},
  {"name": "מי מבצע", "form": "TechnicianPicker, admins only", "what": "Picks who does the job from the company; left empty, the office assigns it."},
  {"name": "שמור", "form": "data.createJob, or data.openJobFromLead when opened from a lead", "what": "Saves the job and opens it."}
 ]},
 {"path": ["הגדרות"], "sentence": "Settings: who is logged in, and logging out.", "rows": [
  {"name": "מחובר", "form": "data.currentTechnician()", "what": "Shows the name of the logged-in technician."},
  {"name": "יציאה", "form": "data.logout, then the sign-in screen", "what": "Logs out and shows the sign-in screen."}
 ]},
 {"path": ["כניסה"], "sentence": "The sign-in screen, shown instead of the rest of the app when nobody is logged in.", "rows": [
  {"name": "אימייל", "form": "LoginScreen field (can't confirm the label)", "what": "Types the technician's email."},
  {"name": "סיסמה", "form": "LoginScreen field", "what": "Types the password."},
  {"name": "קוד חברה", "form": "LoginScreen field", "what": "Types the company code."},
  {"name": "כניסה", "form": "data.login(email, password, companyId)", "what": "Signs in and opens My jobs."}
 ]},
 {"path": ["לידים"], "sentence": "The Leads list for self-workers: open leads, or closed ones, each with its call-back day.", "rows": [
  {"name": "פתוחים", "form": "/leads (open tab)", "what": "Shows the open leads, in call-back order."},
  {"name": "סגורים", "form": "/leads (closed tab)", "what": "Shows the converted and lost leads, read only."},
  {"name": "ליד", "form": "/leads/[id]", "what": "Opens that lead."},
  {"name": "ליד חדש", "form": "/leads/new", "what": "Opens the new-lead form, from the + on the title row."},
  {"name": "ייבוא מאקסל", "form": "/leads/import", "what": "Opens the Excel import, the button at the bottom of the list."}
 ]},
 {"path": ["לידים", "ליד"], "sentence": "One lead: how to reach the person, what they want, and what to do after the call.", "rows": [
  {"name": "יצירת קשר", "form": "ClientCard (name hidden)", "what": "Shows how to reach the lead: phone and address."},
  {"name": "מה רוצה", "form": "lead.interestedIn and lead.notes", "what": "Shows what the lead wants, with notes."},
  {"name": "סיבה", "form": "lead.lostReason", "what": "Shows why a lost lead was lost, when a reason was given."},
  {"name": "חזרה ביום", "form": "data.setCallBack(leadId, day)", "what": "Sets the day to call back; saves and returns to Leads."},
  {"name": "לא רלוונטי", "form": "CloseLeadDialog, then data.closeLead", "what": "Asks for an optional reason, then closes the lead as lost."},
  {"name": "פתח עבודה", "form": "/jobs/new with leadId params, then data.openJobFromLead", "what": "Opens the new-job form filled from the lead; saving marks the lead converted."}
 ]},
 {"path": ["לידים", "ליד חדש"], "sentence": "The form to add a lead, with budget, source, email and notes under more details.", "rows": [
  {"name": "שם, טלפון, מה רוצה", "form": "lead fields (required)", "what": "Types the name, phone and what the lead wants."},
  {"name": "כתובת", "form": "lead.address field", "what": "Types the address (optional)."},
  {"name": "פרטים נוספים", "form": "expander in the form", "what": "Shows the budget, source, email and notes fields, all optional."},
  {"name": "שמור", "form": "data.createLead", "what": "Saves the lead as new, and returns to Leads."}
 ]},
 {"path": ["לידים", "ייבוא מאקסל"], "sentence": "Import leads from an Excel file: how many are ready, and which rows are skipped and why.", "rows": [
  {"name": "בחירת קובץ", "form": "expo-document-picker (xlsx)", "what": "Picks the Excel file."},
  {"name": "החלפה", "form": "expo-document-picker (xlsx)", "what": "Picks a different file."},
  {"name": "שורות שלא ייובאו", "form": "skipped rows from readLeadFile", "what": "Shows the rows that will be skipped, and the missing name or phone."},
  {"name": "ייבוא לידים", "form": "data.importLeads(rows)", "what": "Imports the ready leads in one step, and returns to Leads."}
 ]}
],
"questions": [
 "Leads tab: keep it hidden for org technicians and shown only to self-workers? Recommend yes, as decided.",
 "State word for a job waiting for the office (not confirmed in the dump): recommend one pill, 'waiting for the office'.",
 "Demo login pre-filled on the sign-in screen (user100@gmail.com / 100): recommend removing it from production builds and keeping it for dev only.",
 "'Add as lead' from a job: recommend keeping it out, since org technicians have no Leads screen.",
 "Done jobs show their report summary on the job page, and the report screen redirects there: recommend that is enough; say if a separate read-only report view is wanted."
]}
```

screen-decomposition, final · run 4 exit=0 seconds=62 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.714P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
My jobs: the jobs the office gave you, and the jobs you sent that the office has not assigned yet.
a jobjobs/[id]opens the job: its state, planned day, description, client, and the work on it
New job (+)jobs/newopens the new-job form, to send a job the office will assign
Settings (cog)settingsopens who is logged in, and logging out
My jobs › job
One job: its state at the top, then its planned day, description, client, and the work on it.
Start or stop worksaveWorkState (in_progress, awaiting_signature)tells the office the work started or stopped
PartslistPartsCatalogadds parts from the office's catalog to the job, with quantities
Photoscamera, kept as a draft on the phoneadds photos of the work, shrunk to 1280px
Continue to reportjobs/[id]/reportopens the report: review, notes, and the client's signature
ClientClientCard (client name, phone, address)shows the client's name, phone and address
New job (+ menu)jobs/newopens an empty new-job form from this job's page
Related job (+ menu)jobs/new?relatedJobId=<job id>opens the new-job form with this job's client filled in, and records this job as where it was found
My jobs › job › report
The report of this job: work time, parts, photos, notes, and the client's signature.
Notes (הערה)notes text fieldadds a note that goes into the report
Client signatureSignaturePad, saved as a PNG data URLthe client signs here; send stays off until there is a signature
Send (שלח)data.sendReportsends the report, marks the job done, takes the parts off stock for an org technician, and returns to My jobs
My jobs › new job
A new job: what the job is, the client, and the day planned if known.
Description (תיאור)description text fieldthe job in the client's words; required
Client name, phone, addressname and phone fields (required), address field (optional)who the client is and how to reach them
Planned day (יום ביצוע)DayChoicethe day agreed with the client; optional
Who does it (מי מבצע)TechnicianPicker, data.listCompanyTechnicians (admins only)an admin names who does the job; left empty, the job waits for the office
Save (שמור)data.createJobsaves the job and opens it
My jobs › job › related job
A related job: the new-job form with this job's client filled in, and the job it was found in.
Client (filled in from this job)name, phone and address from the jobthe client's details come from the job you came from; you can change them
Save (שמור)data.createJob with relatedJobIdsaves the related job, to the office or to the technician an admin named, then opens it
settings
Settings: who is logged in, and logging out.
Log out (יציאה)data.logoutlogs you out and returns to the login screen
Questions
  • How should a job waiting for the office look? JobState has no value for it. Recommendation: one pill on the list row and the job page, in the owner's word 'sent to the office'. Which Hebrew word?
  • Should the client's phone number tap to call? Recommendation: yes, one tap from the client row on a job.
  • Keep 'New job' in a job's + menu next to the top +? Recommendation: keep it, since the owner named it.
  • Keep 'job' as the app's word for what the dashboard calls a 'ticket'? Recommendation: yes.
As phone screens

Home

My jobs: the jobs the office gave you, and the jobs you sent that the office has not assigned yet.

a jobopens the job: its state, planned day, description, client, and the work on it
›
New job (+)opens the new-job form, to send a job the office will assign
›
Settings (cog)opens who is logged in, and logging out
›
‹ My jobs

job

One job: its state at the top, then its planned day, description, client, and the work on it.

Start or stop worktells the office the work started or stopped
›
Partsadds parts from the office's catalog to the job, with quantities
›
Photosadds photos of the work, shrunk to 1280px
›
Continue to reportopens the report: review, notes, and the client's signature
›
Clientshows the client's name, phone and address
›
New job (+ menu)opens an empty new-job form from this job's page
›
Related job (+ menu)opens the new-job form with this job's client filled in, and records this job as where it was found
›
‹ job

report

The report of this job: work time, parts, photos, notes, and the client's signature.

Notes (הערה)adds a note that goes into the report
›
Client signaturethe client signs here; send stays off until there is a signature
›
Send (שלח)sends the report, marks the job done, takes the parts off stock for an org technician, and returns to My jobs
›
‹ My jobs

new job

A new job: what the job is, the client, and the day planned if known.

Description (תיאור)the job in the client's words; required
›
Client name, phone, addresswho the client is and how to reach them
›
Planned day (יום ביצוע)the day agreed with the client; optional
›
Who does it (מי מבצע)an admin names who does the job; left empty, the job waits for the office
›
Save (שמור)saves the job and opens it
›
‹ job

related job

A related job: the new-job form with this job's client filled in, and the job it was found in.

Client (filled in from this job)the client's details come from the job you came from; you can change them
›
Save (שמור)saves the related job, to the office or to the technician an admin named, then opens it
›
‹ Home

settings

Settings: who is logged in, and logging out.

Log out (יציאה)logs you out and returns to the login screen
›
Raw answer
## Scenario

A technician, on an Android phone, opens **My jobs** to see the jobs the office gave them. They open one, start work, add parts and photos, then finish: they review the report, take the client's signature, and send it. When they find new work on site, they send it to the office as a job. An admin can also name who does it.

This is my reasoning from the owner's decisions of 2026-10-21 and the code, not from observing real technicians.

## Inventory

Each thing a technician reaches, its form, and where it's defined:

- **Login**: company code, email, password. Shown when nobody is logged in. `src/app/_layout.js`, `LoginScreen` (not read).
- **My jobs**: the list, a page at a time, with the + and the cog. `src/app/(tabs)/index.js`.
- **A job**: state, planned day, description, client, work, related-job menu. `src/app/jobs/[id]/index.js`.
- **Work on a job** (start/stop, parts, photos): `JobWorkspace` (not read); `saveWorkState` in `src/data/contract.js`; parts from `src/data/partsCatalog.js`; drafts in `src/draft/`.
- **Report**: notes, signature, send. `src/app/jobs/[id]/report.js`, `data.sendReport`.
- **New job**: description, client, optional day, optional technician picker for admins. `src/app/jobs/new.js`, `TechnicianPicker` (not read), `data.createJob`.
- **Settings**: who is logged in, log out. `src/app/settings.js`.

**Left out, by the owner's decision:** the Leads tab and every lead screen (`src/app/(tabs)/leads.js`, `src/app/leads/*`, the lead calls in `contract.js`), the tab bar for self-workers, `kind = 'self'`, and "Add as lead" in the job's + menu. The owner's words: "don't remove it just abandon it. leave it for 'self' workers which will never be used", and an org technician has no Leads screen to show "Add as lead" on.

## Screens

The map is in the JSON at the end. Judgment calls:

- **Top screen is My jobs**, with three reachable things. There is no tab bar for org technicians, so it is the only top screen.
- **Login is not in the tree.** It is the gate shown before the top screen, not something reached from a noun.
- **Settings is at the top level**, reached from the cog on My jobs and on a job's page.
- **Related job is its own screen**, not the same as the new-job screen. Its title and its filled-in client differ, so by principle 8 it gets its own line.
- **"New job" appears twice**: on My jobs (+) and in a job's + menu. The job's menu version is worded as "empty, from this job's page", so it stays.
- **A job waiting for the office and a done job show no work section.** A done job's report opens read-only.
- **The app's word is "job".** The dashboard calls the same record a "ticket". I kept "job" so the technician sees one word.
- **Not read:** the dump cut off at about 9,000 characters in `contract.js`, and `JobWorkspace`, `ClientCard`, `LoginScreen`, and `TechnicianPicker` were not in it. Their rows come from the screen files and the README, so check them before building.

## Questions for you

1. **How does a job waiting for the office look?** `JobState` has no value for it, and the owner's word is "sent". My recommendation: one pill on the list row and the job page, in the owner's word, "sent to the office". Which Hebrew word?
2. **Should the client's phone number tap to call?** My recommendation: yes, one tap from the job's client row. Right now the dump doesn't show it either way.
3. **Keep "New job" in a job's + menu** next to the top +? My recommendation: keep it, since the owner named it.
4. **Keep "job" as the app's word for what the dashboard calls a "ticket"?** My recommendation: yes.

```json
{"screens": [
 {"path": [], "sentence": "My jobs: the jobs the office gave you, and the jobs you sent that the office has not assigned yet.", "rows": [
   {"name": "a job", "form": "jobs/[id]", "what": "opens the job: its state, planned day, description, client, and the work on it"},
   {"name": "New job (+)", "form": "jobs/new", "what": "opens the new-job form, to send a job the office will assign"},
   {"name": "Settings (cog)", "form": "settings", "what": "opens who is logged in, and logging out"}
 ]},
 {"path": ["My jobs", "job"], "sentence": "One job: its state at the top, then its planned day, description, client, and the work on it.", "rows": [
   {"name": "Start or stop work", "form": "saveWorkState (in_progress, awaiting_signature)", "what": "tells the office the work started or stopped"},
   {"name": "Parts", "form": "listPartsCatalog", "what": "adds parts from the office's catalog to the job, with quantities"},
   {"name": "Photos", "form": "camera, kept as a draft on the phone", "what": "adds photos of the work, shrunk to 1280px"},
   {"name": "Continue to report", "form": "jobs/[id]/report", "what": "opens the report: review, notes, and the client's signature"},
   {"name": "Client", "form": "ClientCard (client name, phone, address)", "what": "shows the client's name, phone and address"},
   {"name": "New job (+ menu)", "form": "jobs/new", "what": "opens an empty new-job form from this job's page"},
   {"name": "Related job (+ menu)", "form": "jobs/new?relatedJobId=<job id>", "what": "opens the new-job form with this job's client filled in, and records this job as where it was found"}
 ]},
 {"path": ["My jobs", "job", "report"], "sentence": "The report of this job: work time, parts, photos, notes, and the client's signature.", "rows": [
   {"name": "Notes (הערה)", "form": "notes text field", "what": "adds a note that goes into the report"},
   {"name": "Client signature", "form": "SignaturePad, saved as a PNG data URL", "what": "the client signs here; send stays off until there is a signature"},
   {"name": "Send (שלח)", "form": "data.sendReport", "what": "sends the report, marks the job done, takes the parts off stock for an org technician, and returns to My jobs"}
 ]},
 {"path": ["My jobs", "new job"], "sentence": "A new job: what the job is, the client, and the day planned if known.", "rows": [
   {"name": "Description (תיאור)", "form": "description text field", "what": "the job in the client's words; required"},
   {"name": "Client name, phone, address", "form": "name and phone fields (required), address field (optional)", "what": "who the client is and how to reach them"},
   {"name": "Planned day (יום ביצוע)", "form": "DayChoice", "what": "the day agreed with the client; optional"},
   {"name": "Who does it (מי מבצע)", "form": "TechnicianPicker, data.listCompanyTechnicians (admins only)", "what": "an admin names who does the job; left empty, the job waits for the office"},
   {"name": "Save (שמור)", "form": "data.createJob", "what": "saves the job and opens it"}
 ]},
 {"path": ["My jobs", "job", "related job"], "sentence": "A related job: the new-job form with this job's client filled in, and the job it was found in.", "rows": [
   {"name": "Client (filled in from this job)", "form": "name, phone and address from the job", "what": "the client's details come from the job you came from; you can change them"},
   {"name": "Save (שמור)", "form": "data.createJob with relatedJobId", "what": "saves the related job, to the office or to the technician an admin named, then opens it"}
 ]},
 {"path": ["settings"], "sentence": "Settings: who is logged in, and logging out.", "rows": [
   {"name": "Log out (יציאה)", "form": "data.logout", "what": "logs you out and returns to the login screen"}
 ]}
],
"questions": [
 "How should a job waiting for the office look? JobState has no value for it. Recommendation: one pill on the list row and the job page, in the owner's word 'sent to the office'. Which Hebrew word?",
 "Should the client's phone number tap to call? Recommendation: yes, one tap from the client row on a job.",
 "Keep 'New job' in a job's + menu next to the top +? Recommendation: keep it, since the owner named it.",
 "Keep 'job' as the app's word for what the dashboard calls a 'ticket'? Recommendation: yes."
]}
```

No skill · run 5 exit=0 seconds=48 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.542P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 2
As terminal help
My jobs: the jobs this technician can see, newest first, a page at a time, each with its state. A job sent to the office and not yet assigned shows as waiting, read only. The + opens a new job; the cog opens settings.
A jobthe job screen (jobs/[id])open a job to work it, or to read it
New job (+)the new job screen (jobs/new)send a new job to the office, or, for an admin, to a named technician
Settings (cog)the settings screen (settings)see who is logged in, log out
More jobs (scroll)the next page of listMyJobsload the next page of the list
log in
Log in: shown when nobody is logged in. Company code, email and password. It opens filled in with the demo login. After a good login the app opens My jobs.
Log indata.login (email, password, company code), then My jobs (/)start the session on this phone
settings
Settings: the name of the technician who is logged in, and the log-out button.
Log outdata.logout, then the log-in screenend the session on this phone
BackMy jobs (/)return to the list
new job
New job: a job the technician found or was asked to do. Description, client name, phone, optional address, optional planned day. An admin also sees who does it, from their company, themselves included. Saved, it opens the job. Opened from a job's + as a related job, the title says so and the client is filled in from that job.
Savedata.createJob (tech_create_job), then the job screen (jobs/[id])save the job; no technician unless an admin named one, so it waits for the office
Who does it (admins only)technician picker: data.listCompanyTechnicians (tech_list_company_technicians)name the technician who does the job, from their own company, at most 50 names
Planned day (optional)day picker on this screenthe day agreed with the client
BackMy jobs (/)leave without saving
job
Job: one job, in the order the technician needs it: the planned day, the description with its tags, the client (name, phone, address), the parts, and while working, the photos. The state is in the header. A done job is read only. A job waiting for the office has no work on it.
BackMy jobs (/)return to the list
New job (+ menu)the new job screen (jobs/new), emptyopen a job that is not linked to this one
Related job (+ menu)the new job screen with this job's client and relatedJobIdopen a job found while on this one; the office's ticket says where it came from
Start / stop workdata.saveWorkState (in_progress / awaiting_signature)tell the office the work has started or stopped
Partsparts section on this page (catalog from listPartsCatalog)add the parts used, with quantities
Photosphotos section on this page (camera)add photos of the work; optional
Continue to reportthe report screen (jobs/[id]/report)finish the work and go to the report
Another job in progressthe job screen (jobs/[runningId])open the job that is already running
Settings (cog)the settings screen (settings)see who is logged in, log out
job › report
Report: review the time, the parts and the photos, add a note, get the client's signature, send. Sending finishes the job and returns to My jobs. A job already done redirects to the job screen.
Client signaturesignature pad on this page (PNG data URL)the client signs; Send stays off until then
Notetext field on this pageanything to add to the report
Senddata.sendReport (tech_send_report), then My jobs (/)save the report and mark the job done
Backthe job screen (jobs/[id])return without sending
Questions
  • Leads (the tab, the list, new lead, the lead page, Excel import) are left off the map, because an org technician never reaches them and the owner chose to abandon them. Recommendation: leave them off. If the demo self-worker (user200) should still be mapped, say so and they can go in a separate map.
  • How a job waiting for the office looks in My jobs. Today the row shows the state word 'assigned', which does not say the job is waiting for the office. Recommendation: a visible label such as 'waiting for the office' on that row. The owner should choose the Hebrew wording.
  • The log-in screen opens filled in with the demo login (user100 / 100, DEMO_LOGIN). Recommendation: remove that prefill before an APK goes to real technicians, or keep it only in test builds.
  • After saving, can an admin change who a job is assigned to from the app? No screen does that now, and the office can reassign in the dashboard. Recommendation: no change in the app for now.
  • Can a technician open a related job from a job that is itself waiting for the office? The + menu is on the job page, which hides the work area for waiting jobs. Recommendation: allow it, since the job is visible to its creator and the office gets the link.
  • I could not read the job workspace component or the other shared components, only their file names. The parts, photos, start/stop and 'another job in progress' rows are listed as sections of the job page. If any of them opens its own screen, the map needs a row for it. The owner or the code's author should confirm.
As phone screens

Home

My jobs: the jobs this technician can see, newest first, a page at a time, each with its state. A job sent to the office and not yet assigned shows as waiting, read only. The + opens a new job; the cog opens settings.

A jobopen a job to work it, or to read it
›
New job (+)send a new job to the office, or, for an admin, to a named technician
›
Settings (cog)see who is logged in, log out
›
More jobs (scroll)load the next page of the list
›
‹ Home

log in

Log in: shown when nobody is logged in. Company code, email and password. It opens filled in with the demo login. After a good login the app opens My jobs.

Log instart the session on this phone
›
‹ Home

settings

Settings: the name of the technician who is logged in, and the log-out button.

Log outend the session on this phone
›
Backreturn to the list
›
‹ Home

new job

New job: a job the technician found or was asked to do. Description, client name, phone, optional address, optional planned day. An admin also sees who does it, from their company, themselves included. Saved, it opens the job. Opened from a job's + as a related job, the title says so and the client is filled in from that job.

Savesave the job; no technician unless an admin named one, so it waits for the office
›
Who does it (admins only)name the technician who does the job, from their own company, at most 50 names
›
Planned day (optional)the day agreed with the client
›
Backleave without saving
›
‹ Home

job

Job: one job, in the order the technician needs it: the planned day, the description with its tags, the client (name, phone, address), the parts, and while working, the photos. The state is in the header. A done job is read only. A job waiting for the office has no work on it.

Backreturn to the list
›
New job (+ menu)open a job that is not linked to this one
›
Related job (+ menu)open a job found while on this one; the office's ticket says where it came from
›
Start / stop worktell the office the work has started or stopped
›
Partsadd the parts used, with quantities
›
Photosadd photos of the work; optional
›
Continue to reportfinish the work and go to the report
›
Another job in progressopen the job that is already running
›
Settings (cog)see who is logged in, log out
›
‹ job

report

Report: review the time, the parts and the photos, add a note, get the client's signature, send. Sending finishes the job and returns to My jobs. A job already done redirects to the job screen.

Client signaturethe client signs; Send stays off until then
›
Noteanything to add to the report
›
Sendsave the report and mark the job done
›
Backreturn without sending
›
Raw answer
The map covers the screens an organization technician reaches: My jobs, the job, the new job, the report, settings, and log-in as the gate. Leads is left off because the owner abandoned it for org technicians. I could read only part of the dump, so the parts, photos, and start/stop controls are listed as sections of the job page. Question 6 covers this.

```json
{"screens": [
 {"path": [], "sentence": "My jobs: the jobs this technician can see, newest first, a page at a time, each with its state. A job sent to the office and not yet assigned shows as waiting, read only. The + opens a new job; the cog opens settings.", "rows": [
  {"name": "A job", "form": "the job screen (jobs/[id])", "what": "open a job to work it, or to read it"},
  {"name": "New job (+)", "form": "the new job screen (jobs/new)", "what": "send a new job to the office, or, for an admin, to a named technician"},
  {"name": "Settings (cog)", "form": "the settings screen (settings)", "what": "see who is logged in, log out"},
  {"name": "More jobs (scroll)", "form": "the next page of listMyJobs", "what": "load the next page of the list"}
 ]},
 {"path": ["log in"], "sentence": "Log in: shown when nobody is logged in. Company code, email and password. It opens filled in with the demo login. After a good login the app opens My jobs.", "rows": [
  {"name": "Log in", "form": "data.login (email, password, company code), then My jobs (/)", "what": "start the session on this phone"}
 ]},
 {"path": ["settings"], "sentence": "Settings: the name of the technician who is logged in, and the log-out button.", "rows": [
  {"name": "Log out", "form": "data.logout, then the log-in screen", "what": "end the session on this phone"},
  {"name": "Back", "form": "My jobs (/)", "what": "return to the list"}
 ]},
 {"path": ["new job"], "sentence": "New job: a job the technician found or was asked to do. Description, client name, phone, optional address, optional planned day. An admin also sees who does it, from their company, themselves included. Saved, it opens the job. Opened from a job's + as a related job, the title says so and the client is filled in from that job.", "rows": [
  {"name": "Save", "form": "data.createJob (tech_create_job), then the job screen (jobs/[id])", "what": "save the job; no technician unless an admin named one, so it waits for the office"},
  {"name": "Who does it (admins only)", "form": "technician picker: data.listCompanyTechnicians (tech_list_company_technicians)", "what": "name the technician who does the job, from their own company, at most 50 names"},
  {"name": "Planned day (optional)", "form": "day picker on this screen", "what": "the day agreed with the client"},
  {"name": "Back", "form": "My jobs (/)", "what": "leave without saving"}
 ]},
 {"path": ["job"], "sentence": "Job: one job, in the order the technician needs it: the planned day, the description with its tags, the client (name, phone, address), the parts, and while working, the photos. The state is in the header. A done job is read only. A job waiting for the office has no work on it.", "rows": [
  {"name": "Back", "form": "My jobs (/)", "what": "return to the list"},
  {"name": "New job (+ menu)", "form": "the new job screen (jobs/new), empty", "what": "open a job that is not linked to this one"},
  {"name": "Related job (+ menu)", "form": "the new job screen with this job's client and relatedJobId", "what": "open a job found while on this one; the office's ticket says where it came from"},
  {"name": "Start / stop work", "form": "data.saveWorkState (in_progress / awaiting_signature)", "what": "tell the office the work has started or stopped"},
  {"name": "Parts", "form": "parts section on this page (catalog from listPartsCatalog)", "what": "add the parts used, with quantities"},
  {"name": "Photos", "form": "photos section on this page (camera)", "what": "add photos of the work; optional"},
  {"name": "Continue to report", "form": "the report screen (jobs/[id]/report)", "what": "finish the work and go to the report"},
  {"name": "Another job in progress", "form": "the job screen (jobs/[runningId])", "what": "open the job that is already running"},
  {"name": "Settings (cog)", "form": "the settings screen (settings)", "what": "see who is logged in, log out"}
 ]},
 {"path": ["job", "report"], "sentence": "Report: review the time, the parts and the photos, add a note, get the client's signature, send. Sending finishes the job and returns to My jobs. A job already done redirects to the job screen.", "rows": [
  {"name": "Client signature", "form": "signature pad on this page (PNG data URL)", "what": "the client signs; Send stays off until then"},
  {"name": "Note", "form": "text field on this page", "what": "anything to add to the report"},
  {"name": "Send", "form": "data.sendReport (tech_send_report), then My jobs (/)", "what": "save the report and mark the job done"},
  {"name": "Back", "form": "the job screen (jobs/[id])", "what": "return without sending"}
 ]}
],
"questions": [
 "Leads (the tab, the list, new lead, the lead page, Excel import) are left off the map, because an org technician never reaches them and the owner chose to abandon them. Recommendation: leave them off. If the demo self-worker (user200) should still be mapped, say so and they can go in a separate map.",
 "How a job waiting for the office looks in My jobs. Today the row shows the state word 'assigned', which does not say the job is waiting for the office. Recommendation: a visible label such as 'waiting for the office' on that row. The owner should choose the Hebrew wording.",
 "The log-in screen opens filled in with the demo login (user100 / 100, DEMO_LOGIN). Recommendation: remove that prefill before an APK goes to real technicians, or keep it only in test builds.",
 "After saving, can an admin change who a job is assigned to from the app? No screen does that now, and the office can reassign in the dashboard. Recommendation: no change in the app for now.",
 "Can a technician open a related job from a job that is itself waiting for the office? The + menu is on the job page, which hides the work area for waiting jobs. Recommendation: allow it, since the job is visible to its creator and the office gets the link.",
 "I could not read the job workspace component or the other shared components, only their file names. The parts, photos, start/stop and 'another job in progress' rows are listed as sections of the job page. If any of them opens its own screen, the map needs a row for it. The owner or the code's author should confirm."
]}
```

Today's skills · run 5 exit=0 seconds=56 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 0.424P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
app start
The login screen, shown instead of the app while nobody is logged in. Email, password and company code; opens filled with the demo login.
log indata.login(email, password, companyId) then My jobs (/)gets into the app
demo loginDEMO_LOGIN in src/data/seed.js pre-fills the fieldsthe test login the screen opens with
My jobs, the home after login: the technician's jobs, newest first, a page at a time, each with its state. The + in the title row opens a new job.
open a job/jobs/[id]see and work one job
new job/jobs/newopen a job for the office or an admin to assign
settings/settings (cog in the header)who is logged in, log out
Leads tab(tabs)/leads, shown only to self-worker techniciansself-worker leads; unused per the 2026-10-21 decision
settings
Shows the name of the technician who is logged in, and a log-out button.
log outdata.logout() then the login gateends the session
new job
Writes a new job: description, client name, phone, optional address and planned day. An admin can also name who does it. Also opened from a job's + menu (as a related job, with the client filled in) and from a lead (filled in, and the lead becomes converted).
planned day (optional)DayChoice, inlinethe day the job is agreed for
technician (admins only)TechnicianPicker, inline, calls data.listCompanyTechniciansnames who does the job, from their own company
savedata.createJob(input) then /jobs/[id]; from a lead, data.openJobFromLeadsaves the job and opens it
job
One job: state in the header, then the planned day, description and tags, the client, and, unless it is done or waiting for the office, the work section (start, stop, photos, parts). Done jobs are read only.
continue to report/jobs/[id]/reportreview, sign and send the report
related job/jobs/new with the relatedJobId parama new job for the same client, linked to this one
new job from the + menu/jobs/newa new job
job being worked on elsewhere/jobs/[runningId]opens the job the technician is running
client cardcomponents/ClientCard (not read)client name, phone, address
work sectioncomponents/JobWorkspace (not read), calls data.saveWorkStatestart, stop, photos, parts
job › report
Review the minutes, parts and photos, add an optional note, get the client's signature, send. Sending finishes the job and returns to My jobs.
notetext input, inlinean optional note on the report
client signaturecomponents/SignaturePad, inlinethe client signs
senddata.sendReport(...) then / (My jobs)finishes the job and sends the report
leads
Self-worker only, unused now. A self-worker's leads in the order of the day, with Open and Closed tabs, a page at a time.
open leads tabFilterTabs, inline (data.listMyLeads closed: false)leads still to handle
closed leads tabFilterTabs, inline (data.listMyLeads closed: true)converted and lost leads, read only
open a lead/leads/[id]call back, close, or open a job
new lead/leads/newwrite down a new lead
import from Excel/leads/importbring in many leads at once
My jobs tab(tabs)/indexback to jobs
leads › lead
Self-worker only, unused now. One lead: what they want, how to reach them, and after the call one of: a call-back day, not relevant, or open a job. A closed lead is read only.
call-back dayDayChoice, inline, calls data.setCallBackcall back on a day
not relevantCloseLeadDialog, inline, calls data.closeLeadcloses the lead, with an optional reason
open a job/jobs/new with the leadId paramopens a job filled in from the lead
contact detailscomponents/ClientCard (not read)name, phone, address
leads › new lead
Self-worker only, unused now. Writes down a new lead: name, phone and what they want are required; address is optional; budget, source, email and notes are under more details.
more detailsinline expandbudget, source, email, notes
savedata.createLead(lead) then /leadssaves the lead as new
leads › import
Self-worker only, unused now. Picks an Excel file, shows how many rows are ready and which are skipped with the reason, then imports the ready ones in one step.
pick fileexpo-document-picker (system file picker)choose the .xlsx file
import N leadsdata.importLeads(ready) then /leadssaves the ready rows
Questions
  • Leads and the other self-worker screens are kept unused per the 2026-10-21 decision. Should they be in the phone's navigation map at all? Recommendation: keep them, marked self-only, and hide them from org technicians as the app already does, so nothing needs remapping if a self-worker returns.
  • A job waiting for the office has no work section, but the + menu still shows. Should the creator see the related-job option on it? Recommendation: yes. The creator found the work, and a related job from it is the reason they made the ticket.
  • The new-job screen shows the technician picker only to admins. Should admins get a separate assign screen? Recommendation: no; keep one screen, with the picker shown only when the admin flag is set.
  • Login has no route; it is a gate in the root layout. Should it get a URL? Recommendation: no, keep it as the gate, since nothing links to it by name.
As phone screens
‹ Home

app start

The login screen, shown instead of the app while nobody is logged in. Email, password and company code; opens filled with the demo login.

log ingets into the app
›
demo loginthe test login the screen opens with
›

Home

My jobs, the home after login: the technician's jobs, newest first, a page at a time, each with its state. The + in the title row opens a new job.

open a jobsee and work one job
›
new jobopen a job for the office or an admin to assign
›
settingswho is logged in, log out
›
Leads tabself-worker leads; unused per the 2026-10-21 decision
›
‹ Home

settings

Shows the name of the technician who is logged in, and a log-out button.

log outends the session
›
‹ Home

new job

Writes a new job: description, client name, phone, optional address and planned day. An admin can also name who does it. Also opened from a job's + menu (as a related job, with the client filled in) and from a lead (filled in, and the lead becomes converted).

planned day (optional)the day the job is agreed for
›
technician (admins only)names who does the job, from their own company
›
savesaves the job and opens it
›
‹ Home

job

One job: state in the header, then the planned day, description and tags, the client, and, unless it is done or waiting for the office, the work section (start, stop, photos, parts). Done jobs are read only.

continue to reportreview, sign and send the report
›
related joba new job for the same client, linked to this one
›
new job from the + menua new job
›
job being worked on elsewhereopens the job the technician is running
›
client cardclient name, phone, address
›
work sectionstart, stop, photos, parts
›
‹ job

report

Review the minutes, parts and photos, add an optional note, get the client's signature, send. Sending finishes the job and returns to My jobs.

notean optional note on the report
›
client signaturethe client signs
›
sendfinishes the job and sends the report
›
‹ Home

leads

Self-worker only, unused now. A self-worker's leads in the order of the day, with Open and Closed tabs, a page at a time.

open leads tableads still to handle
›
closed leads tabconverted and lost leads, read only
›
open a leadcall back, close, or open a job
›
new leadwrite down a new lead
›
import from Excelbring in many leads at once
›
My jobs tabback to jobs
›
‹ leads

lead

Self-worker only, unused now. One lead: what they want, how to reach them, and after the call one of: a call-back day, not relevant, or open a job. A closed lead is read only.

call-back daycall back on a day
›
not relevantcloses the lead, with an optional reason
›
open a jobopens a job filled in from the lead
›
contact detailsname, phone, address
›
‹ leads

new lead

Self-worker only, unused now. Writes down a new lead: name, phone and what they want are required; address is optional; budget, source, email and notes are under more details.

more detailsbudget, source, email, notes
›
savesaves the lead as new
›
‹ leads

import

Self-worker only, unused now. Picks an Excel file, shows how many rows are ready and which are skipped with the reason, then imports the ready ones in one step.

pick filechoose the .xlsx file
›
import N leadssaves the ready rows
›
Raw answer
I read all 10 route files in the dump (`src/app/`). The dump was cut before the contract details and the Supabase files, and I could not read these components, so their rows are missing: `JobWorkspace`, `ClientCard`, `LoginScreen`, `TechnicianPicker`, `Menu`, `DayChoice`, `CloseLeadDialog`, `SignaturePad`.

**What it is:** the Betec technicians' phone app. A technician sees the jobs that are theirs, works one with the client (start, photos, parts), gets a signature, and sends the report. Every technician can also open a new job, which waits for the office or an admin to assign it.

**The main flow (org technician), one day:** My jobs → open a job → work it → report and sign → send → back to My jobs. Opening a job: New job → saved with no technician → waits in the office.

**Findings:**
- The job page shows the + menu even when the job is waiting for the office, and hides the work section. Creating a related job from a waiting ticket is probably right, but it is untested.
- Three screens have more than one way in: the new-job screen (from My jobs, from a job's + menu, and from a lead). The map gives each screen one path and names the others in its sentence.
- Leads and the lead screens are self-worker only and unused per the 2026-10-21 decision. They stay in the map, marked, and the nav hides them for org technicians.

Every screen except login and the tab roots has a Back to the previous screen. I left those out of the rows.

```json
{"screens": [
 {"path": ["app start"], "sentence": "The login screen, shown instead of the app while nobody is logged in. Email, password and company code; opens filled with the demo login.", "rows": [
  {"name": "log in", "form": "data.login(email, password, companyId) then My jobs (/)", "what": "gets into the app"},
  {"name": "demo login", "form": "DEMO_LOGIN in src/data/seed.js pre-fills the fields", "what": "the test login the screen opens with"}
 ]},
 {"path": [], "sentence": "My jobs, the home after login: the technician's jobs, newest first, a page at a time, each with its state. The + in the title row opens a new job.", "rows": [
  {"name": "open a job", "form": "/jobs/[id]", "what": "see and work one job"},
  {"name": "new job", "form": "/jobs/new", "what": "open a job for the office or an admin to assign"},
  {"name": "settings", "form": "/settings (cog in the header)", "what": "who is logged in, log out"},
  {"name": "Leads tab", "form": "(tabs)/leads, shown only to self-worker technicians", "what": "self-worker leads; unused per the 2026-10-21 decision"}
 ]},
 {"path": ["settings"], "sentence": "Shows the name of the technician who is logged in, and a log-out button.", "rows": [
  {"name": "log out", "form": "data.logout() then the login gate", "what": "ends the session"}
 ]},
 {"path": ["new job"], "sentence": "Writes a new job: description, client name, phone, optional address and planned day. An admin can also name who does it. Also opened from a job's + menu (as a related job, with the client filled in) and from a lead (filled in, and the lead becomes converted).", "rows": [
  {"name": "planned day (optional)", "form": "DayChoice, inline", "what": "the day the job is agreed for"},
  {"name": "technician (admins only)", "form": "TechnicianPicker, inline, calls data.listCompanyTechnicians", "what": "names who does the job, from their own company"},
  {"name": "save", "form": "data.createJob(input) then /jobs/[id]; from a lead, data.openJobFromLead", "what": "saves the job and opens it"}
 ]},
 {"path": ["job"], "sentence": "One job: state in the header, then the planned day, description and tags, the client, and, unless it is done or waiting for the office, the work section (start, stop, photos, parts). Done jobs are read only.", "rows": [
  {"name": "continue to report", "form": "/jobs/[id]/report", "what": "review, sign and send the report"},
  {"name": "related job", "form": "/jobs/new with the relatedJobId param", "what": "a new job for the same client, linked to this one"},
  {"name": "new job from the + menu", "form": "/jobs/new", "what": "a new job"},
  {"name": "job being worked on elsewhere", "form": "/jobs/[runningId]", "what": "opens the job the technician is running"},
  {"name": "client card", "form": "components/ClientCard (not read)", "what": "client name, phone, address"},
  {"name": "work section", "form": "components/JobWorkspace (not read), calls data.saveWorkState", "what": "start, stop, photos, parts"}
 ]},
 {"path": ["job", "report"], "sentence": "Review the minutes, parts and photos, add an optional note, get the client's signature, send. Sending finishes the job and returns to My jobs.", "rows": [
  {"name": "note", "form": "text input, inline", "what": "an optional note on the report"},
  {"name": "client signature", "form": "components/SignaturePad, inline", "what": "the client signs"},
  {"name": "send", "form": "data.sendReport(...) then / (My jobs)", "what": "finishes the job and sends the report"}
 ]},
 {"path": ["leads"], "sentence": "Self-worker only, unused now. A self-worker's leads in the order of the day, with Open and Closed tabs, a page at a time.", "rows": [
  {"name": "open leads tab", "form": "FilterTabs, inline (data.listMyLeads closed: false)", "what": "leads still to handle"},
  {"name": "closed leads tab", "form": "FilterTabs, inline (data.listMyLeads closed: true)", "what": "converted and lost leads, read only"},
  {"name": "open a lead", "form": "/leads/[id]", "what": "call back, close, or open a job"},
  {"name": "new lead", "form": "/leads/new", "what": "write down a new lead"},
  {"name": "import from Excel", "form": "/leads/import", "what": "bring in many leads at once"},
  {"name": "My jobs tab", "form": "(tabs)/index", "what": "back to jobs"}
 ]},
 {"path": ["leads", "lead"], "sentence": "Self-worker only, unused now. One lead: what they want, how to reach them, and after the call one of: a call-back day, not relevant, or open a job. A closed lead is read only.", "rows": [
  {"name": "call-back day", "form": "DayChoice, inline, calls data.setCallBack", "what": "call back on a day"},
  {"name": "not relevant", "form": "CloseLeadDialog, inline, calls data.closeLead", "what": "closes the lead, with an optional reason"},
  {"name": "open a job", "form": "/jobs/new with the leadId param", "what": "opens a job filled in from the lead"},
  {"name": "contact details", "form": "components/ClientCard (not read)", "what": "name, phone, address"}
 ]},
 {"path": ["leads", "new lead"], "sentence": "Self-worker only, unused now. Writes down a new lead: name, phone and what they want are required; address is optional; budget, source, email and notes are under more details.", "rows": [
  {"name": "more details", "form": "inline expand", "what": "budget, source, email, notes"},
  {"name": "save", "form": "data.createLead(lead) then /leads", "what": "saves the lead as new"}
 ]},
 {"path": ["leads", "import"], "sentence": "Self-worker only, unused now. Picks an Excel file, shows how many rows are ready and which are skipped with the reason, then imports the ready ones in one step.", "rows": [
  {"name": "pick file", "form": "expo-document-picker (system file picker)", "what": "choose the .xlsx file"},
  {"name": "import N leads", "form": "data.importLeads(ready) then /leads", "what": "saves the ready rows"}
 ]}
 ],
 "questions": [
  "Leads and the other self-worker screens are kept unused per the 2026-10-21 decision. Should they be in the phone's navigation map at all? Recommendation: keep them, marked self-only, and hide them from org technicians as the app already does, so nothing needs remapping if a self-worker returns.",
  "A job waiting for the office has no work section, but the + menu still shows. Should the creator see the related-job option on it? Recommendation: yes. The creator found the work, and a related job from it is the reason they made the ticket.",
  "The new-job screen shows the technician picker only to admins. Should admins get a separate assign screen? Recommendation: no; keep one screen, with the picker shown only when the admin flag is set.",
  "Login has no route; it is a gate in the root layout. Should it get a URL? Recommendation: no, keep it as the gate, since nothing links to it by name."
 ]}
```

screen-decomposition, first draft · run 5 exit=0 seconds=72 · prompt

P1 Recall: 1.0P2 Nothing invented: 1P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 4P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
My jobs, the home screen: the jobs assigned to this technician and the jobs they sent that are still waiting for the office, newest first, a page at a time.
עבודה (a job row)/jobs/[id]opens the job: its state, description, client, parts and photos
+ עבודה חדשה/jobs/newopens a new job form, to send work to the office
הגדרות (cog)/settingsopens who is logged in and the log-out button
לידים (tab)/leadsopens the leads; shown only to a self-worker, never to an org technician
הגדרות
Settings: the name of the technician who is logged in.
יציאהdata.logout()logs out and returns to the login screen
העבודות שלי › עבודה חדשה
A new job form: the description, the client, the planned day if known, and for an admin, who does it. Saved with no technician it goes to the office as a ticket.
יום ביצוע (optional)DayChoicesets the day agreed with the client, 'YYYY-MM-DD'
מי מבצע (admins only)TechnicianPicker, data.listCompanyTechnicianspicks anyone in the company, themselves included, to do the job
שמורdata.createJob or data.openJobFromLeadsaves the job and opens it; from a lead, also marks the lead converted
העבודות שלי › עבודה
One job: its state at the top, then its planned day, description, client, and while it is open, the parts and photos. A done job is read only; a job waiting for the office has no work to do yet.
+ menuheader menu on the jobopens a menu with two choices: related job, new job
עבודה קשורה/jobs/new?relatedJobId=<id>opens a new job with this job's client filled in; the office's ticket shows where it was found
עבודה חדשה/jobs/newopens an empty new job
לקוח (client card)ClientCard (component, not read)shows the client's name, phone and address; what a tap does: can't confirm
start or stop workJobWorkspace, data.saveWorkStatesaves to the office that the technician started or stopped; button labels not read, can't confirm
חלקים (parts)JobWorkspace, data.listPartsCatalogadds parts used, picked from the catalog; only while the job is open
תמונות (photos)JobWorkspace, expo-image-pickeradds photos of the work; last on the page, optional
המשך לדוח/jobs/[id]/reportopens the report, to sign and send
the job already running/jobs/<runningId>opens the other job that is already in progress
העבודות שלי › עבודה › דוח עבודה
The job report: the time, the parts and photos, an optional note, and the client's signature. Sending it finishes the job.
הערהTextInput, sent as notesadds a note to the report
חתימת הלקוחSignaturePad, saved as a PNG data URLlets the client sign on the phone
שלחdata.sendReport, tech_send_reportsaves the report and marks the job done; for an org technician also takes the parts off stock; returns to My jobs
Back/jobs/[id]returns to the job without sending
לידים
Leads, open or closed, in the order of the day. Self-worker only.
פתוחים (tab)data.listMyLeads with closed falseshows the open leads, call-back days first
סגורים (tab)data.listMyLeads with closed trueshows the converted and lost leads, read only
ליד/leads/[id]opens one lead
+ ליד חדש/leads/newopens the form to add a lead
ייבוא מאקסל/leads/importopens the Excel import, to add many leads at once
לידים › ליד
One lead: the person's name and where the lead stands, what they want, how to reach them, then what to do after the call. A closed lead is read only.
חזרה ביוםdata.setCallBack(leadId, day)sets the day to call back; saves and returns to Leads
לא רלוונטיCloseLeadDialog, data.closeLeadcloses the lead as lost, after asking, with an optional reason
פתח עבודה/jobs/new?leadId=<id>opens a new job filled from the lead; saving marks the lead converted
לידים › ליד חדש
A new lead form: name, phone and what they want are required; the address is optional, and budget, source, email and notes are under more details.
פרטים נוספיםtoggle in the formshows budget, source, email and notes
שמורdata.createLeadsaves the lead as new and returns to Leads
לידים › ייבוא מאקסל
Excel import: the chosen file, how many leads are ready, and which rows will be skipped and why.
בחירת קובץ / החלפהexpo-document-picker, xlsxpicks the Excel file, or replaces the one chosen
ייבוא N לידיםdata.importLeads(rows)saves every ready lead in one call and returns to Leads
Questions
  • The login screen opens filled in with the demo test account (DEMO_LOGIN, user100). The phone APK goes to real technicians on the shared project. Recommendation: remove the prefill from the release build, or put it behind a build flag used only for demos.
  • Leads (the tab and its four screens) stay in the app as the 2026-10-21 decision says, but no org technician reaches them. Recommendation: keep them as they are and hide them from the navigation for every org technician, which is what the code already does. Remove them only if you want the code gone.
  • The README and the contract's comments still describe two kinds of technician, with self-workers opening their own jobs. Recommendation: rewrite them to the 2026-10-21 model (one kind of technician; the office assigns; an admin may name who does a job), so the next reader is not misled.
  • Related job and new job share one screen, with the title and the client filled in differently. Recommendation: keep one screen. Ask only if you want related jobs to have their own title or steps.
As phone screens

Home

My jobs, the home screen: the jobs assigned to this technician and the jobs they sent that are still waiting for the office, newest first, a page at a time.

עבודה (a job row)opens the job: its state, description, client, parts and photos
›
+ עבודה חדשהopens a new job form, to send work to the office
›
הגדרות (cog)opens who is logged in and the log-out button
›
לידים (tab)opens the leads; shown only to a self-worker, never to an org technician
›
‹ Home

הגדרות

Settings: the name of the technician who is logged in.

יציאהlogs out and returns to the login screen
›
‹ העבודות שלי

עבודה חדשה

A new job form: the description, the client, the planned day if known, and for an admin, who does it. Saved with no technician it goes to the office as a ticket.

יום ביצוע (optional)sets the day agreed with the client, 'YYYY-MM-DD'
›
מי מבצע (admins only)picks anyone in the company, themselves included, to do the job
›
שמורsaves the job and opens it; from a lead, also marks the lead converted
›
‹ העבודות שלי

עבודה

One job: its state at the top, then its planned day, description, client, and while it is open, the parts and photos. A done job is read only; a job waiting for the office has no work to do yet.

+ menuopens a menu with two choices: related job, new job
›
עבודה קשורהopens a new job with this job's client filled in; the office's ticket shows where it was found
›
עבודה חדשהopens an empty new job
›
לקוח (client card)shows the client's name, phone and address; what a tap does: can't confirm
›
start or stop worksaves to the office that the technician started or stopped; button labels not read, can't confirm
›
חלקים (parts)adds parts used, picked from the catalog; only while the job is open
›
תמונות (photos)adds photos of the work; last on the page, optional
›
המשך לדוחopens the report, to sign and send
›
the job already runningopens the other job that is already in progress
›
‹ עבודה

דוח עבודה

The job report: the time, the parts and photos, an optional note, and the client's signature. Sending it finishes the job.

הערהadds a note to the report
›
חתימת הלקוחlets the client sign on the phone
›
שלחsaves the report and marks the job done; for an org technician also takes the parts off stock; returns to My jobs
›
Backreturns to the job without sending
›
‹ Home

לידים

Leads, open or closed, in the order of the day. Self-worker only.

פתוחים (tab)shows the open leads, call-back days first
›
סגורים (tab)shows the converted and lost leads, read only
›
לידopens one lead
›
+ ליד חדשopens the form to add a lead
›
ייבוא מאקסלopens the Excel import, to add many leads at once
›
‹ לידים

ליד

One lead: the person's name and where the lead stands, what they want, how to reach them, then what to do after the call. A closed lead is read only.

חזרה ביוםsets the day to call back; saves and returns to Leads
›
לא רלוונטיcloses the lead as lost, after asking, with an optional reason
›
פתח עבודהopens a new job filled from the lead; saving marks the lead converted
›
‹ לידים

ליד חדש

A new lead form: name, phone and what they want are required; the address is optional, and budget, source, email and notes are under more details.

פרטים נוספיםshows budget, source, email and notes
›
שמורsaves the lead as new and returns to Leads
›
‹ לידים

ייבוא מאקסל

Excel import: the chosen file, how many leads are ready, and which rows will be skipped and why.

בחירת קובץ / החלפהpicks the Excel file, or replaces the one chosen
›
ייבוא N לידיםsaves every ready lead in one call and returns to Leads
›
Raw answer
## Screen map: technicians_app_native

**Scenario** (reasoned from the project's README and code, not from real technicians): a technician on a site visit opens the app, starts the job, records parts and photos, has the client sign, and sends the report. If they find new work on site, they send it to the office as a ticket, and an admin may name who does it.

**Gloss:** the names in the JSON use the app's Hebrew labels. העבודות שלי = My jobs, עבודה = job, עבודה חדשה = new job, עבודה קשורה = related job, דוח עבודה = job report, לידים = Leads, ליד = lead, ייבוא מאקסל = Excel import, הגדרות = Settings.

**What I read:** all 11 route files under `src/app/`. I did not read the components (JobWorkspace, ClientCard, LoginScreen, CloseLeadDialog, DayChoice, SignaturePad, TechnicianPicker, DoneJobSummary), the session and data layers, or the SQL. Anything about what those do is marked "can't confirm" in the map, and the map has no rows for them.

**Inventory** (the things a user reaches, with their forms):
- Jobs: `/jobs/[id]`, read through `data.listMyJobs` and `data.getJob`.
- Job report: `/jobs/[id]/report`, sent through `data.sendReport`.
- Parts catalog: `data.listPartsCatalog`, used inside the job.
- Leads, self-worker only: `/leads`, `/leads/[id]`, `/leads/new`, `/leads/import`.
- Settings and log-out: `/settings`.
- Login: the gate `_layout.js` shows when nobody is logged in. It is not a place, so it is not in the map.

**Judgment calls:**
- The top screen is My jobs, the home for every technician. The tab bar shows only for a self-worker.
- Related job and new job are one screen with two entries (the title changes, and the client is filled in for a related job). The map lists it once, under the job path.
- The lead's "open a job" is the same new-job screen with the lead's fields filled in. It is also listed once.
- The Leads screens stay in the map and are marked self-only, as the 2026-10-21 decision says. No org technician reaches them.
- "Add as lead" is left out, as decided on 2026-10-21.
- The top screen holds four rows, well under the limit.

```json
{"screens": [
 {"path": [], "sentence": "My jobs, the home screen: the jobs assigned to this technician and the jobs they sent that are still waiting for the office, newest first, a page at a time.",
  "rows": [
   {"name": "עבודה (a job row)", "form": "/jobs/[id]", "what": "opens the job: its state, description, client, parts and photos"},
   {"name": "+ עבודה חדשה", "form": "/jobs/new", "what": "opens a new job form, to send work to the office"},
   {"name": "הגדרות (cog)", "form": "/settings", "what": "opens who is logged in and the log-out button"},
   {"name": "לידים (tab)", "form": "/leads", "what": "opens the leads; shown only to a self-worker, never to an org technician"}
 ]},
 {"path": ["הגדרות"], "sentence": "Settings: the name of the technician who is logged in.",
  "rows": [
   {"name": "יציאה", "form": "data.logout()", "what": "logs out and returns to the login screen"}
 ]},
 {"path": ["העבודות שלי", "עבודה חדשה"], "sentence": "A new job form: the description, the client, the planned day if known, and for an admin, who does it. Saved with no technician it goes to the office as a ticket.",
  "rows": [
   {"name": "יום ביצוע (optional)", "form": "DayChoice", "what": "sets the day agreed with the client, 'YYYY-MM-DD'"},
   {"name": "מי מבצע (admins only)", "form": "TechnicianPicker, data.listCompanyTechnicians", "what": "picks anyone in the company, themselves included, to do the job"},
   {"name": "שמור", "form": "data.createJob or data.openJobFromLead", "what": "saves the job and opens it; from a lead, also marks the lead converted"}
 ]},
 {"path": ["העבודות שלי", "עבודה"], "sentence": "One job: its state at the top, then its planned day, description, client, and while it is open, the parts and photos. A done job is read only; a job waiting for the office has no work to do yet.",
  "rows": [
   {"name": "+ menu", "form": "header menu on the job", "what": "opens a menu with two choices: related job, new job"},
   {"name": "עבודה קשורה", "form": "/jobs/new?relatedJobId=<id>", "what": "opens a new job with this job's client filled in; the office's ticket shows where it was found"},
   {"name": "עבודה חדשה", "form": "/jobs/new", "what": "opens an empty new job"},
   {"name": "לקוח (client card)", "form": "ClientCard (component, not read)", "what": "shows the client's name, phone and address; what a tap does: can't confirm"},
   {"name": "start or stop work", "form": "JobWorkspace, data.saveWorkState", "what": "saves to the office that the technician started or stopped; button labels not read, can't confirm"},
   {"name": "חלקים (parts)", "form": "JobWorkspace, data.listPartsCatalog", "what": "adds parts used, picked from the catalog; only while the job is open"},
   {"name": "תמונות (photos)", "form": "JobWorkspace, expo-image-picker", "what": "adds photos of the work; last on the page, optional"},
   {"name": "המשך לדוח", "form": "/jobs/[id]/report", "what": "opens the report, to sign and send"},
   {"name": "the job already running", "form": "/jobs/<runningId>", "what": "opens the other job that is already in progress"}
 ]},
 {"path": ["העבודות שלי", "עבודה", "דוח עבודה"], "sentence": "The job report: the time, the parts and photos, an optional note, and the client's signature. Sending it finishes the job.",
  "rows": [
   {"name": "הערה", "form": "TextInput, sent as notes", "what": "adds a note to the report"},
   {"name": "חתימת הלקוח", "form": "SignaturePad, saved as a PNG data URL", "what": "lets the client sign on the phone"},
   {"name": "שלח", "form": "data.sendReport, tech_send_report", "what": "saves the report and marks the job done; for an org technician also takes the parts off stock; returns to My jobs"},
   {"name": "Back", "form": "/jobs/[id]", "what": "returns to the job without sending"}
 ]},
 {"path": ["לידים"], "sentence": "Leads, open or closed, in the order of the day. Self-worker only.",
  "rows": [
   {"name": "פתוחים (tab)", "form": "data.listMyLeads with closed false", "what": "shows the open leads, call-back days first"},
   {"name": "סגורים (tab)", "form": "data.listMyLeads with closed true", "what": "shows the converted and lost leads, read only"},
   {"name": "ליד", "form": "/leads/[id]", "what": "opens one lead"},
   {"name": "+ ליד חדש", "form": "/leads/new", "what": "opens the form to add a lead"},
   {"name": "ייבוא מאקסל", "form": "/leads/import", "what": "opens the Excel import, to add many leads at once"}
 ]},
 {"path": ["לידים", "ליד"], "sentence": "One lead: the person's name and where the lead stands, what they want, how to reach them, then what to do after the call. A closed lead is read only.",
  "rows": [
   {"name": "חזרה ביום", "form": "data.setCallBack(leadId, day)", "what": "sets the day to call back; saves and returns to Leads"},
   {"name": "לא רלוונטי", "form": "CloseLeadDialog, data.closeLead", "what": "closes the lead as lost, after asking, with an optional reason"},
   {"name": "פתח עבודה", "form": "/jobs/new?leadId=<id>", "what": "opens a new job filled from the lead; saving marks the lead converted"}
 ]},
 {"path": ["לידים", "ליד חדש"], "sentence": "A new lead form: name, phone and what they want are required; the address is optional, and budget, source, email and notes are under more details.",
  "rows": [
   {"name": "פרטים נוספים", "form": "toggle in the form", "what": "shows budget, source, email and notes"},
   {"name": "שמור", "form": "data.createLead", "what": "saves the lead as new and returns to Leads"}
 ]},
 {"path": ["לידים", "ייבוא מאקסל"], "sentence": "Excel import: the chosen file, how many leads are ready, and which rows will be skipped and why.",
  "rows": [
   {"name": "בחירת קובץ / החלפה", "form": "expo-document-picker, xlsx", "what": "picks the Excel file, or replaces the one chosen"},
   {"name": "ייבוא N לידים", "form": "data.importLeads(rows)", "what": "saves every ready lead in one call and returns to Leads"}
 ]}
],
"questions": [
 "The login screen opens filled in with the demo test account (DEMO_LOGIN, user100). The phone APK goes to real technicians on the shared project. Recommendation: remove the prefill from the release build, or put it behind a build flag used only for demos.",
 "Leads (the tab and its four screens) stay in the app as the 2026-10-21 decision says, but no org technician reaches them. Recommendation: keep them as they are and hide them from the navigation for every org technician, which is what the code already does. Remove them only if you want the code gone.",
 "The README and the contract's comments still describe two kinds of technician, with self-workers opening their own jobs. Recommendation: rewrite them to the 2026-10-21 model (one kind of technician; the office assigns; an admin may name who does a job), so the next reader is not misled.",
 "Related job and new job share one screen, with the title and the client filled in differently. Recommendation: keep one screen. Ask only if you want related jobs to have their own title or steps."
]}
```

screen-decomposition, final · run 5 exit=0 seconds=97 · prompt

P1 Recall: 1.0P2 Nothing invented: 0P3 Where and what: 1 top, 0 without a sentence, 0 with help in the pathP4 Verb first: 1.0P5 Short top: 3P6 Own words: 1.0P8 Worded per screen: 0
As terminal help
My jobs: the jobs assigned to me, and the jobs I sent to the office that nobody has taken yet, newest first, a page at a time.
Job/jobs/<id> (src/app/jobs/[id]/index.js)opens the job: its state, client, parts and photos, and what is left to finish it.
New job (+ in the title row)/jobs/new (src/app/jobs/new.js)opens the new job form to save a job for the office to assign, or, for an admin, to name who does it.
Settings (cog in the header)/settings (src/app/settings.js)opens settings to see who is logged in and to log out.
login
The login form: email, password and company code. Shown until someone is logged in.
Log inLoginScreen, shown by src/app/_layout.js (can't confirm the component's contents)logs the technician in, then opens My jobs.
job
One job: its state, description, client, parts and photos, and the steps left to finish it.
Related job (menu: עבודה קשורה)/jobs/new with relatedJobId set to this jobopens the new job form with this job's client filled in, and the office's ticket names this job as where it was found.
New job (menu: עבודה חדשה)/jobs/newopens an empty new job form.
Partsparts list on this page (JobWorkspace)lists the parts the office gave this job, and while working adds parts from the catalog.
Photoscamera, on this page (JobWorkspace)adds photos of the work while the job is in progress.
Continue to report/jobs/<id>/reportopens the report to check it, sign it and send it.
new job
The new job form: what is wanted, the client, the planned day and, for an admin, who does it. Opened empty, or with a job's client filled in as a related job.
Description and client (name, phone, address)fields on this page (FormField)types what is wanted and the client's details; name and phone are needed to save.
Planned dayday choice on this page (DayChoice)picks the day the job is planned for, optional.
Who does it (admins only)technician picker on this page (TechnicianPicker)names the technician who does the job, from your company, yourself included.
Savedata.createJob, then the job openssaves the job and opens it.
job › report
The report of this job: the time worked, the parts, the photos, notes, and the client's signature. Send is off until the signature is drawn.
Notestext box on this pagewrites a note that goes with the report.
Client's signaturesignature pad on this page (SignaturePad)draws the client's signature, which the send needs.
Senddata.sendReport, from the send buttonsends the report, finishes the job, and opens My jobs.
settings
Settings: who is logged in.
Log outlogout button on this page (useLogout in src/session)logs out and returns to the login screen.
Questions
  • What should a job still waiting for the office show in My jobs? It is saved with state 'assigned' today, which reads as given to someone. Recommend a label of 'sent to the office', the owner's word 'sent'. Can't confirm how JobRow labels it; the component is not in the dump.
  • The job's + menu has 'New job', which opens the same empty form as the top +. Recommend keeping it, since the owner asked for it on 2026-10-21, even though the repeat rule would drop it. Your call.
  • The login screen opens filled in with the demo login (user100). Recommend the release build opens empty, and the demo prefill stays for development builds only.
  • Should jobs sent to the office and assigned jobs get separate tabs above My jobs? Recommend no: one list with a state label. A split adds a screen, and the owner placed both in My jobs.
As phone screens

Home

My jobs: the jobs assigned to me, and the jobs I sent to the office that nobody has taken yet, newest first, a page at a time.

Jobopens the job: its state, client, parts and photos, and what is left to finish it.
›
New job (+ in the title row)opens the new job form to save a job for the office to assign, or, for an admin, to name who does it.
›
Settings (cog in the header)opens settings to see who is logged in and to log out.
›
‹ Home

login

The login form: email, password and company code. Shown until someone is logged in.

Log inlogs the technician in, then opens My jobs.
›
‹ Home

job

One job: its state, description, client, parts and photos, and the steps left to finish it.

Related job (menu: עבודה קשורה)opens the new job form with this job's client filled in, and the office's ticket names this job as where it was found.
›
New job (menu: עבודה חדשה)opens an empty new job form.
›
Partslists the parts the office gave this job, and while working adds parts from the catalog.
›
Photosadds photos of the work while the job is in progress.
›
Continue to reportopens the report to check it, sign it and send it.
›
‹ Home

new job

The new job form: what is wanted, the client, the planned day and, for an admin, who does it. Opened empty, or with a job's client filled in as a related job.

Description and client (name, phone, address)types what is wanted and the client's details; name and phone are needed to save.
›
Planned daypicks the day the job is planned for, optional.
›
Who does it (admins only)names the technician who does the job, from your company, yourself included.
›
Savesaves the job and opens it.
›
‹ job

report

The report of this job: the time worked, the parts, the photos, notes, and the client's signature. Send is off until the signature is drawn.

Noteswrites a note that goes with the report.
›
Client's signaturedraws the client's signature, which the send needs.
›
Sendsends the report, finishes the job, and opens My jobs.
›
‹ Home

settings

Settings: who is logged in.

Log outlogs out and returns to the login screen.
›
Raw answer
**Scenario (reasoning from experience, not from real data):** A technician on a site finds a second fault behind the one they were called to fix. They open it as a job, with the client's name, phone and address, and mark it as found in the first job. The office sees it as a ticket and assigns it, or an admin technician names who does it from the phone. Later the technician checks My jobs, works the job if it's theirs, gets the client's signature, and sends the report.

**Read:** the screen files and the README, and part of `contract.js`. The dump cuts off at 9,000 characters, and the component files (JobWorkspace, JobRow, LoginScreen, ClientCard, SignaturePad, TechnicianPicker, DoneJobSummary, PageShell) are not in it. Rows that depend on them are marked where they are unconfirmed. The timer and start/stop controls are inside JobWorkspace and are not traced.

**Judgment calls:**

- **Left off the map:** Leads, the lead screens, Excel import, the Leads tab and every self-worker rule. The owner decided on 2026-10-21 to "leave it for self workers which will never be used". The code stays.
- **Names:** the English words are the owner's (new job, related job, job, report, settings). The Hebrew labels stay in the app.
- **Login** is the gate shown before any place, not a child of My jobs, so its path is `["login"]`.
- **Settings** is reached from the cog on My jobs, a job and the new-job form. It is listed once, under My jobs.
- **New job** is one screen. A related job is the same form with the client filled in and a pointer to the job it came from.
- **Back** is not listed as a row. Every non-top screen has one.
- **A job still waiting for the office, or a done job,** offers only the rows its state allows. Parts, Photos and Continue to report are left out.
- **Stale docs:** the README and the `contract.js` header still describe the 2026-10-19 two-kinds model (Leads, "one of two kinds"). They conflict with the 2026-10-21 decisions. I have not changed them.

```json
{"screens": [
 {"path": [], "sentence": "My jobs: the jobs assigned to me, and the jobs I sent to the office that nobody has taken yet, newest first, a page at a time.", "rows": [
   {"name": "Job", "form": "/jobs/<id> (src/app/jobs/[id]/index.js)", "what": "opens the job: its state, client, parts and photos, and what is left to finish it."},
   {"name": "New job (+ in the title row)", "form": "/jobs/new (src/app/jobs/new.js)", "what": "opens the new job form to save a job for the office to assign, or, for an admin, to name who does it."},
   {"name": "Settings (cog in the header)", "form": "/settings (src/app/settings.js)", "what": "opens settings to see who is logged in and to log out."}
 ]},
 {"path": ["login"], "sentence": "The login form: email, password and company code. Shown until someone is logged in.", "rows": [
   {"name": "Log in", "form": "LoginScreen, shown by src/app/_layout.js (can't confirm the component's contents)", "what": "logs the technician in, then opens My jobs."}
 ]},
 {"path": ["job"], "sentence": "One job: its state, description, client, parts and photos, and the steps left to finish it.", "rows": [
   {"name": "Related job (menu: עבודה קשורה)", "form": "/jobs/new with relatedJobId set to this job", "what": "opens the new job form with this job's client filled in, and the office's ticket names this job as where it was found."},
   {"name": "New job (menu: עבודה חדשה)", "form": "/jobs/new", "what": "opens an empty new job form."},
   {"name": "Parts", "form": "parts list on this page (JobWorkspace)", "what": "lists the parts the office gave this job, and while working adds parts from the catalog."},
   {"name": "Photos", "form": "camera, on this page (JobWorkspace)", "what": "adds photos of the work while the job is in progress."},
   {"name": "Continue to report", "form": "/jobs/<id>/report", "what": "opens the report to check it, sign it and send it."}
 ]},
 {"path": ["new job"], "sentence": "The new job form: what is wanted, the client, the planned day and, for an admin, who does it. Opened empty, or with a job's client filled in as a related job.", "rows": [
   {"name": "Description and client (name, phone, address)", "form": "fields on this page (FormField)", "what": "types what is wanted and the client's details; name and phone are needed to save."},
   {"name": "Planned day", "form": "day choice on this page (DayChoice)", "what": "picks the day the job is planned for, optional."},
   {"name": "Who does it (admins only)", "form": "technician picker on this page (TechnicianPicker)", "what": "names the technician who does the job, from your company, yourself included."},
   {"name": "Save", "form": "data.createJob, then the job opens", "what": "saves the job and opens it."}
 ]},
 {"path": ["job", "report"], "sentence": "The report of this job: the time worked, the parts, the photos, notes, and the client's signature. Send is off until the signature is drawn.", "rows": [
   {"name": "Notes", "form": "text box on this page", "what": "writes a note that goes with the report."},
   {"name": "Client's signature", "form": "signature pad on this page (SignaturePad)", "what": "draws the client's signature, which the send needs."},
   {"name": "Send", "form": "data.sendReport, from the send button", "what": "sends the report, finishes the job, and opens My jobs."}
 ]},
 {"path": ["settings"], "sentence": "Settings: who is logged in.", "rows": [
   {"name": "Log out", "form": "logout button on this page (useLogout in src/session)", "what": "logs out and returns to the login screen."}
 ]}
],
"questions": [
 "What should a job still waiting for the office show in My jobs? It is saved with state 'assigned' today, which reads as given to someone. Recommend a label of 'sent to the office', the owner's word 'sent'. Can't confirm how JobRow labels it; the component is not in the dump.",
 "The job's + menu has 'New job', which opens the same empty form as the top +. Recommend keeping it, since the owner asked for it on 2026-10-21, even though the repeat rule would drop it. Your call.",
 "The login screen opens filled in with the demo login (user100). Recommend the release build opens empty, and the demo prefill stays for development builds only.",
 "Should jobs sent to the office and assigned jobs get separate tabs above My jobs? Recommend no: one list with a state label. A split adds a screen, and the owner placed both in My jobs."
]}
```