Skip to content
Build and shipProduct pagePricing

Fir

Fir is Frazer’s version control. It keeps the words every engineer and every model already knows (repository, branch, main, commit, pull request, merge, merge queue) and changes what is underneath: every session works in its own workspace on the server, a pull request keeps one number through every rebase, merges happen on the server, and every step can be undone.

fir is the command line. The commands are shaped like the git and pull request commands you know, every command takes --dry-run where it changes something, and none of them prompts. The full list is in the Fir CLI reference.

Product overview: Fir.

Word What it is in Fir
Repository A repository, such as acme/storefront
Branch A named line of commits that pull requests target. Every new repository’s default branch is main. Release branches are release/*. A personal branch looks like lena/retry-errors
Commit A snapshot with a content hash. A commit merged into a protected branch also gets a sequence number: main@48213
main@verified The newest commit on main that passed verification after merge. Deploys and new work read it
Pull request The unit of review, numbered per repository: #482. It keeps its number through every rebase and update
Version Each push to a pull request makes a new version: v1, v2, v3. Reviews and approvals name the version they were made on
Workspace The working copy of one session, kept on the server, such as ws/s-81f2. A workspace is not a branch: it is a git worktree on the server. fir worktree is another name for fir ws
Stack Pull requests stacked on each other: each targets the one below, and the stack merges as one entry in the merge queue
Merge queue One per protected branch. It tests pull requests on top of the branch and moves the branch once per batch
Activity log Everything that happened in a workspace, a pull request or a branch, in order. Each entry is an operation you can undo
Fork A copy of a repository in your own namespace, made when you open a pull request without write access
Merge request, MR Other names for a pull request
workspace ws/s-81f2 ──fir pr create──► pull request #482 v1 ──fir pr push──► v2, v3
│ checks, reviews, rules
▼
fir pr merge 482 --auto ──► merge queue on main ──► main@48217
│ verification
▼
main@verified, what deploys read
  1. Work in a workspace. A Frazer session (an agent, a devbox, the Frazer app) starts in its own workspace on the server. Every write is snapshotted, so a sandbox that stops loses at most seconds of work.
  2. Open a pull request. fir pr create publishes the workspace as a pull request. The session gets a head branch of its own, such as agent/s-81f2.
  3. Push new versions. fir pr push adds a version to the same pull request. Compare any two versions with fir pr diff 482 --from 2 --to 3; edits that only rebased are hidden.
  4. Merge on the server. fir pr merge 482 --auto waits for the rules and the checks, then joins the merge queue. Nothing merges on your machine.
  5. Deploy what is verified. After a merge, verification runs on main; main@verified moves when it passes.

One person can direct 10,000 to 50,000 pull requests a day on Fir, because almost every pull request merges on its own receipt (Auto-merge and the merge queue). The pull request list stops being a review queue and becomes three things: what needs you (short at any volume), what is happening now (stages and rates), and the controls. Top to bottom, a person sees the count line, the Now strip, Needs you with its budget line, the control strip when anything is paused, frozen or throttled, and then the groups by plan level. Each view is a tab and a view in the API, and your last view and density are remembered per list:

View What it shows Density by default
Now The pipeline by stage: with agents, checks and the second opinion, the merge queue, merged in the last hour, watched; each stage’s count and its rate an hour against the same hour last week, the groups that hold most of it, and a mark on a stage growing faster than its rate, with the cause (a partition stalled, a provider down, a freeze) Standard
Needs you The decisions you owe, one row each; exceptions with one cause as one row that says “covers N”; what each blocks; the one action and its key; your budget line; folded below it, Since you last looked as counts Comfortable
By node (by-plan stays an alias) Program › plan › phase › stack at any depth, at the level that fits the screen; campaign › wave › shard; dependency updates by update group; each line its counts by state and what needs you Standard
Outcomes Where pull requests ended (merged on their receipt, merged with a person, reverted, closed) by class, agent and policy, with what came after: reverts within 14 days, follow-up fixes within 14 and 90 days, incidents linked Standard
All One line a pull request: state · repository#number · title · plan and stack · Next · actor · age; more columns from a picker; sorted on the server; virtualized to 100,000 rows; Space peeks Compact
Needs others Open exceptions by holder (a person or an OWNERS group): the count, the oldest, what they block, and a holder over budget marked Standard
Flow The last 24 hours’ arrivals by hour, each split by its pull requests’ state now, so the bars add up to the count line —
Comfortable inbox The sections a small team works in: Needs you, Your agents, Low risk, Waiting on others, Merging Comfortable

A scope with more than 50 open pull requests, or more than 25 new a day for you, opens on Needs you; a smaller one opens on the Comfortable inbox, and your own choice always wins. Rows come in three densities: Comfortable (two lines, 48 px), Standard (one line, 36 px) and Compact (one line, 28 px); ⇧D cycles them.

The count line counts pull requests over the last 24 hours, because agents work around the clock, and it adds up to the total: needs you · needs others · with agents · merged (and how many needed a person) · closed. The Now strip splits what is not merged yet by stage, and it adds up to its count line too. Demo, Tue Nov 17 at 15:00 (product UI, demo data):

Scope Count line Now strip
lena at Acme, all of lena’s campaigns 224 need you · 10 need others · 4,766 with agents · 44,000 merged (350 with a person) · 1,000 closed · 50,000 in the last 24 h being written 3,134 · checks and the second opinion 1,170 · waiting for a person 234 · being repaired 251 · waiting for a lower layer 186 · in the merge queue 25 (17 testing, 8 waiting) · merged in the last hour 2,350 · watched 822
priya at Pellwyn, priya’s plans and campaigns 45 need you · 8 need others · 1,947 with agents · 17,600 merged (100 with a person) · 400 closed · 20,000 in the last 24 h being written 1,272 · checks and the second opinion 475 · waiting for a person 53 · being repaired 102 · waiting for a lower layer 76 · in the merge queue 22 · merged in the last hour 2,340 · watched 820
All of Pellwyn, eleven people, as priya sees it 45 need you · 141 need others · 3,814 with agents · 35,200 merged (400 with a person) · 800 closed · 40,000 in the last 24 h being written 2,459 · checks and the second opinion 955 · waiting for a person 186 · being repaired 205 · waiting for a lower layer 150 · in the merge queue 45 (31 testing, 14 waiting) · merged in the last hour 4,400 · watched 1,640

The count line counts pull requests; Needs you counts rows. lena’s 224 pull requests that need lena sit in 26 rows, most of them failing campaign shards that one daily campaign review covers. “Watched” counts merged layers whose watch (verification and the canary) is still running. Every level adds up to the one above at the same snapshot: Pellwyn’s 4,000 not merged at 15:00 are about 2,600 plan layers in about 720 stacks under about 240 phases of about 200 plans, about 600 campaign shards in their waves, and about 800 dependency updates, exempt classes and repairs; a program’s line (“#120 · 70 not merged · 19 stacks · 6 phases · 1 needs you”) opens to its plans, phases and stacks with nothing lost on the way.

The control strip. When any control is in force over the scope, one line under the count line says which (“Auto-merge on · 2 scopes paused (#640 P3, agent deps) · freeze release/2026.11 until 18:00 · ledger throttled to 600 an hour · error budget: payments 41 % left”); each part opens its control. The receipt in the peek: Space on a merged row shows its merge receipt in seven glyphs with words, and W opens it whole; on an open row it says which condition is still missing and what will satisfy it (“A4: second opinion running, 3 of 4 lanes · A3: 9 of 11 checks”).

An exception is something a person must decide before work can go on; everything else merges on its receipt, waits for an agent, or is closed by policy. Most never reach a person: agents resolve them (the author’s loop, regenerating a conflicted layer on the new base, a fresh start by another family), the intent declared them (the plan’s approval reviewed its predictable protected patches and settled its overlaps), a standing rule covers them (a decided cause never asks again), or a higher approval covers them (a program’s terms). What is left goes to the person or group that owns its decision, and rows with one cause join one row while its decision waits:

Exception Decided by default The one action
A layer outside its plan’s terms The plan’s approver Approve the layer, or amend the terms, which covers every layer with the same path pattern
A never-automated path The path’s OWNERS group Review
A conflict at the resolver ladder’s last step The people both agents act for, and the paths’ OWNERS Accept the recommended resolution, or choose a side
Checks still failing after the repair rounds The plan’s owner Retry with the fix, quarantine the test, or drop the layer
A decision row The plan’s decider Accept the recommendation, or choose
A Frazer Reviewer escalation The plan’s approver Accept, dismiss with a reason, or ask for a fix
A campaign’s daily review The campaign’s accountable person One row covers its failing shards and holds
A release-time approval The release’s approver Approve the stage, or hold it
A contract break held in the queue Both squads’ accountable people Stay compatible, version, or coordinate
A batch of an exempt class not automated yet The OWNERS Approve the batch: R0 and R1 only, at most 20 a row
A person’s own pull request The OWNERS Review

Rows are ranked by what they block, then due time, then risk class, then age. What one person is asked is budgeted: at most 40 pending, 25 a day and 90 minutes a day by default, and at most 10 new rows in any 10 minutes. A person whose job is supervising agents may choose a supervisor budget instead: on average at most one decision every ten minutes while on duty, at most 48 a day and four hours, with the same flood line and guards; the header then reads “13 of 48 decided · 47 of 240 min (supervisor budget)”. Past the budget, new rows go to other eligible approvers and the header says how many went to whom; rows no one else may decide wait and say so; and the causes that would remove the most rows tomorrow are listed, each with its fix as a plan. Nothing is approved by silence and no row is dropped. Because one campaign’s approval sets thousands of shards going, attention follows campaigns and plans, not pull requests: in the scale-day demo, lena’s 50,000 pull requests come to 53 rows and about 2 hours 50 minutes of decisions, and priya’s 20,000 of plan work to 61 rows and about 3 hours 20 minutes.

Accountable, as facts. Every agent pull request holds five facts as data: its scope inside the plan’s terms, the plan or record it implements, the item’s proofs, the session that answers for it, and the person the agent acts for. The peek lists them, and a pull request missing one is grouped under Needs evidence, never mixed with ready ones.

One query language for the URL (?q=), fir pr list --query, MCP list_pull_requests and saved views: is:open needs:@me kind:outside_terms plan:pellwyn/plans#416 repo:pellwyn/ledger risk:R2..R3 author:agent for:@me cause:<cause> age:>2h group:stack.

Keys and bulk actions. J and K move · X selects · Space peeks · W opens the receipt · ↵ opens · E marks an informational row done · H snoozes · A does what the row allows · ⇧A opens a batch to look at each one first · M merges when ready · R requests changes · G N Now · G O Outcomes · P pauses the selected scope with a reason (⇧P resumes) · T throttles · / filters · ? lists every key. A bulk action does, for each row, only what that row already allows you; layers outside a plan’s terms are decided by amending the terms, never by a bulk approval.

My work follows the same rule across every source: your Needs you count in decisions and your budget line, your scope’s count line, Needs you grouped by kind, your agents and campaigns as counts by state with only their exceptions as rows, your plans as one rollup line each, and Since you last looked as counts. An item exists once: answering it anywhere clears it everywhere.

Terminal window
fir pr list --view now --json
fir pr list --view needs-you --json
fir pr list --view by-node --query "plan:pellwyn/plans#405"
fir pr why ledger#147233
fir work --json

For agents, list_pull_requests {query, view, group_by} returns the counts, the exception groups, the groups and the rows at one as_of; {view: "now"} returns the stages with their counts, rates and top groups, and {view: "by_node"} the plan levels with their counts and what needs the person. get_merge_receipt returns a receipt, and the event inbox.changed updates live screens at most once a second. An agent working for a person may prepare a row (draft the amendment, rerun the check it names) and say so on it; it never answers one. The count line, the Now strip and the rollups are designed to read within 5 ms at p99 on the server for a scope of 50,000 pull requests a day, a receipt within 10 ms, and the All view to paint within 200 ms at 100,000 rows.

A pull request carries what it is for: the task (an issue or a prompt summary), the plan and the acceptance criteria. Agents write it from their task; people write a sentence. Link an issue it fixes with fir pr create --fixes 479. The Frazer Reviewer checks the diff against the intent and flags files the intent does not explain. Text copied from an issue or a web page is labeled untrusted and is never followed as an instruction.

The documents a change is written against live in Fir too, as records: plans, specs, decisions, milestones, runbooks and the rest, stored in the code repository’s own tree or in the project’s plan repository, and read through one index either way. They are numbered, versioned when they merge, typed, and linked to the commits, pull requests and checks that implement them without anyone typing a link. fir why on any line shows the change that wrote it, the plan version it was written against, the requirement that covers it and the decisions in force then and now. People approve plans after Fir has checked them and models of other families have reviewed them cold; layers inside an approved plan’s terms merge on their proofs. See Plan repositories, Record types, Programs, Decisions and The planning flow.

Each path of a repository has one of three merge policies. A path with a fixed policy always uses it.

Policy What happens Right for
direct The pull request merges once its own checks pass; the branch is verified after, a failure is bisected and the culprit reverted Leaf code, tests, docs, most agent pull requests
queue The pull request is checked on top of the current tip first; pull requests with separate paths and build targets never wait Schemas, migrations, auth, release branches
hybrid, the default A risk score picks direct or queue for each pull request from its class, paths, author and evidence Most repositories

Find out exactly what still blocks a merge with fir pr blockers 482: each blocker names its rule, what it needs and what it has. fir rules explain 482 says which rules apply and why.

Inside an approved plan’s terms, a layer auto-merges with no person’s act when seven conditions hold at its exact version (intent, worked through, checks, an independent second opinion, its risk class’s rule, paths and window), and its merge record carries a signed receipt: fir pr why 482 prints it. Every protected branch has one merge queue, split into partitions by affected targets, that tests entries in test batches. See Auto-merge and the merge queue.

Every snapshot, rebase, merge, branch change and policy change is an operation in the activity log. fir activity lists them; fir undo <operation> undoes one in your workspace or on an unmerged pull request, and shows a plan of what it changes first. fir restore <operation> brings back the state an operation left. An undo is itself an operation, so it can be undone. A merged pull request is never erased: fir pr revert 482 opens a pull request that reverts it, and it merges through the same rules.

Every pull request is in a stack, and a single pull request is a stack of one layer. fir stack create --plan 469 makes a stack with a planned layer per plan item; fir stack submit creates or extends a stack from your workspace. The server restacks every layer above one that changes, in one transaction that never fails: a conflict becomes data on the layer, and approvals follow each layer’s own patch. fir stack merge --up-to 483 merges the stack up to #483 as one entry in the merge queue, and a stack’s approver sees only what needs them. Overlaps with other open work are warned on every snapshot and resolved by a ladder of resolvers before a person is asked. See Stacks and conflicts.

The same calls an agent makes through MCP are fir commands. Each answer names where it is true (a commit such as main@48213, a pull request version, or your workspace with its unsaved edits) and how precise it is.

Question Command
Where is this text or symbol? fir search
Show a file or a range of lines fir show main@48213:services/payments/capture.go:40-80
What is defined in this file or directory? fir symbols services/payments
Where is it defined, and who uses it? fir def, fir refs, fir calls
A map of the repository in a token budget fir map --budget 2000
Why does this line exist? fir why services/payments/capture.go:57
Which tests cover it, and what failed here? fir tests, fir failures --since 7d
Who owns this path? fir owners services/checkout-api/payments

Frazer’s own agents and the harnesses Frazer supports call Fir through MCP, and every tool is also a fir command and an API method. Tool names follow the names agents already use for pull requests:

MCP tool fir command What it does
search_code fir search Literal, regex, path and symbol search, up to 16 queries a call
get_file_contents fir show Line-numbered ranges with a token budget, or an outline
create_pull_request fir pr create Open a pull request from a workspace
get_merge_blockers fir pr blockers What still blocks a merge, as data
merge_pull_request fir pr merge Merge, naming the expected version; returns an operation to follow
get_merge_queue fir queue status The merge queue of a branch
submit_stack fir stack submit Create or extend a stack from a workspace
get_stack fir stack view A stack’s layers, states and blockers
get_overlaps fir overlaps Open overlaps with other work, with the hunks and a suggested action
get_activity fir activity The activity log
undo_operation fir undo Undo an operation
why fir why Why a line, symbol or change exists
open_session fir session open Open the Fir session an agent’s commits need
get_merge_receipt fir pr why Why a layer merged, or what it still waits for

Run a local MCP server with only the tools you need: fir mcp --toolsets pull_requests,search --read-only. Connect an agent of any vendor in one step with fir agent setup <harness>; every fir command follows the CLI contract for agents.

Build tools that ask git for a version get it from the environment in every Fir workspace shell and in CI: FIR_COMMIT (the commit ID), FIR_BRANCH, FIR_SEQ (the sequence number once merged), FIR_PR (number and version) and FIR_CHANGE_ID. fir describe prints a string in the shape git describe prints.

  1. Plan the import. Nothing changes until you accept the plan; it lists the history, the owners and branch rules it converts, and every place in the repository, its CI and its scripts that calls git, with the replacement for each.

    Terminal window
    frazer source repositories import --from <git-url> --dry-run
  2. Run it without --dry-run. The full history comes in, original commit IDs kept. .gitignore becomes .fir/ignore, and code owners become OWNERS files.

  3. Rehearse. Agents, CI and devboxes read the Fir copy while people keep writing on git, for at least a week. Then cut over in one window: git becomes read-only, a last sync runs, and open pull requests move to Fir.

Leaving is one command too. frazer source repositories export --to git writes a plain git repository with the full history at any time; fir export does the same from the command line.

FirOn your serversOn the Frazer fleet
PriceIncluded: caches, search and daemons on your servers · stored data as on the fleetStored data $0.012 / GiB-month, counted once after deduplication · workspaces, merges and search free within fair use · no seats for people or agents

Every line, with the estimator: pricing.

CLI

CommandWhat it does
frazer source repositories importImport a git repository into Fir with its full history, as a plan you read before anything changes.
frazer source repositories exportWrite a Fir repository out as a plain git repository, history included, at any time.

All of them: CLI reference.