Skip to content

Lanes

A Lane is a project's pickup rule: when is a ticket handed to the agents, and how does that run behave. The project owns what the work is about — the ticketing destination, the repos, the operational settings; the lane decides which tickets trigger runs and with what agent context. A project has one lane or several — split them by purpose (ai-eligible → a small-fixes lane on a cheap model, ai-complex → a heavy lane on a strong one), and every run (record) belongs to exactly one lane.

Each lane polls its project's ticketing destination on its own interval. How a ticket is picked up depends on the tracker: on a label tracker (GitHub Issues and Tenbi Tickets) a ticket is eligible when it carries all of the Lane's discovery labels; on a status tracker (Jira / Shortcut) when it sits in the Lane's Ready status. Either way it's your per-ticket on/off switch, and it can route tickets to different Lanes (e.g. ai-eligible → a small-fixes Lane on a cheap model, ai-complex → a heavy Lane on a strong one).

Creating a Lane

Prerequisites: a project with a ticketing destination and at least one registered repo. Then, in the project's Lanes tab, press New Lane for this project.

The minimum viable lane:

  1. Name it (Basics).
  2. Set the pickup trigger — discovery labels or a Ready status (Ticketing).
  3. Confirm the Existing tickets (cold-start) check so a pre-existing backlog doesn't run by surprise (create only — see below).
  4. Press Create Lane.

That's it — the destination, repos, and connections all come from the project. Everything else is optional tuning with sensible defaults. Once created, the lane starts polling immediately if enabled.

The rest of this chapter walks the form section by section.

Basics

  • Name (required) — plus an optional Description.
  • Poll interval (seconds) — how often this Lane checks the project's ticketing destination. Default 30 s; min 5 s, max 24 h.
  • Enabled — a disabled Lane keeps its config but stops polling.
  • Repos — which of the project's registered repos this lane runs on. Leave it empty to run on all of them; narrow it when a lane's tickets only ever touch part of the codebase. The registry itself — clone URLs, branches, Version Control connections — is managed in project Settings.
  • Notes — freeform markdown for you and your team: links, quirks, deploy notes, gotchas. Human-only — notes are never included in run context (agent-facing guidance belongs in Coding Standards or the Optimize guide). On a saved Lane, notes save immediately with their own Save button, so a quick note edit doesn't mean re-saving the whole form.

Ticketing & lifecycle

By default a lane polls the project's destination — an external tracker or Tenbi Tickets, set in project Settings — and follows it if the destination changes. A lane may instead pick its own ticketing connection, overriding the default: one project can have a lane pulling bugs from GitHub Issues while the Composer files features into Jira. The override changes only where this lane picks work up — the Composer always files into the project's destination.

Ticketing

The form adapts to the destination tracker's vocabulary:

Label trackers (GitHub) ask for:

  • Discovery (labels — AND together) — a ticket must have all of these labels to be picked up. Most Lanes need exactly one; press Add condition only when you want a narrower AND-match.
  • Re-run label — default ai-redo; covered under Lifecycle below.
  • Label transitions — an expandable panel of per-stage label updates, defaults pre-filled; also under Lifecycle.

Status trackers (Jira / Shortcut) first ask how this lane picks up tickets — by workflow state (recommended) or by labels. Both are native concepts on these trackers; GitHub Issues and Tenbi Tickets have no statuses, so they're always label-triggered. Label mode works exactly like a label tracker (discovery labels, label transitions, the re-run label), wherever the ticket sits on the board. Workflow-state mode shows the Lifecycle mapping:

  • A required Ready status — the pickup trigger.
  • Optional per-stage status moves: the pipeline (ReadyIn ProgressDone) plus the exit states (Failed / Cancelled). In Progress carries a recommended tag in the form — the Lifecycle section below explains why it earns it.
  • The form fetches the real status names from your tracker and renders dropdowns. If that fetch fails (bad credential, network hiccup), you can type the status names manually instead of being blocked.

Statuses, not columns. The status dropdowns list your tracker's workflow statuses — not its board columns. A Kanban column can map to a different underlying status name, so pick from the actual statuses your project defines.

Existing tickets (cold-start)

Shown at create only. Your source may already hold tickets matching the discovery you just configured, and a brand-new Lane must not silently sweep that backlog on its first poll. So before creating, press Check for existing tickets (it needs the ticketing module and the discovery labels — or the Ready status — filled in first; the check works the same on both tracker kinds):

  • No matches — nothing to confirm. (If you expected matches, the discovery config may be mis-scoped — worth a second look before saving.)
  • N matches — the panel shows the count and asks what to do with them:
    • Process none — dismiss them (recommended) (the default) — the backlog is skipped; the Lane only works tickets from here on.
    • Process all — every existing match is worked once the Lane goes live.
    • Pick which to process — a checkbox list of the matching tickets (each linked, so you can open it and decide); ticked tickets are worked, the rest are dismissed.

