Lanes
Lanes are parallel work streams that organize work by domain and prevent overload through WIP (Work-in-Progress) limits. At the kernel level, lanes also define scope boundaries — the scope intersection algorithm uses lane code_paths as one of four permission levels that determine what an agent can access.
Why Lanes?
Section titled “Why Lanes?”Without lanes:
- Everything competes for attention
- Context switching kills productivity
- Bottlenecks form unpredictably
With lanes:
- Work is organized by domain
- Each lane has focused attention
- WIP limits prevent overload
Lane Lifecycle
Section titled “Lane Lifecycle”Lane design is an explicit lifecycle process:
unconfigured -> draft -> locked
lumenflow init bootstraps tooling and sets lane lifecycle to unconfigured. Before creating delivery WUs, run:
Check current state any time:
Defining Lanes
Section titled “Defining Lanes”Lanes use a Parent: Sublane naming convention to organize work hierarchically:
Parent Lane Categories
Section titled “Parent Lane Categories”| Parent | Purpose |
|---|---|
| Framework | Core libraries, CLI, memory, agents |
| Operations | Infrastructure, CI/CD, tooling |
| Content | Documentation, guides |
| Experience | UI components, pages |
WIP Limits
Section titled “WIP Limits”WIP (Work-in-Progress) limits control how many active WUs a lane can have simultaneously. The default is WIP=1, but lanes can be configured with higher limits when work is safely parallelizable.
- WIP=1 (default): One active WU per lane. Prevents context switching and merge conflicts.
- WIP=2+: Multiple active WUs allowed. Use when code paths are disjoint and non-overlapping. Requires a
wip_justificationexplaining why parallelization is safe.
Parallel work across lanes: Each lane operates independently. Even with WIP=1 per lane, you achieve concurrency by working in multiple lanes simultaneously.
Lock Policy
Section titled “Lock Policy”The lock_policy field controls how blocked WUs affect lane availability:
| Policy | Behavior |
|---|---|
all | Default. Blocked WUs count toward WIP. Lane stays occupied when blocked. |
active | Only in_progress WUs count. Blocked WUs release the lane lock. |
none | WIP checking disabled. Multiple WUs can be claimed regardless of status. |
When to Use Each Policy
Section titled “When to Use Each Policy”all(default): High-conflict lanes where blocked work may resume soonactive: Low-conflict lanes like documentation where blocked work is unlikely to cause merge conflictsnone: Experimental. Use only for lanes with guaranteed non-overlapping work
Pilot Recommendation
Section titled “Pilot Recommendation”Start with lock_policy: active on low-conflict lanes like Content: Documentation:
- Documentation WUs are low-conflict (different files, few dependencies)
- Blocked docs WUs rarely resume immediately
- Easy rollback: change
activeback toallin config
Rollback
Section titled “Rollback”If lock_policy: active causes issues:
- Update
workspace.yaml: changelock_policy: activetolock_policy: all - Run
pnpm wu:unlock-lane --lane "<lane>"to clear stale locks
Lane Lock Lifecycle
Section titled “Lane Lock Lifecycle”Lane locks are file-based locks (.lumenflow/locks/<lane-kebab>.lock) that enforce WIP limits. For WIP=1 lanes, a single lock file is used. For WIP=2+ lanes with lock_policy: none, lock checking is bypassed entirely. The lock lifecycle has three key phases:
Acquisition
Section titled “Acquisition”When wu:claim runs, it creates a lock file atomically using the wx (write-exclusive) flag. The lock file contains metadata including the WU ID, timestamp, agent session, and the PID of the claiming process.
Persistence
Section titled “Persistence”Because wu:claim is a short-lived CLI process, the PID stored in the lock becomes invalid as soon as the claim completes. This is expected behavior — the lock persists on disk regardless of whether the original process is still running. The lock remains valid until explicitly released by wu:done or forcibly cleared.
Release
Section titled “Release”Locks are released in three ways:
- Normal release:
wu:doneremoves the lock after merging - Stale zombie auto-clear: If a lock is both stale (older than 2 hours) AND the PID is no longer running, subsequent
wu:claimcalls auto-clear it. This handles genuinely abandoned locks from crashed processes. - Manual unlock:
pnpm wu:unlock-lane --lane "<lane>" --reason "<reason>"with audit logging
Zombie Detection Semantics
Section titled “Zombie Detection Semantics”A “zombie lock” is one where the PID that created it is no longer running. However, a dead PID alone does NOT trigger auto-clearing. Since wu:claim exits immediately after creating the worktree, every lock will have a dead PID shortly after creation.
Auto-clearing requires BOTH conditions:
- The lock PID is no longer running (zombie)
- The lock is older than 2 hours (stale)
This prevents a second wu:claim from stealing a lane that was legitimately claimed by a recently exited wu:claim process.
Why WIP=1 Matters
Section titled “Why WIP=1 Matters”Scope Boundaries
Section titled “Scope Boundaries”Lane code_paths serve a dual purpose: they organize work AND enforce security boundaries through scope intersection.
When a tool call executes, the kernel computes:
The lane’s code_paths act as the second narrowing layer. An agent working in Framework: Core (paths: packages/@lumenflow/core/**) cannot write to packages/@lumenflow/cli/** — the intersection is empty, and the kernel denies the call.
Lane Selection
Section titled “Lane Selection”When claiming a WU, specify the full Parent: Sublane format:
The WU spec should already have a lane assignment:
Auto-Detection via Paths
Section titled “Auto-Detection via Paths”LumenFlow can auto-detect lanes based on file paths using the lane inference system:
If a WU’s code_paths match a pattern, the sublane is suggested automatically.
Note: .lumenflow.lane-inference.yaml is created during lane lifecycle setup (not during lumenflow init).
Multiple Lanes
Section titled “Multiple Lanes”A WU should belong to one lane. If work spans multiple domains:
- Split the WU – One WU per lane
- Choose primary – Assign to the most affected lane
Example: Feature Spanning UI + Core
Section titled “Example: Feature Spanning UI + Core”Instead of one WU: ❌ “Add user preferences (UI + API + DB)”
Split into: ✅ WU-100: “Add preferences API” (lane: Framework: Core) ✅ WU-101: “Add preferences UI” (lane: Experience: UI) ✅ WU-102: “Add preferences schema” (lane: Operations: Infrastructure)
Visualizing Lanes
Section titled “Visualizing Lanes”The status file shows lane state:
Note: WU-103 cannot be claimed because Experience: UI lane already has WU-101 in progress.
Next Steps
Section titled “Next Steps”- Scope Intersection — How lane paths become permission boundaries
- Policy Engine — Lane-level policy rules
- Gates — Quality checks per lane
- Team Workflow — Lane strategies for teams