frob is a Rust workspace, and since the self-host switch this repository
is checked, ticketed and landed by frob v2 built from its own tree. This
page is the workflow; the design lives in docs/design/ and the generated
reference in docs/reference/.
- Install the pinned toolchain (
rust-toolchain.toml),clangplusmold(Linux linker, see.cargo/config.toml) andcargo-nextest. - Build the binary:
cargo build -p frob-cli; it lands intarget/debug/frob. Inside this checkout use that binary (orcargo run -p frob-cli --), not an older globally installed frob. frob doctorconfirms toolchain, git, cache, config and ledger health.frob checkis the gate: built-in rules plus the tool stages offrob.toml(rustfmt, clippy, generated-file freshness).frob test --base <base>runs only the tests your diff reaches and records the evidence.
Tickets live in tickets/<ulid>/ (a ticket.md plus one file per event)
and are written only through frob ticket ..., never by hand. Every
ticket has a 26-character ULID id; humans use the shortest unique suffix
as a ~handle, and any lookup also accepts a v1 alias such as T-0003.
Only the full ULID is ever written into a file or a directive.
- Find work:
frob ticket doablelists todo tickets with no open blocker and a scope nobody has leased.frob ticket brief <handle>prints the description, acceptance criteria, scope and links. - Claim it:
frob work <handle>leases the ticket, creates a worktree and branch, and moves the ticket to in-progress. Work only inside that worktree and only inside the ticket'sscope. If a file outside the scope needs a change, widen the scope withfrob ticket update(recorded as an event) or file a new ticket; never edit silently. - Build and test: run
cargo dev cibefore reporting; it runs locally exactly the checks CI runs (rustfmt, clippy for the host andx86_64-pc-windows-gnu, rustdoc with-D warnings, nextest--profile ci,cargo dev gen all --check, the pinned zizmor and actionlint,frob doctor,frob check,frob test --dry-run). On Windows usecargo dev-isolated ci(a runninggob-dev.execannot be rebuilt).--keep-goingruns every step,--step <name>one,--listnames them. On a busy laptop,CARGO_DEV_CI_REMOTE=goway cargo dev ciruns the heavy steps on a goway host (seedocs/design/build-test-ci.mdsection 4); aGOWAYsummary line means goway failed, not the step. The Windows clippy step needsrustup target add x86_64-pc-windows-gnuand the MinGW C compiler (sudo apt-get install -y gcc-mingw-w64-x86-64, required by libsqlite3-sys); it checks both first and fails naming the install command. Steps declare such prerequisites incrates/gob-dev/src/ci.rs, and the parity test requiresci.ymlto install each one. Runcargo dev gen allafter any change to a rule, knob, directive or verb (generated pages underdocs/reference/anddocs/schemas/). - Evidence:
frob test --base <base>records a measurement for the tests your diff reaches, or bind one yourself withfrob ticket evidence add <handle> --provider nextest --ref <filter> --accepts <N>. - Gate:
frob check --ticket <handle>scopes the run to your ticket. Green means exit 0 atfail_on = "error"; warnings are debt, not failures. - Land: commit, then
frob landfrom the worktree. It re-verifies the evidence, merges onto the base branch, closes the ticket and removes the worktree.frob ticket close <handle>alone is for tickets with no code (decisions, triage). - Out-of-scope work you discover becomes a ticket, not a drive-by fix:
frob ticket new --title "..." --type bug --scope "..." --body "found while working <handle>", and mention its id in the commit body.
Directives are comments (//, # or an HTML comment in markdown) that
bind code, tests and docs to the ledger. Ticket arguments are always full
ULIDs.
| Directive | Meaning |
|---|---|
frob:ticket <ulid> |
This site is accounted for by the ticket; put it on every hunk you change. |
frob:todo <ulid> note |
Deliberately deferred work owned by an open ticket; a bare TODO comment fails TODO001. |
frob:doc path#slug |
This symbol is described at that documentation anchor; the doc and code must change together. |
frob:tests path::Name |
This test covers that symbol (symref grammar path::Qual.Name). |
frob:invariant name |
This site upholds a named property, backed by a test. |
frob:accept RULE because="..." |
A permanent, reasoned exception to one rule at this site. |
frob:defer RULE because="..." ticket=<ulid> |
A finding parked until the named ticket pays it. |
frob ack <symref> records a symbol's digest in frob.lock so later
signature or doc drift is reported; frob ack --help lists the forms.
- ASCII only in every file; no emoji.
- Commit format:
<type>(<scope>): <imperative summary, 72 chars max>, then an optional body wrapped at 72 that explains why. Types: feat, fix, chore, refactor, test, docs, perf, ci, build. No trailing period, one logical change per commit, never amend a pushed commit, never skip hooks. - No
Co-Authored-Bytrailer or any other attribution line, ever. - Every public item has a one-line doc comment (
missing_docsis denied); clippy pedantic and rustdoc lints are errors in CI. - Fallible operations return typed
Results; panics are for programmer bugs. Nostd::processoutsidegob-execandgob-git(PROC001). Log throughtracing, neverprintln!, outside renderers. - Update
docs/in the same change as the code it describes. - No new dependencies without discussion; open an issue first.
- Never read or write
.envfiles or private keys.
.github/workflows/ci.yml runs on every push and pull request: rustfmt,
clippy (-D warnings, host and Windows target), rustdoc (-D warnings),
nextest, cargo dev gen all --check, and on Linux the self-hosted gates
frob doctor, frob check and a dry run of
frob test --base origin/experimental. Each check is cargo dev ci --step <name> (cargo dev-isolated on Windows); the argv lives in crates/gob-dev/src/ci.rs and a parity test
fails when the workflow and cargo dev ci disagree. A change that does not pass
frob check is not merged.
AI assistance is welcome under a strict policy: say in the PR which tool
you used and how, read and understand every line you submit, and expect to
explain it in review. Unreviewed generated diffs, boilerplate that ignores
this repository, sweeping changes without a prior ticket, and tests that
only restate current behavior are not accepted. Agents follow the workflow
above exactly: frob ticket doable, frob work, stay in scope, run
frob check --ticket and frob test --base before claiming done, keep
every directive intact, report gate results honestly, and never merge
their own work. An agent-authored PR still needs a named human author.
Use the issue forms: bug report and feature request.
By contributing to frob you agree that your contributions are licensed under the project's MIT license (see LICENSE).