agentleFS
aku11iaku11i/phantom/AGENTS.md

phantom

AGENTS.md214 starsChanged 9 days agoMITView on GitHub

  • Commits and pushes
  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository2 other files it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

10 rules. About 0 are common, 3 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Very specific:

    Run the CLI: cargo run --locked -- --help.

    line 27
  2. Very specific:

    Before shipping, run cargo fmt --all, cargo clippy --locked --all-targets -- -D warnings, and cargo test --locked.

    line 31
  3. Distinctive:

    Use PascalCase for types, camelCase for functions and variables, and snake_case for modules.

    line 37
  4. Very specific:

    Keep CLI flags and config keys consistent with .rabi.toml and rabi config.

    line 38
  5. Distinctive:

    All files, issues, and pull requests must be written in English.

    line 39
  6. Very specific:

    Use conventional commits as in history: feat:, fix:, chore:, docs:, refactor:.

    line 48
  7. Very specific:

    Do not bump Cargo.toml or Cargo.lock in a feature pull request.

    line 49
  8. Distinctive:

    Follow Review process, REVIEW.md, and risk-tiers.md for review, risk assessment, security review, and merge approval.

    line 51
  9. Very specific:

    Ensure cargo fmt, cargo clippy --locked, and cargo test --locked pass.

    line 52
  10. Very specific:

    Never commit tokens or GitHub credentials.

    line 56

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

Repository Guidelines

