Skip to content

Spawn Manifest Schema

The manifest file (.lumenflow/templates/manifest.yaml) controls how templates are assembled into spawn prompts. It defines the order, requirements, and conditions for each template.

.lumenflow/
  templates/
    manifest.yaml          # This file
    spawn-prompt/
      tdd-directive.md
      constraints.md
      ...
version: '1.0'

templates:
  - id: tdd-directive
    path: spawn-prompt/tdd-directive.md
    required: true
    order: 10
version: '1.0'

defaults:
  tokenFormat: '{TOKEN}'

templates:
  - id: methodology-tdd
    path: spawn-prompt/methodology/tdd-directive.md
    required: false
    order: 5
    condition: "policy.testing === 'tdd' && type !== 'documentation' && type !== 'docs' && type !== 'config' && type !== 'refactor' && type !== 'visual' && type !== 'design' && type !== 'ui' && work.testMethodologyHint !== 'smoke-test' && work.testMethodologyHint !== 'structured-content'"

  - id: methodology-test-after
    path: spawn-prompt/methodology/test-after-directive.md
    required: false
    order: 5
    condition: "policy.testing === 'test-after' && type !== 'documentation' && type !== 'docs' && type !== 'config' && type !== 'refactor' && type !== 'visual' && type !== 'design' && type !== 'ui' && work.testMethodologyHint !== 'smoke-test' && work.testMethodologyHint !== 'structured-content'"

  - id: methodology-none
    path: spawn-prompt/methodology/none-directive.md
    required: false
    order: 5
    condition: "policy.testing === 'none' && type !== 'documentation' && type !== 'docs' && type !== 'config' && type !== 'refactor' && type !== 'visual' && type !== 'design' && type !== 'ui' && work.testMethodologyHint !== 'smoke-test' && work.testMethodologyHint !== 'structured-content'"

  - id: architecture-hexagonal
    path: spawn-prompt/architecture/hexagonal-directive.md
    required: false
    order: 6
    condition: "policy.architecture === 'hexagonal'"

  - id: architecture-layered
    path: spawn-prompt/architecture/layered-directive.md
    required: false
    order: 6
    condition: "policy.architecture === 'layered'"

  - id: architecture-none
    path: spawn-prompt/architecture/none-directive.md
    required: false
    order: 6
    condition: "policy.architecture === 'none'"

  - id: tdd-directive
    path: spawn-prompt/tdd-directive.md
    required: false
    order: 10
    condition: "type !== 'documentation' && type !== 'docs' && type !== 'config'"

  - id: documentation-directive
    path: spawn-prompt/documentation-directive.md
    required: false
    order: 10
    condition: "type === 'documentation' || type === 'docs' || type === 'config'"

  - id: visual-directive
    path: spawn-prompt/visual-directive.md
    required: false
    order: 15
    condition: "type === 'visual' || type === 'design' || type === 'ui' || work.testMethodologyHint === 'smoke-test'"

  - id: refactor-directive
    path: spawn-prompt/refactor-directive.md
    required: false
    order: 15
    condition: "type === 'refactor'"

  - id: structured-content-directive
    path: spawn-prompt/structured-content-directive.md
    required: false
    order: 15
    condition: "work.testMethodologyHint === 'structured-content' && type !== 'documentation' && type !== 'docs' && type !== 'config'"

  - id: verification-requirements
    path: spawn-prompt/verification-requirements.md
    required: false
    order: 18
    condition: 'hasRequiredVerification'

  - id: project-specific-co-change-guidance
    path: spawn-prompt/project-specific-co-change-guidance.md
    required: false
    order: 19
    condition: 'hasCoChangeGuidance'

  - id: skills-selection
    path: spawn-prompt/skills-selection.md
    required: true
    order: 50

  - id: code-craft
    path: spawn-prompt/code-craft.md
    required: true
    order: 55

  - id: read-before-write
    path: spawn-prompt/read-before-write.md
    required: true
    order: 60

  - id: design-context-ui
    path: spawn-prompt/design-context-ui.md
    required: false
    order: 65
    condition: "work.domain === 'ui'"

  - id: mandatory-agents
    path: spawn-prompt/mandatory-agents.md
    required: false
    order: 66
    condition: 'hasMandatoryAgents'

  - id: invariants-prior-art
    path: spawn-prompt/invariants-prior-art.md
    required: false
    order: 67
    condition: 'hasInvariantGuidance'

  - id: implementation-context
    path: spawn-prompt/implementation-context.md
    required: false
    order: 68
    condition: 'hasImplementationContext'

  - id: effort-scaling
    path: spawn-prompt/effort-scaling.md
    required: true
    order: 100

  - id: parallel-tool-calls
    path: spawn-prompt/parallel-tool-calls.md
    required: true
    order: 110

  - id: search-heuristics
    path: spawn-prompt/search-heuristics.md
    required: true
    order: 120

  - id: token-budget
    path: spawn-prompt/token-budget.md
    required: true
    order: 130

  - id: completion-format
    path: spawn-prompt/completion-format.md
    required: false
    order: 135

  - id: completion-workflow
    path: spawn-prompt/completion-workflow.md
    required: false
    order: 136

  - id: agent-coordination
    path: spawn-prompt/agent-coordination.md
    required: false
    order: 137

  - id: bug-discovery
    path: spawn-prompt/bug-discovery.md
    required: true
    order: 200

  - id: quick-fix-commands
    path: spawn-prompt/quick-fix-commands.md
    required: true
    order: 210

  - id: lane-selection
    path: spawn-prompt/lane-selection.md
    required: true
    order: 220

  - id: worktree-recovery
    path: spawn-prompt/worktree-recovery.md
    required: false
    order: 300
    condition: 'worktreePath'

  - id: worktree-path-guidance
    path: spawn-prompt/worktree-path-guidance.md
    required: false
    order: 301
    condition: 'worktreePath'

  - id: lane-guidance-framework
    path: spawn-prompt/lane-guidance/framework.md
    required: false
    order: 400
    condition: "laneParent === 'Framework'"

  - id: lane-guidance-operations
    path: spawn-prompt/lane-guidance/operations.md
    required: false
    order: 400
    condition: "laneParent === 'Operations'"

  - id: lane-guidance-content
    path: spawn-prompt/lane-guidance/content.md
    required: false
    order: 400
    condition: "laneParent === 'Content'"

  - id: action-claimed
    path: spawn-prompt/action-claimed.md
    required: false
    order: 820
    condition: "isClaimed === 'true'"

  - id: action-unclaimed
    path: spawn-prompt/action-unclaimed.md
    required: false
    order: 820
    condition: "isClaimed !== 'true'"

  - id: db-risk-verification
    path: spawn-prompt/db-risk-verification.md
    required: false
    order: 845
    condition: 'hasDbRisk'

  - id: self-review
    path: spawn-prompt/self-review.md
    required: true
    order: 850

  - id: constraints
    path: spawn-prompt/constraints.md
    required: true
    order: 1000