The check itself is read-only — nothing is touched until you press Create Lane. At that point, dismissed tickets are written as cancelled skip-records, so polling never picks them up — but they're not gone for good: open the dismissed ticket's record and press Rerun to revive it later. Tickets labelled (or moved into Ready) after the Lane exists are unaffected either way — cold-start only concerns the pre-existing backlog.

Version Control

The repo host lives on the project: each repo row in the project's registry names its own Version Control connection (GitHub, Bitbucket, or Azure). The repos a lane runs on must share one connection — Tenbi tells you at save time if a selection spans two.

Workspace repos

The lane runs on the project's repo registry, narrowed by its Repos picker under Basics (empty = all). A ticket whose lane spans several repos gets one workspace containing all of them — the agents make coordinated changes, and every repo that ends up modified gets its own PR in one run. Base branch precedence: the registry row's branch → the connection's default → main. Registering, verifying, and removing repos happens in project Settings.

Messaging

Channel pings — PR opened, Run failed, Overlap — are configured once per project under Settings → Operations and apply to every lane in it.

Lifecycle

Configured in the Ticketing section above, but it earns its own walkthrough. As a run progresses, the Lane updates the ticket so anyone looking at the board sees the state without opening Tenbi. The Ticketing section is adapter-aware — it speaks whichever vocabulary your tracker uses:

  • Label trackers (GitHub) — the Label transitions panel: per stage, labels to add and remove (comma-separated). Sensible defaults are pre-filled; clear both fields on a row to disable that transition.
  • Status trackers (Jira / Shortcut) — per stage, a single status to move the ticket to, chosen from the tracker's own workflow statuses.

The stages are the same either way. Only Ready is required; the rest are optional — leave a stage blank to skip it.

StageFires when
Ready (required — the trigger)A ticket here is picked up
In Progress (recommended)The ticket is picked up
DoneThe run finishes (the PR is opened)
FailedThe run fails
CancelledThe run is cancelled

For reference, the pre-filled label-tracker defaults:

StageAddsRemoves
In Progress (on pickup)ai-in-progressai-eligible
Doneai-completedai-in-progress
Failedai-failedai-in-progress
Cancelledai-cancelledai-in-progress

Updates are best-effort — a tracker API hiccup is logged but never fails the run.

Records are the truth. Board labels and statuses are reflection for humans; whether a ticket runs is decided by its run records, not by what's on the board. That's why a stale or failed label write can't cause a double run — a finished ticket is never re-picked-up by accident even if a lifecycle update didn't land.

Re-running a finished ticket

A finished ticket already has a run record, so it won't be picked up again on its own — re-running takes a deliberate, distinct signal:

  • Label trackers — add the Lane's Re-run label (default ai-redo) to the finished ticket. It's removed once the re-run starts. (Re-applying the discovery label does nothing — the ticket already has a record.) Leave the field empty to disable label re-runs; the Rerun button still works.
  • Status trackersmove the ticket back to the Ready status. Tenbi sees it's back in Ready after a finished run and re-runs it.
  • Any tracker — the Rerun button on the record itself.

