Skip to content

Troubleshooting

This guide covers common issues you may encounter with LumenFlow and how to resolve them.

Release reports an incoherent CLI artifact

Section titled “Release reports an incoherent CLI artifact”

The release entry is required to use a dist artifact whose provenance sidecar matches the CLI source, dependency/lockfile, and build configuration digests, the current Node major/ABI, and the expected entry path. A source edit, dependency or build-config change, missing/corrupt sidecar, or Node ABI change therefore causes a locked rebuild; the old dist is never executed.

Follow the exact remediation printed by the launcher (normally: pnpm install && pnpm build) and retry with Node 26. If the rebuild fails or the sidecar remains mismatched, release stops before mutating versions, tags, or registry state. Do not bypass this check with a timestamp assumption or a force flag.

CLI build cache reports an unusable or unactivatable build

Section titled “CLI build cache reports an unusable or unactivatable build”

Lifecycle commands that need a freshly built CLI resolve the build output by a digest of its inputs and keep it in a per-machine cache outside every checkout (~/.lumenflow/cache/cli-dist by default, moved with LUMENFLOW_CLI_DIST_CACHE — see the config reference). Every success claim is verified: the expected entry exists, the provenance sidecar is readable, every declared output file is present, and provenance matches the current inputs.

FreshDistIncompleteArtifactError names which of those failed:

  • A cached build could not be activated (a refused file removal, a full or read-only filesystem, a symlink inside the output directory). The command falls back to a real build on its own; no action is needed unless the real build then fails for the same environmental reason.
  • A peer build did not leave a usable artifact. The command rebuilds instead of trusting the peer’s completion. If it repeats, another process is writing the same output directory outside the lifecycle.
  • The build completed without replacing the output, so its provenance cannot be republished. This is the one case that needs you: an incremental build cannot replace an output it already considers current, so it can never repair a missing or corrupt provenance sidecar and every retry fails identically. Re-run the configured build with its cache disabled so it re-executes — the error prints the exact command. Do not delete a dist directory that other checkouts read through; that empties the artifact those checkouts depend on while your build runs.

A poisoned or partially copied cache entry is rejected before activation rather than published over a working output, so a bad entry costs one rebuild, not a broken checkout. If you must discard the cache entirely, remove the cache root; it is rebuilt on demand and contains no state that is not reproducible from source.

The CLI hashes source, dependencies, and the Node ABI together, so sessions running different Node versions invalidate each other’s dist in a loop: pin the engine version on every command. Treat ERR_MODULE_NOT_FOUND under dist after a successful build as a stale build cache, not a code problem — remedy it with a forced rebuild of the package, not a debugging session.

Symptom:

> Format check... FAILED
>   src/utils/validator.ts needs formatting

Fix:

# Auto-fix formatting
pnpm format
# or
npx prettier --write .
# Or fix only the files listed by gates (copy from the gates output):
pnpm prettier --write "apps/docs/src/content/docs/getting-started/quickstart.mdx"

# Then retry
pnpm wu:prep --id WU-XXX

Symptom:

> Lint check... FAILED
>   src/api/handler.ts:42 - Unexpected any

Fix:

  1. Read the error message to understand the issue
  2. Fix the code (don’t disable the rule unless necessary)
  3. Retry: pnpm wu:prep --id WU-XXX

Common lint fixes:

ErrorFix
no-explicit-anyAdd proper TypeScript types
no-unused-varsRemove the variable or prefix with _
exhaustive-depsAdd missing useEffect dependencies
no-restricted-importsUse the correct import path

Symptom:

> Type check... FAILED
> error TS2322: Type 'string' is not assignable to type 'number'

Fix:

  1. Fix the first error (later errors often cascade from earlier ones)
  2. Save and check again
  3. Repeat until clean

Symptom:

> Tests... FAILED
>   FAIL src/__tests__/auth.test.ts
>   Expected: "success"
>   Received: "error"

Fix:

  1. Run the failing test in isolation: pnpm test src/__tests__/auth.test.ts
  2. Debug: check test setup, mocks, and assertions
  3. Fix and retry

Common causes:

  • Mocks not reset between tests (use beforeEach)
  • Async tests not awaited
  • Environment differences (CI vs local)

