Skip to content

Feature Development Workflow

Leonard Ramminger edited this page Aug 9, 2026 · 2 revisions

Feature Development Workflow

Beez features are implemented vertically: from user story through tests and all affected layers to a green make all. Avoid changing only one layer (for example core models with no DSL binding or tests).

What "vertical" means

User story + acceptance criteria
        ↓
Tests first (unit → integration → system)     ← TDD
        ↓
Core (models, registry, orchestrator)
        ↓
Plugins (Lua DSL, shell executor)
        ↓
CLI (when user-visible behavior changes)
        ↓
Refactor + make all

Not vertical: extend Registry with no Lua parser change and no tests.

Vertical: the user can use the feature via build.lua or CLI, and every applicable test level passes.

Step 1: Define the user story

Before coding, write down:

  • What the user should be able to do
  • Acceptance criteria (concrete, testable)
  • Affected layers (core, lua plugin, orchestrator, CLI)

Example:

As a user, I want tasks to declare depends_on so that execution order respects dependencies.

Layers: Task model, Registry, Lua DSL, Orchestrator, unit + integration + system tests.

Step 2: TDD (Red → Green → Refactor)

Red

  1. Pick the smallest testable slice of an acceptance criterion
  2. Write the test at the appropriate level (unit first)
  3. Register the file in CMakeLists.txt
  4. Run tests and confirm failure (compile error or assertion)

Green

  1. Implement the minimum code to pass
  2. Work inside-out: core → plugins → orchestrator/CLI
  3. Re-run tests until green

Refactor

  1. Clean naming, remove duplication
  2. Run tests after each change
  3. Run make format and make lint-stale as needed

Repeat for each acceptance criterion.

Step 3: Choose test levels

Change type Minimum tests
Pure function / model Unit
DSL field or syntax Unit (lua) + integration
Run behavior / exit codes Integration + system fixture
Parser grammar change Unit + fuzz seed

See Testing for directory conventions.

Step 4: Implementation order

Core

  1. Types in include/beez/core/
  2. Logic in src/core/
  3. Update src/core/CMakeLists.txt

Plugins

  • Lua (src/plugins/lua/lua_dsl.cpp, lua_settings.cpp): parse new DSL keys
  • Shell (src/plugins/shell/): only when command execution changes

Orchestrator

  • src/core/orchestrator.cpp when scheduling, cache, or progress behavior changes

CLI

  • src/cli/ and rarely src/app/main.cpp for new flags or commands

Step 5: DSL / parser changes

When lua_dsl.cpp or DSL syntax changes:

  1. Add a descriptive seed: tests/fuzz/corpus/lua_dsl/<name>.lua
  2. Run make fuzzer-smoke
  3. Never commit fuzzer hash artifacts

Step 6: Finish with QA

make all

Do not mark a feature done until the full pipeline passes. If CI fails, fix and rerun.

Per-feature checklist

Copy into a PR description:

[ ] User story and acceptance criteria documented
[ ] Failing tests written first (Red)
[ ] Minimum implementation (Green)
[ ] Refactor pass, tests still green
[ ] Core updated
[ ] Plugins updated (if DSL/execution affected)
[ ] Orchestrator/CLI updated (if needed)
[ ] CMakeLists.txt updated for new files
[ ] Unit tests (positive + negative)
[ ] Integration tests (if components interact)
[ ] System fixture + scenario (if end-to-end)
[ ] Fuzz seed (if DSL/parser changed)
[ ] make all green

Prompt template (for AI-assisted work)

Implement feature: <short description>

User story:
As a <role>, I want <action> so that <benefit>.

Acceptance criteria:
- ...
- ...

Implement vertically with TDD (Red → Green → Refactor).
Run make all before finishing.

Anti-patterns

  • Production code before tests
  • Tests deferred to a follow-up PR
  • Only make test while skipping format, lint, fuzz, sanitizers
  • New .cpp files not added to CMake
  • Nested module directories under src/

Related pages

Clone this wiki locally