Status trackers: map In Progress. The move-back-to-Ready re-run only works if In Progress is mapped to a status — that's what moves the ticket out of Ready on pickup, so its later return to Ready is an unambiguous "do it again." Leave In Progress blank and a finished ticket just sits in Ready; re-runs then need the Rerun button on the record instead. (Mapping it also keeps the board honest — otherwise a ticket being actively worked still shows as Ready.) One caveat: the mapping has to actually work — if the In Progress move can't be applied (e.g. the transition isn't reachable in your Jira workflow), the ticket never leaves Ready and the re-run edge can fire again. Tenbi logs the failed move; keep the mapping valid.

The signals differ in reach:

  • The two board signals (re-run label, move-back-to-Ready) fire only on tickets whose last run reached Done or Failed — never on a cancelled one. A run you deliberately stopped (or a ticket you dismissed at cold-start) stays stopped no matter what the board says.
  • The Rerun button works on any finished record — Done, Failed, or Cancelled. It's the one way to revive a cancelled run or a cold-start dismissal.
  • On silent Lanes both board signals are disabled (see Silent mode below); the button is the only re-run path.

Two more re-run behaviors worth knowing:

  • One run at a time per ticket. While a run for a ticket is in flight, no re-run signal fires and the Rerun button refuses — two concurrent runs would race toward two PRs for the same ticket. Wait for the current run to finish (or cancel it) first.
  • The ticket is re-fetched. Every re-run re-reads the ticket first, so clarifying comments you added after the last attempt are part of the new run's context.

Agent Context

What the agents know beyond the ticket itself. All of it optional; the defaults are sensible.

Skills (beta)

Guidance documents from your Skills library, attached to this Lane. The library is where skills are written and classified; the Lane is where they take effect — the same skill can be attached to your flagship Lane and left off a prototype Lane.

Attaching. Press Add Skill to search the library and attach any number (each Lane caps at 15). Every attached skill's content travels with every run: agents see an index of the attached docs (name + description) and read the ones relevant to their phase — a testing-style doc guides the test author, a PR-template doc guides DevOps. Write the one-line description well; it's how agents decide what to open.

Required reading. Per attachment, mark a skill Required and the pinned agents must read it before working rather than judging relevance themselves. Required needs the skill pinned to specific agents in the library (a "read everything" instruction to every agent would dilute all of them). Use it sparingly, for the documents that are never optional — your API conventions, a security checklist.

What skills can and can't do. Additions only: they steer style, structure, and conventions, but they never override Tenbi's own quality gates, test immutability, or workflow rules. Skills add prompt context, so very large attachments spend more of each run's tokens — keep them focused.

Skills vs Coding Standards: Coding Standards is one markdown file dropped into every workspace; skills are classified per-agent, searchable, per-Lane, and can be required. New guidance generally belongs in the library.

Coding Standards

Attach a Coding Standards module and its markdown is written into each repo's worktree as CODING-STANDARD.md at the start of every run — the agents find it exactly where a human contributor would look. Good content: naming and style rules, required patterns ("service calls go through the client wrapper"), review norms, things a new senior hire would be told in week one. One module per Lane, shareable across Lanes. For per-agent targeting, search, and required-reading semantics, use Skills instead — see Modules for the module itself.

Optimize

Hosted context optimization — Tenbi pre-digesting your repos so runs skip re-parsing them — is a project setting (Settings → Operations) and applies to every lane in it. The lane form still shows the index status for this lane's repo selection, with Rebuild Now and per-repo Run indexer buttons. It gets a chapter of its own: Optimize.

Cross-ticket history

Two toggles, both on by default.

Let the PM phase consult prior tickets in this Lane — the planning agent can see what this Lane has already done:

  • Recent finished and failed runs — their tickets, PRs, and what they produced, as bounded summaries.
  • One prior artifact in full (e.g. the PRD of a clearly related ticket) when the summary isn't enough.

The point is continuity: the agent doesn't re-derive decisions or retry approaches that already failed. It's pull-based — history is only fetched when the agent judges a past run relevant, so the added cost is small — but it uses your model credits when it does. Turn it off to keep every run strictly scoped to its own ticket.

Read reviewer feedback when re-running a ticket — a re-run reads the reviewer's comments on the prior attempt's PR and folds them into the new plan, so a redo addresses what was flagged instead of repeating it. It only fires on re-runs (a first attempt is a no-op) and uses your model credits when it fetches. Turn it off to keep re-runs clean-room.

Testing

Commit tests to the PR — on by default. When off, Tenbi still writes and runs the tests (the change is verified either way) but leaves them out of the PR — for teams that want the verification without an agent's tests landing in the repo. Only applies when the repo has a test framework; repos with no test setup never get tests either way.

Execution

How the run itself behaves.

Model

Per-lane override of the model defaults: pick the model for this Lane (the list follows your selected AI agent — Claude or Codex models, never mixed), or leave it blank to inherit. Resolution order: ticket-type routing → this lane → the project's run model → the workspace default → the platform default, and every run records which level decided. This is the main cost/quality routing lever — cheaper models for low-risk lanes (small bugs), stronger models for complex ones. A pin belonging to the other provider is skipped safely (the run notes it and uses the default) rather than sent to the wrong agent.

Reasoning effort

Per-lane override of the reasoning-effort defaults (lane → project → workspace → platform; low → max — max is Claude-only, on Codex it clamps to xhigh). Higher effort spends more thinking tokens for harder tickets; the resolved value is recorded on every run.

Model routing by ticket type

An optional ticket-type → model table: rows map a ticket type to a specific model, winning over the Lane pin and the account default for matching tickets (e.g. route chore tickets to a cheaper model, feature tickets to the strongest). An empty table means the normal precedence applies. Each run's detail shows which route decided its model.

Output & Behavior

What the run emits — and who it looks like.

Silent mode (beta)

For working a ticket without the orchestrator visibly touching it. With silent mode on, the run still happens end to end — but every observable surface is muted.

When to reach for it: trialing Tenbi on a repo your team hasn't been told about yet; running against a board where stray labels or comments would cause questions; or building your own confidence — read a few silent runs' would-be PRs before letting the Lane speak in public. Many teams start a Lane silent and flip it loud once the output has earned it.

Still happens:

  • The ticket is picked up, worked, and committed.
  • The branch is pushed to the repo host.
  • The record captures everything on Tenbi's side, as always.

Suppressed:

  • Ticket comments — none are posted.
  • Lifecycle updates — no labels change, no statuses move.
  • The PR — not opened.
  • Notifications — none fire, Messaging channels and email alike.

Everything that would have been posted (comments, labels, the PR title and body) is saved on the record so you can read or copy it later and open the PR yourself.

Silent mode also disables both board re-run signals — the redo label would never be cleared and the status move-out never happens, so either signal would re-fire forever. Silent Lanes re-run via the Rerun button only.

Commit identity — the name and email on the git commits this lane's runs make, what git log and the PR's commit list show as the author. By default the author is the person the ticket is assigned to, resolved to their Tenbi account (matched by email — zero setup when the tracker email matches the account), so the work Tenbi does shows up under the real engineer. The per-lane field (under Silent mode on the Output & Behavior tab) is a fallback: set name + email to author runs that have no attributed assignee — a bot identity, say — and it applies only when nothing is attributed. Absent both, a silent lane auto-detects the identity behind the project's Version Control credential (GitHub today); otherwise commits fall back to Ticket Orchestrator <ai@orchestrator.local>.

Overlap awareness

Two toggles, both on by default — set once per project (Settings → Operations), applying to every lane in it.

Check new PRs against the repo's open PRs — the moment a run opens its pull request, Tenbi merge-probes its branch against the repo's other open pull requests — human-authored ones included — and tags the run when they textually conflict (see When Work Overlaps). Local git plus one listing call; no model credits.

Let planning see open PRs and in-flight work — the planning agent can pull a bounded summary of open PRs (with the files each one changes) and other in-flight runs' planned scopes, and plan around collisions instead of walking into them. Pull-model — uses your model credits only when it's consulted.

When something flags, you'll see it in three places: a conflict badge on the run's row and page, a plain-language banner on the run page explaining what collided, and an advisory comment on the PR itself. None of it blocks anything — the run finished; the flag tells you the merge order now matters. What to do next (including the one-click Resolve) is walked through in When Work Overlaps.

Workflow

The phase list at the bottom — which agents run, in what order — is read-only and shows the engine default:

PhaseAgent
PlanningPM
CodingArchitect
CodingTest Author
CodingDeveloper
ReviewingQA
FinalizingDevOps

Per-Lane workflow editing lands in a later release.

Protected paths

A run's changes should trace to the ticket. Some paths are privileged enough that Tenbi enforces this mechanically: by default, .github/workflows/ (GitHub Actions CI/CD definitions) is protected — if the agents modify a protected path the ticket didn't authorize, those changes are stripped from the branch before anything is pushed. The rest of the work ships normally, and the removed changes are attached to the PR description under "Suggested follow-ups (not applied)", diff included, so you can review the idea and apply it deliberately if you want it.

Two ways to authorize protected-path changes:

  • Per ticket — add the allow-protected-paths label to the ticket before it's picked up. That run may then change protected paths freely (they still go through review like everything else — Tenbi never merges).
  • Per project — the protected-path list lives in project Settings (under Repositories): add prefixes (e.g. infra/, Dockerfile) to protect more, or set the list empty to disable the gate entirely. It applies to every lane in the project.

Heads up on GitHub token scope: pushing workflow-file changes also requires the workflow scope on your PAT — see Credentials. If you grant allow-protected-paths on a ticket that touches CI, make sure the token has that scope, or the push will be rejected by GitHub itself.

Day-to-day

  • Watch it work — once the Lane is live, picked-up tickets appear as records on the Dashboard.
  • Pause a Lane — uncheck Enabled; config and history stay put.
  • Edit safely — each run snapshots the Lane's config when the ticket is picked up, so edits never affect runs already in flight, only future pickups.
  • Delete — removes the Lane, but existing records under it are kept (each carries its own config snapshot).
  • Refresh one repo's optimization — the Run indexer button; details in Optimize.
  • Projects — the unit of work a lane belongs to.
  • Connections — the registry behind the project's bindings.
  • Optimize — the context optimization behind the project's Optimize toggle.
  • Dashboard — watching the records a lane produces.
  • Troubleshooting — when a lane doesn't behave as described here.