Skip to content

feat(cli): run the repo's gate before the handovers that vouch for the code - #38

Merged
Bakhomious merged 1 commit into
mainfrom
step/gates
Nov 4, 2026
Merged

Bakhomious merged 1 commit into
mainfrom
step/gates

Conversation

@Bakhomious

Copy link
Copy Markdown
Contributor

Step gates (plan row 61): the repo's gate, the user's command that checks the repo's code, runs before each handover that vouches for the code, and a red gate refuses the handover.

What changes

  • Config: a new gate setting, layered like the others, with no default of baton's own. The config file refuses a gate of only spaces, and one that starts with -, which sh -c would read as its own options (bash, dash and zsh all do).
  • Handovers: the engineer's handover, QA's approval and the lead's final report run the gate with /bin/sh -c in the feature's worktree, wherever in the repo the role runs baton. Stdin is empty, and stdout and stderr go to baton's output in order, after a Running the gate in <worktree>: <gate> line.
    • A failing gate refuses the handover, and nothing changes.
    • baton checks the move (and the role's open question) first, so a refused move runs no gate. The gate runs without the feature's lock, and the store checks the move again under the lock.
    • The journal logs the gate that passed, with the handover.
    • Ungated: rejections, the reviewer's approval, the lead's brief and the orchestrator's moves.
  • Start: baton start, when it makes the orchestrator's session, and baton feature start refuse a repo without a gate, naming the config file. "true" checks nothing.
  • Guard: denies a role's create and edit in baton's config folder, whose file holds the gate.
  • Prompts: the engineer's, QA's and the lead's prompts describe the gate and what to do when it fails.
  • //nolint:gosec (G204) at gate.Run: the user's call through nudge (2026-11-04, answer A). The gate is a command line by design, the user's own, from the config file.
  • Docs: decision 56, risk 13 (a role can weaken the checks that the gate runs from inside the repo), the design's handover, safety, state and config parts, decisions 34 and 52, the status table (belt Done (feat(cli): belt the role panes' git pushes and gh #37), gates In review (feat(cli): run the repo's gate before the handovers that vouch for the code #38)), and the README's config section.

Checks

  • mise run check: green. Coverage 99.4%; internal/gate 100%.
  • Mutation probes: 34 mutants on the gate's run, the handover's dry run, Gated, the config check and layering, the guard's config rule, the start and open checks, and the journal field. 33 were caught. The survivor, which ignores os.UserConfigDir's error in the guard, is equivalent on macOS: the cache folder, read first, fails on the same missing $HOME.
  • Smoke run: the built binary with a fake copilot, on an isolated tmux server (-f /dev/null, its own TMUX_TMPDIR, HOME and TMPDIR). No model and no remote.
    • The refusals: no gate, and a gate of -x.
    • A red gate kept the feature with the engineer. The gate ran in the worktree's root for a role in a subfolder, and only on the three gated handovers, which the journal logged.
    • The guard denied the config file and allowed a folder beside it.
    • Ctrl-C in a pane stopped the gate and its children. A hangup sent to baton alone killed the gate's shell, and the shell's own child ran on; decision 56 says so.

…e code

The config file gains "gate", the user's command that checks the repo's
code. The engineer's handover, QA's approval and the lead's final report
run it with /bin/sh -c in the feature's worktree, show its output, and
refuse the handover while it fails; the journal logs the gate with the
handover. baton start and baton feature start refuse a repo without a
gate ("true" checks nothing), and the config file refuses a blank gate
and one that starts with "-". The guard denies a role's create and edit
in baton's config folder. The engineer's, QA's and the lead's prompts
describe the gate.

Docs: decision 56, risk 13, the design's handover, safety, state and
config parts, decisions 34 and 52, and the README's config section.
@sonarqubecloud

sonarqubecloud Bot commented Nov 4, 2026

Copy link
Copy Markdown

@Bakhomious
Bakhomious merged commit 352cca0 into main Nov 4, 2026
3 checks passed
@Bakhomious
Bakhomious deleted the step/gates branch November 4, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant