Skip to content

WU Prep Workflow

Completing a Work Unit is a two-step process. This guide explains the workflow.

The previous single-step wu:done ran gates on main, which could cause issues with worktree isolation. The new workflow:

  1. wu:prep runs gates in the worktree (where your changes are)
  2. wu:done does merge and cleanup from main

This ensures gates validate your actual changes, not stale main code.

  1. Work in your worktree

    Complete your implementation, write tests, commit changes.

  2. Run wu:prep from worktree

    pnpm wu:prep --id WU-123

    This command:

    • Validates you’re in a worktree
    • Runs quality gates
    • Prints a copy-paste instruction for the next step
  3. Run wu:done from main (copy-paste)

    Copy the command printed by wu:prep:

    env -C /path/to/main pnpm wu:done --id WU-123

    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.

Refusal or taskSanctioned recovery
Generated manifest or metadata is dirtyRun the repository formatter, review the generated diff, and commit it before prep.
--allow-todo has no notes justificationRun pnpm wu:edit --id WU-123 --notes 'allow-todo: <justification>'; the edit creates a commit, so rerun prep afterward.
Several external PBIs/work items existCover every declared item in acceptance criteria. Leave configured provider close-out and readback to successful wu:done.
Contract completeness failsUpdate the complete named surface: schema, manifest or registry, implementation, tests, and affected docs.
The worktree or main checkout is dirtyInspect status, commit only intended worktree changes, preserve unrelated user changes, and follow the governed recovery printed by the command.
An attestation or artifact is staleRerun its documented producer against the current commit; do not hand-edit its JSON or skip an unrelated producing gate.
Prep succeedsTreat prep and env -C <main> pnpm wu:done --id WU-123 as one uninterrupted landing operation.

Prepares a WU for completion by running gates in the worktree.

pnpm wu:prep --id WU-123 [--docs-only] [--full-tests]
FlagDescription
--idWU ID (required)
--docs-onlyRun docs-only gates (format, spec-linter)
--full-testsDisable 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.

Prep-evidence reuse is default-off. Enable the fast path only with both settings:

local_prep:
  reuse_evidence: true
  report_all: false

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.

wu:prep verifies that every declared code_paths entry covers at least one changed file. Replace a complete scope with explicit repeatable values:

pnpm wu:edit --id WU-123 --replace-code-paths \
  --code-paths "src/app/[orgId]/admin/**" \
  --code-paths "src/shared/**"

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.

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.enabled is true
  • software_delivery.gates.delivery_review.auto_run is true
  • 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:

  • PASS passes gates
  • PARTIAL logs a warning and continues
  • FAIL blocks wu: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.

Completes a WU by merging and cleaning up.

pnpm wu:done --id WU-123
FlagDescription
--idWU 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 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:

  1. wu:claim
  2. wu:brief
  3. implementation
  4. verification / wu:prep
  5. local wu:done
  6. external close-out adapter
  7. readback adapter
  8. 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:

pnpm config:set --key software_delivery.external_work_items.enabled --value true
pnpm config:set --key software_delivery.external_work_items.providers.hub --json-value '{
  "closeout": {
    "kind": "command",
    "command": "pbis",
    "args": ["done", "{{item_id}}", "--status", "{{desired_status}}"]
  },
  "readback": {
    "kind": "command",
    "command": "pbis",
    "args": ["show", "{{item_id}}", "--json"],
    "status_json_path": "state.status"
  },
  "review": {
    "verdict_statuses": ["Pass", "Fail"],
    "worker_may_set_verdict": false
  },
  "rollback_guidance": "Reopen the item or move it out of review if readback diverges."
}'

Adapters may be command or api. Template variables available to adapters are {{wu_id}}, {{provider_id}}, {{item_id}}, {{desired_status}}, and {{lifecycle_intent}}.

# Old workflow (single step)
cd /path/to/main
pnpm wu:done --id WU-123  # Ran gates on main
# New workflow (two steps)
# Step 1: From worktree
pnpm wu:prep --id WU-123

# Step 2: From main (copy-paste from wu:prep output, with no intervening commit)
env -C /path/to/main pnpm wu:done --id WU-123

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:

# Check escalation status
pnpm wu:escalate --id WU-123

# Resolve escalation (uses git user.email)
pnpm wu:escalate --resolve --id WU-123

# Resolve with a specific approver email
pnpm wu:escalate --resolve --id WU-123 --resolver admin@example.com

--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.

FlagDescription
--idWU ID (required)
--resolveResolve the escalation
--resolverOverride resolver email (defaults to git config)

After resolving, wu:done will succeed for escalation-triggered WUs.

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.

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.

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:

env -C /path/to/main pnpm wu:done --id WU-XXX --skip-gate <name> --reason "pre-existing on main" --fix-wu WU-YYY

New failures introduced by your changes remain blocking and must be fixed first. See Troubleshooting: Pre-existing gate failures for the full verification workflow.