If gates fail on code you didn’t change:

  1. Verify the failure existed before your changes

    # Re-run prep — it classifies each named gate against main without
    # mutating your worktree
    pnpm wu:prep --id WU-042
    # A gate the classifier marks pre-existing on main auto-skips; it does
    # not block your WU
  2. Use a named gate skip only when the gate is explicitly skippable

    pnpm wu:done --id WU-042 \
      --skip-gate lane-health \
      --reason "Pre-existing lint failure in src/legacy.ts" \
      --fix-wu WU-050
  3. Create a follow-up WU to fix the issue

Symptom: WU shows in_progress but worktree is gone or work is done elsewhere.

Fix:

# Check current state
pnpm wu:status --id WU-042

# Recover based on situation
pnpm wu:recover --id WU-042

# Choose the appropriate action:
pnpm wu:recover --id WU-042 --action restore  # Recreate missing active worktree from lane branch
pnpm wu:recover --id WU-042 --action resume   # Resume recoverable WU state
pnpm wu:recover --id WU-042 --action reconcile # Unstage only a proven stale completion tuple
pnpm wu:recover --id WU-042 --action reset    # Reset ready/in_progress → ready
pnpm wu:recover --id WU-042 --action cleanup  # Remove orphaned worktree

Use restore first when the WU is active or recently active and its lane branch still exists. It recreates the worktree without resetting WU status, branch, baseline/main metadata, or completion evidence. Use reset for orphaned ready / in_progress state only after restore is impossible or intentionally not wanted.

Current non-PR automatic wu:done publication builds and validates completion metadata in an isolated temporary worktree, then publishes the exact commit without mutating checked-out main. If remote acknowledgement is lost, it preserves that evidence; rerun the same command to prove and retire an accepted publication or rebuild from the latest remote main. For historical residue from older versions, run the read-only analyzer. If it proves that rollback completed but the index retains only the stale completion tuple, use --action reconcile. Reconcile preserves every worktree byte and refuses unrelated staged edits, unregistered worktrees, ambiguous projections, a busy Git index, or missing transaction evidence. Never substitute a raw reset or manual index edit.

Orphan-done worktree repair does not clear a suffixed re-adoption worktree

Section titled “Orphan-done worktree repair does not clear a suffixed re-adoption worktree”

Symptom: a done WU still has a leftover worktree under worktrees/, but the leftover directory uses a suffixed name from re-adoption (<lane-kebab>-<wu-id>-r2, -p0, …) rather than the canonical <lane-kebab>-<wu-id> name — for example a wu:done cleanup step that failed partway through an ownership handoff. wu:repair --id WU-XXXX reports Successfully repaired, but wu:repair --id WU-XXXX --check still reports ORPHAN_WORKTREE_DONE, and every wu:claim in the same lane is refused by the lane’s orphan pre-flight.

Fix: none needed — wu:repair resolves every worktree registered under git worktree list that matches the WU id (by directory basename or branch name), not only the canonical directory name, so a suffixed re-adoption worktree is found and removed in the same pass as the canonical one:

pnpm wu:repair --id WU-XXXX
pnpm wu:repair --id WU-XXXX --check   # confirms no ORPHAN_WORKTREE_DONE remains

Before removing a matched worktree, the repair quarantine-copies its .lumenflow/memory/ store (if present) under .lumenflow/quarantine/worktrees/<worktree-name>/memory/ and records the copy location in .lumenflow/quarantine/worktrees/cleanup.jsonl, so a shared-memory node written inside the leftover worktree is never silently discarded. The repair reports success only once git worktree list no longer matches the WU id at all; if a matched worktree cannot be removed (for example it is git worktree locked), it reports a named failure listing every path it examined instead of a false success.

Symptom: backlog.md says one status, WU YAML says another.

Fix:

# Check for state inconsistencies
pnpm wu:repair --all --check

# Fix detected inconsistencies (regenerates backlog.md and status.md from state store)
pnpm wu:repair --all

wu:release reports WU YAML / state-store divergence

Section titled “wu:release reports WU YAML / state-store divergence”

wu:release compares the WU YAML status with the event-sourced state store before any release mutation. When they disagree, it stops without changing the YAML, event log, derived docs, branch, or lane lock and names both statuses, for example:

WU YAML shows 'in_progress' but the state store shows 'ready' — the event log and WU YAML have diverged.
Run 'pnpm wu:repair --id WU-XXX' to reconcile.

Run the named repair, review its output, then rerun the intended release command. Do not use a release retry or a force flag to choose one state source over the other.

wu:rebase refuses a legacy claim with no claimed_branch

Section titled “wu:rebase refuses a legacy claim with no claimed_branch”

Symptom: wu:rebase fails closed because the WU documents carry no claimed_branch, and wu:repair --claim refuses first with:

Claim repair refuses conflicting local and canonical baseline_main_sha values

Claims minted before the branch-binding mechanism have no claimed_branch in either the canonical or the worktree document, and their local baseline_main_sha is often stale because the branch has not been rebased since it was claimed. The repair needed the rebase, and the rebase needed the repair.

Fix: run the claim repair as the recorded claim owner, with --base-dir naming the canonical main checkout. It now reconciles the binding and the baseline together:

# Audit first; --check makes no changes
pnpm wu:repair --claim --check --id WU-XXX \
  --base-dir /path/to/main --worktree /path/to/worktrees/<lane>-wu-xxx

# Apply, then confirm the governed rebase is unblocked
pnpm wu:repair --claim --id WU-XXX \
  --base-dir /path/to/main --worktree /path/to/worktrees/<lane>-wu-xxx
pnpm wu:rebase --id WU-XXX --dry-run

--check reports the absent binding and, when it applies, the divergent baseline as repairable. It never advertises a repair the apply path would reject: both resolve the canonical baseline through the same authority, so a well-formed but unresolvable object name fails --check closed instead of being reported repairable. The apply path writes the live attached branch into both documents and refreshes the local baseline_main_sha to the canonical value in the same commit, so a half-repaired claim document is never published.

Symptom:

ERROR: Lane "Framework: Core" already has WU-040 in progress

Fix:

  1. Check if WU-040 is truly in progress: pnpm wu:status --id WU-040
  2. If blocked, mark it: pnpm wu:block --id WU-040 --reason "Waiting for API"
  3. If done, complete it: pnpm wu:done --id WU-040
  4. If orphaned, recover: pnpm wu:recover --id WU-040 --action reset

Lane lock not auto-clearing despite dead PID

Section titled “Lane lock not auto-clearing despite dead PID”

Symptom:

ERROR: Lane "Framework: Core" is locked by WU-040 (since 2026-02-19T10:00:00Z)

The lock holder’s process is no longer running, but the lock is not auto-cleared.

Explanation: Lane locks persist after the wu:claim process exits. A dead PID alone does not trigger auto-clearing — the lock must also be older than 2 hours (stale). This prevents a second claim from stealing a legitimately held lane.

Fix:

  1. If the lock is recent (less than 2 hours old), it is likely still valid. Complete or release the existing WU first.
  2. If the lock is genuinely abandoned, unlock manually:
pnpm wu:unlock-lane --lane "Framework: Core" --reason "Abandoned lock"
  1. Locks older than 2 hours with a dead PID will auto-clear on the next wu:claim attempt.

Symptom:

ERROR: Worktree has uncommitted changes. Cannot proceed with wu:done.

But git status shows only .lumenflow/state/packs/software-delivery/wu-events.jsonl as modified (from a recent wu:brief run).

Cause: Running wu:brief records evidence to wu-events.jsonl. If other WUs merged to main and triggered auto-rebase, the rebase could fail because this workflow-generated file was dirty.

Fix: As of v3.19.0, wu:done auto-rebase automatically preserves and restores wu:brief evidence when wu-events.jsonl is the only dirty file. If you’re on an older version, commit the evidence file before retrying:

cd worktrees/<lane>-wu-xxx
git add .lumenflow/state/packs/software-delivery/wu-events.jsonl
git commit -m "wu(wu-xxx): preserve wu:brief evidence"
cd /path/to/repo
pnpm wu:done --id WU-XXX

Ownership violation on wu:block or wu:release

Section titled “Ownership violation on wu:block or wu:release”

Symptom:

❌ SESSION OWNERSHIP VIOLATION: Active session is attached to another WU.

or:

❌ CLAIM OWNERSHIP VIOLATION: WU-XXX was claimed by a different session.

Cause: As of v3.19.0, state-mutating commands validate session ownership. You’re trying to modify a WU that belongs to another agent session.

Fix:

  1. Don’t modify another agent’s WU to free a lane. Wait for the owning WU to complete or block itself.
  2. If you have legitimate reason for cross-session recovery, use the override:
pnpm wu:block --id WU-XXX --override-owner --reason "Manual recovery per team decision"

All overrides are audited to .lumenflow/ownership-override-audit.log.

A claimed worktree cannot run wu:brief, wu:edit or wu:prep

Section titled “A claimed worktree cannot run wu:brief, wu:edit or wu:prep”

Symptom:

Claimed worktree <path> cannot run 'wu-brief' after a successful dependency install,
so it is not lifecycle-runnable and the claim was not completed.

What it means: wu:claim refused to report success for a worktree it could not prove is usable. This is the automatic bootstrap contract: a claim either hands you a worktree that runs the governed commands, or it does not complete.

wu:claim performs three steps, and only reports success after all three:

  1. Seed generated artifact roots from the main checkout, following the workspace dependency graph in deterministic topological order, so a dependency’s artifacts land before a dependent’s. An artifact is refused rather than copied when it resolves outside the main checkout or when its provenance records a different Node major or ABI than the claim is running. Mutable node_modules state is never copied.
  2. Install worktree-local dependencies with the immutable install for your package manager (pnpm install --frozen-lockfile, npm ci, …). This resolves dependencies; it does not build or validate the artifacts those dependencies expose.
  3. Verify by really running wu:brief --help, wu:edit --help and wu:prep --help inside the worktree, through the checkout-local dependency graph. The first of these builds a coherent local CLI dist if one is owed.

Step 3 exists because step 2 can report success over an incoherent artifact graph. Executing the command is the only check that distinguishes artifact presence from artifact coherence.

Fix:

# Repair the main checkout on the Node major this repository pins, then claim again.
pnpm install && pnpm build
pnpm wu:claim --id WU-042 --lane "Framework: Core"

The failed claim rolls back atomically, so no in_progress WU, lane lock, branch or worktree is left behind and nothing needs cleaning up first.

Note on --skip-setup: it opts out of all three steps. It is read-only by design — it seeds nothing, installs nothing, builds nothing and therefore certifies nothing — and a --skip-setup worktree is not certified to run wu:brief, wu:edit or wu:prep. It still fails closed when the main checkout it reuses has unsafe dependency links.

Note on --help: <command> --help skips the build when this checkout already has a CLI dist, but it never answers from another checkout’s dist. What help is being asked in a fresh worktree is whether this checkout can run the command; a file in the main checkout has never been evidence about this one. With no local dist, help builds one.

Symptom:

ERROR: Worktree not found for WU-042

Fix:

# If WU should still be in progress and the lane branch exists, restore first
pnpm wu:recover --id WU-042 --action restore

# If restore is impossible and the WU is genuinely orphaned, reset + reclaim
pnpm wu:recover --id WU-042 --action reset
pnpm wu:claim --id WU-042 --lane "Framework: Core"

# If WU is done but worktree lingers
pnpm wu:recover --id WU-042 --action cleanup

Symptom: You made changes in main instead of the worktree.

Fix:

# From main checkout, save a patch and list exactly which paths changed
git diff > /tmp/main-changes.patch
git diff --name-only > /tmp/main-changed-paths.txt

# Move to worktree, apply, and commit there
cd worktrees/framework-core-wu-042
git apply /tmp/main-changes.patch
git add .
git commit -m "wu(wu-042): implement feature"

# Restore only the paths you just moved — never the whole tree
cd /path/to/main
git restore $(cat /tmp/main-changed-paths.txt)

Symptom: wu:rebase pauses after reporting ordinary content conflicts.

Fix:

cd worktrees/framework-core-wu-042

# Edit and review only the conflict paths reported by wu:rebase
git add <resolved-conflict-paths>
pnpm wu:rebase --id WU-042 --continue

The governed continuation verifies the active WU, lane branch, worktree and claim, integration target and SHA, replayed commit, paused HEAD, unresolved set, and staged path scope. It never selects ours or theirs. If one additional reviewed path must be staged, authorize it explicitly with repeatable --allow-staged <repo-relative-path> flags. To discard the attempt and restore the pre-rebase branch state, run pnpm wu:rebase --id WU-042 --abort.

wu:done fails with “not a fast-forward”

Section titled “wu:done fails with “not a fast-forward””

Symptom:

ERROR: Cannot fast-forward merge lane/framework-core/wu-042 to main

Cause: Main has new commits since you started your WU.

Fix:

cd worktrees/framework-core-wu-042
pnpm wu:rebase --id WU-042
# If that command records a conflict pause, resolve and stage only its named paths,
# then run: pnpm wu:rebase --id WU-042 --continue

# Return to main and retry
cd /path/to/repo
pnpm wu:done --id WU-042

wu:done fails with “Worktree has uncommitted changes”

Section titled “wu:done fails with “Worktree has uncommitted changes””

Symptom:

ERROR: Worktree has uncommitted changes. Cannot proceed with wu:done.

Cause: wu:done requires a clean, committed worktree before it can merge.

Fix:

cd worktrees/<lane>-wu-xxx
git status
git add .
git commit -m "wu(wu-xxx): describe the change"

# Return to main and retry
cd /path/to/repo
pnpm wu:done --id WU-XXX

If the changes were accidental, restore the files, then retry.

Symptom:

ERROR: WU commit attempted from main checkout

Cause: You’re trying to commit WU work from the main directory.

Fix:

# Move to the worktree
cd worktrees/framework-core-wu-042
git add .
git commit -m "wu(wu-042): implement feature"

Symptom:

BLOCKED: Commit message must reference WU-123

Fix: Include the WU ID in the commit message, for example:

git commit -m "wu(wu-1305): document workflow friction"

Symptom:

WARNING: Branch is 15 commits behind origin/main

Fix:

cd worktrees/framework-core-wu-042
pnpm wu:rebase --id WU-042
# If it records a conflict pause, resolve and stage only its named paths, then
# run: pnpm wu:rebase --id WU-042 --continue (or --abort that recorded pause)
cd /path/to/repo
pnpm wu:done --id WU-042

Symptom:

⚠️  PARALLEL COMPLETIONS DETECTED

Cause: Other WUs merged to main while your WU was in progress.

Fix: Use the governed lane rebase from the WU worktree, then retry:

cd worktrees/<lane>-wu-xxx
pnpm wu:rebase --id WU-XXX --dry-run
pnpm wu:rebase --id WU-XXX
# If content resolution pauses, edit and stage the reported paths, then run:
pnpm wu:rebase --id WU-XXX --continue
cd /path/to/repo
pnpm wu:done --id WU-XXX

If a long-lived worktree is pinned to an older CLI (such as 6.0.6 or 6.0.8), its wu:rebase may hard-abort on a spec-YAML content conflict because older versions did not pause for governed conflict resolution. Run the newer CLI from the main checkout and target the old worktree with --base-dir:

# Run the newer CLI from the main checkout; Git operations target the old worktree
cd /path/to/main
pnpm wu:rebase --id WU-XXX --base-dir /path/to/worktrees/<lane>-wu-xxx

# If it pauses, resolve only the paths reported by wu:rebase
cd /path/to/worktrees/<lane>-wu-xxx
git add <resolved-conflict-paths>

# Continue from the main checkout, still targeting the same worktree
cd /path/to/main
pnpm wu:rebase --id WU-XXX --base-dir /path/to/worktrees/<lane>-wu-xxx --continue

This uses the main checkout only for its newer CLI; --base-dir keeps the rebase, conflict state, and Git operations scoped to the worktree. Do not upgrade or reinstall the old worktree’s pinned dependencies to get the newer CLI, and do not resolve or stage paths that the command did not report. Use --dry-run first to inspect the rebase, or --abort with the same --base-dir to discard a paused rebase. Once it succeeds, run pnpm wu:prep in the worktree and finish with wu:done from main.

When wu:done resolves governed metadata conflicts during an automatic rebase, LumenFlow appends an audit row to .lumenflow/meta-rebase-audit.ndjson. The file is append-only local evidence. It is intentionally ignored by Git and remains on disk across lumenflow init and lumenflow:upgrade.

A manually resolved wu:rebase content session appends a terminal row to the same file after a validated --continue or --abort. It includes old and final commits, target ref and SHA, all conflicted paths, explicitly authorized staged paths, resolver identity, timestamps, and the continued or aborted outcome. The ignored pause record at .lumenflow/state/packs/software-delivery/wu-rebase-conflict.json remains available while the rebase is paused and is cleared after the terminal operation succeeds.

