Skip to content

Configuration ​

accept_trailers ​

  • Type: bool
  • Default: false
  • Since: 0.0.14
  • Set with: TAK_ACCEPT_TRAILERS, config gate.accept_trailers

Whether tak compare and tak detect honour Tak-Accept: trailers on the commits they compare.

Off by default, because of who writes those trailers. A trailer is part of a commit message, and the commits tak compare reads are the change being gated — on a pull request, the author's own. Honouring them by default would let any change waive its own gate by adding one line, which makes the gate advisory for exactly the changes it exists to stop. The acceptance would be visible in the report, but visible is not the same as approved.

With this off, trailers are ignored entirely; if the compared range carries any, the report says so in one line, so an author is not left wondering why theirs did nothing. tak compare --accept BENCH works either way, and is the recommended route in CI: pass it from a workflow step driven by something only maintainers can do, such as applying a pull-request label.

Turn it on where every commit in the compared range has already been reviewed by the time the result matters, or where everyone who can push is trusted to waive the gate — a solo project, or comparisons along an already-reviewed main branch.

tak compare reads this key, like the rest of its gate, from the base revision's tak.toml rather than the checkout being measured, so a pull request cannot turn trailers on for itself; turning them on takes effect once that change is merged. tak detect reads the working tree's, which on a main-branch run is merged history. The environment takes precedence over either file.

TAK_ACCEPT_TRAILERS=1 tak compare origin/main

allow_empty ​

  • Type: bool
  • Default: false
  • Since: 0.0.14
  • Set with: --allow-empty, TAK_ALLOW_EMPTY, config gate.allow_empty

Whether a comparison that compared nothing passes, with a warning, instead of failing.

Applies to tak compare, tak detect and tak run --baseline --gate: the case where no series was measured on both sides, so the gate had nothing to check. Off by default, because a gate that passed without running reads exactly like one that ran clean, and the causes nobody notices — a base never recorded, notes never fetched, a recording that stopped producing instruction counts — are the ones a green check hides.

Turn it on where comparing nothing is routine rather than a symptom: a runner class that encodes an image or toolchain version, so every update starts a new series and the first comparison after it has no base; or a project still adopting, whose pull requests branch from commits measured before tak was. With it on, those runs exit successfully, the report says allow_empty let them through, and a warning goes to stderr — as a ::warning:: annotation under GitHub Actions.

The cost is that the broken causes above warn as well instead of failing. Only the empty case is waived: a regression still fails, and so do a failed check and a failed instruction count against a baseline.

--allow-empty turns it on for one run, and TAK_ALLOW_EMPTY=0 off. Like the rest of its gate, tak compare reads it from the base revision's tak.toml, so a pull request cannot waive its own empty comparison; turning it on takes effect once the change is merged. tak detect and tak run --baseline read the working tree's.

tak compare origin/main --allow-empty
TAK_ALLOW_EMPTY=0 tak detect

credit ​

  • Type: bool
  • Default: true
  • Since: 0.0.4
  • Set with: --no-credit, TAK_CREDIT, config report.credit

Whether generated reports end with a line naming tak.

On by default. A report that appears in someone's pull request should say what put it there — a reader who has never heard of tak needs a way to find out, and a maintainer evaluating the comment needs to know what to turn off.

Turn it off with --no-credit, TAK_CREDIT=0, or credit = false under [report]. Nothing else about the report changes.

tak compare origin/main --no-credit
TAK_CREDIT=0 tak compare origin/main

env_allow ​

  • Type: list<string>
  • Since: 0.0.3
  • Set with: --env-allow, TAK_ENV_ALLOW, config env.allow

Environment variables kept even though env_deny lists them.

Subtracted from env_deny, so a project can opt one variable back in without restating the whole default list. A CLI whose measured path genuinely requires a token — a client that cannot start unauthenticated, say — needs this.

Doing so makes the measurement depend on something outside the repository. That is a real cost, not a formality: the numbers become conditional on the environment the run happened to have, and a token expiring will read as a performance change.

Listing a variable here that env_deny does not mention has no effect. This setting removes entries from the deny list; it does not add anything to the environment.

tak run --env-deny GITHUB_TOKEN --env-allow GITHUB_TOKEN

env_deny ​

  • Type: list<string>
  • Default: GITHUB_TOKEN, GH_TOKEN
  • Since: 0.0.3
  • Set with: --env-deny, TAK_ENV_DENY, config env.deny

