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/
      tdd-directive.md     # Test-driven development guidance
      documentation-directive.md
      skills-selection.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-50Type-specific directivestdd-directive, docs-directive
50-100Skills and methodologyskills-selection
100-200Agent guidanceeffort-scaling, parallel-calls
200-300Operational guidancebug-discovery, quick-fix
300-400Recovery and worktreeworktree-recovery
400-500Lane-specific guidancelane-guidance-operations
900+Constraints (always last)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

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

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'"

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. Apply client overrides (e.g., templates.claude/spawn-prompt/)
  4. Sort by order field (ascending)
  5. Evaluate conditions for each template against the WU context
  6. Replace tokens in included templates
  7. 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. Override with templates.claude/spawn-prompt/skills-selection.md
  3. Cursor template is ignored
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