Do not commit the audit and do not delete it to satisfy gates. Incremental format checks exclude only this exact normalized runtime path because Prettier does not parse NDJSON; changed source files are still formatted and checked normally. If an older workspace shows the file as untracked, run lumenflow:upgrade to reconcile .gitignore. Reconciliation adds the canonical ignore entry without deleting or rewriting existing audit bytes.

Control-plane runtime files keep the checkout dirty

Section titled “Control-plane runtime files keep the checkout dirty”

The control-plane sidecar writes its latest-tick snapshot and durable outbox under .lumenflow/state/. These files are local runtime state, including when LumenFlow runs inside a nested workspace. Run pnpm lumenflow:upgrade --latest to reconcile the canonical root and nested ignore rules.

If an older installation already tracked .lumenflow/state/control-plane-sidecar-last-tick.json, upgrade removes the file from Git’s index without deleting or rewriting the working copy. It does not untrack repository-bound lifecycle evidence: wu-events.jsonl, migration-complete.json, and WU done stamps remain versioned.

As of the state-namespace migration (WU-3378), Software Delivery state (the WU event log, stamps, archive, merge lock, telemetry, flow log, incidents, and commands log) resolves under a pack-owned namespace instead of generic shared .lumenflow/<name> paths:

.lumenflow/state/packs/software-delivery/
├── wu-events.jsonl          # WU lifecycle event log
├── stamps/                  # WU completion stamps
├── archive/                 # archived WU events
├── merge.lock                # wu:done merge coordination lock
├── telemetry/                # gates, DORA, costs, tools, etc.
├── flow.log                  # WU flow events
├── incidents/                 # agent incident records
├── commands.log                # git command audit log
└── migration-complete.json    # durable migration sentinel (do not edit)

Agent session state (.lumenflow/sessions/) stays at the shared kernel path — it’s a cross-pack contract with the agent-runtime pack and is not part of this namespace.

Detection and migration: every CLI command checks for the sentinel file above before running main(). If it’s missing and legacy .lumenflow/state, .lumenflow/stamps, etc. exist, LumenFlow runs a one-way, atomic migration: it copies the legacy content into the namespace through a private staging directory, then promotes it with a single atomic rename, then records the sentinel (source digest, target schema version, per-category file counts — no secrets). The legacy directories are never deleted or written back to — they remain on disk as a historical record. Once the sentinel exists, subsequent CLI invocations skip re-verification (a single file-existence check), so steady-state startup cost is unaffected.

Recovery: the migration is fail-closed. If it’s interrupted mid-run, the next invocation either resumes cleanly (a crash before the atomic promote just leaves disposable scratch space that gets cleared) or finalizes cleanly (a crash after the promote but before the sentinel just needs the sentinel written — no data is re-copied or duplicated). If it detects the legacy source has changed since a prior successful migration (tampering or manual edits), or that the target namespace already contains data that doesn’t match what the legacy source would produce, it refuses to proceed and leaves both locations untouched — inspect .lumenflow/state/packs/software-delivery/ manually before retrying.

Removal: lumenflow:uninstall cleans up both the new namespace and any remaining legacy directories.

Configuration: workspace.yaml’s software_delivery.state.* fields (all except base, the kernel-shared .lumenflow root) may still be overridden, but overrides must resolve inside the pack namespace — an override that points outside .lumenflow/state/packs/software-delivery is rejected at startup instead of silently redirecting state to a shared writer path.

Symptom:

bash: wu-create: command not found

Fix:

# Ensure CLI is installed
pnpm add -D @hellmai/lumenflow-cli

# Use npx if not in PATH
npx wu-create --help

# Or add scripts to package.json

Symptom:

ERROR: Invalid workspace.yaml
  - lanes.definitions[0].name must match pattern "^[A-Za-z]+: [A-Za-z]+"

Fix:

  1. Check the error message for the specific field
  2. Compare with the Configuration Reference
  3. Fix the YAML syntax or values

Validate without running:

pnpm validate

Symptom:

ERROR: Cannot create checkpoint - no session active

Fix:

# Initialize memory for this WU
pnpm mem:init --wu WU-042

# Then checkpoint
pnpm mem:checkpoint --wu WU-042

Symptom:

⚠️  No checkpoints found for WU-XXX session.

Fix: Create checkpoints during long sessions:

pnpm mem:checkpoint --wu WU-XXX

LumenFlow commands include context-aware validation that checks your location, WU status, and git state before running. When validation fails, you’ll see an error with a copy-paste fix.

Symptom:

ERROR: WRONG_LOCATION - wu:done must be run from main checkout
FIX: cd /home/user/repo && pnpm wu:done --id WU-042

Fix: Run the command from the correct location. wu:done runs from main; wu:prep runs from the worktree.

Symptom:

ERROR: WRONG_STATUS - WU-042 is in 'ready' status, expected 'in_progress'

Fix: Claim the WU first: pnpm wu:claim --id WU-042 --lane "Your Lane"

Symptom:

ERROR: GIT_DIRTY - Worktree has uncommitted changes

Fix: Commit your changes before running wu:prep:

cd worktrees/lane-wu-xxx
git add .
git commit -m "wu(wu-xxx): describe changes"

You can adjust validation behavior in workspace.yaml:

software_delivery:
  experimental:
    context_validation: true # Enable validation (default: true)
    validation_mode: 'warn' # 'off' | 'warn' | 'error'
    show_next_steps: true # Show guidance after success

pnpm lumenflow:integrate is a deprecation no-op as of WU-3543 — it prints migration guidance and exits 0 without writing any files. LumenFlow no longer generates or manages AI-client-specific enforcement hooks. If your project has a .claude/hooks/ directory from an older LumenFlow version, it is a snapshot — your file now, never regenerated or touched by LumenFlow again. Adapting an enforcement-hook layer into your own tool is a repo-owner task; see AI Coding Assistant Integrations for a copyable example.

If a hook blocks your operation, check:

  1. Are you in a worktree? Hooks block edits outside worktrees. Run pwd and verify.
  2. Do you have a claimed WU? Some hooks require an active WU for edits.
  3. Is the file in your code_paths? Hooks may restrict edits to scoped files.

See Agent Safety for the full enforcement architecture.

pnpm lumenflow:doctor reports lifecycle enforcement as enforced, non-compliant-disabled, missing, stale, tampered, or unavailable. For every remediable non-compliant state, run pnpm lumenflow:enable; it atomically writes the generic delegators and digest-bound manifest, preserving marker-external user bytes. unavailable means repository storage cannot be read safely: restore storage access before retrying. Only enforced is certifying. Disabled and uninstalled consumers cannot claim lifecycle certification.

Local remediation assumes the process follows repository policy. A hostile unsandboxed process with the same OS-user authority can replace local code, hooks, or receipts; preventing that requires an OS sandbox or protected remote/server authority.

Clean WU worktrees may not have packages/@lumenflow/cli/dist built locally. Root LumenFlow package scripts should route through node tools/cli-entry.mjs <entry> so commands can use an existing main checkout dist or build on demand instead of failing with MODULE_NOT_FOUND.

If a package script edit adds or changes LumenFlow CLI aliases, run:

pnpm verify:script-help
pnpm verify:script-help --run-probes

The live probes cover common agent entry points such as mem:create, orchestrate:monitor, lumenflow:commands, and lumenflow:setup-prereqs.

Before local database or local model workflows, run:

pnpm lumenflow:setup-prereqs
pnpm lumenflow:setup-prereqs --json

The report checks Supabase CLI, Docker, and Supabase local stack readiness when Supabase config or deps are detected. It also checks Ollama binary, OpenAI-compatible local API, and configured model readiness when Ollama deps or OLLAMA_* env vars are present.

Official setup references:

The prereq report intentionally omits local service keys and token-shaped values. Do not paste raw supabase start, .envrc, or provider-token output into issues, WU notes, or prompts.

If these solutions don’t help:

  1. Check logs: cat .lumenflow/state/packs/software-delivery/flow.log
  2. Run with debug: DEBUG=lumenflow:* pnpm wu:done --id WU-042
  3. Review the FAQ for common pitfalls.

Include in your question:

  • The exact error message
  • Your workspace.yaml (redact secrets)
  • Output of pnpm wu:status --id WU-XXX
  • Your Node.js version: node --version