| Field | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------- | | version | string | Yes | Manifest schema version | | defaults | object | No | Default settings for processing | | templates | array | Yes | List of template entries |

| Field | Type | Default | Description | | ------------- | ------ | --------- | ------------------------ | | tokenFormat | string | {TOKEN} | Token placeholder format |

Each entry in the templates array:

| Field | Type | Required | Description | | ----------- | ------- | -------- | ----------------------------------------------- | | id | string | Yes | Unique identifier matching template frontmatter | | path | string | Yes | Relative path from .lumenflow/templates/ | | required | boolean | Yes | Whether template must exist | | order | number | Yes | Sort position (ascending) | | condition | string | No | Inclusion condition expression |

The manifest schema version. Currently only 1.0 is supported.

version: '1.0'

Future versions may add new fields or change behavior.

A unique identifier for the template. Must match the id field in the template’s YAML frontmatter.

- id: tdd-directive # Matches template frontmatter id
  path: spawn-prompt/tdd-directive.md

The id is used for:

  • Matching templates during loading
  • Client override resolution
  • Error messages and debugging

Relative path from .lumenflow/templates/ to the template file.

# Direct file
- id: constraints
  path: spawn-prompt/constraints.md

# Nested in subdirectory
- id: lane-guidance-framework
  path: spawn-prompt/lane-guidance/framework.md

Controls behavior when a template cannot be found or loaded.

When true:

- id: constraints
  required: true
  # Error thrown if template is missing

Assembly fails with an error message indicating the expected path.

When false:

- id: visual-directive
  required: false
  # Silently skipped if missing

Missing template is skipped without error.

Numeric value controlling assembly sequence. Lower values appear first in the output.

templates:
  - id: tdd-directive
    order: 10 # Appears first
  - id: constraints
    order: 1000 # Appears last

Recommended ranges:

| Range | Purpose | | ------- | ------------------------------------ | | 10-20 | Type and verification directives | | 50-70 | Skills, craft, and context | | 100-140 | Agent guidance and completion format | | 200-300 | Operational guidance | | 300-310 | Recovery and worktree | | 400-500 | Lane-specific guidance | | 820-850 | Action and completion checks | | 900+ | Constraints (always last) |

Equal order values:

When multiple templates have the same order, their relative order is undefined. Use conditions to ensure only one is included:

# Both have order 10, but conditions are mutually exclusive
- id: tdd-directive
  order: 10
  condition: "type !== 'documentation'"

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

Optional JavaScript-like expression controlling template inclusion.

Syntax:

| Operator | Example | | ---------- | ----------------------------------------- | | Equality | type === 'feature' | | Inequality | type !== 'documentation' | | Truthy | worktreePath | | AND | type === 'bug' && laneParent === 'Core' | | OR | type === 'feature' \|\| type === 'bug' |

