Gates Reference
LumenFlow’s Software Delivery pack runs a layered set of gates at pnpm wu:prep and pnpm wu:done. This page is the public reference for the gate catalogue, native delivery_review, the discriminated GateResult contract, the per-gate skip surface, the opt-in local_prep profile shipped in 5.5.0, and advisory heuristic gates such as test-over-deletion, monolithic-file-contention, and prod-migration-drift.
Gates are intentionally fail-closed: a gate that is applicable, has a missing prereq, and is not skippable: true produces a blocked-missing-prereq result and exits non-zero. The silent-bypass guard cannot be defeated with --skip-gate — see Skip semantics.
Gate catalogue
Section titled “Gate catalogue”The standard catalogue ships in software_delivery.gates. Defaults below show the out-of-the-box skippable value. Per-repo overrides via software_delivery.gates.overrides.<gate_id> take precedence only for mutable policy gates; the safety-critical deny-set is immutable.
| Gate | skippable (default) | Lifecycle surface | Notes |
| ---------------------------- | --------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| format:check | false | prep + done | Prettier check on changed files. Safety-critical. Missing script blocks in default mode. |
| lint | false | prep + done | ESLint. Safety-critical. |
| typecheck | false | prep + done | TypeScript tsc --noEmit. Safety-critical. |
| spec:linter | false | prep + done | WU YAML spec validity. Safety-critical. |
| co-change | false | prep + done | Required co-edits per software_delivery.gates.co_change. Safety-critical. |
| claim-validation | false | prep + done | Branch / lane / WU lock invariants. Safety-critical. |
| unread-directed-signal | false | prep + done | Directed inbox signals must be triaged before completion. Safety-critical. |
| invariants | false | prep + done | Repo-defined hard invariants (paths, status, schema). Safety-critical. |
| safety-critical-test | false | prep + done | Runs on every WU by default. Narrow with applicability_paths, do not flip skippable. |
| delivery_review | false | prep + done | Native completion review gate. Enabled by software_delivery.gates.delivery_review.enabled; wu:prep auto-runs it when auto_run: true. Writes .lumenflow/artifacts/delivery-review/<WU-ID>.json; FAIL blocks, PARTIAL warns, PASS passes. |
| tdd-diff-evidence | true | prep + done | TDD ratchet against baseline. Allow-listed. |
| migration-verify | true | prep + done | DB migration up/down dry-run. Allow-listed. |
| lane-health | true | prep + done | Lane wip-limit / coverage check. Allow-listed. |
| build | true | prep (opt-in) | local_prep.build.enabled=true. prereq_strategy: 'fail'. |
| integration-test | true | prep (opt-in) | local_prep.integration_test.enabled=true. |
| e2e-smoke | true | prep (opt-in) | local_prep.e2e_smoke.enabled=true. Auto not-applicable when no Playwright config. |
| test-over-deletion | true | prep | Advisory heuristic: flags WUs whose diff deletes .test.ts(x) whose describe() symbol is not present in the WU’s code_paths. Skip with --skip-gate test-over-deletion --reason ... --fix-wu .... |
| monolithic-file-contention | true | prep | Advisory heuristic: flags files appearing in 2+ claimed / in-progress WUs’ code_paths including the current WU. Unclaimed ready placeholders are ignored. Output lists claimant WUs and a re-laning hint. |
| prod-migration-drift | true | CI (opt-in) | Advisory CI gate: prod DB more than threshold (default 5) migrations behind main’s migrations/ directory. Auto-skips not-applicable until software_delivery.gates.overrides.prod-migration-drift.connection_string_env_var is configured. |
| cross-cutting-ratchets | true | prep + done | Runs the repo-wide enforcement-baseline suites on every code-gate run — including scoped/agent-mode wu:prep. NEW drift relative to main blocks; pre-existing main debt warns only. Auto-skips outside worktrees and in repos without the suites. |
Gates marked skippable: false belong to the silent-bypass guard: when applicable + missing-prereq, the runtime emits blocked-missing-prereq and refuses to continue. Mutable environmental gates may opt into software_delivery.gates.overrides.<gate_id>.skippable=true. Configuration rejects that override for format:check, lint, typecheck, co-change, spec:linter, claim-validation, unread-directed-signal, invariants, and safety-critical-test. Missing scripts for the first four block even without --strict; trusted applicability policy and validated docs-only scope remain the only non-applicable paths.
Discriminated GateResult states
Section titled “Discriminated GateResult states”Each gate run produces one of six GateResult discriminated states. Glyphs and labels are stable and surfaced verbatim by wu:prep, wu:done, and the audit NDJSON source field.
| State | Glyph | Audit source | Meaning |
| ----------------------------- | ------------------- | -------------------------- | --------------------------------------------------------------------------------- |
| passed | ✅ PASSED | — | Gate ran successfully. |
| failed | ❌ FAILED | — | Gate ran and failed (or applicable + missing + skippable + 'fail'). |
| skipped-by-agent | ⏭ SKIPPED-BY-AGENT | agent | Explicit named --skip-gate <name>. |
| skipped-auto-not-applicable | ⊘ AUTO-SKIPPED | auto-skip-not-applicable | checkApplicability returned not-applicable for this change set. |
| skipped-auto-missing-prereq | ⊘ AUTO-SKIPPED | auto-skip-missing-prereq | Applicable + missing prereq + skippable: true + prereq_strategy: 'auto-skip'. |
| blocked-missing-prereq | 🚫 BLOCKED | blocked | Applicable + missing prereq + skippable: false. Exits non-zero. |
Decision matrix
Section titled “Decision matrix”The four-axis decision: applicability × preconditions × skippable × prereq_strategy.
| Applicability | Preconditions | skippable | prereq_strategy | Result |
| -------------- | ------------- | ----------- | ----------------- | -------------------------------- |
| not-applicable | — | — | — | skipped-auto-not-applicable |
| applicable | satisfied | — | — | run → passed or failed |
| applicable | missing | false | — | blocked-missing-prereq (BLOCK) |
| applicable | missing | true | 'auto-skip' | skipped-auto-missing-prereq |
| applicable | missing | true | 'fail' | failed |
Each gate may implement checkApplicability and checkPreconditions. Defaults return 'applicable' and 'satisfied' so simple gates inherit always-runs semantics with no per-gate code change. Narrow a gate’s reach by setting an explicit override:
Skip semantics
Section titled “Skip semantics”Per-gate skip (preferred, 5.5.0+)
Section titled “Per-gate skip (preferred, 5.5.0+)”pnpm wu:prep and pnpm wu:done accept --skip-gate <name> (repeatable). The flag is symmetric across both lifecycle surfaces and the MCP wu_done tool.
--reason and --fix-wu are required. --fix-wu must reference a real WU that owns the eventual remediation.
Override gates not on the allow-list
Section titled “Override gates not on the allow-list”Only allow-listed gates (migration-verify, lane-health, tdd-diff-evidence, plus local_prep opt-ins build, integration-test, e2e-smoke, plus the advisory heuristic gates test-over-deletion, monolithic-file-contention, the opt-in prod-migration-drift gate, and the cross-cutting-ratchets gate) accept --skip-gate out of the box. To make any other gate skippable per-repo, set the override:
Use this sparingly. Safety-critical gates (format:check, lint, typecheck, co-change, spec:linter, claim-validation, unread-directed-signal, invariants, safety-critical-test) cannot be flipped: configuration rejects skippable: true. Trusted applicability_paths can narrow only the file-scoped subset: format:check, lint, typecheck, co-change, spec:linter, and safety-critical-test. claim-validation and invariants are lifecycle/always-on gates. After signal triage, an unread-signal exception must use the audited --allow-unread-signals --reason flow.
Removed --skip-gates tombstone
Section titled “Removed --skip-gates tombstone”The binary --skip-gates flag has been removed. CLI parsing retains it only as a recognizable tombstone and rejects it before lifecycle side effects.
The MCP/runtime surface exposes skip_gate arrays. Its skip_gates Boolean is likewise a rejected tombstone.
Audit NDJSON & CFR/DORA
Section titled “Audit NDJSON & CFR/DORA”Audit rows gain a discriminated source field (agent | auto-skip-not-applicable | auto-skip-missing-prereq | blocked) and a lifecycle field (prep | done). Legacy audit entries, including historical gate: 'all' rows, remain readable; entries without source read as agent for back-compat. New global rows cannot be written.
CFR (Change Failure Rate) DORA queries filter source: 'agent' so auto-skips and silent-block records never inflate change-failure rate. If you build custom dashboards on the audit stream, mirror this filter to preserve CFR semantics.
Native Delivery Review Gate
Section titled “Native Delivery Review Gate”delivery_review is LumenFlow’s native, vendor-neutral completion review gate. It is configured
under the global Software Delivery gate config, not under a specific agent client:
| Property | Value |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default skippable | false (not on the built-in --skip-gate allow-list). Repos may opt in with software_delivery.gates.overrides.delivery_review.skippable=true, but normal usage is to fix or declare the missing delivery evidence. |
| Lifecycle surface | pnpm gates when enabled: true; pnpm wu:prep when both enabled: true and auto_run: true; pnpm wu:done through the normal gate lifecycle. |
| Applicability | Current WU can be detected and its type is not listed in software_delivery.gates.delivery_review.skip_types. Default skip types are documentation and process. |
| Output | Stable JSON artifact at .lumenflow/artifacts/delivery-review/<WU-ID>.json with PASS, PARTIAL, or FAIL, findings, acceptance-criteria status, and metadata. |
| Verdict semantics | PASS passes; PARTIAL logs a warning and continues by default, or blocks when block_partial: true; FAIL blocks the gate. |
| Evidence semantics | Source-code delivery changes need automated test evidence or meaningful manual evidence. Empty evidence, placeholders such as todo / n/a, and negative entries such as not run are treated as missing evidence and produce FAIL. |
| Truth verification | Optional verifier_command runs from the repo root after native evidence-shape checks. A non-zero exit adds a critical finding and blocks. LumenFlow exports LUMENFLOW_DELIVERY_REVIEW_WU_ID=<WU-ID> to the command so repo tooling can inspect the current WU and evidence files. |
| Legacy client config | software_delivery.agents.clients.<client>.features.delivery_review is accepted temporarily for adapter UX and migration warnings, but core enforcement is controlled by software_delivery.gates.delivery_review.enabled and software_delivery.gates.delivery_review.auto_run. |
Use delivery_review when a repo needs completion evidence beyond raw test execution, such as
manual QA, Playwright-driven visual checks, or acceptance-criteria review that should be enforced
before wu:done. The gate does not require lumenflow.cloud and behaves the same across Claude,
Codex, Cursor, Windsurf, Cline, Aider, custom agents, and hosted workers.
Manual evidence should name what was exercised and what was observed. Structured entries such as
surface: /records/new; action: opened create form; result: expected fields rendered; screenshot: /tmp/record-form.png are accepted, while screenshot: n/a, placeholder, todo, or not run
are blocked as missing evidence.
Use block_partial: true when a repo wants uncertainty to fail closed during wu:prep and
wu:done. Use verifier_command for project-specific truth checks, such as confirming screenshot
paths exist, Playwright traces were produced, or visual QA evidence matches a repo-defined format.
local_prep profile (5.5.0+)
Section titled “local_prep profile (5.5.0+)”software_delivery.gates.local_prep is an opt-in profile that extends wu:prep with the build, integration-test, and e2e-smoke gates that previously only ran in CI. It exists because three P0 hotfixes in 24h slipped past local gates because wu:prep did not run pnpm build, pnpm test:integration, or pnpm test:e2e --smoke.
| Field | Default | Effect |
| --------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| build.enabled | false | When true, registers a build gate that runs pnpm build. prereq_strategy: 'fail' — missing build script in package.json is a misconfig (failed), not an environmental gap. |
| integration_test.enabled | false | When true, makes the integration-test gate applicable. Runs RUN_INTEGRATION_TESTS=1 pnpm vitest run '**/*.integration.*' '**/golden-*.test.*'. Missing script → failed. |
| e2e_smoke.enabled + tag | false / smoke | When true AND playwright.config.{ts,js,mjs} exists at repo root, registers an e2e-smoke gate that runs pnpm test:e2e --tag <tag>. Repos without Playwright auto not-applicable (clean opt-out). |
| latency_budget_warn_ms | 180000 | wu:prep prints total elapsed seconds; if it exceeds the budget, emits a non-failing warning. Soft signal only; never blocks. |
All three local-prep gates are added to the --skip-gate allow-list (skippable: true). Use the skip for legitimate hotfix scenarios where the gate is broken or irrelevant for that WU; the audit row carries source: 'agent'.
Latency budget guidance
Section titled “Latency budget guidance”Local-prep gates intentionally lengthen wu:prep. Budget guidance:
- Default 3 min (
latency_budget_warn_ms: 180000): comfortable headroom for typical JS/TS repos withpnpm buildcached and a small smoke suite. - Tight (60–90s): keep agents on a fast feedback loop in greenfield repos; raises false-positive warnings as suites grow.
- Loose (5–10 min): monorepos with full Playwright matrix; agents may want to disable
e2e_smokeper-WU via--skip-gate e2e-smokefor cosmetic-only changes.
Caching: wu:prep does not cache gate results across runs. Use Turborepo / Nx / pnpm filters in your pnpm build and pnpm test:integration scripts to keep the total under budget.
Backward compatibility
Section titled “Backward compatibility”Omitting local_prep (the default) preserves the pre-5.5.0 behaviour — none of the new gates is applicable, no new commands run.
Advisory heuristic gates (5.6.0+)
Section titled “Advisory heuristic gates (5.6.0+)”Recent versions added three advisory heuristic gates that catch common cross-WU collisions and CI/prod drift earlier than runtime invariants would. All three ship skippable: true so they belong on the per-gate skip allow-list; --skip-gate <name> requires --reason and --fix-wu.
test-over-deletion
Section titled “test-over-deletion”| Property | Value |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default skippable | true (allow-listed for --skip-gate) |
| Lifecycle surface | wu:prep |
| Applicability | The WU diff includes deleted .test.ts / .test.tsx files. |
| Precondition | Each deleted test’s describe() / describe.each() symbol must still be present in one of the WU’s code_paths (i.e. the test is being moved, not silently lost). |
| Output on fail | Lists each unrecognised symbol, the deleted file, and a remediation hint. |
| Override | pnpm config:set software_delivery.gates.overrides.test-over-deletion.skippable=false to make the gate strict. |
| Skip | pnpm wu:prep --id WU-XXX --skip-gate test-over-deletion --reason "..." --fix-wu WU-YYY |
monolithic-file-contention
Section titled “monolithic-file-contention”| Property | Value |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default skippable | true (allow-listed for --skip-gate) |
| Lifecycle surface | wu:prep |
| Applicability | Always (every wu:prep). |
| Precondition | A file in the current WU’s code_paths does not appear in any other claimed / in-progress WU’s code_paths. Unclaimed ready placeholders are ignored. |
| Output on fail | Lists the contended file, claimant WUs, and a re-laning hint pointing to pnpm wu:infer-lane. |
| Override | pnpm config:set software_delivery.gates.overrides.monolithic-file-contention.skippable=false to make the gate strict. |
| Skip | pnpm wu:prep --id WU-XXX --skip-gate monolithic-file-contention --reason "..." --fix-wu WU-YYY |
prod-migration-drift
Section titled “prod-migration-drift”Opt-in CI gate. Auto-skips with not-applicable until both override keys are configured — no surprise activation in fresh repos.
| Property | Value |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default skippable | true (allow-listed; auto-skips when not configured) |
| Lifecycle surface | CI (advisory; not wu:prep) |
| Applicability | Both software_delivery.gates.overrides.prod-migration-drift.connection_string_env_var AND a reachable prod DB at that env var must be set. Otherwise auto-skips under prereq_strategy: 'auto-skip'. |
| Precondition | Prod DB is no more than threshold (default 5) migrations behind main’s migrations/ directory. |
| Override | pnpm config:set software_delivery.gates.overrides.prod-migration-drift.connection_string_env_var=PROD_DATABASE_URLpnpm config:set software_delivery.gates.overrides.prod-migration-drift.threshold=5pnpm config:set software_delivery.gates.overrides.prod-migration-drift.skippable=false (to harden) |
| Skip | --skip-gate prod-migration-drift --reason "..." --fix-wu WU-YYY (advisory only — prefer fixing drift) |
cross-cutting-ratchets
Section titled “cross-cutting-ratchets”Runs the repo-wide enforcement-baseline ratchet suites (console-call baseline, throw-new-Error count, file-size baseline, path/env-literal zero-tolerance) on every code-gate run — including scoped/agent-mode wu:prep, which previously ran only the WU’s declared tests. This closes the gap where parallel WUs each passed scoped prep, merged, and main accumulated ratchet debt that surfaced only when a later WU ran a full suite (forcing dedicated reconcile WUs).
Drift attribution uses the same pre-existing-on-main triage semantics as the test-baseline ratchet:
- Worktree passes → clean, no main comparison runs (one vitest invocation, ~13s on the LumenFlow repo).
- Worktree fails, main passes → NEW drift introduced by this WU → blocks the WU’s own prep.
- Worktree fails, main fails → pre-existing debt → warns only; a WU is never blocked by debt it did not add.
- Main comparison unrunnable → fail-closed (treated as NEW drift).
Gate-spawned suite runs execute with LUMENFLOW_WRITE_CONTEXT and UPDATE_BASELINE scrubbed from the child env, so the suites never persist baseline JSON into the worktree or the main checkout.
| Property | Value |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Default skippable | true (allow-listed escape hatch; skips audited with source: 'agent') |
| Lifecycle surface | prep + done (code gates only — docs-only WUs cannot add code drift) |
| Applicability | Running inside a worktree AND the ratchet suite files exist in the repo. Consumer repos without the suites auto-skip not-applicable with zero added latency. |
| Budget | One serialized vitest invocation across the four suites (~13s measured); a second invocation against main runs only on worktree failure. Timeout cap 180s. |
| Override | pnpm config:set software_delivery.gates.overrides.cross-cutting-ratchets.skippable=false to remove the escape hatch and hard-block. |
| Skip | pnpm wu:prep --id WU-XXX --skip-gate cross-cutting-ratchets --reason "..." --fix-wu WU-YYY (use only when a dedicated WU is already reconciling the flagged debt) |
Telemetry sync-health gate (5.15.0+)
Section titled “Telemetry sync-health gate (5.15.0+)”Separate from the --skip-gate catalogue, wu:done runs an advisory telemetry
sync-health gate when a control_plane endpoint is configured. It is governed by
software_delivery.telemetry.cloud_sync.enforcement (off | warn | block,
default warn):
| Level | wu:done behaviour |
| ------- | ----------------------------------------------------------------------------------------------------------- |
| off | No gate. Health still surfaces in lumenflow:doctor / compute:doctor. |
| warn | Default. Prints per-stream pending counts + remediation; never blocks. |
| block | Blocks wu:done only on a deterministic failure class (HTTP 4xx auth/config rejection, missing token). |
Transient failures (timeouts, 5xx, DNS, connection resets) never block, even
under block. Bypass a single completion with the audited flag — distinct from
--skip-gate because this gate is not in the per-gate allow-list:
The bypass is recorded to .lumenflow/force-bypasses.log and emitted as a
governance:force_bypass_recorded kernel event, so it is cloud-visible. See
Cloud Sync — Sync-health enforcement
for the full telemetry routing context.
Cross-references
Section titled “Cross-references”The same release also added the following non-gate vocabulary that gates docs reference. See LUMENFLOW.md for canonical specifications.
pnpm wu:edit --estimated-files <n> --estimated-tool-calls <n> --sizing-strategy <s>: non-destructive sizing-estimate edits for in-progress WUs without thewu:deletedance.pnpm mem:signal '<msg>' --wu WU-XXX --interrupt-class <advisory|priority|urgent|soon|immediate>: canonical interrupt-class flag;--interruptremains a back-compat alias.pnpm mem:create --wu '' --type discovery --tags pre-wu-artifact ...: pre-WU memory artifacts feed §4.4 Pre-Phase Audits (wu-sizing-guide) before a WU is claimed.pnpm wu:release --keep-branch: retain the lane branch instead of resetting; default behaviour configurable viasoftware_delivery.wu_release.branch_action.- File-overlap preflight & Lane-fit suggestions:
pnpm orchestrate:initiativeemits both sections after the wave breakdown. Configure viasoftware_delivery.orchestrate.preflight: 'advisory' | 'strict' | 'off'or pass--strict-preflightfor one run. pnpm db:journal-recover: drizzle journal collision recovery (dry-run by default;--confirmapplies and writes audit log under.lumenflow/db-recovery/). Idempotent on healthy chains.
See also
Section titled “See also”- Workspace YAML reference — full schema for
software_delivery.gates. - Agent Safety Architecture — defense-in-depth model that gates plug into.
- CLI reference —
pnpm wu:prep,pnpm wu:done,pnpm gates.