Skip to content

Template Format

Templates are markdown files with YAML frontmatter that define reusable prompt sections for wu:brief. The template system enables customization of agent prompts without modifying core LumenFlow code.

Templates live in .lumenflow/templates/spawn-prompt/:

.lumenflow/
  templates/
    manifest.yaml          # Assembly order configuration
    spawn-prompt/
      methodology/
        tdd-directive.md
        test-after-directive.md
      architecture/
        hexagonal-directive.md
      tdd-directive.md     # Compatibility fallback
      documentation-directive.md
      visual-directive.md
      structured-content-directive.md
      verification-requirements.md
      skills-selection.md
      design-context-ui.md
      effort-scaling.md
      constraints.md       # Always included last
      lane-guidance/       # Lane-specific templates
        operations.md
        framework.md
        content.md

Every template has two parts: YAML frontmatter and markdown content.

---
id: my-template
name: My Template
required: false
order: 100
---

## Template Content

Your markdown content here.
---
id: tdd-directive
name: TDD Directive
required: false
order: 10
tokens: [WU_ID, LANE]
condition: "type !== 'documentation'"
---

## TDD Directive for {WU_ID}

Working in lane: {LANE}

Your markdown content with token placeholders...
FieldTypeRequiredDescription
idstringYesUnique identifier matching manifest entry
namestringYesHuman-readable name for debugging
requiredbooleanYesIf true, assembly fails when template is missing
ordernumberYesAssembly position (lower numbers appear first)
tokensstring[]NoToken names used in this template
conditionstringNoExpression that must be true for template inclusion

The id must match an entry in manifest.yaml. It’s used to:

  • Look up the template during assembly
  • Apply client-specific overrides (matching by id)
  • Reference templates in error messages

Templates are sorted by order before assembly. Use these ranges:

RangePurposeExamples
10-20Type and verification directivestdd-directive, verification-requirements
50-70Skills, craft, and contextskills-selection, mandatory-agents
100-140Agent guidance and completion formateffort-scaling, completion-format
200-300Operational guidancebug-discovery, quick-fix-commands
300-310Recovery and worktreeworktree-recovery, worktree-path-guidance
400-500Lane-specific guidancelane-guidance-operations
820-850Action and completion checksaction-unclaimed, self-review
900+Constraints (always last)constraints, codex-constraints

When required: true:

  • Template must exist for assembly to succeed
  • Missing template throws an error with the expected path
  • Use for critical sections like constraints

When required: false:

  • Template is optional
  • Missing template is silently skipped
  • Use for type-specific or conditional content

Lists token names that appear in the template content:

tokens: [WU_ID, LANE, WORKTREE_PATH]

This field is informational (documents which tokens the template uses) but token replacement happens automatically for all known tokens regardless of this field.

A JavaScript-like expression evaluated against the WU context. Template is included only when the condition evaluates to true.

See Condition Syntax for details.

Tokens are placeholders in template content that get replaced with actual values during assembly.

Use curly braces with uppercase names:

Working on {WU_ID} in lane {LANE}.
Navigate to: {WORKTREE_PATH}
TokenDescriptionExample Value
{WU_ID}Work Unit identifierWU-1253
{LANE}Full lane nameFramework: Core
{TYPE}WU typefeature, bug, documentation
{TITLE}WU titleAdd template loader
{DESCRIPTION}WU descriptionImplement the template system...
{WORKTREE_PATH}Path to worktree (if claimed)worktrees/framework-core-wu-1253
{WORK_DOMAIN}Classified work domainui, backend, docs
{WORK_TEST_METHODOLOGY_HINT}Classifier-driven methodology hintsmoke-test, structured-content
{REQUIRED_VERIFICATION}Rendered required verification text block1. Run ...

Template:

## Action

Claim this WU before starting:

