WU Prep Workflow
Completing a Work Unit is a two-step process. This guide explains the workflow.
Why Two Steps?
Section titled “Why Two Steps?”The previous single-step wu:done ran gates on main, which could cause issues with worktree isolation. The new workflow:
wu:prepruns gates in the worktree (where your changes are)wu:donedoes merge and cleanup from main
This ensures gates validate your actual changes, not stale main code.
The Workflow
Section titled “The Workflow”-
Work in your worktree
Complete your implementation, write tests, commit changes.
-
Run wu:prep from worktree
This command:
- Validates you’re in a worktree
- Runs quality gates
- Prints a copy-paste instruction for the next step
-
Run wu:done from main (copy-paste)
Copy the command printed by
wu:prep:This command:
- Validates you’re in main checkout
- Fast-forward merges your changes
- Creates completion stamp
- Runs configured external work-item close-out/readback hooks after successful local completion
- Removes the worktree
If a commit does invalidate the checkpoint, wu:done prints both the prepared commit and the
current commit before rerunning gates. The fallback retains the WU identity and replays named gate
skips recorded at prep. After any intentional fix or notes edit, the normal recovery remains:
commit, rerun wu:prep, then run the printed wu:done command without another commit.
Landing Playbook
Section titled “Landing Playbook”| Refusal or task | Sanctioned recovery |
|---|---|
| Generated manifest or metadata is dirty | Run the repository formatter, review the generated diff, and commit it before prep. |
--allow-todo has no notes justification | Run pnpm wu:edit --id WU-123 --notes 'allow-todo: <justification>'; the edit creates a commit, so rerun prep afterward. |
| Several external PBIs/work items exist | Cover every declared item in acceptance criteria. Leave configured provider close-out and readback to successful wu:done. |
| Contract completeness fails | Update the complete named surface: schema, manifest or registry, implementation, tests, and affected docs. |
| The worktree or main checkout is dirty | Inspect status, commit only intended worktree changes, preserve unrelated user changes, and follow the governed recovery printed by the command. |
| An attestation or artifact is stale | Rerun its documented producer against the current commit; do not hand-edit its JSON or skip an unrelated producing gate. |
| Prep succeeds | Treat prep and env -C <main> pnpm wu:done --id WU-123 as one uninterrupted landing operation. |
Command Reference
Section titled “Command Reference”wu:prep
Section titled “wu:prep”Prepares a WU for completion by running gates in the worktree.
| Flag | Description |
|---|---|
--id | WU ID (required) |
--docs-only | Run docs-only gates (format, spec-linter) |
--full-tests | Disable tests.unit scoping and run the default incremental/full test gate behavior |
When the active preset supports path-scoped execution, wu:prep uses the current WU’s
tests.unit entries to scope the test gate.
Safe prep-evidence reuse (WU-3949)
Section titled “Safe prep-evidence reuse (WU-3949)”Prep-evidence reuse is default-off. Enable the fast path only with both settings:
Only an identical eligible low- or medium-risk plan can reuse passed evidence. Missing, malformed,
stale, cross-workspace, or mismatched evidence runs gates fresh. --full-tests, report-all, and
high-risk prep run gates fresh; --full-tests also forces full test execution. Snapshot isolation
remains OFF: reuse does not pin or execute an immutable workspace snapshot.
For presets that do not support path-scoped execution, such as dotnet, wu:prep falls back to
the configured default test gate flow instead of trying a JavaScript-specific scoped runner.
Scope Coverage and Route Directories
Section titled “Scope Coverage and Route Directories”wu:prep verifies that every declared code_paths entry covers at least one changed file. Replace
a complete scope with explicit repeatable values:
Bracketed framework route segments such as [orgId] are matched literally when that segment exists
in the changed path. Ordinary glob character classes keep their normal meaning, so [ab] still
matches either a or b when no literal [ab] segment is present.
The same matcher is authoritative during wu:claim overlap checks and wu:done completion
validation. Claim also completes all blocking overlap, mode, and branch checks before it records an
ownership advisory or persists claim state, a session, a worktree, or a branch. A rejected
preflight therefore does not leave a claim or ownership-advisory event behind; a validated claim
records its applicable ownership advisory exactly once before continuing.
When software_delivery.gates.delivery_review.enabled: true, wu:prep can also run the native
delivery_review gate. Auto-run is controlled globally by
software_delivery.gates.delivery_review.auto_run.
Must be run from worktree - errors if run from main.
Native Delivery Review During wu:prep
Section titled “Native Delivery Review During wu:prep”delivery_review is a Software Delivery pack feature, not a vendor overlay. Enforcement is
registered from the global gate config and behaves the same for Claude, Codex, Cursor, Windsurf,
Cline, Aider, custom agents, and hosted cloud workers.
wu:prep auto-runs delivery_review only when:
software_delivery.gates.delivery_review.enabledistruesoftware_delivery.gates.delivery_review.auto_runistrue- the WU type does not match
software_delivery.gates.delivery_review.skip_types
Direct gate execution with pnpm gates uses the same global config, but does not require
auto_run: true.
When a verifier_command is configured, software_delivery.gates.delivery_review.verifier_command_mode
(default always) decides whether wu:prep runs it unconditionally or only when native evidence
is insufficient (on-insufficient-evidence) — see the
Gates Reference for the full semantics.
Legacy client-scoped software_delivery.agents.clients.<client>.features.delivery_review blocks
are accepted for one release and emit a migration warning. They may still be used for adapter UX or
prompt hints, but they are not the core enforcement switch.
The review writes a stable artifact at .lumenflow/artifacts/delivery-review/<WU-ID>.json with a
portable verdict contract:
PASSpasses gatesPARTIALlogs a warning and continuesFAILblockswu:prep
The result is designed for any host or product to consume later. It does not require
lumenflow-cloud, does not assume a specific agent vendor, and does not rename or overload
wu:verify. See the Gates Reference for the
catalogue entry, skippability default, and artifact contract.
wu:done
Section titled “wu:done”Completes a WU by merging and cleaning up.
| Flag | Description |
|---|---|
--id | WU ID (required) |
--skip-gate <name> | Skip one explicitly named skippable gate (repeatable; requires —reason and —fix-wu) |
Must be run from main - errors if run from worktree.
External QA / Work-Item Close-Out
Section titled “External QA / Work-Item Close-Out”External systems are side effects, so LumenFlow treats them as lifecycle hooks instead of worker
instructions. A worker may see external_work_items in wu:brief, but those items are context
only. The safe sequence is:
wu:claimwu:brief- implementation
- verification /
wu:prep - local
wu:done - external close-out adapter
- readback adapter
- audit trail
If wu:prep fails, wu:done fails, or branch-pr mode only creates a PR, close-out does not run.
When it does run, audit events are appended to
.lumenflow/telemetry/external-closeout.ndjson.
Configure providers through config:set:
Adapters may be command or api. Template variables available to adapters are {{wu_id}},
{{provider_id}}, {{item_id}}, {{desired_status}}, and {{lifecycle_intent}}.
Error Messages
Section titled “Error Messages”Migration Notes
Section titled “Migration Notes”Before two-step completion
Section titled “Before two-step completion”After two-step completion
Section titled “After two-step completion”Escalation Resolution
Section titled “Escalation Resolution”If a WU has escalation_triggers (e.g., sensitive_data, security_p0), wu:done blocks until the escalation is resolved. Use wu:escalate to check status or resolve:
--resolve is idempotent. After wu:release --keep-branch, wu:recover --action reset, or a
re-claim, run the same resolve command again. LumenFlow reads the active worktree’s WU as the
completion authority and reconciles an existing resolution without creating an empty commit. No
force flag or manual YAML edit is required.
| Flag | Description |
|---|---|
--id | WU ID (required) |
--resolve | Resolve the escalation |
--resolver | Override resolver email (defaults to git config) |
After resolving, wu:done will succeed for escalation-triggered WUs.
Can I skip wu:prep?
Section titled “Can I skip wu:prep?”No. If you run wu:done from main without running wu:prep first, gates won’t have run in the worktree where your changes are. The previous behavior of running gates on main has been removed.
What if gates fail in wu:prep?
Section titled “What if gates fail in wu:prep?”Fix the issues in your worktree, then run wu:prep again. The workflow prevents partial completions.
Do I still need --full-tests for .NET repos?
Section titled “Do I still need --full-tests for .NET repos?”Usually no. For presets such as dotnet, wu:prep already falls back to the configured default
test flow when path-scoped execution is unsupported. Use --full-tests when you want to force the
default incremental/full flow even for presets that support scoped execution.
Does this change named gate skips?
Section titled “Does this change named gate skips?”Named --skip-gate <name> requests remain available for explicitly skippable gates with matching structured failure evidence on main. They require --reason and --fix-wu.
What if gates fail on code I didn’t change?
Section titled “What if gates fail on code I didn’t change?”wu:prep probes the named gate against main. When structured evidence proves the same failure is pre-existing, you may request that specific skippable gate:
New failures introduced by your changes remain blocking and must be fixed first. See Troubleshooting: Pre-existing gate failures for the full verification workflow.