Environment variables removed from every command tak measures.

Two reasons this defaults to a non-empty list rather than to nothing.

Determinism. A CLI that finds a forge token in its environment often does more with it than without — authenticating, fetching, checking rate limits. A measurement that moves depending on whether CI happened to export a token is not a measurement of the code under test. It lands in the series as an unexplained step change on the day someone edits an unrelated workflow.

This is not a credential sandbox. The listed variables are absent from the child's direct environment, but a hostile binary can still inspect accessible same-user processes and files. In particular, tak backfill downloads and executes release binaries; run it on an isolated credential-free machine when those assets are not fully trusted.

Setting this replaces the default list rather than adding to it. To keep the defaults and remove more, list them alongside. To keep the defaults and remove fewer, use env_allow — it is subtracted from this list, so the two compose without either having to restate the other.

Names are matched exactly. There is no globbing: a benchmark whose behaviour depends on which variables happen to match a pattern is the problem this setting exists to avoid.

tak's own network calls are unaffected. backfill authenticates with curl directly rather than through the measurement path.

tak run --env-deny AWS_PROFILE --env-deny AWS_REGION
TAK_ENV_DENY=GITHUB_TOKEN,GH_TOKEN,NPM_TOKEN tak run

gate_min_delta ​

  • Type: uint
  • Default: 0
  • Since: 0.0.14
  • Set with: --gate-min-delta, TAK_GATE_MIN_DELTA, config gate.min_delta

How many instructions a count may rise by before tak compare or tak detect fails, whatever the percentage.

A regression has to exceed both this and gate_pct. A percentage alone serves small benchmarks badly: on a 450k-instruction startup check, 1% is 4,500 instructions, which one new dependency's relocations in the dynamic loader can account for before main runs. A floor lets such a benchmark keep a tight percentage without failing on a handful of instructions.

The default of 0 means no floor: any rise beyond gate_pct fails. A benchmark or subject can set its own with gate = { min_delta = N } in tak.toml.

tak compare origin/main --gate-min-delta 20000

gate_pct ​

  • Type: float
  • Default: 1.0
  • Since: 0.0.4
  • Set with: --gate-pct, TAK_GATE_PCT, config gate.pct

How much an instruction count may rise before tak compare or tak detect fails.

A percentage of the base measurement. Only instruction counts are gated. Wall clock is reported and never gated: on the same hardware it moves 4-20% run to run, so a threshold tight enough to catch a real regression would fire constantly, and one loose enough to stay quiet would catch nothing.

The default of 1% is about fifty times the ~0.02% instruction counting reproduces to, leaving room for the small differences a compiler or dependency bump can produce without turning the gate into noise.

Raise it to report without effectively failing. Setting it to zero fails on any increase at all, which sounds appealing and is not: one extra instruction on a startup path is not worth blocking a pull request over.

This is the gate for every series without its own. A benchmark or subject can set one with gate = { pct = N } in tak.toml, and that wins over this setting from any source, --gate-pct included: the flag moves the default, not the benchmarks a project has singled out.

tak compare origin/main --gate-pct 0.5
TAK_GATE_PCT=5 tak compare origin/main

runner_class ​

  • Type: string
  • Default: derived from the machine
  • Since: 0.0.6
  • Set with: --runner, TAK_RUNNER, config runner.class

The machine class a measurement is recorded under, and compared within.

Empty means derive it: gha-<os>-<arch> under GitHub Actions, local-<os>-<arch> otherwise. That is right until something about the machine changes without the name changing.

Series are partitioned on this, and must be. Absolute instruction counts shift between machine types by more than a real regression does, so tak will not compare across classes — it reports the old series as removed and the new one as added rather than inventing a step change.

Set it when the environment changes in a way the derived name cannot see. The common case is a toolchain bump: a hosted runner image or a compiler upgrade between the base measurement and this one is attributed to the code otherwise, and on a one-percent gate that is a false failure. Encoding the compiler version into the class starts a fresh series at the bump, which is honest — the numbers either side genuinely are not comparable.

tak cannot detect this for you. It measures programs, not build systems, and has no way to know what produced the binary it is timing.

TAK_RUNNER=gha-linux-x64-rust1.85 tak run --record
tak run --runner gha-linux-x64-glibc2.39