These rules apply to every session — a person in a terminal, Claude Code, Codex, or Modex itself driving one of them.
-
Never edit in the primary checkout. It stays on
mainand only ever receivesgit pull. Each session gets its own worktree under.worktrees/<name>on a branch of the same name, cut fromorigin/main:scripts/worktree.sh new <name> # prints the worktree path; cd into it scripts/worktree.sh check # exits 1 if you are still in the primary checkout scripts/worktree.sh remove <name> # after the PR merged
Pick a short slug for
<name>that says what the session is doing (thinking-item,fix-scroll,ci-macos)..worktrees/is git-ignored. -
Two sessions must not share a worktree or a branch. If you find commits you did not make on your branch, stop and reconcile before pushing.
-
newclaims ownership. Before resuming a legacy or released worktree, runscripts/worktree.sh claim <name> --owner <session>and thencheck. Claims never expire by age. When finished, save evidence outside the worktree, end its session, and runscripts/worktree.sh release <branch> --expect-head <full-SHA>. Only the owner may release its work. Unknown, active, dirty, and uncertain work stays. -
Use the pruning procedure.
removeand the daily installed job require fresh merge proof and a verified recovery bundle before deleting local work. Do not bypass this with force removal, branch force-deletion, or manual directory deletion.scripts/worktree.sh auditreports eligibility;schedule statusreports the local job. These tools never delete remote branches or recovery archives. GitHub deletes a PR's branch itself when the PR merges (delete_branch_on_merge, on since 2026-10-15) and moves PRs stacked on it to its base, so put follow-up work on a new branch. -
Modex's own worktree threads (
⑂) honour this convention: when a project shipsscripts/worktree.sh, Modex callsnew modex-<thread id>/remove …on it, so threads on this repo land in.worktrees/like any other session. Projects without the script get a plaingit worktreeunder~/.modex/worktrees/.
mainis protected by a ruleset (.github/rulesets/main.json): signed commits and theunit + e2e (macOS)check are required; direct pushes are rejected.- Flow: worktree → signed commits (
git commit -S) → push the branch → PR → CI green → add it to the merge queue (squash). The queue tests it on top ofmain, so the branch needn't be up to date first. Thenscripts/worktree.sh remove <name>. - Install with pnpm (
pnpm install);packageManagerinpackage.jsonpins the version. npm and Yarn refuse to run here; any other installer fails at the rootpreinstallguard. - Before pushing, run what CI runs:
pnpm build && pnpm testand, for UI changes,pnpm test:e2e.
apps/desktop— the Electron app (src/mainprocess + backends,src/rendererReact UI,e2e/Playwright).packages/core— the offline scripted engine used by demos and tests.docs/release-signing.md— how release builds are signed and notarized, and where the credentials live (never in the tree).pnpm --filter @modex/desktop diststays ad-hoc for everyday builds.docs/status.md— what has shipped, what is onmainbut unreleased, what is in flight, what is next. Update it in the PR that changes any of those.docs/reviews/holds release evidence.- Real models run only through the
claude,codex,opencodeandmimoCLIs (the last two over theiracpserver,docs/opencode.md). There is no API mode for coding turns; do not add one. App-owned Sign in with ChatGPT may make authentication-only requests to OpenAI's authorization, OpenID metadata/JWKS, token and revocation endpoints; tokens stay in main-process OS-encrypted storage and the account's Codex child environment. These calls never carry prompts or files or execute inference. The optional Auto routing judge (Jev,apps/desktop/src/main/engine/routing/) answers typed questions for Auto routing and approval rules; it never runs a turn or sees file contents. Without Jev, Auto uses its heuristic and approval rules use only exact matches or ask a human. Seedocs/auto-routing.mdanddocs/approval-rules.md. - Modex account sign-in may make identity-only requests to WorkOS's public authentication
endpoint and open its authorization/logout URLs. Main owns public-client PKCE and
OS-encrypted refresh credentials; provider/access tokens are discarded. No prompts,
files, inference or repository actions use this connection. See
docs/modex-signin.md. - Installed desktop builds may fetch public GitHub release metadata for update banners. The fixed release endpoint receives only application/version headers; no prompts, files or account credentials. Development, demos and tests keep this network check disabled.
- Approved by Val on 2026-10-24 (#377 / #376): Main may read bounded model metadata from an explicitly configured loopback connection using Ollama's
/api/tags,/api/psand metadata-only/api/show, LM Studio's model listings, or a compatible/v1/modelslisting. Requests use only that connection's credential, refuse redirects, proxy routing and non-loopback destinations, and carry no prompts, files or cloud-account credentials. Discovery must never generate inference, download/load/unload models or execute tools. Coding inference remains insidecodex app-serverorclaude -p; discovery proves neither coding compatibility nor offline inference. This exception authorizes only metadata discovery; local execution admission and runtime qualification retain their separate gates. - Approved by Val on 2026-10-25 (#326): Code Review may write to GitHub through the person's own
ghlogin, on a separate main-ownedcode-review:writechannel that is nevercode-review:read. Main runs only fixedgh apimutation endpoints it builds from its own reads (a top-level PR comment; a submitted review; a merge that passes the reviewed head SHA and offers only the methods the repository allows; and decisions 2–4: closing, reopening and draft state, title and description edits that are refused if GitHub's text changed, and reviewer requests). The only GraphQL is GitHub's two fixed draft mutations; there is no DELETE. Before a preview and again before sending, main reads the signed-in account, the repository's permission for it and the PR's head and target itself; the renderer's word, model findings and check counts are never authority. Sends are explicit, preview-bound and never retried on their own; an unclear outcome stays unknown until a read-back proves it or the person decides. Modex never sees or stores the token. Tests use a syntheticgh; a live write runs only against a disposable repository Val names. - Scratch scripts go in
apps/desktop/.probes/(git-ignored). Playwright wipesapps/desktop/test-results/on every run.