Skip to content

feat(dynamic): add devflow-dynamic plugin — MDS-composed dynamic workflow recipes#242

Merged
dean0x merged 11 commits into
mainfrom
feat/dynamic-workflow-recipes
Jun 12, 2026
Merged

feat(dynamic): add devflow-dynamic plugin — MDS-composed dynamic workflow recipes#242
dean0x merged 11 commits into
mainfrom
feat/dynamic-workflow-recipes

Conversation

@dean0x

@dean0x dean0x commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

Adds devflow-dynamic — a new opt-in plugin shipping 5 dynamic workflow recipe commands that teach the main model to author and run Claude Code dynamic Workflows (the Workflow tool) at runtime, reusing devflow's existing agents via agentType. It layers a tickets → plan → build → merge delivery pipeline on top of devflow's existing commands. Additive — nothing is replaced.

Implements the design at .devflow/docs/design/dynamic-workflow-recipes.2026-06-10_2347.md.

Commands (all opt-in via --plugin devflow-dynamic)

  • /devflow:dynamic-tickets — generalized ticket-factory: initiative/spec → reviewed, wave-structured ticket slate + tracking issue
  • /devflow:dynamic-plan — parallel wave planning + plan-challenge gate → per-ticket plans with acceptance criteria + test plan, one DECISIONS-NEEDED.md; surfaces open decisions via AskUserQuestion at the command boundary
  • /devflow:dynamic-build — single-ticket or dependency-ordered wave engine (implement → review → resolve → merge), Gate 1 after every code write + Gate 2 once at acceptance; never auto-merges to main
  • /devflow:dynamic-profile — mines past sessions across all projects → prose ~/.devflow/preference-profile.md
  • /devflow:dynamic-wave — thin driver that sequences tickets→plan→build with human gates between runs

Architecture — MDS build-time composition