\`\`\`bash
pnpm wu:claim --id {WU_ID} --lane "{LANE}"
cd {WORKTREE_PATH}
\`\`\`

Output (after replacement):

## Action

Claim this WU before starting:

\`\`\`bash
pnpm wu:claim --id WU-1253 --lane "Framework: Core"
cd worktrees/framework-core-wu-1253
\`\`\`

Conditions control whether a template is included in the assembled prompt.

OperatorSyntaxDescription
Equalityfield === 'value'Exact match
Inequalityfield !== 'value'Not equal
TruthyfieldField exists and truthy
ANDexpr1 && expr2Both must be true
ORexpr1 || expr2Either can be true

Conditions use lowercase aliases of token values:

VariableMaps ToExample Values
type{TYPE}feature, bug, documentation
lane{LANE}Framework: Core
wuId{WU_ID}WU-1253
title{TITLE}Add template loader
description{DESCRIPTION}Full description text
worktreePath{WORKTREE_PATH}Path or undefined
laneParentExtractedFramework, Content, Operations
policy.testingResolved policytdd, test-after, none
policy.architectureResolved policyhexagonal, layered, none
work.domain{WORK_DOMAIN}ui, backend, docs, infra, mixed
work.testMethodologyHint{WORK_TEST_METHODOLOGY_HINT}smoke-test, structured-content
hasRequiredVerificationDerived from WU test requirementstruthy when any required verification exists
tests.hasUnitDerived from WU test pathstruthy when unit paths are declared
tests.hasE2EDerived from WU test pathstruthy when E2E paths are declared
tests.hasManualDerived from WU test pathstruthy when manual checks are declared

Type-based inclusion:

# Include for features and bugs, exclude for docs
condition: "type !== 'documentation'"

# Include only for documentation WUs
condition: "type === 'documentation' || type === 'docs'"

Lane-based inclusion:

# Include only for Framework lanes
condition: "laneParent === 'Framework'"

# Include for Operations or Framework
condition: "laneParent === 'Operations' || laneParent === 'Framework'"

Truthy checks:

# Include only when worktree exists
condition: 'worktreePath'

Policy-based inclusion:

# Include only when TDD methodology is active
condition: "policy.testing === 'tdd'"

# Include for test-after methodology
condition: "policy.testing === 'test-after'"

Work-classification inclusion:

# Include only for UI-classified work
condition: "work.domain === 'ui'"

# Include only for structured-content work
condition: "work.testMethodologyHint === 'structured-content'"

# Include only when the WU spec declares required verification
condition: 'hasRequiredVerification'

Combined conditions:

# Feature in Framework lane
condition: "type === 'feature' && laneParent === 'Framework'"

When wu:brief runs, templates are assembled in this order:

  1. Load manifest from .lumenflow/templates/manifest.yaml
  2. Load templates from spawn-prompt/ directory
  3. Resolve client alias (for example claude-code -> claude, codex-cli -> codex)
  4. Apply client overrides (e.g., templates.claude/spawn-prompt/)
  5. Sort by order field (ascending)
  6. Evaluate conditions for each template against the WU context
  7. Replace tokens in included templates
  8. Concatenate with double newlines between sections

Client-specific templates take priority:

.lumenflow/
  templates/
    spawn-prompt/
      skills-selection.md     # Base template (order 50)
  templates.claude/
    spawn-prompt/
      skills-selection.md     # Claude override (same id, replaces base)
  templates.cursor/
    spawn-prompt/
      skills-selection.md     # Cursor override (same id)

When running wu:brief --id WU-XXX --client <client>:

  1. Load base skills-selection.md
  2. Resolve alias (claude-code -> claude)
  3. Override with templates.claude/spawn-prompt/skills-selection.md
  4. Other client directories are ignored
Client Flag (--client)AliasOverride Directory
claude-codeclaudetemplates.claude/
codex-clicodextemplates.codex/
gemini-cligeminitemplates.gemini/
cursorcursortemplates.cursor/
windsurfwindsurftemplates.windsurf/
Error: Required template 'constraints' is missing.
Expected at: spawn-prompt/constraints.md

Fix: Create the template at the expected path or mark it required: false in the manifest.

Error: Template spawn-prompt/my-template.md: 'id' field is required in frontmatter

Fix: Add the missing frontmatter field.

Error: manifest.yaml: Template entry 'my-template' is missing required fields: order

Fix: Add the missing field to the manifest entry.

  • One concern per template - Keep templates focused
  • Use conditions - Avoid including irrelevant content
  • Document tokens - List tokens in frontmatter even though optional
  • Leave order gaps - Use increments of 10 for flexibility
  • File names: Lowercase with hyphens (tdd-directive.md)
  • Template IDs: Match file name without extension (tdd-directive)
  • Subdirectories: Use for related groups (lane-guidance/)
# Type directives (mutually exclusive)
- id: tdd-directive
  order: 10
  condition: "type !== 'documentation'"

- id: documentation-directive
  order: 10
  condition: "type === 'documentation'"

# Common sections (always included)
- id: skills-selection
  order: 50

# Constraints (always last)
- id: constraints
  order: 1000

LUMENFLOW.md is fully managed by LumenFlow and force-synced on every upgrade. To add project-specific workflow additions without losing them on upgrade, create LUMENFLOW.local.md in the project root.

  • Agents read LUMENFLOW.local.md after LUMENFLOW.md when present.
  • init and upgrade never touch LUMENFLOW.local.md.
  • If a user-modified LUMENFLOW.md is detected on the first force-sync, the CLI backs up the custom content to LUMENFLOW.local.md automatically.

This is separate from the template system above — templates customize wu:brief prompts, while LUMENFLOW.local.md customizes the workflow documentation that agents read at startup.