Project Structure & Module Organization

  • rabi is a Rust CLI that manages local Git workspaces so many coding agents and humans can work independently in the same repository. The crate lives at the repository root (Cargo.toml, src/, tests/).
  • Development happens on main. Open pull requests against main.
  • Modules follow the old package boundaries: cli, worktree, git, config, preferences, projects, github, help.
  • Command help text and bash/zsh/fish completions are generated from help-data.json; do not maintain separate command or flag lists. Selector completion queries command rabi list --names at completion time, honors -R/--repo, and silently ignores query failures. Quote candidates for shell input before insertion (Bash uses printf %q; zsh/fish use native completion quoting).
  • Keep README.md and README.ja.md aligned in sections, commands, flags, and examples. Document breaking CLI changes in CHANGELOG.md under Unreleased; verify CLI guidance against the implementation and tests. Keep the READMEs concise; detailed English reference material lives in docs/ (commands, JSON, exit codes, installation, configuration, hooks, safety, sync, and shell integration). Documentation consistency checks live in tests/docs.rs.
  • completions bash|zsh|fish and shell-init bash|zsh|fish output raw scripts, ignore RABI_OUTPUT, and refuse explicit JSON output with usage exit 2. Missing or unknown shells exit 2. shell-init defines only the rabi function for rabi cd [SEL] [-R REF] (also rabi -R REF cd [SEL]): resolve command rabi path as text, change directory only on success, preserve trailing path newlines by removing exactly one output delimiter, and preserve lookup errors/status. Other argv pass through unchanged. Load completions separately; zsh requires compinit. No sessions or panes. Shell smoke tests live in tests/cli.rs and explicitly skip unavailable shells; CI installs zsh and fish.
  • Project hooks live in .rabi.toml ([hooks] setup and pre-remove) in the invoking checkout, or the selected primary checkout with -R/--repo. setup/remove --source-checkout overrides that source with a checkout in the same repository. RABI_REPO_PATH always points to the primary checkout. Hooks and exec also receive RABI=1, RABI_WORKSPACE, RABI_WORKSPACE_ID (empty when unrecorded), and RABI_WORKSPACE_PATH. Hooks run only after that git common directory is trusted (rabi trust add or RABI_TRUST_ALL=1). rabi does not ask with nonempty CI, JSON output, --no-input, RABI_NO_INPUT other than empty or 0, or when stdin or stderr is not a terminal. create --no-setup skips copying and hooks; setup/remove/gc --no-hooks skips hooks. Unknown hook fields fail with exit 1 through normal validation. rabi gc skips an untrusted repository that has pre-remove hooks and does not ask. Trust is the common-dir path, so a re-clone at the same path stays trusted until rabi trust remove.
  • rabi run [--provider codex|cursor|claude] [--skill VALUE] [--fresh] [--timeout DURATION] [TASK | -] starts one parent per current workspace, resuming it by default. rabi run [options] SEL -- [TASK | -] selects a workspace without cd; -R/--repo requires SEL. Without a separator a single positional remains TASK; option values never act as separators. The selected repository must be trusted before status inspection, without prompting. Primary and orphaned checkouts are refused. The parent manages progress and its own subagents; rabi only launches, stops, locks and records sessions. Skill values are injected verbatim without resolution. First/fresh runs require --skill. Missing/broken sessions fail with a --fresh hint. Provider defaults to codex on first/fresh runs; resume uses the record provider, permits the same explicit flag, and rejects a different flag with exit 2 before state changes. list/show expose a read-only run summary including provider (null if absent or invalid, warning on invalid data); stale running records display stopped unless their lock pid or process group is alive.
  • Codex parents use auto mode (--approve-for-me) without --sandbox, including resume; Codex, Cursor and Claude receive --add-dir <memory dir> when handoff is enabled (default for recorded workspaces), unless --no-handoff; model/effort are internal constants. Timeout defaults to 2h per launch; interruption/timeout kills the whole process group, reaps the parent and releases the per-workspace pid lock. rabi reports parent exit status without deciding task completion.
  • Cursor parents resolve cursor-agent, then agent, and use -p --output-format stream-json --workspace WS --trust --sandbox enabled --auto-review --model grok-4.7-high, plus --resume ID. Prompt is stdin. Resume requires HOME-based Cursor metadata with hasConversation:true under the MD5 of the same absolute workspace path. Existing .cursor/sandbox.json is preserved; absent files get the GitHub allowlist and a common-directory info/exclude entry. Completed insecure-policy tool requests produce an audit count/message. Cursor stops with INT -> TERM -> KILL and best-effort Linux descendant cleanup; Codex stop behavior is unchanged. Cursor answers come from the last result event, atomically written after reap.
  • Claude parents resolve only PATH claude, use -p --output-format stream-json --verbose --session-id UUID --permission-mode auto --permission-prompts none --model opus --effort high, replacing --session-id UUID with --resume ID on resume. Prompt is stdin; no workspace settings are written. New launches record requestedSessionId separately from the observed session id; init must report permissionMode auto before the session is resumable. Mismatched ids or non-auto/missing init permissionMode stop with an error. Probe checks CLAUDE_CONFIG_DIR (nonempty) or HOME/.claude projects/*/ID.jsonl, returning Present or Unknown. Claude uses INT -> 2s -> TERM -> 1s -> KILL with the existing Linux descendant cleanup. Result finalization follows Cursor; timeout/interrupt win over exit-0 error results, including null result strings.
  • Handoff memory lives under paths::state_dir()/repositories/<sha256(canonical common-dir bytes)>/memory/<workspace-id>/, bound to workspace id and createdAt. rabi handoff show/path are read-only; add appends under a dedicated file lock. First/fresh runs inject bounded memory, resume injects foreign entries with createdAt after the last delivered handoff snapshotAt (startedAt fallback for old records), or the full first/fresh snapshot when none exists in the run. Capture reads the snapshot under the memory lock; delivery requires an observed launch session id or exit code 0; --no-handoff skips capture, injection, grants and run env vars. Parents receive RABI_BIN, RABI_RUN_ID, RABI_RUN_LAUNCH, RABI_RUN_PROVIDER and workspace variables RABI, RABI_REPO_PATH, RABI_WORKSPACE, RABI_WORKSPACE_ID, RABI_WORKSPACE_PATH when memory is enabled; RABI_BIN is the launcher’s absolute executable path (canonicalized when possible, falling back to rabi if lookup fails), also used with shell quoting where needed in injected commands. Memory is retained by remove/gc/forget. Existing runs/workspaces remain in the git common directory.
  • trust add lists hooks and grants common-dir execution trust; JSON data stays {path,trustedAt}. rabi skill list independently lists direct child SKILL.md directories in checkout .agents/.codex/.claude skills, then user equivalents (respect CODEX_HOME); sort within each source, retain duplicates. Run never uses discovery.
  • Outer commands are repo add/list/show/forget, config get/set/unset/list (--sources for reads), trust add/remove/list, help [COMMAND...] [--json], and --version/-v. trust add shows hooks and records trust without prompting. Global -R/--repo REF selects a repository; exec requires it before SEL, followed by the required -- before the child command. Unknown commands and flags return ordinary usage errors (exit 2); do not add compatibility shims for retired interfaces before v7 stable.
  • User config keys are workspace-root, clone-root, discover-ghq, sync.strategy (auto|rebase|merge, default auto), and sync.rewrite-published (boolean, default false). Sync policy lives under [sync] in user config.toml, never in repository .rabi.toml. Invalid policy values exit 2. Unknown config keys are rejected without rewriting. Workspace names preserve hierarchical slashes. Clone-root keeps ghq.root -> GHQ_ROOT -> ~/ghq defaults. help --json includes help-data.json and its schemaVersion/exitCodes/errorCodes contract; --version --json keeps the application version in data.version.
  • Principles: single responsibility, a centralized git executor, and Result for every fallible path.

Build, Test, and Development Commands

  • Prerequisite: Rust 1.99.1, pinned in rust-toolchain.toml. The same version is pinned in .github/workflows/ci.yml and release-compile.yml (toolchain and RUSTUP_TOOLCHAIN). Dependabot opens Cargo and GitHub Actions updates from .github/dependabot.yml. It does not bump rust-toolchain.toml or those workflow strings. To move the pin, change every one of those places together, then run fmt, clippy, and tests on the new compiler. Change rust-version in Cargo.toml only when the MSRV changes. It is 1.89 because uuid 1.28 declares rust-version = "1.89.0".
  • mise.toml defines optional task aliases. mise run fmt, mise run clippy, and mise run test run the same checks as CI. It does not install Rust or other tools.
  • The installed command is rabi (rabi create, rabi --help). The Cargo package name is rabi. There is no ptm or phantom binary.
  • Run the CLI: cargo run --locked -- --help.
  • Format: cargo fmt --all.
  • Lint: cargo clippy --locked --all-targets -- -D warnings.
  • Tests: cargo test --locked.
  • Before shipping, run cargo fmt --all, cargo clippy --locked --all-targets -- -D warnings, and cargo test --locked.

Coding Style & Naming Conventions

  • Rust 2021. rustfmt is the formatter.
  • Non-test code must not use unwrap(), expect(), or panic!. Propagate errors with Result and thiserror. The crate denies clippy::unwrap_used, clippy::expect_used, and clippy::panic outside tests.
  • Use PascalCase for types, camelCase for functions and variables, and snake_case for modules.
  • Keep CLI flags and config keys consistent with .rabi.toml and rabi config.
  • All files, issues, and pull requests must be written in English. Follow existing patterns.

Testing Guidelines

  • Unit tests sit next to the module in src/. CLI coverage lives in tests/.
  • Cover success and error paths for workspace creation, git flows, and the project registry. Use temporary directories and the git executor.

Commit & Pull Request Guidelines

  • Use conventional commits as in history: feat:, fix:, chore:, docs:, refactor:.
  • Do not bump Cargo.toml or Cargo.lock in a feature pull request. Change the version by hand in a dedicated pull request against main. See Releases.
  • PRs should include a summary, verification steps, and CLI output for UX-facing changes.
  • Follow Review process, REVIEW.md, and risk-tiers.md for review, risk assessment, security review, and merge approval.
  • Ensure cargo fmt, cargo clippy --locked, and cargo test --locked pass. Note known gaps in the PR body.

Security & Configuration Tips

  • Never commit tokens or GitHub credentials. create --pr and create --issue use the gh CLI (GH_TOKEN / GH_HOST).
  • New workspaces go under $XDG_DATA_HOME/rabi/workspaces/<checkout>-<hash>/ (~/.local/share/rabi/workspaces/... when XDG_DATA_HOME is unset, empty, or relative) unless overridden with the workspace-root config key, which accepts absolute paths, ~/, or paths relative to the repository root. remove and gc may also remove a workspace recorded in rabi/workspaces/<id>.json when it sits outside that directory. An unrecorded workspace outside the configured directory is left alone. Avoid leaking local paths in logs.
  • Config lives at $XDG_CONFIG_HOME/rabi/config.toml (default ~/.config/rabi/config.toml); state lives under $XDG_STATE_HOME/rabi/ (default ~/.local/state/rabi/), with repos/ and trust.toml. Unset, empty or relative XDG values use the HOME defaults. Only current rabi paths and individual record formats are read or written. Project markers use .rabi-common-dir; clone staging uses .rabi-clone-. Do not move or delete old directories.
  • Workspace metadata uses <git-common-dir>/rabi/workspaces/ws_<uuid v4>.json (schema 2); project registrations use $XDG_STATE_HOME/rabi/repos/proj_<uuid>.json. Use the shared atomic writer for state files; workspace metadata has no internal file locks (handoff appends use a dedicated lock). Different-record additions preserve both records; same-record concurrent updates use the last write. Project readers deduplicate roots by oldest createdAt.
  • Internal run schema 2 uses <git-common-dir>/rabi/runs/run_<uuid>/state.json plus numbered launches/<n>/ prompt/events/stderr/answer files. Use the shared atomic writer for state and current pointers under runs/current/<sha256-of-absolute-checkout-path>; .lock contains the launcher pid and, once spawned, the parent process group id. Takeover requires both to be gone. Resume validates the checkout path, independently of branch-derived names. Incomplete numbered launch directories are skipped. Old schema-1 runs and user workflow files remain untouched. Workspace schema 2 stays unchanged.
  • Workspace records store purpose, links, base, and creation details. show, path, list, and exec read metadata without rewriting records. gc --older-than uses createdAt; sync --all selects every workspace in the selected repository.
  • Selectors for show/path/set/setup/exec/run/sync/remove/forget are name, ., pr:N, issue:N, a PR/issue URL, or an absolute path / path starting with ./ or ../. Linked selectors only find recorded links; multiple matches use ambiguous (2), missing matches use not_found (3). A dot with a different -R is usage (2). show/path/set/setup/exec default to dot; sync defaults to only the current workspace (primary acts as --main). show includes unmanaged checkouts. path text is only the absolute path; JSON is data.path.
  • set --unset FIELD accepts one of purpose/base/pr/issue per occurrence; repeat the flag to clear multiple fields. Validate and normalize --base, and apply edits atomically. list supports --kind workspace|primary, --names, --paths and --all-repos. Workspace objects include repo/current/managed/upstream/updatedAt; unknown values are null. Usage help goes to stderr.
  • create unifies new branches, --branch, --pr, --issue, and --detach. --base/--branch/--pr are exclusive. --reuse returns a matching workspace without copying files or running hooks; mismatches exit 4 exists. New-branch names matching local or observed remote branches exit 4 exists_remote without fetching. JSON includes workspace/source/setup/copy/metadata; source.kind is new/branch/pr/issue/detach. adopt PATH records an existing linked checkout without setup (createdAt/createdFrom null); forget SEL... only drops records, preserving files, branches and Git registration, and returns items:[{workspace,ok}].
  • setup [SEL] [--copy-file PAT] [--no-hooks] [--source-checkout PATH] copies ignored matches from the primary checkout, then runs trusted setup hooks from --source-checkout when supplied, otherwise the invoking checkout. Primary targets exit 4 primary; untrusted hooks exit 4 before any copying or record update; hook/copy failures exit 1. Create shares preparation, takes --no-setup (conflicting with --copy-file), and returns exit 6 with a shell-quoted cd '/absolute/source/checkout' && rabi setup 'SELECTOR' retry hint (a uniquely resolving name or PR/issue selector), preserving the original hook configuration and all copy patterns. Retry hints require bash or zsh and use ANSI-C quoting for control characters or non-UTF-8 bytes. When no selector resolves uniquely, the hint uses (cd WORKSPACE && rabi setup . --source-checkout SOURCE); the source must belong to the same repository. Hooks must tolerate reruns. Records store setup {state, at, error}: pending/running/ok/failed/skipped; records without setup information, including adopted records, report unknown, unrecorded ones null. A running record with a dead pid on the same host displays interrupted without writing or blocking; no locks or in-use detection. Shared workspace objects include setup and human list shows non-ok states.
  • remove SEL... requires explicit selectors; preflight all targets before hooks or removal. Dirty means modified/staged tracked files (including submodule changes) and non-ignored untracked files, matching list/show regardless of Git status display settings, and requires --discard-changes; ignored files are deleted with the workspace without warning or permission. Even when clean, workspaces with populated submodules or retained submodule data are refused during remove preflight (exit 4 dirty, including --dry-run) and skipped by gc (plan and --apply) with a rabi remove NAME --discard-changes hint; review the submodule contents, including unpushed commits, before using that permission. Known limitation: nested Git repositories inside ignored directories (for example, ignored vendor/x/.git) are also deleted; unpreserved detached commits require --delete-unpreserved-branch. Primary is always refused. Branches are deleted only if integrated into the recorded base (repository default fallback when absent), exactly matching their own upstream, or covered by verified merged PR evidence; otherwise keep with branch_kept_unpreserved and branchKeptReason. Local preservation requires an independent ref in the common Git directory after resolving symbolic refs; the retiring ref, detached HEAD, and bare object IDs are insufficient. Squash/rebase preservation requires exact tree-entry transitions (paths, modes, full before/after object IDs) in non-merge commits on the base first-parent history; textual patch IDs are insufficient. A squash matches one complete transition; rebased commits must match distinct base commits in ancestor-to-tip order without reusing evidence. Checks must remain read-only and retain uncertain history. --keep-branch always keeps branches. --dry-run returns a read-only plan. data.items contains workspace/removed/branchDeleted/branchKeptReason/detail/alreadyGone/error; unknown selectors with neither metadata nor a matching Git worktree exit 3 not_found (also with --dry-run), aborting all hooks/removal and listing every unknown selector in text. alreadyGone requires evidence: a missing directory with metadata and/or an eligible Git registration succeeds, cleaning only stale records/registrations without hooks or branch deletion. A record with remaining files but no Git registration also succeeds with alreadyGone while retaining the files, record and branch. A branch alone is insufficient. If branch deletion fails after checkout removal, remove keeps the branch with warning branch_kept_delete_failed, branchKeptReason: delete_failed, and the Git error in the item detail. This does not fail the item or stop later targets; branch-only failures exit 0 and have no retry command. Decide on any later branch cleanup with Git. A failure after persistent removal exits 6 and retains every item result. Completed removals also remove their records, so repeating the original command may exit 3. Fix the cause, then run error.details.retryCommand, also shown as Retry with in text. The retry is one invocation: cd <primary> && rabi -R <primary> remove [flags] -- <unfinished paths>. It selects only unfinished checkout or record work, preserves permission flags and output mode, and protects selectors with --. Run hints in bash or zsh; paths are shell-quoted and control characters use ANSI-C quoting. Metadata cleanup is retried only for recorded targets, using the absolute path spelling saved in the record before removal. Location selectors are fixed before removal. A linked checkout supplying pre-remove hooks is removed last; retries preserve its configuration with --source-checkout PATH, which must belong to the selected repository. Once that source is removed, only record cleanup remains and retries disable hooks. Retries add --no-hooks when the original command disabled hooks or its source had no pre-remove hooks, preserving hook non-execution even if primary defines hooks. With -R PRIMARY, dot also resolves a recorded checkout whose Git registration disappeared.
  • After local preservation checks fail, remove and gc can use GitHub evidence for a named branch. A recorded PR (set --pr or create --pr) must be MERGED, and its headRefOid must equal the local tip or contain it as an ancestor. Ancestry is checked only when that PR commit already exists locally; nothing is fetched. Partial clones (extensions.partialClone configured or any remote with promisor=true) require an exact tip match and skip PR object and ancestry probes on every Git version. A recorded URL is passed to gh and must match the checkout repository resolved by gh repo view; number-only links use that repository. Unlinked branches use one gh pr list --head BRANCH --state merged --limit 2 query and require exactly one result with the same head name and exact tip ID; ancestry is never used. Repository identity is resolved once per command. Missing or unauthenticated gh, failed queries, invalid JSON, ambiguous identities, and timeouts keep the existing local verdict. Each gh call has a 10-second deadline (shorten it with positive RABI_GH_TIMEOUT_MS); authentication prompts are disabled and non-interactive stdin is /dev/null. Remote responses, including failures, are cached for the command, while local tips and ancestry are rechecked after hooks. JSON items add preservationReason: merged_pr for GitHub proof, local for remove's local proof, otherwise null or absent. Text details identify merged-PR proof. These rules also apply to plans.
  • gc defaults to --merged/--closed-pr/--orphaned; --older-than only narrows by createdAt, excluding null. --apply is required for mutations. Dirty/unpreserved candidates skip with targeted remove hints, with separate permissions. Plan and --apply use the same dirty rule as remove/list/show: ignored files do not count as dirty and are deleted with the workspace, including nested Git repositories inside ignored directories. Hint selectors must resolve uniquely to the target; use cd/dot only for an existing directory, and a linked selector or explicit path-scoped Git removal for a missing directory. Orphan cleanup leaves branches and files. data is {plan,items:[{workspace,reasons,action,detail}]}. No ownership, internal locks, or in-use detection.
  • sync [SEL... | --all | --main] [--auto | --rebase | --merge] [--rewrite-published] [--keep-conflicts] [--dry-run]: no args only current; --main ff-only advances primary only while on default branch, otherwise not-default-branch. SEL may combine with --main, never --all. --all selects all workspaces, primary only with --main. Fetch involved remotes once, including dry-run; never push, change upstreams, or run hooks. Dry-run changes no checkout/index/local branch/record and reports plan:true; unknown future commit IDs are null. Auto rebases unpublished work and merges published work. Publication evidence includes observed remote-tracking refs, configured fetch destinations and the workspace upstream, even independent local branch refs or destinations of remotes not fetched by this sync. Only the current branch itself is excluded. Flags override sync.strategy. Published rebase refuses with exit 4 published unless flag/config rewrite permission allows it; permission never chooses strategy. Items expose strategySource, rewriteAllowed, rewriteSource, rewrotePublished; actual rewrites emit published_rewritten (updating the existing remote branch may require a force push). data is {plan,items:[{workspace,status,strategy,strategySource,rewriteAllowed,rewriteSource,rewrotePublished,before,after,conflicts,detail,code}],main:item|null}. Conflicts restore (5); --keep-conflicts requires exactly one workspace integration target. Persistent integration changes followed by failure/conflict/refusal exit 6. No ownership, internal locks, or in-use detection.
  • Both execution and dry runs use ordinary git fetch in the invoking repository. Before any fetch or integration, sync checks every configured fetch refspec of every involved remote and refuses with exit 4 refused if a positive refspec has a destination outside refs/remotes/ (including explicit refs/tags/ destinations and mirror mappings). Negative exclusions do not relax this conservative check; a missing or empty destination only writes FETCH_HEAD and is allowed. Use a tracking destination under refs/remotes/ for custom namespaces. Sync also refuses any existing symbolic ref visible to git for-each-ref under refs/remotes/ or refs/tags/ that points outside refs/remotes/; repair or remove the alias before retrying. Dangling symbolic refs are omitted by Git's enumeration and are not detected: this is a known limit shared with plain git fetch. Git retains its configured pruning, automatic tag following, negative exclusions and followRemoteHEAD behavior; automatic tag following is not an explicit fetch refspec. Combined dry runs evaluate local bases against tips planned for primary and earlier workspaces, in selection order. Planned branch tips are keyed by full refs: the short branch name refs/heads/a maps to refs/heads/refs/heads/a, independently of branch a at refs/heads/a. When an earlier planned tip is unknown, dependent items report updated, after:null, strategy:null and a dependency explanation in detail, without deciding against the old base.
  • Exec requires -- before the child command; missing delimiters return usage (2). Reuse validate_worktree_name for name parsing and the shared selector resolver for workspace selection.

Releases

  • The version lives in Cargo.toml and the rabi entry in Cargo.lock. Change it by hand in a dedicated pull request against main. Do not bump the version in other pull requests.
  • Title that pull request chore(version): vX.Y.Z (for example, chore(version): v7.0.0; prereleases are also fine). Review and approve its exact HEAD SHA, then squash-merge it into main under risk-tiers.md. Merging does not create a tag.
  • Create a draft at the full merge commit SHA: gh release create v<version> --draft --target <merge-commit-SHA> --title "rabi v<version>" --generate-notes. Create the draft without Latest flags; add only --prerelease for prereleases. Choose Latest at dispatch with -f make_latest=true|false|legacy (default true); stable 7.x releases use true even during the v7 beta, and prereleases are forced to false. Backports to an older release line (for example, a patch for an older minor after a newer minor has shipped) dispatch with -f make_latest=false. Polish the draft notes before dispatching when possible; notes remain editable after publishing. Dispatch .github/workflows/release-compile.yml with gh workflow run release-compile.yml --ref main -f tag=v<version> -f make_latest=true and watch the run. CI resolves the unique draft and its commit, builds, verifies and attests all six assets, uploads them to that draft, checks its complete asset list and sizes, then publishes it. For a new tag, the draft target must be a full SHA reachable from main; an existing tag must resolve to the intended commit, also reachable from main, and match any full target SHA on the draft. The workflow packages the version in Cargo.toml as rabi-v<version>-<os>-<arch>.tar.gz for linux/darwin x64/arm64, each containing only rabi. install.sh supports only rabi-v<version>-<os>-<arch>.tar.gz archives. v7.0.0-alpha.10, v7.0.0-alpha.9 and v7.0.0-alpha.8 must each be installed with that release's own install.sh at https://github.com/yoiailabs/rabi/releases/download/<TAG>/install.sh (replace <TAG> with the release tag); v7.0.0-alpha.7 and older have no installer and must be installed manually. Linux binaries use static musl. Releases upload all four archives, install.sh from the tag, and sorted SHA256SUMS covering those five files, with GitHub artifact attestations for all six assets. Artifact attestations name the main workflow commit that ran the build; the built commit is the resolved release commit shown in the run summary alongside the tag, release ID, workflow commit and six asset SHA256s. GitHub's own immutable-release attestation binds the tag, commit and assets. Before publishing, the finalize job installs the linux-x64 archive with install.sh from a local file:// mirror of the assets. PR dry runs build and verify checksums without attesting or uploading to a release; only dry runs may skip a missing install.sh. npm is not published.
  • PR dry runs still run on pull requests to main touching .github/workflows/release-compile.yml, Cargo.toml, Cargo.lock, rust-toolchain.toml, or install.sh, building all four targets and running the installer smoke test.
  • Before the first ship, enable release immutability in Settings → General → Releases → "Enable release immutability". Publishing locks assets and the tag. CI fails after publishing if the release API reports immutability is disabled, and warns if the field is absent. If CI fails before publishing, fix the cause and re-dispatch (draft assets can be replaced), or delete the draft. Never patch a published release's assets or tag. A deleted immutable release's tag cannot be reused; ship a new patch version instead.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.