Available variables:

| Variable | Description | | -------------------------- | ---------------------------------------------------------- | | type | WU type (feature, bug, documentation) | | lane | Full lane name | | laneParent | Parent lane (Framework, Content, etc.) | | wuId | Work Unit ID | | worktreePath | Worktree path (truthy if claimed) | | title | WU title | | description | WU description | | policy.testing | Resolved testing policy (tdd, test-after, none) | | policy.architecture | Resolved architecture policy | | work.domain | Classified work domain (ui, backend, docs, etc.) | | work.testMethodologyHint | Classifier hint (smoke-test, structured-content) | | hasRequiredVerification | Truthy when any required verification is declared | | tests.hasUnit | Truthy when the WU spec declares unit test paths | | tests.hasE2E | Truthy when the WU spec declares E2E test paths | | tests.hasManual | Truthy when the WU spec declares manual verification items |

Examples:

# Feature and bug WUs only
condition: "type === 'feature' || type === 'bug'"

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

# Only when worktree exists
condition: "worktreePath"

# Framework lane only
condition: "laneParent === 'Framework'"

# UI work only
condition: "work.domain === 'ui'"

# Structured-content guidance only
condition: "work.testMethodologyHint === 'structured-content'"

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

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

The manifest is validated when loaded. Errors include:

Error: manifest.yaml: 'version' field is required and must be a string
Error: manifest.yaml: 'templates' field is required and must be an array
Error: manifest.yaml: Template entry 'my-template' is missing required fields: order, required
Error: Failed to parse manifest.yaml: <yaml error details>

When wu:brief assembles templates:

  1. Parse manifest - Validate structure and entries
  2. Load templates - Read files from spawn-prompt/
  3. Resolve client alias - Example: claude-code -> claude, codex-cli -> codex
  4. Apply overrides - Replace base templates with client-specific versions
  5. Sort entries - Order by order field ascending
  6. Evaluate conditions - Skip templates where condition is false
  7. Check required - Error if required template is missing
  8. Replace tokens - Substitute {TOKEN} placeholders
  9. Join sections - Concatenate with double newlines

Client-specific manifests are not supported. Overrides work at the template level:

.lumenflow/
  templates/
    manifest.yaml              # Single manifest for all clients
    spawn-prompt/
      skills-selection.md      # Base template
  templates.claude/
    spawn-prompt/
      skills-selection.md      # Claude override (same id)

When assembling for --client claude-code:

  1. Load base template with id: skills-selection
  2. Resolve alias to claude
  3. Load override from templates.claude/spawn-prompt/skills-selection.md
  4. Override replaces base (matched by id)

| Client Flag (--client) | Alias | Override Directory | | ------------------------ | -------- | --------------------- | | claude-code | claude | templates.claude/ | | codex-cli | codex | templates.codex/ | | gemini-cli | gemini | templates.gemini/ | | cursor | cursor | templates.cursor/ | | windsurf | windsurf | templates.windsurf/ |

These are the built-in sections most consumers override first:

| Template ID | When it is included | Typical reason to override | | ------------------------------ | ------------------------------------------------------ | -------------------------------------------------- | | visual-directive | UI work or work.testMethodologyHint === 'smoke-test' | Add project-specific UI verification commands | | structured-content-directive | work.testMethodologyHint === 'structured-content' | Add content/config evaluators or schema checks | | verification-requirements | hasRequiredVerification | Reformat or extend WU-declared verification output | | design-context-ui | work.domain === 'ui' | Add design system or accessibility review guidance | | code-craft | Always | Tighten implementation standards | | read-before-write | Always | Add repo-specific discovery expectations | | self-review | Always | Add completion checklist items |

These shipped ids are selected directly by the CLI prompt builders and often carry section-specific tokens in addition to the shared {WU_ID}, {LANE}, and {WORKTREE_PATH} values:

| Template ID | Primary token(s) | Notes | | ------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | project-specific-co-change-guidance | CO_CHANGE_GUIDANCE_SECTION | Wrapper token containing the fully rendered co-change section | | mandatory-agents | MANDATORY_AGENTS | Injects the rendered bullet list of required agents | | invariants-prior-art | INVARIANTS_PRIOR_ART_SECTION | Wrapper token for the full invariants/prior-art section | | implementation-context | IMPLEMENTATION_CONTEXT_SECTION | Wrapper token for the full implementation-context section | | agent-coordination | AGENT_COORDINATION_SECTION | Wrapper token preserving config-driven progress-signal wording | | action-unclaimed | WORKTREE_PATH_HINT, WU_EVENTS_PATH | Use alongside shared {WU_ID} and {LANE} | | constraints | TDD_CHECKPOINT_BLOCK, numbering tokens (ANTI_LOOP_NUM, STOP_ASK_NUM, …) | Single renderer for every client (WU-3542); TDD-checkpoint numbering shifts via tokens, not a separate per-client template |