Skip to content
WARDEN DOCS Get Warden free
03SOFTWARE FACTORY

Lanes and gates

How triage picks a lane, how to override it, and how your rules hold Factory work for a person at the moments that matter.

View .md

A lane is how much ceremony a piece of work gets on its way to main. A gate is a point where an item waits for a person, or for your rules to let it through. Together they decide where people sign off, and where the line runs on its own.

The three lanes#

ExpressStandardAssured
ForTrivial and low riskMost workRisky or important work
ShapeNoneA plan a person approvesA full spec; a person approves each phase
Assurance levelL1L1L2
BuildSandboxed run, starts by itselfChat in a worktree, you start itChat in a worktree, you start it
ReviewPolicy engineA personA person
Review against the original askFrom L2OffOn
MergeWhen policy allowsA personA person
Triage may auto-acceptYesNoNo

Assurance levels (L0 to L4) say how much proof a change needs. See Assurance levels.

Every column can be changed per project in Customize → Lanes: Shape (None, Plan, Spec or Triage decides), Level (L0 to L4 or Triage decides), Build, whether it starts by itself, Review (A person, Policy engine or None), Review against the original ask, Deliver (Merge here or Open a pull request), Merge (A person or When policy allows), Triage may auto-accept, and How it builds (like the Build stage, or its own model, skill and instructions).

How a lane is picked#

Triage picks the lightest lane that is safe. Work touching any of these never goes to the lightest lane: authentication, permissions, migrations or schemas, payments, secrets, infrastructure or CI, public APIs, security.

With Pick the lane by size on (the default, in the Triage stage's settings):

  • One-file shortcut. A short ask (up to 280 characters) that names exactly one existing file, isn't high-risk and doesn't use words that suggest risk or design work skips triage and goes straight to the lightest lane, with no shaping.
  • Confident triage. An accept with medium or high confidence takes triage's lane with nobody asked. The item notes why, for example by size: S -> Standard.
  • Unsure or rejected. Anything else waits for a person in Needs you.

Before an automatically picked item starts building, you get a 20-second window: Building in Ns: change the lane to stop it.

Overriding the lane#

  • At triage: the item's drawer shows the lane, shape and level pickers with Accept as ‹lane›, Needs info, Reject and Run triage.
  • After acceptance: Change lane works until the build starts.
  • With rules: Customize → Who decides adds rules that change review, merge, auto-start or the minimum level for matching items, by size, kind, lane or path. They apply in this order: lane defaults, then triage's choice, then your rules in order, then path rules from your policy (always enforced). Levels only ever go up.

Gates: your rules at every step#

Every move the Factory makes is checked live by the policy engine, the same engine that checks your agent's commands. The checked moves are start the build, review, merge and open a pull request. Each check gets facts about the item: who is making the move (a person or the Factory), the lane, the files changed, whether migrations are touched, and the time.

VerdictWhat happens to the item
RUNSIt moves on.
ASKS YOUIt is held for a person. If you pressed the button yourself, you get one confirmation naming the rule.
BLOCKEDIt is held, with Allow once and Always allow this exact action. Company rules can't be waived.
Engine offlineNothing moves. Press Retry.

A held item shows a card with the Rule, Why, To satisfy it and Who can override, plus Approve and merge (or start the build, or open the PR) and Send back to the agent.

For an unattended review or merge, Warden also checks every changed file as an automated write, and the merge command itself, against your rules. A change with more than 300 changed files, or with none, is held.

Ready-made lifecycle rules#

Customize → Lifecycle rules has templates, all off until you turn them on:

RuleWhat it does
Merges are a person's callThe Factory never merges by itself, a person confirms every merge, and agents in chats ask before git merge, gh pr merge or a push to main.
Migrations need a personA change that touches database migrations (migrations/, migrate/, alembic/ or *.sql) waits for a person before merge.
No unattended merge after hours or on FridaysThe Factory merges by itself only Monday to Thursday, 09:00 to 18:00 local time. A person can still merge.
Code changes need testsA change that touches code but no test waits for a person at review and merge. The approval is the waiver.
Large changes need a personA change of more than 20 files waits for a person before merge.
Link a ticket before mergeAn item with no linked issue or ticket (its source, or #123, ABC-123 or an issue link in its text) waits before merge.

Write your own Factory rule#

The templates are ordinary rules on the Factory tool, so you can write your own in your rule file. Each check carries these facts:

FactValuesMeaning
factory_transitionstart_build, review, merge, open_prThe move being made
factory_byperson, factoryA person's click, or the Factory on its own
factory_laneexpress, standard, assured, or your lane's idThe item's lane
factory_levelL1 to L4The assurance level it is built to
factory_shapeplan, spec, chat, prHow the work was shaped
factory_kindfeature, bug, choreWhat kind of item it is
factory_sizesmall, medium, largeUp to 5 files, up to 20, more
factory_files, factory_linesa numberFiles changed; lines added plus deleted
factory_code_touched, factory_tests_touched"true", "false"A non-test code file changed; a test file changed
factory_migrations_touched"true", "false"migrations/, migrate/, alembic/ or *.sql changed
factory_ticket"true", "false"The item links an issue or ticket
factory_verified"true", "false"Verify passed on the branch's current commit
factory_weekdaymon to sunLocal day
factory_working_hours"true", "false"Monday to Friday, 09:00 to 18:00 local
Hold unverified Express merges, block big unattended bug fixes
rules:
  - ask: { tool: Factory }
    when: { factory_transition: merge, factory_lane: express, factory_verified: "false" }
    reason: "Express merges need Verify to pass on this commit"
  - deny: { tool: Factory }
    when: { factory_transition: start_build, factory_by: factory, factory_kind: bug, factory_size: large }
    reason: "Large bug fixes are started by a person"

Quote "true" and "false": unquoted, YAML reads them as booleans.

Paths that always need a person#

Customize → Who decides → Always needs a person takes path patterns such as */migrations/*, */auth/* or */.github/workflows/*. They become rules in your policy that apply only to automated runs:

What Warden writes for you
rules:
  - ask: { path: "*/migrations/*" }
    when: { trigger_mode: automated }
    reason: "Software Factory: a person reviews changes here"

An unattended build that tries to edit one of those paths is held, and so is a merge that touches one. You aren't prompted for them when you work in a chat yourself. See Automated runs for the general version.