Recipes are authored as .mds (mdscript) partials in shared/recipes/ and composed at build time into self-contained command .md files via scripts/build-recipes.ts (compiled output is gitignored, mirroring the shared/skills/plugins/*/skills/ precedent). Each command @imports only the @define doctrine blocks it needs; the shared _plan_contract block is imported by both dynamic-plan (produces) and dynamic-build Gate 2 (consumes) → single source, no drift.

Iron Rule (ADR-008): zero deterministic feature code. The only new executable is scripts/build-recipes.ts — a markdown-compiler invocation that hard-fails the build on any MDS error. All issue-reading, dependency-reasoning, scheduling, and cycle-count is LLM judgment at runtime, performed by the workflow's agents.

Changes

  • New: shared/recipes/ (7 partials + 5 command sources), scripts/build-recipes.ts, plugins/devflow-dynamic/.claude-plugin/plugin.json
  • Modified: src/cli/plugins.ts (DEVFLOW_PLUGINS entry + WORKFLOW_ORDER), package.json (build:recipes chained into build; @mdscript/mds@0.2.0 devDep), .gitignore, CLAUDE.md (22 plugins), tests/plugins.test.ts + tests/skill-references.test.ts (register the new plugin/commands in the tests' known-good sets)

Verification

  • npm run build green (compiles all 5 commands); npm test 1810 passed / 0 failed
  • MDS compile hard-fail confirmed (undefined-var → mds::undefined_var, exit 1; circular import → build fails)
  • Single-source/no-drift confirmed (a sentinel in _plan_contract.mds appears in both dynamic-plan.md and dynamic-build.md)
  • Install/uninstall lifecycle verified (init --plugin devflow-dynamic installs 5 commands + 11 agents; scoped uninstall removes them)
  • Negative criteria verified in compiled output: no AskUserQuestion inside workflow scripts, no model:+agentType, only roster agentTypes, no merge target of main/master
  • Full quality pipeline passed: Validator → Simplifier → Scrutinizer (fixed 2 compiled-output defects) → Evaluator (ALIGNED, 27/27 ACs) → Tester (PASS)

Notes

  • Snyk SAST was not run (MCP requires interactive auth, unavailable in this session). scripts/build-recipes.ts had an equivalent manual security review (no exec/child_process/eval; path.basename prevents output-path traversal; no secrets; build-time only). Run snyk auth + a code scan on it in an interactive session if a Snyk gate is required.
  • Out of scope (v1): the generate-then-freeze .js cache and a devflow workflows feature toggle (plugin selection is the toggle).

🤖 Generated with Claude Code

dean0x and others added 9 commits June 11, 2026 23:00
Dream-Task: knowledge
Dream-Session: bec47322-36b6-42ad-8fe7-b83592137071
Co-Authored-By: Devflow Dream <dream@devflow.local>
…olchain

Introduces the `devflow-dynamic` plugin (opt-in) and the MDS-based build
toolchain that compiles shared/recipes/*.mds partials into installable
Claude Code command files at build time.

Phase A delivers:
- shared/recipes/ — 6 partials (_preamble, _roster, _engine, _plan_contract,
  _ticket_template, _wave) encoding the full single-ticket engine spine (§7),
  wave doctrine (§8–§11), evaluator panel (§12), agent roster, and authoring
  preamble; all @exported for selective import by Phase B commands
- shared/recipes/dynamic-build.mds — the /devflow:dynamic-build command recipe
  (SINGLE + WAVE modes, full engine + wave blocks inlined via @import)
- scripts/build-recipes.ts — MDS compiler invocation (build plumbing only;
  globs shared/recipes/*.mds, skips partials, hard-fails on mds::* errors,
  writes to plugins/devflow-dynamic/commands/)
- plugins/devflow-dynamic/.claude-plugin/plugin.json — plugin manifest
  (11 shared agents + 4 skills, rules: [])
- src/cli/plugins.ts — DEVFLOW_PLUGINS entry for devflow-dynamic
- package.json — build:recipes script + chained into build
- .gitignore — plugins/devflow-dynamic/commands/ excluded (generated)

build exits 0; npm run build produces dynamic-build.md; devflow init
--plugin devflow-dynamic --recommended installs the command and agents.
Applies ADR-008 (LLM-vs-plumbing: zero deterministic feature code authored).
…ynamic-profile, dynamic-wave + _factory partial

Completes the devflow-dynamic plugin with 4 remaining commands and one new partial:
- dynamic-tickets: generalized ticket-factory pipeline (draft to 2-lens review to revise to cross-critic to amend to tracking-issue)
- dynamic-plan: parallel planning + plan-challenge (§5.1 verbatim intent) + acceptance criteria contract + preference-profile auto-resolution + DECISIONS-NEEDED.md
- dynamic-profile: decision-preference distiller mining past sessions via bounded grep+sample; writes ~/.devflow/preference-profile.md
- dynamic-wave: thin human-gated driver sequencing tickets→plan→build with AskUserQuestion gates between runs (F4 compliant)
- _factory.mds: factory_shape() partial generalizing the ticket-factory.js pipeline with DRAFT/REVIEW/REVISE/CRITIC schemas

All 5 commands compile clean; no leaked MDS directives; no AskUserQuestion inside workflow scripts; all agentTypes from valid 11-agent roster; never auto-merges to main. Applies ADR-008.
- dynamic-plan.mds: remove duplicated "### Acceptance criteria + test plan
  contract" heading (recipe emitted its own heading + intro immediately before
  the _plan_contract partial re-emitted the same heading)
- dynamic-plan.mds: maintenance note interpolated the FULL contract macro inline
  mid-sentence; replace {acceptance_criteria_contract()} with a literal
  section-name reference so it stays a cross-reference, not an expansion
- build-recipes.ts: add main().catch() so non-compile errors (init/readdir
  failure) hard-fail cleanly with a message instead of an unhandled rejection
Dream-Task: decisions
Dream-Session: 2ce4cd2d-f535-4f49-af2f-05e2672630e4
Co-Authored-By: Devflow Dream <dream@devflow.local>
Dream-Task: knowledge
Dream-Session: c822d576-bb7e-44dc-b28f-6f1f33bc6b7c
Co-Authored-By: Devflow Dream <dream@devflow.local>
@dean0x

dean0x commented Jun 12, 2026

Copy link
Copy Markdown
Owner Author

Review Findings Summary

Review of PR #242 (feat/dynamic-workflow-recipes) | 11 reviewer reports analyzed.

Blocking Issues (≥80% confidence)

1. Missing marketplace.json entry — CRITICAL (97%)

  • Location: .claude-plugin/marketplace.json (not modified in PR)
  • Problem: Plugin registered in src/cli/plugins.ts, CLAUDE.md, and tests, but absent from the marketplace registry that the install flow reads.
  • Impact: Uninstallable via documented marketplace path; silently downgrades install for selecting users.
  • Fix: Add entry to .claude-plugin/marketplace.json:
    {
      "name": "devflow-dynamic",
      "source": "./plugins/devflow-dynamic",
      "description": "Dynamic workflow recipes — dependency-aware tickets→plan→build delivery pipeline",
      "version": "2.0.0"
    }
  • Reviewer: documentation | applies ADR-008

2. Node engine floor mismatch — HIGH (88%)

  • Location: package.json:67@mdscript/mds requires node >=22 but CI runs [18, 20, 22]
  • Problem: Produces EBADENGINE warnings (violates zero-warnings policy); caret pin ^0.2.0 risks latent break.
  • Fix: Drop Node 18/20 from CI and bump engines.node to >=22; OR exact-pin 0.2.0.
  • Reviewer: dependencies

3. Build script idempotency — HIGH (90%)

  • Location: scripts/build-recipes.ts lines 66-67
  • Problem: Script asserts "never ship stale command" but never cleans output dir. Renamed/deleted recipes leave orphaned .md files.
  • Fix: Clean .md files before compile loop (after await init() line 70), mirroring build-plugins.ts pattern:
    if (fs.existsSync(OUTPUT_DIR)) {
      for (const f of fs.readdirSync(OUTPUT_DIR)) {
        if (f.endsWith('.md')) fs.rmSync(path.join(OUTPUT_DIR, f));
      }
    }
  • Reviewer: reliability | applies ADR-008

Should-Fix Issues (≥80%, merge-scoped)

4. Stale README count (95%)

  • Location: README.md:60
  • Problem: Still says "21 plugins" after CLAUDE.md was bumped to "22 plugins (12 core + 9 language/ecosystem + 1 workflow)"
  • Fix: Update to "22 plugins (12 core + 9 language/ecosystem + 1 workflow)"
  • Reviewer: documentation

5. Consistency: "(optional)" divergence (88%)

  • Location: src/cli/plugins.ts:190
  • Problem: Description ends with "(optional)" but plugin.json:3 omits it. All other optional plugins don't encode it in plugins.ts.
  • Fix: Remove "(optional)" suffix from plugins.ts:190
  • Reviewer: consistency

6. Garbled timestamp note (90%)

  • Location: shared/recipes/dynamic-tickets.mds:208
  • Problem: Prose first asserts wrong format YYYY-MM-DDHHMM then corrects to YYYY-MM-DD_HHMM. Confusing to LLM.
  • Fix: Single clear statement: "Timestamps follow the devflow `YYYY-MM-DD_HHMM` convention (e.g. `2026-06-12_1148`)."
  • Reviewer: consistency

7. Ambiguous DECISIONS-NEEDED path (85%)

  • Location: shared/recipes/dynamic-plan.mds:78
  • Problem: Instructions read flat path .devflow/docs/design/DECISIONS-NEEDED.md but workflow writes OUTDIR-scoped path. Load-bearing gate silently skipped.
  • Fix: Unambiguous: "Read ${OUTDIR}/DECISIONS-NEEDED.md (the slug/ts-scoped path)" — remove flat form.
  • Reviewer: documentation

Additional Notes

  • Files not in diff (manual review needed): README.md (count), docs/reference/release-process.md (stale x21), .github/workflows/ci.yml (node matrix)
  • Lower-confidence findings (60-79%) consolidated into summary above; see full review reports for detailed rationales.

Recommendation: Merge only after addressing the 3 CRITICAL/HIGH blocking items (marketplace, node engine, idempotency). Issues 4-7 should be fixed while here as polish.


Claude Code | devflow code-review (reliability, architecture, security, testing, documentation, consistency, dependencies, performance, complexity, typescript, regression)

dean0x added 2 commits June 12, 2026 19:36
Address findings from the 11-reviewer code review (2026-06-12_1148):

- marketplace.json: add missing devflow-dynamic entry. Without it the
  native `claude plugin install` path fails and silently downgrades the
  whole session to file-copy install (regression + documentation, blocking)
- build-recipes.ts: clean OUTPUT_DIR of stale *.md before writing
  (idempotency, mirrors build-plugins.ts) + assert output dir writable so
  I/O errors aren't misreported as MDS compile errors (reliability)
- package.json / ci.yml: @mdscript/mds requires node>=22 — bump
  engines.node to >=22, narrow CI matrix to node 22 (matches release
  pipeline), exact-pin @mdscript/mds@0.2.0 (dependencies).
  NOTE: drops node 18/20 from CI + engines floor.
- recipes: fix dynamic-plan F4 gate-skip (use OUTDIR-scoped
  DECISIONS-NEEDED path), bound dynamic-build verification to a 3-agent
  majority panel per ADR-020 (was unbounded per-finding fan-out), clarify
  dynamic-tickets timestamp prose, add large-wave batching + untrusted-
  input notes
- plugins.ts / plugin.json: drop redundant "(optional)" suffix, normalize
  description separator (consistency)
- docs: README + release-process plugin count 21->22; register
  .devflow/docs/{tickets,waves}/ roots in CLAUDE.md + docs-framework skill
- tests: add build-recipes exit-code/compile coverage,
  declared-commands<->recipe-sources parity, and
  marketplace.json<->DEVFLOW_PLUGINS parity (the test that would have
  caught the missing marketplace entry)

Build green; 1824 tests pass.
The engine floor moved to node>=22 (dropping 18/20). Bump @types/node from ^20 to ^22 so dev type definitions match the runtime. tsc typecheck + full build green, 1824 tests pass under node 22.
@dean0x dean0x merged commit f5fc93f into main Jun 12, 2026
2 checks passed
@dean0x dean0x deleted the feat/dynamic-workflow-recipes branch June 12, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant